Index: C:/Java/castor-4/src/main/java/org/exolab/castor/jdo/engine/JDOClassDescriptor.java
===================================================================
--- C:/Java/castor-4/src/main/java/org/exolab/castor/jdo/engine/JDOClassDescriptor.java (revision 6373)
+++ C:/Java/castor-4/src/main/java/org/exolab/castor/jdo/engine/JDOClassDescriptor.java (working copy)
@@ -48,38 +48,29 @@
import java.util.Map;
import java.util.Properties;
-import org.castor.cache.Cache;
-import org.castor.cache.simple.CountLimited;
-import org.castor.cache.simple.TimeLimited;
-import org.castor.util.Messages;
-import org.exolab.castor.jdo.OQLQuery;
-import org.exolab.castor.jdo.QueryException;
-import org.exolab.castor.jdo.TimeStampable;
+import org.exolab.castor.mapping.AccessMode;
import org.exolab.castor.mapping.ClassDescriptor;
-import org.exolab.castor.mapping.MappingException;
+import org.exolab.castor.mapping.FieldDescriptor;
import org.exolab.castor.mapping.loader.ClassDescriptorImpl;
-import org.exolab.castor.mapping.xml.CacheTypeMapping;
-import org.exolab.castor.mapping.xml.Param;
/**
- * JDO class descriptors. Extends {@link ClassDescriptor} to include the
- * table name and other SQL-related information. All fields are of
- * type {@link JDOFieldDescriptor}, identity field is not included in the
- * returned field list, and contained fields are flattened out for
- * efficiency (thus all fields are directly accessible).
+ * JDO class descriptors. Extends {@link ClassDescriptor} to include the table name and
+ * other SQL-related information. All fields are of type {@link JDOFieldDescriptor},
+ * identity field is not included in the returned field list, and contained fields are
+ * flattened out for efficiency (thus all fields are directly accessible).
*
- * @author Assaf Arkin
+ * @author Assaf Arkin
+ * @author Ralf Joachim
* @version $Revision$ $Date: 2006-04-10 16:39:24 -0600 (Mon, 10 Apr 2006) $
*/
public class JDOClassDescriptor extends ClassDescriptorImpl {
+ //-----------------------------------------------------------------------------------
+
/** The name of the SQL table. */
- private final String _tableName;
+ private String _tableName;
- /** The names of columns that the identity consists of. */
- private final String[] _idnames;
-
- /** The key generator specified for this class. */
- private final KeyGeneratorDescriptor _keyGenDesc;
+ /** The access mode specified for this class. */
+ private AccessMode _accessMode = AccessMode.Shared;
/** The properties defining cache type and parameters. */
private final Properties _cacheParams = new Properties();
@@ -84,69 +75,24 @@
/** The properties defining cache type and parameters. */
private final Properties _cacheParams = new Properties();
- /**
- * Associated named queries, keyed by their name
- */
- private Map _namedQueries = new HashMap();
+ /** Associated named queries, keyed by their name. */
+ private final Map _namedQueries = new HashMap();
- public JDOClassDescriptor(final ClassDescriptor clsDesc,
- final KeyGeneratorDescriptor keyGenDesc)
- throws MappingException {
- super((ClassDescriptorImpl) clsDesc);
-
- _tableName = getMapping().getMapTo().getTable();
- if (_tableName == null) {
- throw new IllegalArgumentException("Argument 'tableName' is null");
- }
-
- if (getIdentity() == null) {
- throw new MappingException("mapping.noIdentity", getJavaClass().getName());
- }
-
- if (!(getIdentity() instanceof JDOFieldDescriptor)) {
- throw new IllegalArgumentException("Identity field must be of type JDOFieldDescriptor");
- }
-
- if ((getExtends() != null) && !(getExtends() instanceof JDOClassDescriptor)) {
- throw new IllegalArgumentException( "Extended class does not have a JDO descriptor" );
- }
-
- _idnames = new String[_identities.length];
- for (int i = 0; i < _idnames.length; i++) {
- String[] sqlNames = ((JDOFieldDescriptor) _identities[i]).getSQLName();
- if (sqlNames == null) {
- throw new MappingException("mapping.noSqlName", _identities[i].getFieldName(), getJavaClass().getName());
- }
- _idnames[i] = sqlNames[0];
- }
-
- _keyGenDesc = keyGenDesc;
+ /** The key generator specified for this class. */
+ private KeyGeneratorDescriptor _keyGenDesc;
- CacheTypeMapping cacheMapping = getMapping().getCacheTypeMapping();
- if (cacheMapping != null) {
- String capacity = Integer.toString(cacheMapping.getCapacity());
- _cacheParams.put(CountLimited.PARAM_CAPACITY, capacity);
- _cacheParams.put(TimeLimited.PARAM_TTL, capacity);
-
- Param[] params = cacheMapping.getParam();
- for (int i = 0; i < params.length; i++) {
- _cacheParams.put(params[i].getName(), params[i].getValue());
- }
+ //-----------------------------------------------------------------------------------
- String debug = new Boolean(cacheMapping.getDebug()).toString();
- _cacheParams.put(Cache.PARAM_DEBUG, debug);
-
- String type = cacheMapping.getType();
- if ((TimeStampable.class.isAssignableFrom(getJavaClass()))
- && (type != null) && (type.equalsIgnoreCase("none"))) {
- throw new MappingException(Messages.format("persist.wrongCacheTypeSpecified", getMapping().getName()));
- }
- _cacheParams.put(Cache.PARAM_TYPE, type);
- }
-
- _cacheParams.put(Cache.PARAM_NAME, getMapping().getName());
+ public JDOClassDescriptor() {
+ super();
}
+
+ //-----------------------------------------------------------------------------------
+ protected void setTableName(final String tableName) {
+ _tableName = tableName;
+ }
+
/**
* Returns the table name to which this object maps.
*
@@ -155,6 +101,18 @@
public String getTableName() {
return _tableName;
}
+
+ protected void setAccessMode(final AccessMode accessMode) {
+ _accessMode = accessMode;
+ }
+
+ public AccessMode getAccessMode() {
+ return _accessMode;
+ }
+
+ protected void addCacheParam(final String key, final String value) {
+ _cacheParams.put(key, value);
+ }
public Properties getCacheParams() {
return _cacheParams;
@@ -160,77 +118,78 @@
return _cacheParams;
}
+ protected void addNamedQuery(final String name, final String query) {
+ _namedQueries.put(name, query);
+ }
+
+ /**
+ * Get map of named query strings associated with their names.
+ *
+ * @return Map of named query strings associated with their names.
+ */
+ public Map getNamedQueries() {
+ return _namedQueries;
+ }
+
+ /**
+ * Set key generator specified for this class.
+ *
+ * @param keyGenDesc Key generator descriptor.
+ */
+ protected void setKeyGeneratorDescriptor(final KeyGeneratorDescriptor keyGenDesc) {
+ _keyGenDesc = keyGenDesc;
+ }
+
+ /**
+ * Get key generator specified for this class.
+ *
+ * @return Key generator descriptor.
+ */
+ public KeyGeneratorDescriptor getKeyGeneratorDescriptor() {
+ return _keyGenDesc;
+ }
+
+ //-----------------------------------------------------------------------------------
+
/**
- * Returns a JDOFieldDescriptor for the field with the name passed. Null
+ * Returns a JDOFieldDescriptor for the field with the name passed. 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 6373)
+++ 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,133 +133,321 @@
//-----------------------------------------------------------------------------------
+ /** 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;
+
+ //-----------------------------------------------------------------------------------
+ public JDOMappingLoader(ClassLoader loader) {
+ super(loader);
+ }
+
+ //-----------------------------------------------------------------------------------
/**
- * Used by the constructor for creating key generators.
- * See {@link #loadMapping}.
+ * {@inheritDoc}
*/
- private Hashtable _keyGenDescs = new Hashtable();
-
- /**
- * Used to locally register all loaded queries
- * to detect duplicated query names.
- * See {@link #createDescriptor(ClassMapping)}.
- */
- private Hashtable _namedQueries = new Hashtable();
+ 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());
+ }
- // create a key generator descriptor
- keyGenName = clsMap.getKeyGenerator();
- keyGenDesc = null;
- if (keyGenName != null) {
- String keyGenFactoryName;
- KeyGeneratorDef keyGenDef;
- Enumeration enumeration;
- Properties params;
-
- // 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());
+ 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());
+ }
}
}
- keyGenDesc = (KeyGeneratorDescriptor) _keyGenDescs.get(keyGenName);
- if (keyGenDesc == null) {
- keyGenDesc = new KeyGeneratorDescriptor(keyGenName,
- keyGenFactoryName, params, _keyGenReg);
- _keyGenDescs.put(keyGenName, keyGenDesc);
+ } 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); }
}
}
- JDOClassDescriptor classDescriptor = new JDOClassDescriptor(clsDesc, keyGenDesc);
+ // Set identities on class descriptor.
+ FieldDescriptor[] ids = new FieldDescriptor[idList.size()];
+ clsDesc.setIdentities((FieldDescriptor[]) idList.toArray(ids));
+
+ // Set fields on class descriptor.
+ FieldDescriptor[] fields = new FieldDescriptor[fieldList.size()];
+ clsDesc.setFields((FieldDescriptor[]) fieldList.toArray(fields));
+
+ clsDesc.setTableName(clsMap.getMapTo().getTable());
- // extract named queries and add to (JDO) class descriptor
+ 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());
+
+ 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 = Integer.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 namedQuery = (NamedQuery) namedQueriesEnum.nextElement();
- try {
- if(_namedQueries.contains(namedQuery.getName())) {
- throw new MappingException("Duplicate entry for named query with name " + namedQuery.getName());
- }
- classDescriptor.addNamedQuery(namedQuery.getName(), namedQuery.getQuery());
- _namedQueries.put(namedQuery.getName(), namedQuery);
- } catch (QueryException e) {
- throw new MappingException(e);
+ 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, keyGenName, new Properties(), _keyGenReg);
+ _keyGenDescs.put(keyGenName, keyGenDesc);
}
}
- return classDescriptor;
+ clsDesc.setKeyGeneratorDescriptor(keyGenDesc);
+ }
+
+ 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 +573,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 +586,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 +619,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 +727,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 6373)
+++ 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;
/**
@@ -140,9 +141,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 6373)
+++ 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 6373)
+++ 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 6373)
+++ 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 6373)
+++ 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 6373)
+++ 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 6373)
+++ C:/Java/castor-4/src/main/java/org/exolab/castor/mapping/loader/AbstractMappingLoader.java (working copy)
@@ -58,9 +58,7 @@
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.jdo.engine.JDOFieldDescriptor;
import org.exolab.castor.mapping.ClassDescriptor;
import org.exolab.castor.mapping.CollectionHandler;
import org.exolab.castor.mapping.ExtendedFieldHandler;
@@ -86,9 +84,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";
@@ -129,6 +125,8 @@
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 +136,8 @@
super(loader);
}
+ //--------------------------------------------------------------------------
+
/**
* {@inheritDoc}
*/
@@ -145,21 +145,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.
- */
- protected final Class resolveType(final String typeName)
- throws ClassNotFoundException {
- return Types.typeFromName(getClassLoader(), typeName);
- }
+ //--------------------------------------------------------------------------
/**
- * {@inheritDoc}
+ * 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 void loadMappingInternal(final MappingRoot mapping, final Object param)
+ public abstract void loadMapping(final MappingRoot mapping, final Object param)
+ throws MappingException;
+
+ 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 +166,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 +174,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,17 +180,12 @@
// 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();) {
+ // iterate over all class descriptors and resolve relations between them
+ for (Iterator i = descriptorIterator(); i.hasNext();) {
ClassDescriptor clsDesc = (ClassDescriptor) i.next();
if (clsDesc != NO_DESCRIPTOR) { resolveRelations(clsDesc); }
}
@@ -206,119 +190,10 @@
if (clsDesc != NO_DESCRIPTOR) { resolveRelations(clsDesc); }
}
}
-
- 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 )
- if ((origin == clsMap) && (ids.length > fields.length)) {
- StringBuffer badIdentities = new StringBuffer();
- for (int index = 0; index < ids.length; index++) {
- if (index != 0) { badIdentities.append(" or "); }
- badIdentities.append(ids[index]);
- }
- throw new MappingException(
- "mapping.identityMissing", badIdentities, javaClass.getName());
- }
-
- // Divide fields into identity fields and regular fields
- FieldDescriptor[] identities = new FieldDescriptor[ids.length];
- fields = divideFieldDescriptors(fields, ids, identities);
-
- if (extend != null) {
- // We allow identity fields to be re-defined in the extends class mapping to
- // override some properties of the field, for example, .
- if (extend instanceof ClassDescriptorImpl) {
- ClassDescriptorImpl extendImpl = (ClassDescriptorImpl) extend;
- for (int i = 0; i < identities.length; i++) {
- if (identities[i] == null) {
- identities[i] = extendImpl.getIdentities()[i];
- }
- }
- } else {
- // We leave things in the old way for the XML side
- if (identities[0] == null) {
- if (extend.getIdentity() != null) {
- identities = new FieldDescriptor[] {extend.getIdentity()};
- } else {
- identities = new FieldDescriptor[0];
- }
- }
- }
- }
-
- // A general test of identities
- if ((ids != null) && (ids.length > 0)) {
- if ((identities == null) || (identities.length <= 0 )) {
- StringBuffer badIdentities = new StringBuffer();
- for (int i = 0; i < ids.length; i++) {
- if (i != 0) { badIdentities.append("/"); }
- badIdentities.append(ids[i]);
- }
- throw new MappingException(
- "mapping.identityMissing", badIdentities, javaClass.getName());
- }
- }
-
- // Create the class descriptor.
- return new ClassDescriptorImpl(
- clsMap, javaClass, fields, identities, extend, depend);
- }
-
+
+ protected abstract ClassDescriptor createClassDescriptor(final ClassMapping clsMap)
+ throws MappingException;
+
/**
* Gets the ClassDescriptor the given classMapping extends.
*
@@ -330,27 +205,31 @@
* @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());
+ 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);
- }
+ if (result == null) {
+ throw new MappingException(
+ "mapping.extendsMissing", mapping, javaClass.getName());
+ }
- if (result == NO_DESCRIPTOR) {
- throw new MappingException("mapping.extendsNoMapping", mapping, clsName);
- }
+ if (result == NO_DESCRIPTOR) {
+ throw new MappingException(
+ "mapping.extendsNoMapping", 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,26 +243,94 @@
* @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) || (result == NO_DESCRIPTOR)) {
+ 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 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());
+ }
- return result;
- } catch (ClassNotFoundException e) {
- throw new MappingException(e);
+ fldList.remove(i);
+ return field;
+ }
}
+ return null;
}
+ protected abstract void resolveRelations(final ClassDescriptor clsDesc);
+
+ //--------------------------------------------------------------------------
+
+
+
+
+
+
+
+ /**
+ * 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);
+ }
+ }
+
/**
* Create field descriptors. The class mapping information is used to create
* descriptors for all the fields in the class, except for container fields.
@@ -395,7 +342,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 +351,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 +366,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 +373,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 +383,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 +419,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 +439,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 +446,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 +466,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 +977,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 6373)
+++ 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 6373)
+++ C:/Java/castor-4/src/main/java/org/exolab/castor/mapping/loader/ClassDescriptorImpl.java (working copy)
@@ -42,168 +42,56 @@
*
* $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;
-
-
- /**
- * The descriptor of the class which this class extends,
- * or null if this is a top-level class.
- */
- private final ClassDescriptor _extends;
+ private ClassMapping _mapping;
- /**
- * 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();
-
- private final ClassDescriptor _depends;
+ /** The Java class for this descriptor. */
+ private Class _javaClass;
- /**
- * The field of the identity for this class.
- */
- protected final FieldDescriptor[] _identities;
-
-
- /**
- * The access mode specified for this class.
- */
- private AccessMode _accessMode;
-
-
- /**
- * 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();
- }
+ /** The descriptor of the class which this class extends,
+ * or null if this is a top-level class. */
+ private ClassDescriptor _extends;
- 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());
+ /** 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();
- if (map.getAccess() == null) {
- _accessMode = AccessMode.Shared;
- } else {
- _accessMode = AccessMode.valueOf(map.getAccess().toString());
- }
- }
-
- 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();
+ private ClassDescriptor _depends;
- _depends = depend;
+ /** The fields described for this class. */
+ private FieldDescriptor[] _fields;
- 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;
- }
+ /** The field of the identity for this class. */
+ private FieldDescriptor[] _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);
- }
- }
+ //-----------------------------------------------------------------------------------
+
+ public ClassDescriptorImpl() { }
/**
- * Constructor used by derived classes.
+ * Constructor used for AbstractMappingLoader.NO_DESCRIPTOR only.
*/
protected ClassDescriptorImpl(final Class javaClass) {
- _map = null;
+ _mapping = null;
_javaClass = javaClass;
_extends = null;
_fields = null;
@@ -208,34 +96,36 @@
_extends = null;
_fields = null;
_identities = null;
- _depends = null;
- _accessMode = null;
-
}
+ //-----------------------------------------------------------------------------------
+
+ public void setMapping(final ClassMapping mapping) {
+ _mapping = mapping;
+ }
+
public ClassMapping getMapping() {
- return _map;
+ return _mapping;
+ }
+
+ public void setJavaClass(final Class javaClass) {
+ _javaClass = javaClass;
}
- 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 +133,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 +145,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 +161,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/mapping/loader/FieldHandlerImpl.java
===================================================================
--- C:/Java/castor-4/src/main/java/org/exolab/castor/mapping/loader/FieldHandlerImpl.java (revision 6373)
+++ C:/Java/castor-4/src/main/java/org/exolab/castor/mapping/loader/FieldHandlerImpl.java (working copy)
@@ -759,7 +759,7 @@
/**
* Mutator method used by {@link AbstractMappingLoader}.
*/
- void setRequired(final boolean required) { }
+ public void setRequired(final boolean required) { }
/**
* Sets the TypeConvertor used during calls to getValue
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 6373)
+++ 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 6373)
+++ 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 6373)
+++ 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 6373)
+++ C:/Java/castor-4/src/main/java/org/exolab/castor/xml/XMLMappingLoader.java (working copy)
@@ -1,6 +1,6 @@
/**
+ * ("Software"), with or without modification, are permitted provided
* Redistribution and use of this software and associated documentation
- * ("Software"), with or without modification, are permitted provided
* that the following conditions are met:
*
* 1. Redistributions of source code must retain copyright
@@ -49,7 +49,10 @@
*/
package org.exolab.castor.xml;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
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;
@@ -57,10 +60,14 @@
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.ClassDescriptorImpl;
import org.exolab.castor.mapping.loader.CollectionHandlers;
import org.exolab.castor.mapping.loader.AbstractMappingLoader;
+import org.exolab.castor.mapping.loader.FieldDescriptorImpl;
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;
@@ -65,6 +72,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;
@@ -83,6 +91,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
@@ -93,52 +103,41 @@
* @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.
- */
+ //-----------------------------------------------------------------------------------
+
+ /** The Jakarta Commons
+ * Logging instance used for all logging. */
+ private static final Log LOG = LogFactory.getLog(XMLMappingLoader.class);
+
+ /** 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
- **/
+ /** 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
- */
+ /** The default NodeType for primitives. */
private NodeType _primitiveNodeType = null;
+ /** Naming conventions. */
+ private XMLNaming _naming = null;
+
+ //-----------------------------------------------------------------------------------
/**
* Creates a new XMLMappingLoader
@@ -145,61 +144,48 @@
*/
public XMLMappingLoader(ClassLoader loader) {
super(loader);
-
+
LocalConfiguration config = LocalConfiguration.getInstance();
-
_primitiveNodeType = config.getPrimitiveNodeType();
- _naming = config.getXMLNaming();
+ _naming = config.getXMLNaming();
+ }
- } //-- XMLMappingLoader
-
-
+ //-----------------------------------------------------------------------------------
+ /**
+ * {@inheritDoc}
+ */
public BindingType getBindingType() { return BindingType.XML; }
- private void createResolver() {
- _cdResolver = (XMLClassDescriptorResolverImpl)
- ClassDescriptorResolverFactory.createClassDescriptorResolver(BindingType.XML);
- _cdResolver.setIntrospection(false);
- _cdResolver.setLoadPackageMappings(false);
+ //-----------------------------------------------------------------------------------
+
+ /**
+ * {@inheritDoc}
+ */
+ public void loadMapping(final MappingRoot mapping, final Object param)
+ throws MappingException {
+ if (loadMapping()) { createClassDescriptors(mapping); }
}
-
- 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;
-
- 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 );
- }
- }
+ //-----------------------------------------------------------------------------------
+
+ protected final ClassDescriptor createClassDescriptor(final ClassMapping clsMap)
+ throws MappingException {
+ ClassDescriptor clsDesc = createDescriptor(clsMap);
+ if (clsDesc == NO_DESCRIPTOR) {
+ // 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()));
+ return null;
}
- if ( clsDesc instanceof XMLClassDescriptorImpl )
- ( (XMLClassDescriptorImpl) clsDesc ).sortDescriptors();
+ return clsDesc;
}
-
- protected ClassDescriptor createDescriptor( ClassMapping clsMap )
- throws MappingException
- {
- ClassDescriptor clsDesc;
- String xmlName;
-
+ /**
+ * {@inheritDoc}
+ */
+ protected final ClassDescriptor createDescriptor(final ClassMapping clsMap)
+ throws MappingException {
if (clsMap.getAutoComplete()) {
if ((clsMap.getMapTo() == null) &&
((clsMap.getClassChoice() == null) ||
@@ -206,25 +192,131 @@
(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) {
+
+ }
+ }
+ }
+
+
+
+
+
+
+ // Create the class descriptor.
+ ClassDescriptorImpl clsDesc = new ClassDescriptorImpl();
+
+ // Set reference to class mapping on class descriptor.
+ clsDesc.setMapping(clsMap);
+
+ // Obtain the Java class.
+ Class javaClass = resolveType(clsMap.getName());
+ if (clsMap.getVerifyConstructable()) {
+ 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);
+ 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);
+
+ // Make sure there are no two fields with the same name.
+ checkFieldNameDuplicates(allFields, javaClass);
+
+ // 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]);
}
- catch(ResolverException rx) {}
+ }
+
+ 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); }
}
}
- // Use super class to create class descriptor. Field descriptors will be
- // generated only for supported fields, see createFieldDesc later on.
- clsDesc = super.createDescriptor( clsMap );
+ // Set identities on class descriptor.
+ if (idList.size() != 0) {
+ for (int i = 0; i < idList.size(); i++) {
+ FieldDescriptor field = (FieldDescriptor) idList.get(i);
+ if (field instanceof FieldDescriptorImpl) {
+ ((FieldDescriptorImpl) field).setRequired(true);
+ }
+ if (field.getHandler() instanceof FieldHandlerImpl) {
+ ((FieldHandlerImpl) field.getHandler()).setRequired(true);
+ }
+ }
+
+ FieldDescriptor[] ids = new FieldDescriptor[idList.size()];
+ clsDesc.setIdentities((FieldDescriptor[]) idList.toArray(ids));
+ }
+
+ // Set fields on class descriptor.
+ FieldDescriptor[] fields = new FieldDescriptor[fieldList.size()];
+ clsDesc.setFields((FieldDescriptor[]) fieldList.toArray(fields));
+
+
+
+
+
+
+
+
MapTo mapTo = clsMap.getMapTo();
+ String xmlName;
if (( mapTo == null) || (mapTo.getXml() == null)) {
String clsName = clsDesc.getJavaClass().getName();
int idx = clsName.lastIndexOf('.');
@@ -248,13 +340,10 @@
Class type = xmlClassDesc.getJavaClass();
//-- check compiled descriptors
- if (_cdResolver == null) {
- createResolver();
- }
+ if (_cdResolver == null) { createResolver(); }
try {
referenceDesc = _cdResolver.resolveXML(type);
- }
- catch(ResolverException rx) {
+ } catch (ResolverException rx) {
throw new MappingException(rx);
}
@@ -280,7 +369,7 @@
identity = clsMap.getIdentity(0);
- FieldDescriptor[] fields = xmlClassDesc.getFields();
+ FieldDescriptor[] xmlFields = xmlClassDesc.getFields();
// Attributes
XMLFieldDescriptor[] introFields = referenceDesc.getAttributeDescriptors();
@@ -285,7 +374,7 @@
// Attributes
XMLFieldDescriptor[] introFields = referenceDesc.getAttributeDescriptors();
for (int i = 0; ifieldName is in fields
*/
@@ -343,7 +469,7 @@
} //-- method: isMatchFieldName
- protected FieldDescriptor createFieldDesc( Class javaClass, FieldMapping fieldMap )
+ protected AbstractFieldDescriptor createFieldDesc( Class javaClass, FieldMapping fieldMap )
throws MappingException
{
@@ -479,7 +605,7 @@
//-- has class descriptor for type specified
if (xml.getClassMapping() != null) {
ClassDescriptor cd = createDescriptor(xml.getClassMapping());
- xmlDesc.setClassDescriptor((XMLClassDescriptor)cd);
+ xmlDesc.setClassDescriptor(cd);
}
//-- has location path?
Index: C:/Java/castor-4/src/main/java/org/exolab/castor/xml/util/XMLClassDescriptorAdapter.java
===================================================================
--- C:/Java/castor-4/src/main/java/org/exolab/castor/xml/util/XMLClassDescriptorAdapter.java (revision 6373)
+++ C:/Java/castor-4/src/main/java/org/exolab/castor/xml/util/XMLClassDescriptorAdapter.java (working copy)
@@ -68,19 +68,6 @@
*
* @param classDesc the ClassDescriptor to "adapt"
* @param xmlName the XML name for the class
- */
- public XMLClassDescriptorAdapter(ClassDescriptor classDesc, String xmlName)
- throws org.exolab.castor.mapping.MappingException
- {
- this(classDesc, xmlName, null);
- } //-- XMLClassDescriptor
-
- /**
- * Creates a new XMLClassDescriptorAdapter using the
- * given ClassDescriptor
- *
- * @param classDesc the ClassDescriptor to "adapt"
- * @param xmlName the XML name for the class
* @param primitiveNodeType the NodeType to use for primitives
*/
public XMLClassDescriptorAdapter(ClassDescriptor classDesc, String xmlName, NodeType primitiveNodeType)
@@ -240,9 +227,7 @@
*
* @param classDesc the XMLClassDescriptor to process
**/
- private void process(XMLClassDescriptor classDesc)
- throws org.exolab.castor.mapping.MappingException
- {
+ private void process(XMLClassDescriptor classDesc) {
FieldDescriptor identity = classDesc.getIdentity();
FieldDescriptor[] fields = classDesc.getFields();
for (int i = 0; i < fields.length; i++) {
@@ -260,7 +245,7 @@
setIdentity((XMLFieldDescriptor)identity);
}
setXMLName(classDesc.getXMLName());
- setExtendsWithoutFlatten((XMLClassDescriptor)classDesc.getExtends());
+ setExtendsWithoutFlatten((XMLClassDescriptor) classDesc.getExtends());
} //-- process