Author: arminw
Date: Tue May 15 15:41:31 2007
New Revision: 538346

URL: http://svn.apache.org/viewvc?view=rev&rev=538346
Log:
initial check in

Added:
    
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/PersistenceChecker.java
    
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/PersistenceCheckerOptImpl.java
    
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/PersistenceCheckerSolidImpl.java
    
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/util/ShortcutMapper.java

Added: 
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/PersistenceChecker.java
URL: 
http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/PersistenceChecker.java?view=auto&rev=538346
==============================================================================
--- 
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/PersistenceChecker.java
 (added)
+++ 
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/PersistenceChecker.java
 Tue May 15 15:41:31 2007
@@ -0,0 +1,68 @@
+package org.apache.ojb.broker;
+
+/* Copyright 2002-2007 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.lang.Object;
+
+import org.apache.ojb.broker.metadata.ClassDescriptor;
+
+/**
+ * This class provide methods to differ persistent objects from othe ones.
+ *
+ * @version $Id$
+ */
+public interface PersistenceChecker
+{
+    /**
+     * Checks if the specified object is <em>transient</em> or 
<em>persistent</em>.
+     * For objects with primary key values NOT handled by OJB (autoincrement 
of PK is
+     * not enabled, OJB can't manage PK assignment by using a sequence 
manager),
+     * it could happen that OJB needs a persistence storage roundup to check 
the object
+     * was already persisted.
+     *
+     * @param obj The persistence capable object to check.
+
+     * @return The persistence-state of the object.
+     */
+    boolean isPersistent(Object obj);
+
+    /**
+     * Checks if the specified object is <em>transient</em> or 
<em>persistent</em>.
+     * For objects with primary key values NOT handled by OJB (autoincrement 
of PK is
+     * not enabled, OJB can't manage PK assignment by using a sequence 
manager),
+     * it could happen that OJB needs a persistence storage roundup to check 
the object
+     * was already persisted.
+     *
+     * @param obj The persistence capable object to check.
+     * @param cld The [EMAIL PROTECTED] 
org.apache.ojb.broker.metadata.ClassDescriptor} of the object.
+     * @return The persistence-state of the object.
+     */
+    boolean isPersistent(Object obj, ClassDescriptor cld);
+
+    /**
+     * Checks if the specified object is <em>transient</em> or 
<em>persistent</em>.
+     * For objects with primary key values NOT handled by OJB (autoincrement 
of PK is
+     * not enabled, OJB can't manage PK assignment by using a sequence 
manager),
+     * it could happen that OJB needs a persistence storage roundup to check 
the object
+     * was already persisted.
+     *
+     * @param obj The persistence capable object to check.
+     * @param cld The [EMAIL PROTECTED] 
org.apache.ojb.broker.metadata.ClassDescriptor} of the object.
+     * @param oid The [EMAIL PROTECTED] Identity} of the object.
+     * @return The persistence-state of the object.
+     */
+    boolean isPersistent(Object obj, ClassDescriptor cld, Identity oid);
+}

Added: 
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/PersistenceCheckerOptImpl.java
URL: 
http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/PersistenceCheckerOptImpl.java?view=auto&rev=538346
==============================================================================
--- 
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/PersistenceCheckerOptImpl.java
 (added)
+++ 
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/PersistenceCheckerOptImpl.java
 Tue May 15 15:41:31 2007
@@ -0,0 +1,101 @@
+package org.apache.ojb.broker.core;
+
+/* Copyright 2002-2007 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.lang.Object;
+
+import org.apache.ojb.broker.metadata.ClassDescriptor;
+import org.apache.ojb.broker.Identity;
+import org.apache.ojb.broker.PersistenceBrokerInternal;
+import org.apache.ojb.broker.PersistenceChecker;
+import org.apache.ojb.broker.util.BrokerHelper;
+import org.apache.ojb.broker.core.proxy.ProxyFactory;
+
+/**
+ * This class checks for persistent objects using optimized checks to avoid
+ * persistence storage roundup for object existence.
+ *
+ * @version $Id$
+ */
+public class PersistenceCheckerOptImpl implements PersistenceChecker
+{
+    private PersistenceBrokerInternal broker;
+    private ProxyFactory proxyFactory;
+    private BrokerHelper brokerHelper;
+    protected boolean optimized = true;
+
+    public PersistenceCheckerOptImpl(PersistenceBrokerInternal broker)
+    {
+        this.broker = broker;
+        this.proxyFactory = broker.getProxyFactory();
+        this.brokerHelper = broker.serviceBrokerHelper();
+    }
+
+    public boolean isPersistent(final Object obj)
+    {
+        return isPersistent(obj, null, null);
+    }
+
+    public boolean isPersistent(final Object obj, final ClassDescriptor cld)
+    {
+        return isPersistent(obj, cld, null);
+    }
+
+    public boolean isPersistent(final Object obj, ClassDescriptor cld, final 
Identity oid)
+    {
+        boolean isTransient;
+        /*
+        arminw: The Identity object doesn't guarantee that method 
Identity.isPersistent()
+        reliably identify transient objects (only if the id generation is 
managed by OJB),
+        thus we have to further checks for objects without autoincrement PK 
values
+        */
+        if(oid != null)
+        {
+            // if the Identity is transient, the associated object is 
transient (not persistent) too
+            isTransient = oid.isTransient();
+            if(!isTransient)
+            {
+                isTransient = isTransientCheck(obj, cld, oid);
+            }
+        }
+        else
+        {
+            isTransient = isTransientCheck(obj, cld, oid);
+        }
+        return !isTransient;
+    }
+
+    protected boolean isTransientCheck(final Object obj, ClassDescriptor cld, 
final Identity oid)
+    {
+        boolean isTransient;
+        if(cld == null)
+        {
+            cld = broker.getClassDescriptor(proxyFactory.getRealClass(obj));
+        }
+        isTransient = brokerHelper.hasNullPKField(cld, obj);
+        /*
+         if OJB can't detect nullified PK fields and the object id generation
+         wasn't managed by OJB we can't decide if the object (with associated 
PK values)
+         is transient or persistent. In this case we have to do a DB roundup.
+        */
+        if(!isTransient && (!cld.hasAutoincrementPrimaryKey() || !optimized))
+        {
+            isTransient = broker.serviceObjectCache().lookup(oid) == null
+                    && !brokerHelper.doesExist(cld, oid, obj);
+        }
+        return isTransient;
+    }
+}

Added: 
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/PersistenceCheckerSolidImpl.java
URL: 
http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/PersistenceCheckerSolidImpl.java?view=auto&rev=538346
==============================================================================
--- 
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/PersistenceCheckerSolidImpl.java
 (added)
+++ 
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/PersistenceCheckerSolidImpl.java
 Tue May 15 15:41:31 2007
@@ -0,0 +1,34 @@
+package org.apache.ojb.broker.core;
+
+/* Copyright 2002-2007 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.ojb.broker.PersistenceBrokerInternal;
+
+/**
+ * This class checks for persistent objects using all possible checks to 
determine
+ * the persistent state of the objects - Note: This implementation can cause 
additional
+ * persistence storage roundups to detect the state of the objects.
+ *
+ * @version $Id$
+ */
+public class PersistenceCheckerSolidImpl extends PersistenceCheckerOptImpl
+{
+    public PersistenceCheckerSolidImpl(PersistenceBrokerInternal broker)
+    {
+        super(broker);
+        this.optimized = false;
+    }
+}

Added: 
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/util/ShortcutMapper.java
URL: 
http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/util/ShortcutMapper.java?view=auto&rev=538346
==============================================================================
--- 
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/util/ShortcutMapper.java
 (added)
+++ 
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/util/ShortcutMapper.java
 Tue May 15 15:41:31 2007
@@ -0,0 +1,402 @@
+package org.apache.ojb.broker.util;
+
+/* Copyright 2002-2007 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Locale;
+
+import org.apache.ojb.broker.util.sequence.SequenceManagerHighLowImpl;
+import org.apache.ojb.broker.util.sequence.SequenceManagerSeqHiLoImpl;
+import org.apache.ojb.broker.util.sequence.SequenceManagerInMemoryImpl;
+import org.apache.ojb.broker.util.sequence.SequenceManagerMSSQLGuidImpl;
+import org.apache.ojb.broker.util.sequence.SequenceManagerIdentityImpl;
+import org.apache.ojb.broker.util.sequence.SequenceManagerNextValImpl;
+import org.apache.ojb.broker.util.sequence.SequenceManagerStoredProcedureImpl;
+import org.apache.ojb.broker.util.sequence.SequenceManager;
+import org.apache.ojb.broker.util.collections.ManageableArrayList;
+import org.apache.ojb.broker.util.collections.ManageableHashMap;
+import org.apache.ojb.broker.util.collections.ManageableVector;
+import org.apache.ojb.broker.util.collections.ManageableHashSet;
+import org.apache.ojb.broker.util.collections.RemovalAwareList;
+import org.apache.ojb.broker.util.collections.RemovalAwareCollection;
+import org.apache.ojb.broker.util.collections.RemovalAwareSet;
+import org.apache.ojb.broker.util.collections.RemovalAwareVector;
+import org.apache.ojb.broker.core.PersistenceCheckerOptImpl;
+import org.apache.ojb.broker.core.PersistenceCheckerSolidImpl;
+import org.apache.ojb.broker.cache.ObjectCacheTwoLevelImpl;
+import org.apache.ojb.broker.cache.ObjectCacheDefaultImpl;
+import org.apache.ojb.broker.cache.ObjectCacheEmptyImpl;
+import org.apache.ojb.broker.cache.ObjectCachePerBrokerImpl;
+import org.apache.ojb.broker.cache.ObjectCacheJCSImpl;
+import org.apache.ojb.broker.cache.ObjectCache;
+import org.apache.ojb.broker.accesslayer.NullCheckDefaultImpl;
+import org.apache.ojb.broker.accesslayer.NullCheckRelaxedImpl;
+import org.apache.ojb.broker.accesslayer.ConnectionFactoryPooledImpl;
+import org.apache.ojb.broker.accesslayer.ConnectionFactoryDBCPImpl;
+import org.apache.ojb.broker.accesslayer.ConnectionFactoryNotPooledImpl;
+import org.apache.ojb.broker.accesslayer.ConnectionFactory;
+import org.apache.ojb.broker.accesslayer.NullCheck;
+import org.apache.ojb.broker.accesslayer.RowReaderDefaultImpl;
+import org.apache.ojb.broker.accesslayer.RowReader;
+import org.apache.ojb.broker.metadata.fieldaccess.PersistentFieldAutoProxyImpl;
+import org.apache.ojb.broker.metadata.fieldaccess.PersistentFieldDirectImpl;
+import org.apache.ojb.broker.metadata.fieldaccess.PersistentFieldCGLibImpl;
+import 
org.apache.ojb.broker.metadata.fieldaccess.PersistentFieldPrivilegedImpl;
+import 
org.apache.ojb.broker.metadata.fieldaccess.PersistentFieldIntrospectorImpl;
+import org.apache.ojb.broker.metadata.fieldaccess.PersistentFieldDynaBeanImpl;
+import org.apache.ojb.broker.metadata.fieldaccess.PersistentField;
+import org.apache.ojb.broker.transaction.tm.JBossTransactionManagerFactory;
+import org.apache.ojb.broker.transaction.tm.WebSphereTransactionManagerFactory;
+import org.apache.ojb.broker.transaction.tm.WeblogicTransactionManagerFactory;
+import org.apache.ojb.broker.transaction.tm.OrionTransactionManagerFactory;
+import org.apache.ojb.broker.transaction.tm.SunOneTransactionManagerFactory;
+import org.apache.ojb.broker.transaction.tm.JOnASTransactionManagerFactory;
+import org.apache.ojb.broker.transaction.tm.OC4JTransactionManagerFactory;
+import org.apache.ojb.broker.transaction.tm.ResinTransactionManagerFactory;
+import org.apache.ojb.broker.transaction.tm.JRunTransactionManagerFactory;
+import org.apache.ojb.broker.transaction.tm.TransactionManagerFactory;
+import org.apache.ojb.broker.PersistenceChecker;
+import org.apache.ojb.broker.ManageableCollection;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.ClassUtils;
+
+/**
+ * This class contains specific shortcut name mappings for many classes 
shipped with OJB and the ability
+ * to resolve shortcut names based on a naming convention.
+ *
+ * @version $Id$
+ */
+public class ShortcutMapper
+{
+    private static Map allShortcutMappings = new HashMap();
+
+    private static void addMapping(Mapping mapping)
+    {
+        allShortcutMappings.put(mapping.targetInterface, mapping);
+    }
+
+    static
+    {
+        Mapping mapping = new Mapping(ObjectCache.class)
+                .add("twolevel", ObjectCacheTwoLevelImpl.class)
+                .add("default", ObjectCacheDefaultImpl.class)
+                .add("empty", ObjectCacheEmptyImpl.class)
+                .add("session", ObjectCachePerBrokerImpl.class)
+                .add("jcs", ObjectCacheJCSImpl.class);
+        addMapping(mapping);
+
+        mapping = new Mapping(ObjectCacheTwoLevelImpl.CopyStrategy.class)
+                .add("default", 
ObjectCacheTwoLevelImpl.CopyStrategyImpl.class);
+        addMapping(mapping);
+
+        mapping = new Mapping(ManageableCollection.class)
+                .add("collection", ManageableArrayList.class)
+                .add("list", ManageableArrayList.class)
+                .add("map", ManageableHashMap.class)
+                .add("vector", ManageableVector.class)
+                .add("set", ManageableHashSet.class)
+                .add("removalcollection", RemovalAwareCollection.class)
+                .add("removal.collection", RemovalAwareCollection.class)
+                .add("removallist", RemovalAwareList.class)
+                .add("removal.list", RemovalAwareList.class)
+                .add("removalset", RemovalAwareSet.class)
+                .add("removal.set", RemovalAwareSet.class)
+                .add("removalvector", RemovalAwareVector.class)
+                .add("removal.vector", RemovalAwareVector.class);
+        addMapping(mapping);
+
+        mapping = new Mapping(PersistentField.class)
+                .add("auto", PersistentFieldAutoProxyImpl.class)
+                .add("direct", PersistentFieldDirectImpl.class)
+                .add("cglib", PersistentFieldCGLibImpl.class)
+                .add("privileged", PersistentFieldPrivilegedImpl.class)
+                .add("introspector", PersistentFieldIntrospectorImpl.class)
+                .add("dynabean", PersistentFieldDynaBeanImpl.class);
+        addMapping(mapping);
+
+        mapping = new Mapping(TransactionManagerFactory.class)
+                .add("jboss", JBossTransactionManagerFactory.class)
+                .add("websphere", WebSphereTransactionManagerFactory.class)
+                .add("weblogic", WeblogicTransactionManagerFactory.class)
+                .add("orion", OrionTransactionManagerFactory.class)
+                .add("sunone", SunOneTransactionManagerFactory.class)
+                .add("jonas", JOnASTransactionManagerFactory.class)
+                .add("oc4j", OC4JTransactionManagerFactory.class)
+                .add("resin", ResinTransactionManagerFactory.class)
+                .add("jrun", JRunTransactionManagerFactory.class);
+        addMapping(mapping);
+
+        mapping = new Mapping(ConnectionFactory.class)
+                .add("pooled", ConnectionFactoryPooledImpl.class)
+                .add("dbcp", ConnectionFactoryDBCPImpl.class)
+                .add("none", ConnectionFactoryNotPooledImpl.class)
+                .add("notpooled", ConnectionFactoryNotPooledImpl.class);
+        addMapping(mapping);
+
+        mapping = new Mapping(NullCheck.class)
+                .add("default", NullCheckDefaultImpl.class)
+                .add("relaxed", NullCheckRelaxedImpl.class);
+        addMapping(mapping);
+
+        mapping = new Mapping(RowReader.class)
+                .add("default", RowReaderDefaultImpl.class);
+        addMapping(mapping);
+
+        mapping = new Mapping(SequenceManager.class)
+                .add("hilo", SequenceManagerHighLowImpl.class)
+                .add("seqhilo", SequenceManagerSeqHiLoImpl.class)
+                .add("memory", SequenceManagerInMemoryImpl.class)
+                .add("msguid", SequenceManagerMSSQLGuidImpl.class)
+                .add("identity", SequenceManagerIdentityImpl.class)
+                .add("sequence", SequenceManagerNextValImpl.class)
+                .add("procedure", SequenceManagerStoredProcedureImpl.class);
+        addMapping(mapping);
+
+        mapping = new Mapping(PersistenceChecker.class)
+                .add("optimized", PersistenceCheckerOptImpl.class)
+                .add("opt", PersistenceCheckerOptImpl.class)
+                .add("solid", PersistenceCheckerSolidImpl.class);
+        addMapping(mapping);
+
+        /*
+        mapping = new Mapping(.class)
+                .add()
+                .add();
+        addMapping(mapping);
+        */
+    }
+
+    /**
+     * This methods tries to resolve an implementation class of the specified
+     * interface class. Many specific mappings are provided by this class, e.g
+     * <p>
+     * ShortcutMapper.resolve("memory", SequenceManager.class)
+     * </p>
+     * returns the class name 
<code>org.apache.ojb.broker.util.sequence.SequenceManagerInMemoryImpl</code>.
+     * <p>
+     * But also automatic resolving of shortcut names is supported if the 
implementation class
+     * use one of the following naming convention:
+     * </p>
+     * <p>
+     * interface name: <code>org.test.MyTest</code> OR 
<code>org.test.IMyTest</code>
+     * <br/>
+     * shortcut name: foo
+     * </p>
+     * <p>
+     * Then the implementation class has to be named
+     * <p/>
+     * <ul>
+     * <li>org.test.MyTestFoo</li>
+     * <li>org.test.MyTestFooImpl</li>
+     * <li>org.test.FooMyTest</li>
+     * <li>org.test.FooMyTestImpl</li>
+     * </ul>
+     *
+     * @param shortcut The shortcut name of the implementation class.
+     * @param targetInterface The interface of the implementation class.
+     * @param defaultImplClass The default implementation class to use if no 
match can be found
+     * or <em>null</em>.
+     * @return The associated class name of the specified shortcut name or
+     *         the specified shortcut name if no matching class can be found 
or the specified name
+     *         is already a matching class name.
+     */
+    public static String resolveName(String shortcut, Class targetInterface, 
Class defaultImplClass)
+    {
+        Class result = resolve(shortcut, targetInterface, defaultImplClass);
+        return result != null ? result.getName() : shortcut;
+    }
+
+    /**
+     * Convenience method for [EMAIL PROTECTED] #resolveName(String, Class, 
Class)}.
+     *
+     * @param shortcut The shortcut name of the implementation class.
+     * @param targetInterface The interface of the implementation class.
+     * @return The associated class name of the specified shortcut name or
+     *         the specified shortcut name if no matching class can be found 
or the specified name
+     *         is already a matching class name.
+     */
+    public static String resolveName(String shortcut, Class targetInterface)
+    {
+        return resolveName(shortcut, targetInterface, null);
+    }
+
+    /**
+     * Convenience method for [EMAIL PROTECTED] #resolve(String, Class, 
Class)}.
+     *
+     * @param shortcut The shortcut name of the implementation class.
+     * @param targetInterface The interface of the implementation class.
+     * @return The associated class of the specified shortcut name or
+     *         <em>null</em> if no matching class can be found.
+     */
+    public static Class resolve(String shortcut, Class targetInterface)
+    {
+        return resolve(shortcut, targetInterface, null);
+    }
+
+    /**
+     * This methods tries to resolve an implementation class of the specified
+     * interface class. Many specific mappings are provided by this class, e.g
+     * <p>
+     * ShortcutMapper.resolve("memory", SequenceManager.class)
+     * </p>
+     * returns the class name 
<code>org.apache.ojb.broker.util.sequence.SequenceManagerInMemoryImpl</code>.
+     * <p>
+     * But also automatic resolving of shortcut names is supported if the 
implementation class
+     * use one of the following naming convention:
+     * </p>
+     * <p>
+     * interface name: <code>org.test.MyTest</code> OR 
<code>org.test.IMyTest</code>
+     * <br/>
+     * shortcut name: foo
+     * </p>
+     * <p>
+     * Then the implementation class has to be named
+     * <p/>
+     * <ul>
+     * <li>org.test.MyTestFoo</li>
+     * <li>org.test.MyTestFooImpl</li>
+     * <li>org.test.FooMyTest</li>
+     * <li>org.test.FooMyTestImpl</li>
+     * </ul>
+     *
+     * @param shortcut The shortcut name of the implementation class.
+     * @param targetInterface The interface of the implementation class.
+     * @param defaultImplClass The default implementation class to use if no 
match can be found
+     * or <em>null</em>.
+     * @return The associated class of the specified shortcut name or
+     *         <em>null</em> if no matching class can be found.
+     */
+    public static Class resolve(String shortcut, Class targetInterface, Class 
defaultImplClass)
+    {
+        if(shortcut == null)
+        {
+            return defaultImplClass;
+        }
+
+        Class result = null;
+        if(targetInterface != null)
+        {
+            Mapping mapping = (Mapping) 
allShortcutMappings.get(targetInterface);
+            if(mapping != null)
+            {
+                result = mapping.resolve(shortcut.toLowerCase(Locale.ENGLISH));
+            }
+        }
+
+        if(result == null)
+        {
+            try
+            {
+                result = ClassHelper.getClass(shortcut);
+            }
+            catch(ClassNotFoundException e)
+            {/*ignore*/}
+        }
+        if(result == null && targetInterface != null)
+        {
+            String packageName = ClassUtils.getPackageName(targetInterface);
+            String shortInterfaceName = 
ClassUtils.getShortClassName(targetInterface);
+            result = genericResolve(shortcut, packageName, shortInterfaceName);
+            if(result == null && StringUtils.indexOf(shortInterfaceName, 'I') 
== 0)
+            {
+                String shorted = 
StringUtils.capitalize(StringUtils.substring(shortInterfaceName, 1));
+                result = genericResolve(shortcut, packageName, shorted);
+            }
+        }
+        if(result != null)
+        {
+            result = result.isInterface() ? null : result;
+        }
+//        if(result != null && !result.getName().equals(shortcut))
+//        {
+//            System.out.println("## " + shortcut + " ==> " + result);
+//        }
+        return result == null ? defaultImplClass : result;
+    }
+
+    private static Class genericResolve(String shortcut, String packageName, 
String shortInterfaceName)
+    {
+        Class result = null;
+        String className = packageName + shortInterfaceName + 
StringUtils.capitalize(shortcut) + "Impl";
+        try
+        {
+            result = ClassHelper.getClass(className, false);
+        }
+        catch(ClassNotFoundException e)
+        {/*ignore*/}
+
+        if(result == null)
+        {
+            className = packageName + shortInterfaceName + 
StringUtils.capitalize(shortcut);
+            try
+            {
+                result = ClassHelper.getClass(className, false);
+            }
+            catch(ClassNotFoundException e)
+            {/*ignore*/}
+        }
+
+        if(result == null)
+        {
+            className = packageName + "." + StringUtils.capitalize(shortcut) + 
shortInterfaceName;
+            try
+            {
+                result = ClassHelper.getClass(className, false);
+            }
+            catch(ClassNotFoundException e)
+            {/*ignore*/}
+
+            if(result == null)
+            {
+                className = className + "Impl";
+                try
+                {
+                    result = ClassHelper.getClass(className, false);
+                }
+                catch(ClassNotFoundException e)
+                {/*ignore*/}
+            }
+        }
+        if(result != null)
+        {
+            result = result.isInterface() ? null : result;
+        }
+        return result;
+    }
+
+    private static class Mapping
+    {
+        Class targetInterface;
+        Map shortcutMap = new HashMap();
+
+        public Mapping(Class targetInterface)
+        {
+            this.targetInterface = targetInterface;
+        }
+
+        Mapping add(String shortcut, Class resolvedClass)
+        {
+            shortcutMap.put(shortcut, resolvedClass);
+            return this;
+        }
+
+        Class resolve(String shortcut)
+        {
+            return (Class) shortcutMap.get(shortcut);
+        }
+    }
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to