Index: xml/src/main/java/org/exolab/castor/xml/util/JDOClassDescriptorResolverImpl.java
===================================================================
--- xml/src/main/java/org/exolab/castor/xml/util/JDOClassDescriptorResolverImpl.java (revision 7639)
+++ xml/src/main/java/org/exolab/castor/xml/util/JDOClassDescriptorResolverImpl.java (working copy)
@@ -1,26 +1,63 @@
package org.exolab.castor.xml.util;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
import java.util.Map;
import org.exolab.castor.mapping.ClassDescriptor;
import org.exolab.castor.mapping.MappingLoader;
import org.exolab.castor.xml.ClassDescriptorResolver;
import org.exolab.castor.xml.ResolverException;
+import org.exolab.castor.xml.util.resolvers.ResolveHelpers;
public class JDOClassDescriptorResolverImpl implements ClassDescriptorResolver {
- private Map _classToClassDescriptors = new HashMap();
+ /**
+ * File name prefix used for JDO-specific descriptor classes.
+ */
+ private static final String JDO_DESCRIPTOR_PREFIX = "JDO";
+
+ /**
+ * File name suffix used for JDO-specific descriptor classes.
+ */
+ private static final String JDO_DESCRIPTOR_SUFFIX = "Descriptor";
+
+ /**
+ * Package name of the sub-package where descriptors can be found.
+ */
+ private static final String JDO_DESCRIPTOR_PACKAGE = "descriptors";
+
+ /**
+ * A key ({@link Class}) value ({@link ClassDescriptor})
+ * pair to cache already resolved jdo class descriptors.
+ */
+ private Map _classDescriptorCache = new HashMap();
+
private MappingLoader _mappingLoader;
+ /**
+ * List of manually added domain Classes.
+ */
+ private List _classes = new LinkedList();
+
public JDOClassDescriptorResolverImpl() {
super();
}
/**
- * Returns the ClassDescriptor for the given class
- *
- * @param type the Class to find the ClassDescriptor for
+ * Returns the ClassDescriptor for the given class using the following
+ * strategy.
+ *
+ * - Lookup the class descriptor cache
+ *
- Call {@link JDOClassDescriptorResolverImpl#loadClassDescriptor(Class)}
+ *
- Ask the {@link MappingLoader}
+ *
+ *
+ * @param type
+ * the Class to find the ClassDescriptor for
* @return the ClassDescriptor for the given class
*/
public ClassDescriptor resolve(Class type) throws ResolverException {
@@ -28,43 +65,97 @@
return null;
}
+ ClassDescriptor classDesc;
+
// TODO: use ClassDescriptor instead
- ClassDescriptor classDesc = (ClassDescriptor) _classToClassDescriptors.get(type);
+ classDesc = (ClassDescriptor) _classDescriptorCache.get(type);
+ if (classDesc != null) {
+ return classDesc;
+ }
+ classDesc = loadClassDescriptor(type);
if (classDesc != null) {
return classDesc;
}
- // -- check mapping loader first
+ // -- check mapping
if (_mappingLoader != null) {
classDesc = _mappingLoader.getDescriptor(type.getName());
if (classDesc != null) {
- _classToClassDescriptors.put(type, classDesc);
+ _classDescriptorCache.put(type, classDesc);
return classDesc;
}
}
// TODO: consider for future extensions
-// String pkgName = getPackageName(type.getName());
-//
-// //-- check package mapping
-// Mapping mapping = loadPackageMapping(pkgName, type.getClassLoader());
-// if (mapping != null) {
-// try {
-// MappingLoader mappingLoader = mapping.getResolver(BindingType.JDO);
-// classDesc = mappingLoader.getDescriptor(type);
-// }
-// catch(MappingException mx) {}
-// if (classDesc != null) {
-// associate(type, classDesc);
-// return classDesc;
-// }
-// }
+ // String pkgName = getPackageName(type.getName());
+ //
+ // //-- check package mapping
+ // Mapping mapping = loadPackageMapping(pkgName, type.getClassLoader());
+ // if (mapping != null) {
+ // try {
+ // MappingLoader mappingLoader = mapping.getResolver(BindingType.JDO);
+ // classDesc = mappingLoader.getDescriptor(type);
+ // }
+ // catch(MappingException mx) {}
+ // if (classDesc != null) {
+ // associate(type, classDesc);
+ // return classDesc;
+ // }
+ // }
return classDesc;
} // -- resolve
+ /**
+ * Tries to load a {@link ClassDescriptor} for the given type
+ * from the filesystem using a {@link ClassLoader} by
+ *
+ * - Lookup the same package
+ * - Lookup the subpackage
descriptors
+ *
.
+ *
+ * @param type to lookup the descriptor for.
+ * @return an instance of ClassDescriptor if found. null if not.
+ */
+ private ClassDescriptor loadClassDescriptor(final Class type) {
+ ClassDescriptor classDesc = null;
+ ClassLoader classLoader = type.getClassLoader();
+ StringBuffer descriptorClassName = new StringBuffer(type.getName());
+ descriptorClassName.append(JDO_DESCRIPTOR_PREFIX);
+ descriptorClassName.append(JDO_DESCRIPTOR_SUFFIX);
+ // Try to load descriptor in the same package
+ Class descriptorClass = ResolveHelpers.loadClass(
+ classLoader, descriptorClassName.toString());
+
+ // If descriptor was not found, lookup the descriptor package
+ if (descriptorClass == null) {
+ int offset = descriptorClassName.lastIndexOf(".");
+ if (offset != -1) {
+ descriptorClassName.insert(offset , ".");
+ descriptorClassName.insert(offset + 1, JDO_DESCRIPTOR_PACKAGE);
+ descriptorClass = ResolveHelpers.loadClass(
+ classLoader, descriptorClassName.toString());
+ }
+ }
+
+ // Descriptor was found, instantiate and return it
+ if (descriptorClass != null) {
+ try {
+ classDesc = (ClassDescriptor) descriptorClass.newInstance();
+ // Put descriptor into cache
+ _classDescriptorCache.put(type.getName(), classDesc);
+ return classDesc;
+ } catch (InstantiationException e) {
+ new RuntimeException(e.getMessage());
+ } catch (IllegalAccessException e) {
+ new RuntimeException(e.getMessage());
+ }
+ }
+ return classDesc;
+ }
+
public MappingLoader getMappingLoader() {
return _mappingLoader;
}
@@ -73,4 +164,24 @@
this._mappingLoader = mappingLoader;
}
+ public void addClass(Class domainClass) {
+ _classes.add(domainClass);
+ }
+
+ /**
+ * Returns an iterator over all the known descriptors in the original order they have been
+ * added. Each element is of type {@link ClassDescriptor}.
+ */
+ public Iterator descriptorIterator() {
+ List allDescriptors = new ArrayList();
+ allDescriptors.addAll(_mappingLoader.getDescriptors());
+ for (Iterator iterator = _classes.iterator(); iterator.hasNext();) {
+ allDescriptors.add(loadClassDescriptor((Class) iterator.next()));
+ }
+ return allDescriptors.iterator();
+ }
+
+ public ClassLoader getClassLoader() {
+ return _mappingLoader.getClassLoader();
+ }
}
Index: xml/src/main/java/org/exolab/castor/mapping/MappingLoader.java
===================================================================
--- xml/src/main/java/org/exolab/castor/mapping/MappingLoader.java (revision 7639)
+++ xml/src/main/java/org/exolab/castor/mapping/MappingLoader.java (working copy)
@@ -45,6 +45,7 @@
package org.exolab.castor.mapping;
import java.util.Iterator;
+import java.util.List;
import org.castor.mapping.BindingType;
@@ -89,4 +90,10 @@
* added. Each element is of type {@link ClassDescriptor}.
*/
Iterator descriptorIterator();
+
+ /**
+ * Returns a List of {@link ClassDescriptor}s of all known descriptors.
+ * @return List of {@link ClassDescriptor}
+ */
+ List getDescriptors();
}
Index: xml/src/main/java/org/exolab/castor/mapping/loader/AbstractMappingLoader2.java
===================================================================
--- xml/src/main/java/org/exolab/castor/mapping/loader/AbstractMappingLoader2.java (revision 7639)
+++ xml/src/main/java/org/exolab/castor/mapping/loader/AbstractMappingLoader2.java (working copy)
@@ -129,6 +129,10 @@
return _descriptors.iterator();
}
+ public final List getDescriptors() {
+ return _descriptors;
+ }
+
//--------------------------------------------------------------------------
/**