Index: C:/Java/castor-4/src/doc/release-notes.xml =================================================================== --- C:/Java/castor-4/src/doc/release-notes.xml (revision 6773) +++ C:/Java/castor-4/src/doc/release-notes.xml (working copy) @@ -65,7 +65,7 @@
If you are using the Castor code generator to generate code
- from schemas that use xsd:import, whether or not code
+ from schemas that use xsd:import, whether or not code
was generated from the imported schemas was controlled by a
combination of switches. Now it is controlled only by the
"-generateImportedSchemas" option of SourceGeneratorMain, the
@@ -76,6 +76,26 @@
null
* if named field does not exist.
*
- * @param name The name of the field to return
- * @return The field if it exists, otherwise null.
+ * @param name Name of the field to return.
+ * @return Field if it exists, otherwise null.
*/
public JDOFieldDescriptor getField(String name) {
- JDOFieldDescriptor field = null;
- for (int i = 0 ; i < _fields.length ; ++i) {
- if ((_fields[i] instanceof JDOFieldDescriptor)
- && (_fields[i].getFieldName().equals(name))) {
+ FieldDescriptor[] fields = getFields();
+ for (int i = 0 ; i < fields.length ; ++i) {
+ FieldDescriptor field = fields[i];
+ if ((field instanceof JDOFieldDescriptor)
+ && (field.getFieldName().equals(name))) {
- field = (JDOFieldDescriptor) _fields[i];
- break;
+ return (JDOFieldDescriptor) field;
}
}
- if (field == null) {
- for (int i = 0 ; i < _identities.length ; ++i) {
- if ((_identities[i] instanceof JDOFieldDescriptor)
- && (_identities[i].getFieldName().equals(name))) {
-
- field = (JDOFieldDescriptor) _identities[i];
- }
+ FieldDescriptor[] identities = getIdentities();
+ for (int i = 0 ; i < identities.length ; ++i) {
+ FieldDescriptor field = identities[i];
+ if ((field instanceof JDOFieldDescriptor)
+ && (field.getFieldName().equals(name))) {
+
+ return (JDOFieldDescriptor) field;
}
}
- return field;
+ return null;
}
- /**
- * Returns the key generator specified for this class.
- *
- * @return The key generator descriptor
- */
- public KeyGeneratorDescriptor getKeyGeneratorDescriptor() {
- return _keyGenDesc;
- }
+ //-----------------------------------------------------------------------------------
/**
- * @return The names of columns that the identity consists of.
+ * {@inheritDoc}
*/
- public String[] getIdentityColumnNames() {
- return _idnames;
- }
-
public String toString() {
- return super.toString() + " AS " + _tableName;
+ return getJavaClass().getName() + " AS " + _tableName;
}
- /**
- * Returns the OQL statement from a named query instance associated with the given name
- * @param name Name of the named query
- * @return the OQL statement from a named query instance associated with the given name
- */
- public String getNamedQuery(String name) {
- String namedQuery = (String) _namedQueries.get(name);
- return namedQuery;
- }
-
- /**
- * Adds a new named query for the given name for future usage (through Database.getNamedQuery()).
- * @param name Name of the named query.
- * @param namedQuery Named query to be associated with the given name
- * @throws QueryException If there's already a named query for the given name
- */
- public void addNamedQuery(final String name, final String namedQuery) throws QueryException {
- if (_namedQueries.containsKey(name)) {
- throw new QueryException ("Duplicate entry for named query " + name);
- }
- _namedQueries.put(name, namedQuery);
- }
+ //-----------------------------------------------------------------------------------
}
Index: C:/Java/castor-4/src/main/java/org/exolab/castor/jdo/engine/JDOMappingLoader.java
===================================================================
--- C:/Java/castor-4/src/main/java/org/exolab/castor/jdo/engine/JDOMappingLoader.java (revision 6773)
+++ C:/Java/castor-4/src/main/java/org/exolab/castor/jdo/engine/JDOMappingLoader.java (working copy)
@@ -44,6 +44,11 @@
*/
package org.exolab.castor.jdo.engine;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.castor.cache.Cache;
+import org.castor.cache.simple.CountLimited;
+import org.castor.cache.simple.TimeLimited;
import org.castor.jdo.engine.SQLTypeInfos;
import org.castor.jdo.engine.SQLTypeConverters;
import org.castor.jdo.engine.SQLTypeConverters.Convertor;
@@ -49,9 +54,11 @@
import org.castor.jdo.engine.SQLTypeConverters.Convertor;
import org.castor.mapping.BindingType;
import org.castor.util.Messages;
-import org.exolab.castor.jdo.QueryException;
+import org.exolab.castor.jdo.TimeStampable;
import org.exolab.castor.mapping.*;
+import org.exolab.castor.mapping.loader.AbstractFieldDescriptor;
import org.exolab.castor.mapping.loader.CollectionHandlers;
+import org.exolab.castor.mapping.loader.FieldDescriptorImpl;
import org.exolab.castor.mapping.loader.FieldHandlerFriend;
import org.exolab.castor.mapping.loader.FieldHandlerImpl;
import org.exolab.castor.mapping.loader.AbstractMappingLoader;
@@ -65,8 +72,12 @@
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Enumeration;
-import java.util.Hashtable;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
import java.util.Properties;
+import java.util.Set;
/**
* A JDO implementation of mapping helper. Creates JDO class descriptors
@@ -72,7 +83,8 @@
* A JDO implementation of mapping helper. Creates JDO class descriptors
* from the mapping file.
*
- * @author Assaf Arkin
+ * @author Assaf Arkin
+ * @author Ralf Joachim
* @version $Revision$ $Date: 2006-04-13 07:37:49 -0600 (Thu, 13 Apr 2006) $
*/
public final class JDOMappingLoader extends AbstractMappingLoader {
@@ -78,6 +90,10 @@
public final class JDOMappingLoader extends AbstractMappingLoader {
//-----------------------------------------------------------------------------------
+ /** The Jakarta Commons
+ * Logging instance used for all logging. */
+ private static final Log LOG = LogFactory.getLog(JDOMappingLoader.class);
+
/** Separators between type name and parameter, e.g. "char[01]". */
private static final char LEFT_PARAM_SEPARATOR = '[';
@@ -84,6 +100,8 @@
/** Separators after parameter, e.g. "char[01]". */
private static final char RIGHT_PARAM_SEPARATOR = ']';
+ //-----------------------------------------------------------------------------------
+
/**
* Extracts parameter for type convertor from the SQL type definition of the
* form "SQL_TYPE_NAME[PARAMETER]". If the type is not parameterized, returns
@@ -115,109 +133,301 @@
//-----------------------------------------------------------------------------------
+ /** Map of key generator descriptors associated by their name. */
+ private final Map _keyGenDescs = new HashMap();
+ /** Used by the constructor for creating key generators. Each database must have a
+ * proprietary KeyGeneratorRegistry instance, otherwise it is impossible to
+ * implement stateful key generator algorithms like HIGH-LOW correctly. */
+ private final KeyGeneratorRegistry _keyGenReg = new KeyGeneratorRegistry();
- /**
- * Used by the constructor for creating key generators.
- * See {@link #loadMapping}.
- */
- private Hashtable _keyGenDefs = new Hashtable();
+ /** Set of names of all named queries to identify duplicate names. */
+ private final Set _queryNames = new HashSet();
+
+ /** The JDO PersistenceFactory (aka BaseFactory) is used for adjusting SQL type for
+ * the given database. */
+ private BaseFactory _factory;
+ //-----------------------------------------------------------------------------------
- /**
- * Used by the constructor for creating key generators.
- * See {@link #loadMapping}.
- */
- private Hashtable _keyGenDescs = new Hashtable();
+ public JDOMappingLoader(ClassLoader loader) {
+ super(loader);
+ }
+ //-----------------------------------------------------------------------------------
+
/**
- * Used to locally register all loaded queries
- * to detect duplicated query names.
- * See {@link #createDescriptor(ClassMapping)}.
- */
- private Hashtable _namedQueries = new Hashtable();
+ * {@inheritDoc}
+ */
+ public BindingType getBindingType() { return BindingType.JDO; }
+ //-----------------------------------------------------------------------------------
/**
- * The JDO PersistenceFactory (aka BaseFactory) is used for adjusting
- * SQL type for the given database.
+ * {@inheritDoc}
*/
- private BaseFactory _factory;
-
+ public void loadMapping(final MappingRoot mapping, final Object param)
+ throws MappingException {
+ if (loadMapping()) {
+ _factory = (BaseFactory) param;
+
+ createKeyGenDescriptors(mapping);
+ createClassDescriptors(mapping);
+ }
+ }
+
/**
- * Used by the constructor for creating key generators.
- * Each database must have a proprietary KeyGeneratorRegistry instance
- * Otherwise it is impossible to implement correctly stateful
- * key generator algorithms like HIGH-LOW.
- * See {@link #loadMapping}.
+ * Load key generator definitions, check for duplicate definitions and convert them
+ * to key generator descriptors.
+ *
+ * @param mapping Mapping to load key generator defintions from.
+ * @throws MappingException If mapping contains more then one key generator
+ * definition with same name.
*/
- private KeyGeneratorRegistry _keyGenReg = new KeyGeneratorRegistry();
-
-
- public JDOMappingLoader(ClassLoader loader) {
- super(loader);
+ private void createKeyGenDescriptors(final MappingRoot mapping)
+ throws MappingException {
+ Enumeration enumeration = mapping.enumerateKeyGeneratorDef();
+ while (enumeration.hasMoreElements()) {
+ KeyGeneratorDef def = (KeyGeneratorDef) enumeration.nextElement();
+
+ String name = def.getAlias();
+ if (name == null) { name = def.getName(); }
+
+ KeyGeneratorDescriptor desc = (KeyGeneratorDescriptor) _keyGenDescs.get(name);
+ if (desc != null) {
+ throw new MappingException(Messages.format("mapping.dupKeyGen", name));
+ }
+
+ Properties params = new Properties();
+
+ Enumeration enumerateParam = def.enumerateParam();
+ while (enumerateParam.hasMoreElements()) {
+ Param par = (Param) enumerateParam.nextElement();
+ params.put(par.getName(), par.getValue());
+ }
+
+ desc = new KeyGeneratorDescriptor(
+ name, def.getName(), params, _keyGenReg);
+
+ _keyGenDescs.put(name, desc);
+ }
}
- public BindingType getBindingType() { return BindingType.JDO; }
+ //-----------------------------------------------------------------------------------
- protected ClassDescriptor createDescriptor(final ClassMapping clsMap)
+ protected final ClassDescriptor createClassDescriptor(final ClassMapping clsMap)
throws MappingException {
- ClassDescriptor clsDesc;
- String keyGenName;
- KeyGeneratorDescriptor keyGenDesc;
-
- // If no SQL information for class, ignore it. JDO only
- // supports JDO class descriptors.
+ // If there is no SQL information for class, ignore it.
if ((clsMap.getMapTo() == null) || (clsMap.getMapTo().getTable() == null)) {
- return AbstractMappingLoader.NO_DESCRIPTOR;
+ LOG.info(Messages.format("mapping.ignoringMapping", clsMap.getName()));
+ return null;
}
- // See if we have a compiled descriptor.
- clsDesc = null;
- if ((clsDesc != null) && (clsDesc instanceof JDOClassDescriptor)) {
- return clsDesc;
+ // Create the class descriptor.
+ JDOClassDescriptor clsDesc = new JDOClassDescriptor();
+
+ // Set reference to class mapping on class descriptor.
+ clsDesc.setMapping(clsMap);
+
+ // Obtain the Java class.
+ Class javaClass = resolveType(clsMap.getName());
+ if (!Types.isConstructable(javaClass, true)) {
+ throw new MappingException(
+ "mapping.classNotConstructable", javaClass.getName());
+ }
+ clsDesc.setJavaClass(javaClass);
+
+ // If this class extends another class, we need to obtain the extended
+ // class and make sure this class indeed extends it.
+ ClassDescriptor extDesc = getExtended(clsMap, javaClass);
+ if (extDesc != null) {
+ if (!(extDesc instanceof JDOClassDescriptor)) {
+ throw new IllegalArgumentException(
+ "Extended class does not have a JDO descriptor");
+ }
+
+ ((JDOClassDescriptor) extDesc).addExtended(clsDesc);
}
+ clsDesc.setExtends(extDesc);
+
+ // If this class depends on another class, obtain the depended class.
+ clsDesc.setDepends(getDepended(clsMap, javaClass));
+
+ // Create all field descriptors.
+ AbstractFieldDescriptor[] allFields = createFieldDescriptors(clsMap, javaClass);
- // Use super class to create class descriptor. Field descriptors will be
- // generated only for supported fields, see createFieldDesc later on.
- // This class may only extend a JDO class, otherwise no mapping will be
- // found for the parent.
- clsDesc = super.createDescriptor(clsMap);
+ // Make sure there are no two fields with the same name.
+ checkFieldNameDuplicates(allFields, javaClass);
- // JDO descriptor must include an identity field, the identity field
- // is either a field, or a container field containing only JDO fields.
- // If the identity field is not a JDO field, it will be cleaned later
- // on (we need the descriptor for relations mapping).
- if (clsDesc.getIdentity() == null) {
- throw new MappingException("mapping.noIdentity", clsDesc.getJavaClass().getName());
+ // Set class descriptor containing the field
+ for (int i = 0; i < allFields.length; i++) {
+ allFields[i].setContainingClassDescriptor(clsDesc);
}
+
+ // Identify identity and normal fields. Note that order must be preserved.
+ List fieldList = new ArrayList(allFields.length);
+ List idList = new ArrayList();
+ if (extDesc == null) {
+ // Sort fields into 2 lists based on identity definition of field.
+ for (int i = 0; i < allFields.length; i++) {
+ if (!allFields[i].isIdentity()) {
+ fieldList.add(allFields[i]);
+ } else {
+ idList.add(allFields[i]);
+ }
+ }
+
+ if (idList.size() == 0) {
+ // Found no identities based on identity definition of field.
+ // Try to find identities based on identity definition on class.
+ String[] idNames = clsMap.getIdentity();
+ if ((idNames == null) || (idNames.length == 0)) {
+ // There are also no identity definitions on class.
+ throw new MappingException("mapping.noIdentity", javaClass.getName());
+ }
+
+ FieldDescriptor identity;
+ for (int i = 0; i < idNames.length; i++) {
+ identity = findIdentityByName(fieldList, idNames[i], javaClass);
+ if (identity != null) {
+ idList.add(identity);
+ } else {
+ throw new MappingException("mapping.identityMissing",
+ idNames[i], javaClass.getName());
+ }
+ }
+ }
+ } else {
+ // Add all fields of extending class to field list.
+ for (int i = 0; i < allFields.length; i++) { fieldList.add(allFields[i]); }
+
+ // Add all identities of extended class to identity list.
+ FieldDescriptor[] extIds = ((JDOClassDescriptor) extDesc).getIdentities();
+ for (int i = 0; i < extIds.length; i++) { idList.add(extIds[i]); }
+
+ // Search redefined identities in extending class.
+ FieldDescriptor identity;
+ for (int i = 0; i < idList.size(); i++) {
+ String idName = ((FieldDescriptor) idList.get(i)).getFieldName();
+ identity = findIdentityByName(fieldList, idName, javaClass);
+ if (identity != null) { idList.set(i, identity); }
+ }
+ }
+
+ // Set identities on class descriptor.
+ FieldDescriptor[] ids = new FieldDescriptor[idList.size()];
+ clsDesc.setIdentities((FieldDescriptor[]) idList.toArray(ids));
- // create a key generator descriptor
- keyGenName = clsMap.getKeyGenerator();
- keyGenDesc = null;
- if (keyGenName != null) {
- String keyGenFactoryName;
- KeyGeneratorDef keyGenDef;
- Enumeration enumeration;
- Properties params;
+ // Set fields on class descriptor.
+ FieldDescriptor[] fields = new FieldDescriptor[fieldList.size()];
+ clsDesc.setFields((FieldDescriptor[]) fieldList.toArray(fields));
+
+ clsDesc.setTableName(clsMap.getMapTo().getTable());
+
+ extractAndSetAccessMode(clsDesc, clsMap);
+ extractAndAddCacheParams(clsDesc, clsMap, javaClass);
+ extractAndAddNamedQueries(clsDesc, clsMap);
+ extractAndSetKeyGeneratorDescriptor(clsDesc, clsMap);
+
+ return clsDesc;
+ }
+
+ /**
+ * Extract access mode from class mapping and set it at JDO class descriptor.
+ *
+ * @param clsDesc JDO class descriptor to set the access mode on.
+ * @param clsMap Class mapping to extract the access mode from.
+ */
+ private void extractAndSetAccessMode(final JDOClassDescriptor clsDesc,
+ final ClassMapping clsMap) {
+ if (clsMap.getAccess() != null) {
+ clsDesc.setAccessMode(AccessMode.valueOf(clsMap.getAccess().toString()));
+ }
+ }
+
+ /**
+ * Extract cache parameters from class mapping and add them to JDO class descriptor.
+ *
+ * @param clsDesc JDO class descriptor to add the cache parameters to.
+ * @param clsMap Class mapping to extract the cache parameters from.
+ * @param javaClass Class the cache parameters are defined for.
+ * @throws MappingException If cache type none has been specified for
+ * a class that implements TimeStampable interface.
+ */
+ private void extractAndAddCacheParams(final JDOClassDescriptor clsDesc,
+ final ClassMapping clsMap, final Class javaClass)
+ throws MappingException {
+ clsDesc.addCacheParam(Cache.PARAM_NAME, clsMap.getName());
- // first search among declared key generators
- // and resolve alias
- keyGenDef = (KeyGeneratorDef) _keyGenDefs.get(keyGenName);
- params = new Properties();
- keyGenFactoryName = keyGenName;
- if (keyGenDef != null) {
- keyGenFactoryName = keyGenDef.getName();
- enumeration = keyGenDef.enumerateParam();
- while (enumeration.hasMoreElements()) {
- Param par = (Param) enumeration.nextElement();
- params.put(par.getName(), par.getValue());
+ CacheTypeMapping cacheMapping = clsMap.getCacheTypeMapping();
+ if (cacheMapping != null) {
+ String type = cacheMapping.getType();
+ if ("none".equalsIgnoreCase(type)) {
+ if (TimeStampable.class.isAssignableFrom(javaClass)) {
+ throw new MappingException(Messages.format(
+ "persist.wrongCacheTypeSpecified", clsMap.getName()));
}
}
+ clsDesc.addCacheParam(Cache.PARAM_TYPE, type);
+
+ Param[] params = cacheMapping.getParam();
+ for (int i = 0; i < params.length; i++) {
+ clsDesc.addCacheParam(params[i].getName(), params[i].getValue());
+ }
+
+ String debug = new Boolean(cacheMapping.getDebug()).toString();
+ clsDesc.addCacheParam(Cache.PARAM_DEBUG, debug);
+
+ String capacity = Long.toString(cacheMapping.getCapacity());
+ clsDesc.addCacheParam(CountLimited.PARAM_CAPACITY, capacity);
+ clsDesc.addCacheParam(TimeLimited.PARAM_TTL, capacity);
+ }
+ }
+
+ /**
+ * Extract named queries from class mapping and add them to JDO class descriptor.
+ *
+ * @param clsDesc JDO class descriptor to add the named queries to.
+ * @param clsMap Class mapping to extract the named queries from.
+ * @throws MappingException On duplicate query names.
+ */
+ private void extractAndAddNamedQueries(final JDOClassDescriptor clsDesc,
+ final ClassMapping clsMap)
+ throws MappingException {
+ Enumeration namedQueriesEnum = clsMap.enumerateNamedQuery();
+ while (namedQueriesEnum.hasMoreElements()) {
+ NamedQuery query = (NamedQuery) namedQueriesEnum.nextElement();
+ String queryName = query.getName();
+ if (_queryNames.contains(queryName)) {
+ throw new MappingException(
+ "Duplicate entry for named query with name " + queryName);
+ }
+ _queryNames.add(queryName);
+
+ clsDesc.addNamedQuery(queryName, query.getQuery());
+ }
+ }
+
+ /**
+ * Extract name of key generator to use from class mapping. Search for an already
+ * existing key generator descriptor, e.g. those generated from the key generator
+ * definitions in mapping. If no descriptor can be found a new one is created and
+ * added to the map of class descriptors. Set the key generator descriptor at the
+ * class descriptor.
+ *
+ * @param clsDesc JDO class descriptor to set the key generator descriptor at.
+ * @param clsMap Class mapping name of key generator.
+ */
+ private void extractAndSetKeyGeneratorDescriptor(final JDOClassDescriptor clsDesc,
+ final ClassMapping clsMap) {
+ KeyGeneratorDescriptor keyGenDesc = null;
+
+ String keyGenName = clsMap.getKeyGenerator();
+ if (keyGenName != null) {
keyGenDesc = (KeyGeneratorDescriptor) _keyGenDescs.get(keyGenName);
if (keyGenDesc == null) {
- keyGenDesc = new KeyGeneratorDescriptor(keyGenName,
- keyGenFactoryName, params, _keyGenReg);
+ keyGenDesc = new KeyGeneratorDescriptor(
+ keyGenName, keyGenName, new Properties(), _keyGenReg);
_keyGenDescs.put(keyGenName, keyGenDesc);
}
}
@@ -222,26 +432,46 @@
}
}
- JDOClassDescriptor classDescriptor = new JDOClassDescriptor(clsDesc, keyGenDesc);
-
- // extract named queries and add to (JDO) class descriptor
- Enumeration namedQueriesEnum = clsMap.enumerateNamedQuery();
- while (namedQueriesEnum.hasMoreElements()) {
- NamedQuery namedQuery = (NamedQuery) namedQueriesEnum.nextElement();
- try {
- if(_namedQueries.contains(namedQuery.getName())) {
- throw new MappingException("Duplicate entry for named query with name " + namedQuery.getName());
+ clsDesc.setKeyGeneratorDescriptor(keyGenDesc);
+ }
+
+ protected final FieldDescriptor findIdentityByName(
+ final List fldList, final String idName, final Class javaClass)
+ throws MappingException {
+ for (int i = 0; i < fldList.size(); i++) {
+ FieldDescriptor field = (FieldDescriptor) fldList.get(i);
+ if (idName.equals(field.getFieldName())) {
+ if (!(field instanceof JDOFieldDescriptor)) {
+ throw new IllegalStateException(
+ "Identity field must be of type JDOFieldDescriptor");
+ }
+
+ String[] sqlName = ((JDOFieldDescriptor) field).getSQLName();
+ if (sqlName == null) {
+ throw new MappingException("mapping.noSqlName",
+ field.getFieldName(), javaClass.getName());
}
- classDescriptor.addNamedQuery(namedQuery.getName(), namedQuery.getQuery());
- _namedQueries.put(namedQuery.getName(), namedQuery);
- } catch (QueryException e) {
- throw new MappingException(e);
+
+ fldList.remove(i);
+ return field;
}
}
-
- return classDescriptor;
+ return null;
+ }
+
+ protected final void resolveRelations(final ClassDescriptor clsDesc) {
+ FieldDescriptor[] fields = clsDesc.getFields();
+ for (int i = 0 ; i < fields.length ; ++i) {
+ FieldDescriptor field = fields[i];
+ ClassDescriptor desc = getDescriptor(field.getFieldType().getName());
+ if ((desc != null) && (field instanceof FieldDescriptorImpl)) {
+ ((FieldDescriptorImpl) field).setClassDescriptor(desc);
+ }
+ }
}
+ //-----------------------------------------------------------------------------------
+
/**
* Parse the sql type attribute to build an
* array of types, needed to support whitespace inside
@@ -367,7 +597,7 @@
}
- protected FieldDescriptor createFieldDesc( Class javaClass, FieldMapping fieldMap )
+ protected AbstractFieldDescriptor createFieldDesc( Class javaClass, FieldMapping fieldMap )
throws MappingException {
// If not an SQL field, return a stock field descriptor.
@@ -380,11 +610,7 @@
// field/accessor.
Class fieldType = null;
if ( fieldMap.getType() != null ) {
- try {
- fieldType = resolveType( fieldMap.getType() );
- } catch ( ClassNotFoundException except ) {
- throw new MappingException( "mapping.classNotFound", fieldMap.getType() );
- }
+ fieldType = resolveType( fieldMap.getType() );
}
// If the field is declared as a collection, grab the collection type as
@@ -417,13 +643,7 @@
//-- check for user supplied FieldHandler
if (fieldMap.getHandler() != null) {
- Class handlerClass = null;
- try {
- handlerClass = resolveType( fieldMap.getHandler() );
- }
- catch (ClassNotFoundException except) {
- throw new MappingException( "mapping.classNotFound", fieldMap.getHandler() );
- }
+ Class handlerClass = resolveType(fieldMap.getHandler());
if (!FieldHandler.class.isAssignableFrom(handlerClass)) {
String err = "The class '" + fieldMap.getHandler() +
@@ -531,31 +751,5 @@
return jdoFieldDescriptor;
}
- protected void loadMappingInternal(final MappingRoot mapping, final Object param)
- throws MappingException {
- Enumeration enumeration;
- _factory = (BaseFactory) param;
- // Load the key generator definitions and check for duplicate names
- enumeration = mapping.enumerateKeyGeneratorDef();
- while ( enumeration.hasMoreElements() ) {
- KeyGeneratorDef keyGenDef;
- String name;
-
- keyGenDef = (KeyGeneratorDef) enumeration.nextElement();
- name = keyGenDef.getAlias();
- if (name == null) {
- name = keyGenDef.getName();
- }
- if ( _keyGenDefs.get( name ) != null ) {
- throw new MappingException( Messages.format( "mapping.dupKeyGen", name ) );
- }
- _keyGenDefs.put( name, keyGenDef );
- }
-
- super.loadMappingInternal(mapping, null);
-
- _keyGenDefs = null;
- _keyGenDescs = null;
- _keyGenReg = null;
- }
+ //-----------------------------------------------------------------------------------
}
Index: C:/Java/castor-4/src/main/java/org/exolab/castor/jdo/engine/SQLHelper.java
===================================================================
--- C:/Java/castor-4/src/main/java/org/exolab/castor/jdo/engine/SQLHelper.java (revision 6773)
+++ C:/Java/castor-4/src/main/java/org/exolab/castor/jdo/engine/SQLHelper.java (working copy)
@@ -27,6 +27,7 @@
import org.apache.commons.logging.LogFactory;
import org.castor.jdo.engine.SQLTypeInfos;
import org.exolab.castor.mapping.FieldDescriptor;
+import org.exolab.castor.mapping.MappingException;
import org.exolab.castor.persist.spi.Identity;
/**
@@ -142,9 +143,19 @@
for (Iterator iter = extendingClassDescriptors.iterator(); iter.hasNext(); ) {
classDescriptor = (JDOClassDescriptor) iter.next();
classDescriptorsToAdd.add (classDescriptor);
- addExtendingClassDescriptors(classDescriptorsToAdd, classDescriptor.getExtendedBy());
+ addExtendingClassDescriptors(classDescriptorsToAdd, classDescriptor.getExtended());
}
}
+
+ public static String[] getIdentitySQLNames(final JDOClassDescriptor desc) {
+ FieldDescriptor[] identities = desc.getIdentities();
+ String[] sqlNames = new String[identities.length];
+ for (int i = 0; i < identities.length; i++) {
+ sqlNames[i] = ((JDOFieldDescriptor) identities[i]).getSQLName()[0];
+ }
+
+ return sqlNames;
+ }
private SQLHelper() { }
}
Index: C:/Java/castor-4/src/main/java/org/exolab/castor/jdo/engine/SQLQuery.java
===================================================================
--- C:/Java/castor-4/src/main/java/org/exolab/castor/jdo/engine/SQLQuery.java (revision 6773)
+++ C:/Java/castor-4/src/main/java/org/exolab/castor/jdo/engine/SQLQuery.java (working copy)
@@ -461,8 +461,8 @@
// "multi field" each fetchRaw is called, we might reuse them.
int originalFieldNumber = _requestedEngine.getInfo().length;
- if (_requestedEngine.getDescriptor().isExtended()) {
- Collection extendingClassDescriptors = _requestedEngine.getDescriptor().getExtendedBy();
+ Collection extendingClassDescriptors = _requestedEngine.getDescriptor().getExtended();
+ if (extendingClassDescriptors.size() > 0) {
int numberOfExtendLevels = SQLHelper.numberOfExtendingClassDescriptors(_requestedEngine.getDescriptor());
JDOClassDescriptor leafDescriptor = null;
Object[] returnValues = null;
Index: C:/Java/castor-4/src/main/java/org/exolab/castor/jdo/engine/SQLStatementLoad.java
===================================================================
--- C:/Java/castor-4/src/main/java/org/exolab/castor/jdo/engine/SQLStatementLoad.java (revision 6773)
+++ C:/Java/castor-4/src/main/java/org/exolab/castor/jdo/engine/SQLStatementLoad.java (working copy)
@@ -80,7 +80,7 @@
// obtain the number of ClassDescriptor that extend this one.
_numberOfExtendLevels = SQLHelper.numberOfExtendingClassDescriptors(engine.getDescriptor());
- _extendingClassDescriptors = engine.getDescriptor().getExtendedBy();
+ _extendingClassDescriptors = engine.getDescriptor().getExtended();
buildStatement();
}
@@ -97,8 +97,10 @@
JDOClassDescriptor baseDesc;
while (curDesc.getExtends() != null) {
baseDesc = (JDOClassDescriptor) curDesc.getExtends();
- expr.addInnerJoin(curDesc.getTableName(), curDesc.getIdentityColumnNames(),
- baseDesc.getTableName(), baseDesc.getIdentityColumnNames());
+ String[] curDescIdNames = SQLHelper.getIdentitySQLNames(curDesc);
+ String[] baseDescIdNames = SQLHelper.getIdentitySQLNames(baseDesc);
+ expr.addInnerJoin(curDesc.getTableName(), curDescIdNames,
+ baseDesc.getTableName(), baseDescIdNames);
joinTables.add(baseDesc.getTableName());
curDesc = baseDesc;
}
@@ -118,7 +120,7 @@
// add id fields for root table if first field points to a separate table
if ((i == 0) && field.isJoined()) {
- String[] identities = _engine.getDescriptor().getIdentityColumnNames();
+ String[] identities = SQLHelper.getIdentitySQLNames(_engine.getDescriptor());
for (int j = 0; j < identities.length; j++) {
expr.addColumn(curDesc.getTableName(), identities[j]);
}
@@ -130,7 +132,7 @@
if (!alias.equals(aliasOld) && !field.isJoined()) {
JDOClassDescriptor classDescriptor = (JDOClassDescriptor)
field.getFieldDescriptor().getContainingClassDescriptor();
- String[] identities = classDescriptor.getIdentityColumnNames();
+ String[] identities = SQLHelper.getIdentitySQLNames(classDescriptor);
for (int j = 0; j < identities.length; j++) {
boolean isTableNameAlreadyAdded = identitiesUsedForTable.containsKey(classDescriptor.getTableName());
if (!isTableNameAlreadyAdded) {
@@ -167,7 +169,7 @@
// 'join' all the extending tables
List classDescriptorsToAdd = new LinkedList();
JDOClassDescriptor classDescriptor = null;
- SQLHelper.addExtendingClassDescriptors(classDescriptorsToAdd, _engine.getDescriptor().getExtendedBy());
+ SQLHelper.addExtendingClassDescriptors(classDescriptorsToAdd, _engine.getDescriptor().getExtended());
if (classDescriptorsToAdd.size() > 0) {
for (Iterator iter = classDescriptorsToAdd.iterator(); iter.hasNext(); ) {
@@ -179,8 +181,10 @@
+ classDescriptor.getTableName());
}
- expr.addOuterJoin(_mapTo, _engine.getDescriptor().getIdentityColumnNames(),
- classDescriptor.getTableName(), classDescriptor.getIdentityColumnNames());
+ String[] engDescIdNames = SQLHelper.getIdentitySQLNames(_engine.getDescriptor());
+ String[] clsDescIdNames = SQLHelper.getIdentitySQLNames(classDescriptor);
+ expr.addOuterJoin(_mapTo, engDescIdNames,
+ classDescriptor.getTableName(), clsDescIdNames);
Persistence persistenceEngine;
try {
Index: C:/Java/castor-4/src/main/java/org/exolab/castor/jdo/oql/ParseTreeWalker.java
===================================================================
--- C:/Java/castor-4/src/main/java/org/exolab/castor/jdo/oql/ParseTreeWalker.java (revision 6773)
+++ C:/Java/castor-4/src/main/java/org/exolab/castor/jdo/oql/ParseTreeWalker.java (working copy)
@@ -26,6 +26,7 @@
import org.exolab.castor.jdo.engine.JDOClassDescriptor;
import org.exolab.castor.jdo.engine.JDOFieldDescriptor;
import org.exolab.castor.jdo.engine.SQLEngine;
+import org.exolab.castor.jdo.engine.SQLHelper;
import org.exolab.castor.mapping.loader.Types;
import org.exolab.castor.persist.LockEngine;
import org.exolab.castor.persist.spi.QueryExpression;
@@ -370,9 +371,11 @@
tableAlias2 = buildTableAlias(tableAlias2, path, tableIndex);
}
expr.addTable(cd.getTableName(), tableAlias2);
+ String[] clsDescIdNames = SQLHelper.getIdentitySQLNames(clsDesc);
+ String[] cdIdNames = SQLHelper.getIdentitySQLNames(cd);
expr.addInnerJoin(
- clsDesc.getTableName(), clsDesc.getIdentityColumnNames(), tableAlias1,
- cd.getTableName(), cd.getIdentityColumnNames(), tableAlias2);
+ clsDesc.getTableName(), clsDescIdNames, tableAlias1,
+ cd.getTableName(), cdIdNames, tableAlias2);
}
return retVal;
}
Index: C:/Java/castor-4/src/main/java/org/exolab/castor/mapping/ClassDescriptor.java
===================================================================
--- C:/Java/castor-4/src/main/java/org/exolab/castor/mapping/ClassDescriptor.java (revision 6773)
+++ C:/Java/castor-4/src/main/java/org/exolab/castor/mapping/ClassDescriptor.java (working copy)
@@ -42,11 +42,8 @@
*
* $Id$
*/
-
-
package org.exolab.castor.mapping;
-
/**
* Describes the properties of a class and its fields. Implementations
* will extend this inteface to provide additional properties.
@@ -55,10 +52,7 @@
* @version $Revision$ $Date: 2003-03-03 00:05:44 -0700 (Mon, 03 Mar 2003) $
* @see FieldDescriptor
*/
-public interface ClassDescriptor
-{
-
-
+public interface ClassDescriptor {
/**
* Returns the Java class represented by this descriptor.
*
@@ -66,7 +60,6 @@
*/
public Class getJavaClass();
-
/**
* Returns a list of fields represented by this descriptor.
*
@@ -74,7 +67,6 @@
*/
public FieldDescriptor[] getFields();
-
/**
* Returns the class descriptor of the class extended by this class.
*
@@ -82,7 +74,6 @@
*/
public ClassDescriptor getExtends();
-
/**
* Returns the identity field, null if this class has no identity.
*
@@ -89,16 +80,6 @@
* @return The identity field
*/
public FieldDescriptor getIdentity();
-
-
- /**
- * Returns the access mode specified for this class.
- *
- * @return The access mode
- */
- public AccessMode getAccessMode();
-
-
}
Index: C:/Java/castor-4/src/main/java/org/exolab/castor/mapping/loader/AbstractFieldDescriptor.java
===================================================================
--- C:/Java/castor-4/src/main/java/org/exolab/castor/mapping/loader/AbstractFieldDescriptor.java (revision 6773)
+++ C:/Java/castor-4/src/main/java/org/exolab/castor/mapping/loader/AbstractFieldDescriptor.java (working copy)
@@ -33,6 +33,9 @@
/** True if the object described by this descriptor is multivalued. */
private boolean _multivalued;
+
+ /** True if the field is part of the identity of the class. */
+ private boolean _identity;
//--------------------------------------------------------------------------
@@ -190,6 +193,24 @@
public final boolean isMultivalued() {
return _multivalued;
}
+
+ /**
+ * Set wether the described field is part of the identity of the class it belongs to.
+ *
+ * @param identity true if field is part of the classes identity.
+ */
+ public final void setIdentity(final boolean identity) {
+ _identity = identity;
+ }
+
+ /**
+ * Is the described field is part of the identity of the class it belongs to?
+ *
+ * @return true if field is part of the classes identity.
+ */
+ public final boolean isIdentity() {
+ return _identity;
+ }
//--------------------------------------------------------------------------
}
Index: C:/Java/castor-4/src/main/java/org/exolab/castor/mapping/loader/AbstractMappingLoader.java
===================================================================
--- C:/Java/castor-4/src/main/java/org/exolab/castor/mapping/loader/AbstractMappingLoader.java (revision 6773)
+++ C:/Java/castor-4/src/main/java/org/exolab/castor/mapping/loader/AbstractMappingLoader.java (working copy)
@@ -58,9 +58,6 @@
import java.util.List;
import java.util.Enumeration;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.castor.util.Messages;
import org.exolab.castor.mapping.ClassDescriptor;
import org.exolab.castor.mapping.CollectionHandler;
import org.exolab.castor.mapping.ExtendedFieldHandler;
@@ -86,9 +83,7 @@
* @version $Revision$ $Date: 2006-04-10 16:39:24 -0600 (Mon, 10 Apr 2006) $
*/
public abstract class AbstractMappingLoader extends AbstractMappingLoader2 {
- /** The Jakarta Commons
- * Logging instance used for all logging. */
- private static final Log LOG = LogFactory.getLog(AbstractMappingLoader.class);
+ //--------------------------------------------------------------------------
/** The prefix for the "add" method. */
private static final String ADD_METHOD_PREFIX = "add";
@@ -127,7 +122,7 @@
/** Factory method name for type-safe enumerations. */
protected static final String VALUE_OF = "valueOf";
- protected static final ClassDescriptor NO_DESCRIPTOR = new ClassDescriptorImpl(Class.class);
+ //--------------------------------------------------------------------------
/**
* Constructs a new mapping helper. This constructor is used by a derived class.
@@ -138,6 +133,8 @@
super(loader);
}
+ //--------------------------------------------------------------------------
+
/**
* {@inheritDoc}
*/
@@ -145,21 +142,19 @@
return "CastorXmlMapping";
}
+ //--------------------------------------------------------------------------
+
/**
- * Returns the Java class for the named type. The type name can be one of the
- * accepted short names (e.g. integer) or the full Java class name (e.g.
- * java.lang.Integer). If the short name is used, the primitive type might
- * be returned.
+ * Loads the mapping from the specified mapping object if not loaded previously.
+ *
+ * @param mapping The mapping information.
+ * @param param Arbitrary parameter that can be used by subclasses.
+ * @throws MappingException The mapping file is invalid.
*/
- protected final Class resolveType(final String typeName)
- throws ClassNotFoundException {
- return Types.typeFromName(getClassLoader(), typeName);
- }
+ public abstract void loadMapping(final MappingRoot mapping, final Object param)
+ throws MappingException;
- /**
- * {@inheritDoc}
- */
- protected void loadMappingInternal(final MappingRoot mapping, final Object param)
+ protected final void createClassDescriptors(final MappingRoot mapping)
throws MappingException {
// Load the mapping for all the classes. This is always returned
// in the same order as it appeared in the mapping file.
@@ -168,10 +163,9 @@
List retryList = new ArrayList();
while (enumeration.hasMoreElements()) {
ClassMapping clsMap = (ClassMapping) enumeration.nextElement();
- ClassDescriptor clsDesc = null;
-
try {
- clsDesc = createDescriptor(clsMap);
+ ClassDescriptor clsDesc = createClassDescriptor(clsMap);
+ if (clsDesc != null) { addDescriptor(clsDesc); }
} catch (MappingException mx) {
// save for later for possible out-of-order mapping files...
retryList.add(clsMap);
@@ -177,14 +171,6 @@
retryList.add(clsMap);
continue;
}
-
- if (clsDesc != NO_DESCRIPTOR) {
- addDescriptor(clsDesc);
- } else {
- // If the return value is NoDescriptor then the derived
- // class was not successful in constructing a descriptor.
- LOG.info(Messages.format("mapping.ignoringMapping", clsMap.getName()));
- }
}
// handle possible retries, for now we only loop once on the retries, but we
@@ -191,134 +177,19 @@
// should change this to keep looping until we have no more success rate.
for (Iterator i = retryList.iterator(); i.hasNext();) {
ClassMapping clsMap = (ClassMapping) i.next();
- ClassDescriptor clsDesc = createDescriptor(clsMap);
- if (clsDesc != NO_DESCRIPTOR) {
- addDescriptor(clsDesc);
- } else {
- // If the return value is NoDescriptor then the derived
- // class was not successful in constructing a descriptor.
- LOG.info(Messages.format("mapping.ignoringMapping", clsMap.getName()));
- }
+ ClassDescriptor clsDesc = createClassDescriptor(clsMap);
+ if (clsDesc != null) { addDescriptor(clsDesc); }
}
- for (Iterator i = this.descriptorIterator(); i.hasNext();) {
- ClassDescriptor clsDesc = (ClassDescriptor) i.next();
- if (clsDesc != NO_DESCRIPTOR) { resolveRelations(clsDesc); }
+ // iterate over all class descriptors and resolve relations between them
+ for (Iterator i = descriptorIterator(); i.hasNext();) {
+ resolveRelations((ClassDescriptor) i.next());
}
}
-
- protected void resolveRelations(final ClassDescriptor clsDesc) {
- FieldDescriptor[] fields = clsDesc.getFields();
- for ( int i = 0 ; i < fields.length ; ++i ) {
- FieldDescriptor field = fields[i];
- ClassDescriptor desc = getDescriptor(field.getFieldType().getName());
- if (desc == NO_DESCRIPTOR) {
- // XXX Error message should come here
- continue;
- } else if ((desc != null) && (field instanceof FieldDescriptorImpl)) {
- ( (FieldDescriptorImpl) field ).setClassDescriptor( desc );
- }
- }
- }
-
- /**
- * Creates a new descriptor. The class mapping information is used to create a new
- * stock {@link ClassDescriptor}. Implementations may extend this class to create a
- * more suitable descriptor.
- *
- * @param clsMap The class mapping information.
- * @throws MappingException An exception indicating why mapping for the class cannot
- * be created.
- */
- protected ClassDescriptor createDescriptor(final ClassMapping clsMap)
- throws MappingException {
- // Obtain the Java class.
- Class javaClass;
- try {
- javaClass = resolveType(clsMap.getName());
- } catch (ClassNotFoundException ex) {
- throw new MappingException("mapping.classNotFound", clsMap.getName());
- }
-
- // If this class extends another class, we need to obtain the extended
- // class and make sure this class indeed extends it.
- ClassDescriptor extend = getExtended(clsMap, javaClass.getName());
-
- // If this class depends another class, need to obtain the depended class
- ClassDescriptor depend = getDepended(clsMap, javaClass.getName());
-
- // Get field descriptors first. Note: order must be preserved for fields, but not
- // for relations or container fields. Add all the container fields in there.
- FieldDescriptor[] fields = createFieldDescriptors(clsMap, javaClass);
-
- // Make sure there are no two fields with the same name.
- checkFieldNames(fields, javaClass.getName());
-
- ClassMapping origin = getOrigin(clsMap);
- String[] ids = getIdentityColumnNames(origin.getIdentity(), origin);
-
- if ((ids == null) || (ids.length == 0)) {
- return new ClassDescriptorImpl(
- clsMap, javaClass, fields, null, extend, depend);
- }
-
- // Check that an XML mapping file does not declare more identity attributes for a
- // given class than there are field elements defined for that class.
- // (Patch submitted by Gabriel Richard Pack classMapping extends.
*
@@ -330,27 +201,26 @@
* @throws MappingException If the given ClassMapping extends another ClassMapping but
* its descriptor could not be found.
*/
- private ClassDescriptor getExtended(final ClassMapping clsMap, final String clsName)
+ protected final ClassDescriptor getExtended(
+ final ClassMapping clsMap, final Class javaClass)
throws MappingException {
if (clsMap.getExtends() == null) { return null; }
- try {
- ClassMapping mapping = (ClassMapping) clsMap.getExtends();
- Class type = resolveType(mapping.getName());
- ClassDescriptor result = getDescriptor(type.getName());
-
- if (result == null) {
- throw new MappingException("mapping.extendsMissing", mapping, clsName);
- }
+ ClassMapping mapping = (ClassMapping) clsMap.getExtends();
+ Class type = resolveType(mapping.getName());
+ ClassDescriptor result = getDescriptor(type.getName());
- if (result == NO_DESCRIPTOR) {
- throw new MappingException("mapping.extendsNoMapping", mapping, clsName);
- }
+ if (result == null) {
+ throw new MappingException(
+ "mapping.extendsMissing", mapping, javaClass.getName());
+ }
- return result;
- } catch (ClassNotFoundException ex) {
- throw new MappingException(ex);
+ if (!result.getJavaClass().isAssignableFrom(javaClass)) {
+ throw new MappingException("mapping.classDoesNotExtend",
+ javaClass.getName(), result.getJavaClass().getName());
}
+
+ return result;
}
/**
@@ -364,23 +234,67 @@
* @throws MappingException If the given ClassMapping depends on another ClassMapping
* but its descriptor could not be found.
*/
- private ClassDescriptor getDepended(final ClassMapping clsMap, final String clsName)
+ protected final ClassDescriptor getDepended(
+ final ClassMapping clsMap, final Class javaClass)
throws MappingException {
if (clsMap.getDepends() == null) { return null; }
- try {
- ClassMapping mapping = (ClassMapping) clsMap.getDepends();
- Class type = resolveType(mapping.getName());
- ClassDescriptor result = getDescriptor(type.getName());
+ ClassMapping mapping = (ClassMapping) clsMap.getDepends();
+ Class type = resolveType(mapping.getName());
+ ClassDescriptor result = getDescriptor(type.getName());
+
+ if (result == null) {
+ throw new MappingException(
+ "Depends not found: " + mapping + " " + javaClass.getName());
+ }
- if ((result == null) || (result == NO_DESCRIPTOR)) {
- String msg = "Depends not found: " + mapping + " " + clsName;
- throw new MappingException(msg);
+ return result;
+ }
+
+ /**
+ * Checks all given fields for name equality and throws a MappingException if at
+ * least two fields have the same name.
+ *
+ * @param fields The fields to be checked.
+ * @param cls Class that is checked (this is used for generating the exception).
+ * @throws MappingException If at least two fields have the same name.
+ */
+ protected final void checkFieldNameDuplicates(
+ final FieldDescriptor[] fields, final Class cls)
+ throws MappingException {
+ for (int i = 0; i < fields.length - 1; i++) {
+ String fieldName = fields[i].getFieldName();
+ for (int j = i + 1; j < fields.length; j++) {
+ if (fieldName.equals(fields[j].getFieldName())) {
+ throw new MappingException("The field " + fieldName
+ + " appears twice in the descriptor for " + cls.getName());
+ }
}
+ }
+ }
+
+ protected abstract void resolveRelations(final ClassDescriptor clsDesc);
- return result;
- } catch (ClassNotFoundException e) {
- throw new MappingException(e);
+ //--------------------------------------------------------------------------
+
+
+
+
+
+
+
+ /**
+ * Returns the Java class for the named type. The type name can be one of the
+ * accepted short names (e.g. integer) or the full Java class name (e.g.
+ * java.lang.Integer). If the short name is used, the primitive type might
+ * be returned.
+ */
+ protected final Class resolveType(final String typeName)
+ throws MappingException {
+ try {
+ return Types.typeFromName(getClassLoader(), typeName);
+ } catch (ClassNotFoundException ex) {
+ throw new MappingException("mapping.classNotFound", typeName);
}
}
@@ -395,7 +309,7 @@
* @throws MappingException An exception indicating why mapping for the class cannot
* be created.
*/
- private FieldDescriptor[] createFieldDescriptors(final ClassMapping clsMap,
+ protected final AbstractFieldDescriptor[] createFieldDescriptors(final ClassMapping clsMap,
final Class javaClass) throws MappingException {
FieldMapping[] fldMap = null;
@@ -404,12 +318,15 @@
}
if ((fldMap == null) || (fldMap.length == 0)) {
- return new FieldDescriptor[0];
+ return new AbstractFieldDescriptor[0];
}
- FieldDescriptor[] fields = new FieldDescriptor[fldMap.length];
+ AbstractFieldDescriptor[] fields = new AbstractFieldDescriptor[fldMap.length];
for (int i = 0; i < fldMap.length; i++) {
fields[i] = createFieldDesc(javaClass, fldMap[i]);
+
+ // set identity flag
+ fields[i].setIdentity(fldMap[i].getIdentity());
}
return fields;
@@ -416,29 +333,6 @@
}
/**
- * Checks all given fields for name equality and throws a MappingException if at least
- * two fields have the same name.
- *
- * @param fields The fields to be checked.
- * @param clsName The name of the class that is checked (this is used for generating
- * the exception).
- * @throws MappingException If at least two fields have the same name.
- */
- private void checkFieldNames(final FieldDescriptor[] fields, final String clsName)
- throws MappingException {
- for (int i = 0; i < fields.length - 1; i++) {
- String fieldName = fields[i].getFieldName();
-
- for (int j = i + 1; j < fields.length; j++) {
- if (fieldName.equals(fields[j].getFieldName())) {
- throw new MappingException("The field " + fieldName
- + " appears twice in the descriptor for " + clsName);
- }
- }
- }
- }
-
- /**
* Gets the top-most (i.e. without any further 'extends') extends of the given
* classMapping.
*
@@ -446,7 +340,7 @@
* @return The top-most extends of the given ClassMapping or the ClassMapping itself
* if it does not extend any other ClassMapping.
*/
- private ClassMapping getOrigin(final ClassMapping clsMap) {
+ protected final ClassMapping getOrigin(final ClassMapping clsMap) {
ClassMapping result = clsMap;
while (result.getExtends() != null) {
@@ -456,7 +350,7 @@
return result;
}
- private FieldDescriptor[] divideFieldDescriptors(final FieldDescriptor[] fields,
+ protected final FieldDescriptor[] divideFieldDescriptors(final FieldDescriptor[] fields,
final String[] ids, final FieldDescriptor[] identities) {
List fieldList = new ArrayList(fields.length);
@@ -492,7 +386,7 @@
* @return The index of the id column name that matches the given field's name or
* -1 if no such id column name exists.
*/
- private int getIdColumnIndex(FieldDescriptor field, String[] ids) {
+ protected int getIdColumnIndex(FieldDescriptor field, String[] ids) {
for (int i = 0; i < ids.length; i++) {
if (field.getFieldName().equals(ids[i])) {
return i;
@@ -512,7 +406,7 @@
* @throws MappingException The field or its accessor methods are not
* found, not accessible, not of the specified type, etc.
*/
- protected FieldDescriptor createFieldDesc(final Class javaClass,
+ protected AbstractFieldDescriptor createFieldDesc(final Class javaClass,
final FieldMapping fieldMap) throws MappingException {
String fieldName = fieldMap.getName();
@@ -519,11 +413,7 @@
// If the field type is supplied, grab it and use it to locate the field/accessor.
Class fieldType = null;
if (fieldMap.getType() != null) {
- try {
- fieldType = resolveType(fieldMap.getType());
- } catch (ClassNotFoundException ex) {
- throw new MappingException("mapping.classNotFound", fieldMap.getType());
- }
+ fieldType = resolveType(fieldMap.getType());
}
// If the field is declared as a collection, grab the collection type as
@@ -543,12 +433,7 @@
// Check for user supplied FieldHandler
if (fieldMap.getHandler() != null) {
Class handlerClass = null;
- try {
- handlerClass = resolveType(fieldMap.getHandler());
- } catch (ClassNotFoundException ex) {
- throw new MappingException(
- "mapping.classNotFound", fieldMap.getHandler());
- }
+ handlerClass = resolveType(fieldMap.getHandler());
if (!FieldHandler.class.isAssignableFrom(handlerClass)) {
String err = "The class '" + fieldMap.getHandler() + "' must implement "
@@ -1059,7 +944,7 @@
* @throws MappingException The method is not accessible or is not of the
* specified type.
*/
- protected static final Method findAccessor(final Class javaClass,
+ public static final Method findAccessor(final Class javaClass,
final String methodName, Class fieldType, final boolean getMethod)
throws MappingException {
try {
Index: C:/Java/castor-4/src/main/java/org/exolab/castor/mapping/loader/AbstractMappingLoader2.java
===================================================================
--- C:/Java/castor-4/src/main/java/org/exolab/castor/mapping/loader/AbstractMappingLoader2.java (revision 6773)
+++ C:/Java/castor-4/src/main/java/org/exolab/castor/mapping/loader/AbstractMappingLoader2.java (working copy)
@@ -9,7 +9,6 @@
import org.exolab.castor.mapping.ClassDescriptor;
import org.exolab.castor.mapping.MappingException;
import org.exolab.castor.mapping.MappingLoader;
-import org.exolab.castor.mapping.xml.MappingRoot;
public abstract class AbstractMappingLoader2 implements MappingLoader {
//--------------------------------------------------------------------------
@@ -126,32 +125,18 @@
//--------------------------------------------------------------------------
/**
- * Loads the mapping from the specified mapping object if not loaded previously.
- *
- * @param mapping The mapping information.
- * @param param Arbitrary parameter that can be used by subclasses.
- * @throws MappingException The mapping file is invalid.
+ * Return if mapping should be loaded with this MappingLoader instance or if another
+ * mapping have been loaded previously. If no mapping have been loaded previously
+ * then prevent any other mapping to be loaded later on.
+ *
+ * @return true if mapping should be loaded, false
+ * otherwise.
*/
- public final void loadMapping(final MappingRoot mapping, final Object param)
- throws MappingException {
- if (!_loaded) {
- _loaded = true;
-
- loadMappingInternal(mapping, param);
- }
+ protected final boolean loadMapping() {
+ if (_loaded) { return false; }
+ _loaded = true;
+ return true;
}
- /**
- * Loads the mapping from the specified mapping object. Calls {@link #createDescriptor} to
- * create each descriptor and {@link #addDescriptor} to store it. Also loads all the included
- * mapping files.
- *
- * @param mapping The mapping information.
- * @param param Arbitrary parameter that can be used by subclasses.
- * @throws MappingException The mapping file is invalid.
- */
- protected abstract void loadMappingInternal(MappingRoot mapping, Object param)
- throws MappingException;
-
//--------------------------------------------------------------------------
}
Index: C:/Java/castor-4/src/main/java/org/exolab/castor/mapping/loader/ClassDescriptorImpl.java
===================================================================
--- C:/Java/castor-4/src/main/java/org/exolab/castor/mapping/loader/ClassDescriptorImpl.java (revision 6773)
+++ C:/Java/castor-4/src/main/java/org/exolab/castor/mapping/loader/ClassDescriptorImpl.java (working copy)
@@ -42,200 +42,75 @@
*
* $Id$
*/
-
-
package org.exolab.castor.mapping.loader;
-
import java.util.Collection;
import java.util.LinkedList;
-import org.exolab.castor.mapping.ValidityException;
import org.exolab.castor.mapping.ClassDescriptor;
import org.exolab.castor.mapping.FieldDescriptor;
-import org.exolab.castor.mapping.MappingException;
-import org.exolab.castor.mapping.AccessMode;
import org.exolab.castor.mapping.xml.ClassMapping;
-
/**
- * A basic class descriptor implementation. Engines will extend this
- * class to provide additional functionality.
- *
+ * A basic class descriptor implementation. Engines will extend this class to provide
+ * additional functionality.
*
- * @author Assaf Arkin
+ * @author Assaf Arkin
+ * @author Ralf Joachim
* @version $Revision$ $Date: 2006-01-07 15:48:31 -0700 (Sat, 07 Jan 2006) $
*/
public class ClassDescriptorImpl implements ClassDescriptor {
- private final ClassMapping _map;
- /**
- * The Java class for this descriptor.
- */
- private final Class _javaClass;
+ //-----------------------------------------------------------------------------------
- /**
- * The fields described for this class.
- */
- protected final FieldDescriptor[] _fields;
-
+ private ClassMapping _mapping;
+
+ /** The Java class for this descriptor. */
+ private Class _javaClass;
- /**
- * The descriptor of the class which this class extends,
- * or null if this is a top-level class.
- */
- private final ClassDescriptor _extends;
+ /** The descriptor of the class which this class extends,
+ * or null if this is a top-level class. */
+ private ClassDescriptor _extends;
- /**
- * A collection of class descriptors that extend this class, or
- * an empty collection if this is a leaf class.
- */
- private final Collection _extendedBy = new LinkedList();
+ /** A collection of class descriptors that extend this class, or
+ * an empty collection if this is a leaf class. */
+ private final Collection _extended = new LinkedList();
- private final ClassDescriptor _depends;
+ private ClassDescriptor _depends;
- /**
- * The field of the identity for this class.
- */
- protected final FieldDescriptor[] _identities;
-
+ /** The fields described for this class. */
+ private FieldDescriptor[] _fields;
- /**
- * The access mode specified for this class.
- */
- private AccessMode _accessMode;
+ /** The field of the identity for this class. */
+ private FieldDescriptor[] _identities;
+ //-----------------------------------------------------------------------------------
- /**
- * Constructs a new descriptor for the specified class. When describing
- * inheritence, the descriptor of the parent class should be used and only
- * the fields added in this object must be supplied here.
- *
- * @throws MappingException The extended descriptor does not match
- * a parent class of this type
- */
-
- public ClassDescriptorImpl(final ClassDescriptorImpl clsDesc)
- throws MappingException {
- this(clsDesc.getMapping(), clsDesc.getJavaClass(), clsDesc.getFields(),
- clsDesc.getIdentities(), clsDesc.getExtends(), clsDesc.getDepends(), true);
-
- _accessMode = clsDesc.getAccessMode();
+ public void setMapping(final ClassMapping mapping) {
+ _mapping = mapping;
}
- public ClassDescriptorImpl(final ClassMapping map, final Class javaClass,
- final FieldDescriptor[] fields, final FieldDescriptor[] identities,
- final ClassDescriptor extend, final ClassDescriptor depend)
- throws MappingException {
- this(map, javaClass, fields, identities, extend, depend,
- map.getVerifyConstructable());
-
- if (map.getAccess() == null) {
- _accessMode = AccessMode.Shared;
- } else {
- _accessMode = AccessMode.valueOf(map.getAccess().toString());
- }
+ public ClassMapping getMapping() {
+ return _mapping;
}
- private ClassDescriptorImpl(final ClassMapping clsMap, final Class javaClass,
- final FieldDescriptor[] fields, final FieldDescriptor[] identities,
- final ClassDescriptor extend, final ClassDescriptor depend,
- final boolean verifyConstructable)
- throws MappingException {
- if (verifyConstructable && (!Types.isConstructable(javaClass, true))) {
- throw new MappingException("mapping.classNotConstructable", javaClass.getName());
- }
-
- _map = clsMap;
- _javaClass = javaClass;
-
- if (fields == null) {
- throw new IllegalArgumentException("Argument 'fields' is null");
- }
- _fields = (FieldDescriptor[]) fields.clone();
-
- _depends = depend;
-
- if (extend != null) {
- if (!extend.getJavaClass().isAssignableFrom(javaClass)) {
- throw new MappingException("mapping.classDoesNotExtend",
- javaClass.getName(), extend.getJavaClass().getName());
- }
- _extends = extend;
-
- if (_extends.getClass().getName().equals("org.exolab.castor.jdo.engine.JDOClassDescriptor") &&
- this.getClass().getName().equals("org.exolab.castor.jdo.engine.JDOClassDescriptor")) {
- ((ClassDescriptorImpl) _extends).addExtendedBy(this);
- }
-
- if (_extends instanceof ClassDescriptorImpl) {
- _identities = ( identities == null ? ((ClassDescriptorImpl)_extends).getIdentities() : identities );
- } else {
- // a quick hack to fix a ClassCastException :-(
- _identities = ( identities == null ?
- (_extends.getIdentity() == null? null : new FieldDescriptor[] { _extends.getIdentity() } )
- : identities );
- }
- } else {
- _extends = null;
- _identities = identities;
- }
-
- // fritz: propagate containing class to fields
- // oleg: don't alter the identity's info if the identity was taken
- // from the ancestor class.
- // So complicated condition is needed since for JDO fields first a pure
- // ClassDescriptorImpl is created, and then JDOClassDescriptorImpl for
- // the same class
- if ((_identities != null) && (_identities.length > 0) && (_identities[0] != null)
- && ((_identities[0].getContainingClassDescriptor() == null)
- || (_identities[0].getContainingClassDescriptor().getJavaClass() == _javaClass))) {
- for (int i = 0; i < _identities.length; i++) {
- _identities[i].setContainingClassDescriptor(this);
- }
- }
-
- for (int i = 0; i < _fields.length; i++) {
- _fields[i].setContainingClassDescriptor(this);
- }
- }
-
- /**
- * Constructor used by derived classes.
- */
- protected ClassDescriptorImpl(final Class javaClass) {
- _map = null;
+ public void setJavaClass(final Class javaClass) {
_javaClass = javaClass;
- _extends = null;
- _fields = null;
- _identities = null;
- _depends = null;
- _accessMode = null;
-
- }
-
- public ClassMapping getMapping() {
- return _map;
}
- public Class getJavaClass()
- {
+ public Class getJavaClass() {
return _javaClass;
}
-
-
- public FieldDescriptor[] getFields()
- {
- return _fields;
+
+ public void setExtends(final ClassDescriptor extend) {
+ _extends = extend;
}
-
-
- public ClassDescriptor getExtends()
- {
+
+ public ClassDescriptor getExtends() {
return _extends;
}
- public boolean isExtending() {
- return (_extends != null);
+ public void addExtended(final ClassDescriptor classDesc) {
+ _extended.add(classDesc);
}
/**
@@ -243,16 +118,12 @@
*
* @return A collection of class descriptors.
*/
- public Collection getExtendedBy() {
- return _extendedBy;
- }
-
- public boolean isExtended() {
- return (_extendedBy.size() > 0);
+ public Collection getExtended() {
+ return _extended;
}
- public void addExtendedBy(ClassDescriptor classDesc) {
- _extendedBy.add(classDesc);
+ public void setDepends(final ClassDescriptor depends) {
+ _depends = depends;
}
public ClassDescriptor getDepends() {
@@ -259,8 +130,16 @@
return _depends;
}
- public FieldDescriptor getIdentity() {
- return _identities == null? null : _identities[0];
+ public void setFields(final FieldDescriptor[] fields) {
+ _fields = fields;
+ }
+
+ public FieldDescriptor[] getFields() {
+ return _fields;
+ }
+
+ public void setIdentities(final FieldDescriptor[] identities) {
+ _identities = identities;
}
public FieldDescriptor[] getIdentities() {
@@ -267,42 +146,20 @@
return _identities;
}
-
- public AccessMode getAccessMode()
- {
- return _accessMode;
+ public FieldDescriptor getIdentity() {
+ return (_identities == null) ? null : _identities[0];
}
-
+
+ //-----------------------------------------------------------------------------------
/**
- * Checks the object validity. Returns successfully if the object
- * can be stored, is valid, etc, throws an exception otherwise.
- *
- * @param object The object
- * @throws ValidityException The object is invalid, a required is
- * null, or any other validity violation
- * @throws IllegalStateException The Java object has changed and
- * is no longer supported by this handler, or the handler
- * is not compatiable with the Java object
+ * {@inheritDoc}
*/
- public void checkValidity( Object object )
- throws ValidityException, IllegalStateException
- {
- // Object cannot be saved if one of the required fields is null
- for ( int i = 0 ; i < _fields.length ; ++i ) {
- if ( _fields[ i ].isRequired() && _fields[ i ].getHandler().getValue( object ) == null )
- throw new ValidityException( "mapping.requiredField",
- object.getClass().getName(), _fields[ i ].getFieldName() );
- }
- }
-
-
- public String toString()
- {
+ public String toString() {
return _javaClass.getName();
}
-
+ //-----------------------------------------------------------------------------------
}
Index: C:/Java/castor-4/src/main/java/org/exolab/castor/persist/ClassMolder.java
===================================================================
--- C:/Java/castor-4/src/main/java/org/exolab/castor/persist/ClassMolder.java (revision 6773)
+++ C:/Java/castor-4/src/main/java/org/exolab/castor/persist/ClassMolder.java (working copy)
@@ -1458,7 +1458,7 @@
* @return The actual (OQL) statement
*/
public String getNamedQuery(String name) {
- return ((JDOClassDescriptor) _clsDesc).getNamedQuery(name);
+ return (String) ((JDOClassDescriptor) _clsDesc).getNamedQueries().get(name);
}
}
Index: C:/Java/castor-4/src/main/java/org/exolab/castor/tools/MappingToolMappingLoader.java
===================================================================
--- C:/Java/castor-4/src/main/java/org/exolab/castor/tools/MappingToolMappingLoader.java (revision 6773)
+++ C:/Java/castor-4/src/main/java/org/exolab/castor/tools/MappingToolMappingLoader.java (working copy)
@@ -46,7 +46,6 @@
import java.lang.reflect.Array;
-import org.castor.mapping.BindingType;
import org.exolab.castor.mapping.loader.AbstractMappingLoader;
import org.exolab.castor.xml.JavaNaming;
@@ -53,7 +52,7 @@
/**
* Extend mapping loader to give us access to the findAccessor method.
*/
-public final class MappingToolMappingLoader extends AbstractMappingLoader {
+public final class MappingToolMappingLoader {
private static final String GET = "get";
private static final String SET = "set";
private static final String ADD = "add";
@@ -58,10 +57,6 @@
private static final String SET = "set";
private static final String ADD = "add";
- MappingToolMappingLoader() { super(null); }
-
- public BindingType getBindingType() { return null; }
-
/**
* Returns true if the get method returns an array.
* This method is used for greater compatability with
@@ -69,7 +64,7 @@
*
* @return if get method returns an array.
**/
- boolean returnsArray(final Class clazz, final String fieldName, final Class type) {
+ public static boolean returnsArray(final Class clazz, final String fieldName, final Class type) {
try {
Class array = null;
if (type.isArray()) {
@@ -81,7 +76,7 @@
String prefix = JavaNaming.toJavaClassName(fieldName);
String method = GET + prefix;
boolean isGet = true;
- if (findAccessor(clazz, method, array, isGet) != null) {
+ if (AbstractMappingLoader.findAccessor(clazz, method, array, isGet) != null) {
return true;
}
} catch(Exception ex) {
@@ -90,7 +85,7 @@
return false;
}
- boolean canFindAccessors(final Class clazz, final String fieldName, final Class type) {
+ public static boolean canFindAccessors(final Class clazz, final String fieldName, final Class type) {
try {
//-- getMethod
String prefix = JavaNaming.toJavaClassName(fieldName);
@@ -96,7 +91,7 @@
String prefix = JavaNaming.toJavaClassName(fieldName);
String method = GET + prefix;
boolean isGet = true;
- if (findAccessor(clazz, method, type, isGet) != null) {
+ if (AbstractMappingLoader.findAccessor(clazz, method, type, isGet) != null) {
return true;
}
@@ -103,11 +98,11 @@
//-- setMethod and/or addMethod
isGet = false;
method = SET + prefix;
- if (findAccessor(clazz, method, type, isGet) != null) {
+ if (AbstractMappingLoader.findAccessor(clazz, method, type, isGet) != null) {
return true;
}
method = ADD + prefix;
- if (findAccessor(clazz, method, type, isGet) != null) {
+ if (AbstractMappingLoader.findAccessor(clazz, method, type, isGet) != null) {
return true;
}
} catch(Exception ex) {
Index: C:/Java/castor-4/src/main/java/org/exolab/castor/xml/MarshalFramework.java
===================================================================
--- C:/Java/castor-4/src/main/java/org/exolab/castor/xml/MarshalFramework.java (revision 6773)
+++ C:/Java/castor-4/src/main/java/org/exolab/castor/xml/MarshalFramework.java (working copy)
@@ -627,18 +627,5 @@
public FieldDescriptor getIdentity() {
return _classDesc.getIdentity();
} //-- getIdentity
-
-
- /**
- * Returns the access mode specified for this class.
- *
- * @return The access mode
- */
- public AccessMode getAccessMode() {
- return _classDesc.getAccessMode();
- } //-- getAccessMode
-
} //-- InternalXMLClassDescriptor
-
-
} //-- MarshalFramework
Index: C:/Java/castor-4/src/main/java/org/exolab/castor/xml/XMLMappingLoader.java
===================================================================
--- C:/Java/castor-4/src/main/java/org/exolab/castor/xml/XMLMappingLoader.java (revision 6773)
+++ C:/Java/castor-4/src/main/java/org/exolab/castor/xml/XMLMappingLoader.java (working copy)
@@ -50,7 +50,6 @@
package org.exolab.castor.xml;
import org.castor.mapping.BindingType;
-import org.castor.util.Messages;
import org.exolab.castor.mapping.ClassDescriptor;
import org.exolab.castor.mapping.FieldDescriptor;
import org.exolab.castor.mapping.FieldHandler;
@@ -58,6 +57,7 @@
import org.exolab.castor.mapping.MappingException;
import org.exolab.castor.mapping.TypeConvertor;
import org.exolab.castor.mapping.CollectionHandler;
+import org.exolab.castor.mapping.loader.AbstractFieldDescriptor;
import org.exolab.castor.mapping.loader.CollectionHandlers;
import org.exolab.castor.mapping.loader.AbstractMappingLoader;
import org.exolab.castor.mapping.loader.FieldHandlerImpl;
@@ -62,6 +62,7 @@
import org.exolab.castor.mapping.loader.AbstractMappingLoader;
import org.exolab.castor.mapping.loader.FieldHandlerImpl;
import org.exolab.castor.mapping.loader.TypeInfo;
+import org.exolab.castor.mapping.loader.Types;
import org.exolab.castor.mapping.xml.ClassMapping;
import org.exolab.castor.mapping.xml.FieldMapping;
import org.exolab.castor.mapping.xml.BindXml;
@@ -66,6 +67,7 @@
import org.exolab.castor.mapping.xml.FieldMapping;
import org.exolab.castor.mapping.xml.BindXml;
import org.exolab.castor.mapping.xml.MapTo;
+import org.exolab.castor.mapping.xml.MappingRoot;
import org.exolab.castor.mapping.xml.Property;
import org.exolab.castor.mapping.xml.types.BindXmlAutoNamingType;
import org.exolab.castor.mapping.xml.types.FieldMappingCollectionType;
@@ -85,6 +87,8 @@
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.List;
/**
* An XML implementation of mapping helper. Creates XML class
@@ -95,52 +99,37 @@
* @version $Revision$ $Date: 2006-02-23 01:37:50 -0700 (Thu, 23 Feb 2006) $
*/
public final class XMLMappingLoader extends AbstractMappingLoader {
- /**
- * The default xml prefix used on certain
- * attributes such as xml:lang, xml:base, etc.
- */
- private static final String XML_PREFIX = "xml:";
+ //-----------------------------------------------------------------------------------
-
- /**
- * Empty array of class types used for reflection
- **/
+ /** The default xml prefix used on certain attributes such as xml:lang, xml:base,
+ * etc. */
+ private static final String XML_PREFIX = "xml:";
+
+ /** Empty array of class types used for reflection. */
private static final Class[] EMPTY_ARGS = new Class[0];
- /**
- * The NCName Schema type
- **/
+ /** The NCName Schema type. */
private static final String NCNAME = "NCName";
- /**
- * The string argument for the valueOf method, used
- * for introspection.
- **/
+ /** The string argument for the valueOf method, used for introspection. */
private static final Class[] STRING_ARG = { String.class };
- /**
- * Factory method name for type-safe enumerations. This
- * is primarily for allowing users to map classes that
- * were created by Castor's SourceGenerator.
- **/
+ /** Factory method name for type-safe enumerations. This is primarily for allowing
+ * users to map classes that were created by Castor's SourceGenerator. */
private static final String VALUE_OF = "valueOf";
+ //-----------------------------------------------------------------------------------
- /**
- * A reference to the internal ClassDescriptorResolver
- */
+ /** A reference to the internal ClassDescriptorResolver. */
private XMLClassDescriptorResolverImpl _cdResolver;
- /**
- * naming conventions
- */
- private XMLNaming _naming = null;
+ /** The default NodeType for primitives. */
+ private NodeType _primitiveNodeType = null;
- /**
- * The default NodeType for primitives
- */
- private NodeType _primitiveNodeType = null;
+ /** Naming conventions. */
+ private XMLNaming _naming = null;
+ //-----------------------------------------------------------------------------------
/**
* Creates a new XMLMappingLoader
@@ -149,59 +138,31 @@
super(loader);
LocalConfiguration config = LocalConfiguration.getInstance();
-
_primitiveNodeType = config.getPrimitiveNodeType();
- _naming = config.getXMLNaming();
-
- } //-- XMLMappingLoader
-
-
-
- public BindingType getBindingType() { return BindingType.XML; }
-
- private void createResolver() {
- _cdResolver = (XMLClassDescriptorResolverImpl)
- ClassDescriptorResolverFactory.createClassDescriptorResolver(BindingType.XML);
- _cdResolver.setIntrospection(false);
- _cdResolver.setLoadPackageMappings(false);
+ _naming = config.getXMLNaming();
}
- protected void resolveRelations(ClassDescriptor clsDesc) {
- FieldDescriptor[] fields;
+ //-----------------------------------------------------------------------------------
- fields = clsDesc.getFields();
- for ( int i = 0 ; i < fields.length ; ++i ) {
- if (fields[i].getClassDescriptor() != null) continue;
- ClassDescriptor relDesc;
+ /**
+ * {@inheritDoc}
+ */
+ public BindingType getBindingType() { return BindingType.XML; }
- Class fieldType = fields[i].getFieldType();
- if (fieldType != null) {
- relDesc = getDescriptor(fieldType.getName());
- if ( relDesc == NO_DESCRIPTOR ) {
- // XXX Error message should come here
- }
- else if ( relDesc != null &&
- relDesc instanceof XMLClassDescriptor &&
- fields[ i ] instanceof XMLFieldDescriptorImpl )
- {
- ( (XMLFieldDescriptorImpl) fields[ i ] ).setClassDescriptor( (XMLClassDescriptor) relDesc );
+ //-----------------------------------------------------------------------------------
- //-- removed kvisco 20010814
- // ( (XMLFieldDescriptorImpl) fields[ i ] ).setNodeType( NodeType.Element );
- }
- }
- }
- if ( clsDesc instanceof XMLClassDescriptorImpl )
- ( (XMLClassDescriptorImpl) clsDesc ).sortDescriptors();
+ /**
+ * {@inheritDoc}
+ */
+ public void loadMapping(final MappingRoot mapping, final Object param)
+ throws MappingException {
+ if (loadMapping()) { createClassDescriptors(mapping); }
}
-
- protected ClassDescriptor createDescriptor( ClassMapping clsMap )
- throws MappingException
- {
- ClassDescriptor clsDesc;
- String xmlName;
-
+ //-----------------------------------------------------------------------------------
+
+ protected final ClassDescriptor createClassDescriptor(final ClassMapping clsMap)
+ throws MappingException {
if (clsMap.getAutoComplete()) {
if ((clsMap.getMapTo() == null) &&
((clsMap.getClassChoice() == null) ||
@@ -208,55 +169,124 @@
(clsMap.getClassChoice().getFieldMappingCount() == 0)) &&
(clsMap.getIdentityCount() == 0))
{
- //-- if we make it here we simply try
- //-- to load a compiled mapping
- if (_cdResolver == null) {
- createResolver();
- }
+ // If we make it here we simply try to load a compiled mapping
+ if (_cdResolver == null) { createResolver(); }
try {
- clsDesc = _cdResolver.resolve(clsMap.getName());
- if (clsDesc != null)
- return clsDesc;
+ ClassDescriptor clsDesc = _cdResolver.resolve(clsMap.getName());
+ if (clsDesc != null) { return clsDesc; }
+ } catch(ResolverException rx) {
+
}
- catch(ResolverException rx) {}
-
+ }
+ }
+
+ // Create the class descriptor.
+ XMLClassDescriptorAdapter xmlClassDesc = new XMLClassDescriptorAdapter();
+
+ // Obtain the Java class.
+ Class javaClass = resolveType(clsMap.getName());
+ if (clsMap.getVerifyConstructable()) {
+ if (!Types.isConstructable(javaClass, true)) {
+ throw new MappingException(
+ "mapping.classNotConstructable", javaClass.getName());
}
}
+ xmlClassDesc.setJavaClass(javaClass);
- // Use super class to create class descriptor. Field descriptors will be
- // generated only for supported fields, see createFieldDesc later on.
- clsDesc = super.createDescriptor( clsMap );
+ // Obtain XML name.
+ String xmlName;
MapTo mapTo = clsMap.getMapTo();
- if (( mapTo == null) || (mapTo.getXml() == null)) {
- String clsName = clsDesc.getJavaClass().getName();
+ if ((mapTo != null) && (mapTo.getXml() != null)) {
+ xmlName = mapTo.getXml();
+ } else {
+ String clsName = javaClass.getName();
int idx = clsName.lastIndexOf('.');
- if (idx >= 0) {
- clsName = clsName.substring(idx+1);
- }
- xmlName = _naming.toXMLName( clsName );
+ if (idx >= 0) { clsName = clsName.substring(idx + 1); }
+ xmlName = _naming.toXMLName(clsName);
}
- else {
- xmlName = clsMap.getMapTo().getXml();
+ xmlClassDesc.setXMLName(xmlName);
- }
+ // If this class extends another class, we need to obtain the extended
+ // class and make sure this class indeed extends it.
+ ClassDescriptor extDesc = getExtended(clsMap, javaClass);
+ xmlClassDesc.setExtends((XMLClassDescriptor) extDesc);
+
+ // Create all field descriptors.
+ AbstractFieldDescriptor[] allFields = createFieldDescriptors(clsMap, javaClass);
- XMLClassDescriptorImpl xmlClassDesc
- = new XMLClassDescriptorAdapter( clsDesc, xmlName, _primitiveNodeType );
-
+ // Make sure there are no two fields with the same name.
+ checkFieldNameDuplicates(allFields, javaClass);
+
+ // Identify identity and normal fields. Note that order must be preserved.
+ List fieldList = new ArrayList(allFields.length);
+ List idList = new ArrayList();
+ if (extDesc == null) {
+ // Sort fields into 2 lists based on identity definition of field.
+ for (int i = 0; i < allFields.length; i++) {
+ if (!allFields[i].isIdentity()) {
+ fieldList.add(allFields[i]);
+ } else {
+ idList.add(allFields[i]);
+ }
+ }
+
+ if (idList.size() == 0) {
+ // Found no identities based on identity definition of field.
+ // Try to find identities based on identity definition on class.
+ String[] idNames = clsMap.getIdentity();
+
+ FieldDescriptor identity;
+ for (int i = 0; i < idNames.length; i++) {
+ identity = findIdentityByName(fieldList, idNames[i], javaClass);
+ if (identity != null) {
+ idList.add(identity);
+ } else {
+ throw new MappingException("mapping.identityMissing",
+ idNames[i], javaClass.getName());
+ }
+ }
+ }
+ } else {
+ // Add all fields of extending class to field list.
+ for (int i = 0; i < allFields.length; i++) { fieldList.add(allFields[i]); }
+
+ // Add identity of extended class to identity list.
+ if (extDesc.getIdentity() != null) { idList.add(extDesc.getIdentity()); }
+
+ // Search redefined identities in extending class.
+ FieldDescriptor identity;
+ for (int i = 0; i < idList.size(); i++) {
+ String idname = ((FieldDescriptor) idList.get(i)).getFieldName();
+ identity = findIdentityByName(fieldList, idname, javaClass);
+ if (identity != null) { idList.set(i, identity); }
+ }
+ }
+
+ FieldDescriptor xmlId = null;
+ if (idList.size() != 0) { xmlId = (FieldDescriptor) idList.get(0); }
+
+ for (int i = 0; i < allFields.length; i++) {
+ FieldDescriptor fieldDesc = allFields[i];
+ if (fieldDesc != null) {
+ if (fieldDesc == xmlId) {
+ xmlClassDesc.setIdentity((XMLFieldDescriptorImpl) fieldDesc);
+ } else {
+ xmlClassDesc.addFieldDescriptor((XMLFieldDescriptorImpl) fieldDesc);
+ }
+ }
+ }
+
if (clsMap.getAutoComplete()) {
XMLClassDescriptor referenceDesc = null;
-
+
Class type = xmlClassDesc.getJavaClass();
-
- //-- check compiled descriptors
- if (_cdResolver == null) {
- createResolver();
- }
+
+ //-- check compiled descriptors
+ if (_cdResolver == null) { createResolver(); }
try {
referenceDesc = _cdResolver.resolveXML(type);
- }
- catch(ResolverException rx) {
+ } catch (ResolverException rx) {
throw new MappingException(rx);
}
@@ -281,8 +311,8 @@
if (clsMap.getIdentityCount() > 0)
identity = clsMap.getIdentity(0);
-
- FieldDescriptor[] fields = xmlClassDesc.getFields();
+
+ FieldDescriptor[] xmlFields2 = xmlClassDesc.getFields();
// Attributes
XMLFieldDescriptor[] introFields = referenceDesc.getAttributeDescriptors();
@@ -287,7 +317,7 @@
// Attributes
XMLFieldDescriptor[] introFields = referenceDesc.getAttributeDescriptors();
for (int i = 0; i