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 6342)
+++ C:/Java/castor-4/src/main/java/org/exolab/castor/jdo/engine/JDOClassDescriptor.java (working copy)
@@ -44,7 +44,6 @@
*/
package org.exolab.castor.jdo.engine;
-import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
@@ -52,34 +51,34 @@
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.FieldDescriptor;
import org.exolab.castor.mapping.MappingException;
import org.exolab.castor.mapping.loader.ClassDescriptorImpl;
import org.exolab.castor.mapping.xml.CacheTypeMapping;
+import org.exolab.castor.mapping.xml.ClassMapping;
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;
- /** 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 final AccessMode _accessMode;
/** The properties defining cache type and parameters. */
private final Properties _cacheParams = new Properties();
@@ -84,15 +83,19 @@
/** 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();
+ /** The key generator specified for this class. */
+ private KeyGeneratorDescriptor _keyGenDesc;
+
+ /** Associated named queries, keyed by their name. */
+ private Map _namedQueries;
- public JDOClassDescriptor(final ClassDescriptor clsDesc,
- final KeyGeneratorDescriptor keyGenDesc)
+ //-----------------------------------------------------------------------------------
+
+ public JDOClassDescriptor(final ClassMapping clsMap, final Class javaClass,
+ final FieldDescriptor[] fields, final FieldDescriptor[] identities,
+ final ClassDescriptor extend)
throws MappingException {
- super((ClassDescriptorImpl) clsDesc);
+ super(clsMap, javaClass, fields, identities, extend);
_tableName = getMapping().getMapTo().getTable();
if (_tableName == null) {
@@ -107,6 +110,13 @@
throw new IllegalArgumentException("Identity field must be of type JDOFieldDescriptor");
}
+ for (int i = 0; i < getIdentities().length; i++) {
+ String[] sqlNames = ((JDOFieldDescriptor) getIdentities()[i]).getSQLName();
+ if (sqlNames == null) {
+ throw new MappingException("mapping.noSqlName", getIdentities()[i].getFieldName(), getJavaClass().getName());
+ }
+ }
+
if ((getExtends() != null) && !(getExtends() instanceof JDOClassDescriptor)) {
throw new IllegalArgumentException( "Extended class does not have a JDO descriptor" );
}
@@ -111,17 +121,6 @@
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;
-
CacheTypeMapping cacheMapping = getMapping().getCacheTypeMapping();
if (cacheMapping != null) {
String capacity = Integer.toString(cacheMapping.getCapacity());
@@ -145,7 +144,15 @@
}
_cacheParams.put(Cache.PARAM_NAME, getMapping().getName());
+
+ if (getMapping().getAccess() == null) {
+ _accessMode = AccessMode.Shared;
+ } else {
+ _accessMode = AccessMode.valueOf(getMapping().getAccess().toString());
+ }
}
+
+ //-----------------------------------------------------------------------------------
/**
* Returns the table name to which this object maps.
@@ -155,6 +162,10 @@
public String getTableName() {
return _tableName;
}
+
+ public AccessMode getAccessMode() {
+ return _accessMode;
+ }
public Properties getCacheParams() {
return _cacheParams;
@@ -161,40 +172,18 @@
}
/**
- * 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.
+ * Set key generator specified for this class.
+ *
+ * @param keyGenDesc Key generator descriptor.
*/
- 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))) {
-
- field = (JDOFieldDescriptor) _fields[i];
- break;
- }
- }
-
- 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];
- }
- }
- }
-
- return field;
+ protected void setKeyGeneratorDescriptor(final KeyGeneratorDescriptor keyGenDesc) {
+ _keyGenDesc = keyGenDesc;
}
/**
- * Returns the key generator specified for this class.
+ * Get key generator specified for this class.
*
- * @return The key generator descriptor
+ * @return Key generator descriptor.
*/
public KeyGeneratorDescriptor getKeyGeneratorDescriptor() {
return _keyGenDesc;
@@ -199,38 +188,66 @@
public KeyGeneratorDescriptor getKeyGeneratorDescriptor() {
return _keyGenDesc;
}
-
+
/**
- * @return The names of columns that the identity consists of.
+ * Set map of named query strings associated with their names.
+ *
+ * @param namedQueries Map of named query strings associated with their names.
*/
- public String[] getIdentityColumnNames() {
- return _idnames;
- }
-
- public String toString() {
- return super.toString() + " AS " + _tableName;
+ protected void setNamedQueries(final Map namedQueries) {
+ _namedQueries = namedQueries;
}
/**
- * 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
+ * Get map of named query strings associated with their names.
+ *
+ * @return Map of named query strings associated with their names.
*/
- public String getNamedQuery(String name) {
- String namedQuery = (String) _namedQueries.get(name);
- return namedQuery;
+ public Map getNamedQueries() {
+ return _namedQueries;
}
+ //-----------------------------------------------------------------------------------
+
/**
- * 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
+ * Returns a JDOFieldDescriptor for the field with the name passed. null
+ * if named field does not exist.
+ *
+ * @param name Name of the field to return.
+ * @return Field if it exists, otherwise null.
*/
- public void addNamedQuery(final String name, final String namedQuery) throws QueryException {
- if (_namedQueries.containsKey(name)) {
- throw new QueryException ("Duplicate entry for named query " + name);
+ public JDOFieldDescriptor getField(String name) {
+ FieldDescriptor[] fields = getFields();
+ for (int i = 0 ; i < fields.length ; ++i) {
+ FieldDescriptor field = fields[i];
+ if ((field instanceof JDOFieldDescriptor)
+ && (field.getFieldName().equals(name))) {
+
+ return (JDOFieldDescriptor) field;
+ }
}
- _namedQueries.put(name, namedQuery);
+
+ 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 null;
+ }
+
+ //-----------------------------------------------------------------------------------
+
+ /**
+ * {@inheritDoc}
+ */
+ public String toString() {
+ return super.toString() + " AS " + _tableName;
}
+
+ //-----------------------------------------------------------------------------------
}
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 6342)
+++ C:/Java/castor-4/src/main/java/org/exolab/castor/jdo/engine/JDOMappingLoader.java (working copy)
@@ -49,8 +49,8 @@
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.mapping.*;
+import org.exolab.castor.mapping.loader.ClassDescriptorImpl;
import org.exolab.castor.mapping.loader.CollectionHandlers;
import org.exolab.castor.mapping.loader.FieldHandlerFriend;
import org.exolab.castor.mapping.loader.FieldHandlerImpl;
@@ -65,8 +65,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 +76,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 {
@@ -84,6 +89,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,59 +122,68 @@
//-----------------------------------------------------------------------------------
+ /** Used by the constructor for creating key generators. */
+ private Map _keyGenDefs;
+ /** Used by the constructor for creating key generators. */
+ private Map _keyGenDescs;
- /**
- * Used by the constructor for creating key generators.
- * See {@link #loadMapping}.
- */
- private Hashtable _keyGenDefs = new Hashtable();
+ /** 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 KeyGeneratorRegistry _keyGenReg;
+ /** An association map between class name and a list of query definitions of this
+ * class. */
+ private Map _namedQueryDefs;
- /**
- * Used by the constructor for creating key generators.
- * See {@link #loadMapping}.
- */
- 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();
+ /** The JDO PersistenceFactory (aka BaseFactory) is used for adjusting SQL type for
+ * the given database. */
+ private BaseFactory _factory;
+
+ //-----------------------------------------------------------------------------------
+ public JDOMappingLoader(ClassLoader loader) {
+ super(loader);
+ }
+
+ //-----------------------------------------------------------------------------------
/**
- * The JDO PersistenceFactory (aka BaseFactory) is used for adjusting
- * SQL type for the given database.
+ * {@inheritDoc}
*/
- private BaseFactory _factory;
-
+ public BindingType getBindingType() { return BindingType.JDO; }
+
/**
- * 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}.
+ * {@inheritDoc}
*/
- private KeyGeneratorRegistry _keyGenReg = new KeyGeneratorRegistry();
+ public void loadMapping(final MappingRoot mapping, final Object param)
+ throws MappingException {
+ if (loadMapping()) {
+ _factory = (BaseFactory) param;
+
+ loadKeyGenDefinitions(mapping);
+ loadNamedQueryDefinitions(mapping);
+
+ loadClassMapping(mapping);
+
+ cleanupNamedQueryDefinitions();
+ cleanupKeyGenDefinitions();
+ }
+ }
+
- public JDOMappingLoader(ClassLoader loader) {
- super(loader);
- }
-
- public BindingType getBindingType() { return BindingType.JDO; }
+
+
+ /**
+ * {@inheritDoc}
+ */
protected ClassDescriptor createDescriptor(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. JDO only supports
+ // JDO class descriptors.
if ((clsMap.getMapTo() == null) || (clsMap.getMapTo().getTable() == null)) {
return AbstractMappingLoader.NO_DESCRIPTOR;
}
@@ -172,76 +188,121 @@
return AbstractMappingLoader.NO_DESCRIPTOR;
}
- // See if we have a compiled descriptor.
- clsDesc = null;
- if ((clsDesc != null) && (clsDesc instanceof JDOClassDescriptor)) {
- return clsDesc;
+ // Obtain the Java class.
+ Class javaClass;
+ try {
+ javaClass = resolveType(clsMap.getName());
+ } catch (ClassNotFoundException ex) {
+ throw new MappingException("mapping.classNotFound", clsMap.getName());
}
- // 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);
+ // 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());
- // 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());
- }
+ // If this class depends another class, need to obtain the depended class
+ ClassDescriptor depend = getDepended(clsMap, javaClass.getName());
+
+ FieldDescriptor[] identities = null;
+
+ // 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)) {
+ // 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());
+ }
- // create a key generator descriptor
- keyGenName = clsMap.getKeyGenerator();
- keyGenDesc = null;
- if (keyGenName != null) {
- String keyGenFactoryName;
- KeyGeneratorDef keyGenDef;
- Enumeration enumeration;
- Properties params;
+ // Divide fields into identity fields and regular fields
+ identities = new FieldDescriptor[ids.length];
+ fields = divideFieldDescriptors(fields, ids, identities);
- // 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());
+ 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];
+ }
+ }
}
}
- keyGenDesc = (KeyGeneratorDescriptor) _keyGenDescs.get(keyGenName);
- if (keyGenDesc == null) {
- keyGenDesc = new KeyGeneratorDescriptor(keyGenName,
- keyGenFactoryName, params, _keyGenReg);
- _keyGenDescs.put(keyGenName, keyGenDesc);
+
+ // 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());
+ }
}
}
- JDOClassDescriptor classDescriptor = new JDOClassDescriptor(clsDesc, keyGenDesc);
+ if (!Types.isConstructable(javaClass, true)) {
+ throw new MappingException("mapping.classNotConstructable", javaClass.getName());
+ }
- // 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());
- }
- classDescriptor.addNamedQuery(namedQuery.getName(), namedQuery.getQuery());
- _namedQueries.put(namedQuery.getName(), namedQuery);
- } catch (QueryException e) {
- throw new MappingException(e);
- }
+ // 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 ((identities == null) || (identities[0] == null)) {
+ throw new MappingException("mapping.noIdentity", javaClass.getName());
}
+
+ // Create the class descriptor.
+ JDOClassDescriptor clsDesc = new JDOClassDescriptor(
+ clsMap, javaClass, fields, identities, extend);
- return classDescriptor;
+ clsDesc.setDepends(depend);
+
+ String keyGenName = clsMap.getKeyGenerator();
+ clsDesc.setKeyGeneratorDescriptor(createKeyGenDescriptor(keyGenName));
+ clsDesc.setNamedQueries(createNamedQueryDescriptors(clsMap.getName()));
+
+ return clsDesc;
}
+
+
+
+
+
+
+
+
+
/**
* Parse the sql type attribute to build an
* array of types, needed to support whitespace inside
@@ -531,31 +592,122 @@
return jdoFieldDescriptor;
}
- protected void loadMappingInternal(final MappingRoot mapping, final Object param)
+ //-----------------------------------------------------------------------------------
+
+ /**
+ * Load the key generator definitions and check for duplicate names.
+ *
+ * @param mapping
+ * @throws MappingException
+ */
+ private void loadKeyGenDefinitions(final MappingRoot mapping)
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;
+ _keyGenDefs = new HashMap();
+
+ Enumeration enumeration = mapping.enumerateKeyGeneratorDef();
+ while (enumeration.hasMoreElements()) {
+ KeyGeneratorDef keyGenDef = (KeyGeneratorDef) enumeration.nextElement();
+ String 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);
+ }
- keyGenDef = (KeyGeneratorDef) enumeration.nextElement();
- name = keyGenDef.getAlias();
- if (name == null) {
- name = keyGenDef.getName();
+ _keyGenDescs = new HashMap();
+ _keyGenReg = new KeyGeneratorRegistry();
+ }
+
+ private KeyGeneratorDescriptor createKeyGenDescriptor(final String keyGenName) {
+ if (keyGenName == null) { return null; }
+
+ String keyGenFactoryName = keyGenName;
+ Properties params = new Properties();
+
+ // First search among declared key generators and resolve alias
+ KeyGeneratorDef keyGenDef = (KeyGeneratorDef) _keyGenDefs.get(keyGenName);
+ if (keyGenDef != null) {
+ keyGenFactoryName = keyGenDef.getName();
+ Enumeration enumeration = keyGenDef.enumerateParam();
+ while (enumeration.hasMoreElements()) {
+ Param par = (Param) enumeration.nextElement();
+ params.put(par.getName(), par.getValue());
}
- if ( _keyGenDefs.get( name ) != null ) {
- throw new MappingException( Messages.format( "mapping.dupKeyGen", name ) );
+ }
+
+ Object keyGenDesc = _keyGenDescs.get(keyGenName);
+ if (keyGenDesc == null) {
+ keyGenDesc = new KeyGeneratorDescriptor(
+ keyGenName, keyGenFactoryName, params, _keyGenReg);
+ _keyGenDescs.put(keyGenName, keyGenDesc);
+ }
+ return (KeyGeneratorDescriptor) keyGenDesc;
+ }
+
+ private void cleanupKeyGenDefinitions() {
+ if (_keyGenReg != null) { _keyGenReg.clear(); }
+ _keyGenReg = null;
+ if (_keyGenDescs != null) { _keyGenDescs.clear(); }
+ _keyGenDescs = null;
+ if (_keyGenDefs != null) { _keyGenDefs.clear(); }
+ _keyGenDefs = null;
+ }
+
+ //-----------------------------------------------------------------------------------
+
+ private void loadNamedQueryDefinitions(final MappingRoot mapping)
+ throws MappingException {
+ _namedQueryDefs = new HashMap();
+
+ Set queryNames = new HashSet();
+
+ Enumeration enumeration = mapping.enumerateClassMapping();
+ while (enumeration.hasMoreElements()) {
+ ClassMapping clsMap = (ClassMapping) enumeration.nextElement();
+
+ List definitions = new ArrayList();
+
+ Enumeration namedQueriesEnum = clsMap.enumerateNamedQuery();
+ while (namedQueriesEnum.hasMoreElements()) {
+ NamedQuery namedQuery = (NamedQuery) namedQueriesEnum.nextElement();
+ String queryName = namedQuery.getName();
+ if (queryNames.contains(queryName)) {
+ String msg = "Duplicate entry for named query with name " + queryName;
+ throw new MappingException(msg);
+ }
+ queryNames.add(queryName);
+
+ definitions.add(namedQuery);
}
- _keyGenDefs.put( name, keyGenDef );
+
+ _namedQueryDefs.put(clsMap.getName(), definitions);
}
+
+ queryNames.clear();
+ }
- super.loadMappingInternal(mapping, null);
-
- _keyGenDefs = null;
- _keyGenDescs = null;
- _keyGenReg = null;
+ /**
+ * Extract named queries and add them to JDO class descriptor.
+ *
+ * @param className
+ */
+ private Map createNamedQueryDescriptors(final String className) {
+ Map namedQueries = new HashMap();
+
+ List definitions = (List) _namedQueryDefs.get(className);
+ for (int i = 0; i < definitions.size(); i++) {
+ NamedQuery def = (NamedQuery) definitions.get(i);
+ namedQueries.put(def.getName(), def.getQuery());
+ }
+
+ return namedQueries;
+ }
+
+ private void cleanupNamedQueryDefinitions() {
+ if (_namedQueryDefs != null) { _namedQueryDefs.clear(); }
+ _namedQueryDefs = null;
}
+
+ //-----------------------------------------------------------------------------------
}
Index: C:/Java/castor-4/src/main/java/org/exolab/castor/jdo/engine/KeyGeneratorRegistry.java
===================================================================
--- C:/Java/castor-4/src/main/java/org/exolab/castor/jdo/engine/KeyGeneratorRegistry.java (revision 6342)
+++ C:/Java/castor-4/src/main/java/org/exolab/castor/jdo/engine/KeyGeneratorRegistry.java (working copy)
@@ -128,4 +128,6 @@
}
return keyGen;
}
+
+ public void clear() { _keyGens.clear(); }
}
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 6342)
+++ 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 6342)
+++ 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 6342)
+++ 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 6342)
+++ 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 6342)
+++ 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/AbstractMappingLoader.java
===================================================================
--- C:/Java/castor-4/src/main/java/org/exolab/castor/mapping/loader/AbstractMappingLoader.java (revision 6342)
+++ C:/Java/castor-4/src/main/java/org/exolab/castor/mapping/loader/AbstractMappingLoader.java (working copy)
@@ -86,6 +86,8 @@
* @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);
@@ -129,6 +131,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 +142,8 @@
super(loader);
}
+ //--------------------------------------------------------------------------
+
/**
* {@inheritDoc}
*/
@@ -146,20 +152,16 @@
}
/**
- * 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 void loadClassMapping(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 +170,8 @@
List retryList = new ArrayList();
while (enumeration.hasMoreElements()) {
ClassMapping clsMap = (ClassMapping) enumeration.nextElement();
- ClassDescriptor clsDesc = null;
-
try {
- clsDesc = createDescriptor(clsMap);
+ createClassDescriptor(clsMap);
} catch (MappingException mx) {
// save for later for possible out-of-order mapping files...
retryList.add(clsMap);
@@ -177,14 +177,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 +183,11 @@
// 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()));
- }
+ createClassDescriptor(clsMap);
}
- 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,18 +192,18 @@
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 );
- }
+
+ //--------------------------------------------------------------------------
+
+ private void createClassDescriptor(final ClassMapping clsMap)
+ throws MappingException {
+ 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()));
}
}
@@ -230,93 +216,38 @@
* @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());
- }
+ protected abstract ClassDescriptor createDescriptor(final ClassMapping clsMap)
+ throws MappingException;
+
+
+
+
+
+
+
+ /**
+ * 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);
+ }
- // 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]);
+ 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 );
}
- 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);
}
/**
@@ -330,7 +261,7 @@
* @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 String clsName)
throws MappingException {
if (clsMap.getExtends() == null) { return null; }
@@ -364,7 +295,7 @@
* @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 String clsName)
throws MappingException {
if (clsMap.getDepends() == null) { return null; }
@@ -395,7 +326,7 @@
* @throws MappingException An exception indicating why mapping for the class cannot
* be created.
*/
- private FieldDescriptor[] createFieldDescriptors(final ClassMapping clsMap,
+ protected final FieldDescriptor[] createFieldDescriptors(final ClassMapping clsMap,
final Class javaClass) throws MappingException {
FieldMapping[] fldMap = null;
@@ -424,7 +355,7 @@
* the exception).
* @throws MappingException If at least two fields have the same name.
*/
- private void checkFieldNames(final FieldDescriptor[] fields, final String clsName)
+ protected final void checkFieldNames(final FieldDescriptor[] fields, final String clsName)
throws MappingException {
for (int i = 0; i < fields.length - 1; i++) {
String fieldName = fields[i].getFieldName();
@@ -446,7 +377,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 +387,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);
@@ -1059,7 +990,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 6342)
+++ 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 6342)
+++ C:/Java/castor-4/src/main/java/org/exolab/castor/mapping/loader/ClassDescriptorImpl.java (working copy)
@@ -42,109 +42,115 @@
*
* $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 final ClassMapping _map;
- /**
- * 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();
+ /** The Java class for this descriptor. */
+ private final Class _javaClass;
- private final ClassDescriptor _depends;
+ /** The fields described for this class. */
+ private final FieldDescriptor[] _fields;
- /**
- * The field of the identity for this class.
- */
- protected final FieldDescriptor[] _identities;
+ /** The field of the identity for this class. */
+ private final FieldDescriptor[] _identities;
+ /** The descriptor of the class which this class extends,
+ * or null if this is a top-level class. */
+ private final ClassDescriptor _extends;
+
+ /** 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();
- /**
- * The access mode specified for this class.
- */
- private AccessMode _accessMode;
+ private ClassDescriptor _depends;
+ //-----------------------------------------------------------------------------------
- /**
- * 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 ClassDescriptorImpl(final ClassMapping map, final Class javaClass,
+ public ClassDescriptorImpl(final ClassMapping clsMap, 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());
+ _map = clsMap;
+ _javaClass = javaClass;
+
+ if (fields == null) {
+ throw new IllegalArgumentException("Argument 'fields' is null");
+ }
+ _fields = (FieldDescriptor[]) fields.clone();
+
+ _depends = depend;
- if (map.getAccess() == null) {
- _accessMode = AccessMode.Shared;
+ 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).addExtended(this);
+ }
+
+ if (identities == null) {
+ if (_extends instanceof ClassDescriptorImpl) {
+ _identities = ((ClassDescriptorImpl) _extends).getIdentities();
+ } else if (_extends.getIdentity() == null) {
+ _identities = null;
+ } else {
+ _identities = new FieldDescriptor[] {_extends.getIdentity()};
+ }
+ } else {
+ _identities = identities;
+ }
} else {
- _accessMode = AccessMode.valueOf(map.getAccess().toString());
+ _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);
}
}
-
- private ClassDescriptorImpl(final ClassMapping clsMap, final Class javaClass,
+
+ public ClassDescriptorImpl(final ClassMapping clsMap, final Class javaClass,
final FieldDescriptor[] fields, final FieldDescriptor[] identities,
- final ClassDescriptor extend, final ClassDescriptor depend,
- final boolean verifyConstructable)
+ final ClassDescriptor extend)
throws MappingException {
- if (verifyConstructable && (!Types.isConstructable(javaClass, true))) {
- throw new MappingException("mapping.classNotConstructable", javaClass.getName());
- }
-
_map = clsMap;
_javaClass = javaClass;
@@ -153,8 +159,6 @@
}
_fields = (FieldDescriptor[]) fields.clone();
- _depends = depend;
-
if (extend != null) {
if (!extend.getJavaClass().isAssignableFrom(javaClass)) {
throw new MappingException("mapping.classDoesNotExtend",
@@ -163,17 +167,20 @@
_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);
+ this.getClass().getName().equals("org.exolab.castor.jdo.engine.JDOClassDescriptor")) {
+ ((ClassDescriptorImpl) _extends).addExtended(this);
}
- if (_extends instanceof ClassDescriptorImpl) {
- _identities = ( identities == null ? ((ClassDescriptorImpl)_extends).getIdentities() : identities );
+ if (identities == null) {
+ if (_extends instanceof ClassDescriptorImpl) {
+ _identities = ((ClassDescriptorImpl) _extends).getIdentities();
+ } else if (_extends.getIdentity() == null) {
+ _identities = null;
+ } else {
+ _identities = new FieldDescriptor[] {_extends.getIdentity()};
+ }
} else {
- // a quick hack to fix a ClassCastException :-(
- _identities = ( identities == null ?
- (_extends.getIdentity() == null? null : new FieldDescriptor[] { _extends.getIdentity() } )
- : identities );
+ _identities = identities;
}
} else {
_extends = null;
@@ -200,7 +207,7 @@
}
/**
- * Constructor used by derived classes.
+ * Constructor used for AbstractMappingLoader.NO_DESCRIPTOR only.
*/
protected ClassDescriptorImpl(final Class javaClass) {
_map = null;
@@ -208,10 +215,9 @@
_extends = null;
_fields = null;
_identities = null;
- _depends = null;
- _accessMode = null;
+ }
- }
+ //-----------------------------------------------------------------------------------
public ClassMapping getMapping() {
return _map;
@@ -217,25 +223,24 @@
return _map;
}
- public Class getJavaClass()
- {
+ public Class getJavaClass() {
return _javaClass;
}
-
- public FieldDescriptor[] getFields()
- {
+ public FieldDescriptor[] getFields() {
return _fields;
}
+ public FieldDescriptor[] getIdentities() {
+ return _identities;
+ }
- public ClassDescriptor getExtends()
- {
- return _extends;
+ public FieldDescriptor getIdentity() {
+ return (_identities == null) ? null : _identities[0];
}
- public boolean isExtending() {
- return (_extends != null);
+ public ClassDescriptor getExtends() {
+ return _extends;
}
/**
@@ -243,16 +248,16 @@
*
* @return A collection of class descriptors.
*/
- public Collection getExtendedBy() {
- return _extendedBy;
+ public Collection getExtended() {
+ return _extended;
}
- public boolean isExtended() {
- return (_extendedBy.size() > 0);
+ private void addExtended(ClassDescriptor classDesc) {
+ _extended.add(classDesc);
}
- public void addExtendedBy(ClassDescriptor classDesc) {
- _extendedBy.add(classDesc);
+ public void setDepends(final ClassDescriptor depends) {
+ _depends = depends;
}
public ClassDescriptor getDepends() {
@@ -259,50 +264,16 @@
return _depends;
}
- public FieldDescriptor getIdentity() {
- return _identities == null? null : _identities[0];
- }
-
- public FieldDescriptor[] getIdentities() {
- return _identities;
- }
-
-
- public AccessMode getAccessMode()
- {
- return _accessMode;
- }
-
+ //-----------------------------------------------------------------------------------
/**
- * 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 6342)
+++ 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 6342)
+++ 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 6342)
+++ 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 6342)
+++ 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
@@ -57,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.ClassDescriptorImpl;
import org.exolab.castor.mapping.loader.CollectionHandlers;
import org.exolab.castor.mapping.loader.AbstractMappingLoader;
import org.exolab.castor.mapping.loader.FieldHandlerImpl;
@@ -61,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;
@@ -65,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;
@@ -93,6 +96,8 @@
* @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.
@@ -140,6 +145,8 @@
private NodeType _primitiveNodeType = null;
+ //-----------------------------------------------------------------------------------
+
/**
* Creates a new XMLMappingLoader
*/
@@ -145,60 +152,39 @@
*/
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);
- }
-
- 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 );
- }
- }
- }
- if ( clsDesc instanceof XMLClassDescriptorImpl )
- ( (XMLClassDescriptorImpl) clsDesc ).sortDescriptors();
+ /**
+ * {@inheritDoc}
+ */
+ public void loadMapping(final MappingRoot mapping, final Object param)
+ throws MappingException {
+ if (loadMapping()) { loadClassMapping(mapping); }
}
- protected ClassDescriptor createDescriptor( ClassMapping clsMap )
- throws MappingException
- {
+
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ protected final ClassDescriptor createDescriptor(final ClassMapping clsMap)
+ throws MappingException {
ClassDescriptor clsDesc;
- String xmlName;
if (clsMap.getAutoComplete()) {
if ((clsMap.getMapTo() == null) &&
@@ -206,25 +192,111 @@
(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;
+ if (clsDesc != null) { return clsDesc; }
+ } catch(ResolverException rx) {
+
+ }
+ }
+ }
+
+ // 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)) {
+ if (clsMap.getVerifyConstructable() && (!Types.isConstructable(javaClass, true))) {
+ throw new MappingException("mapping.classNotConstructable", javaClass.getName());
+ }
+ clsDesc = new ClassDescriptorImpl(
+ clsMap, javaClass, fields, null, extend, depend);
+ } else {
+ // 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());
}
- catch(ResolverException rx) {}
-
+ }
+
+ // Create the class descriptor.
+ if (clsMap.getVerifyConstructable() && (!Types.isConstructable(javaClass, true))) {
+ throw new MappingException("mapping.classNotConstructable", javaClass.getName());
}
+ clsDesc = new ClassDescriptorImpl(
+ clsMap, javaClass, fields, identities, extend, depend);
}
- // Use super class to create class descriptor. Field descriptors will be
- // generated only for supported fields, see createFieldDesc later on.
- clsDesc = super.createDescriptor( clsMap );
MapTo mapTo = clsMap.getMapTo();
+ String xmlName;
if (( mapTo == null) || (mapTo.getXml() == null)) {
String clsName = clsDesc.getJavaClass().getName();
int idx = clsName.lastIndexOf('.');
@@ -248,13 +320,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 +349,7 @@
identity = clsMap.getIdentity(0);
- FieldDescriptor[] fields = xmlClassDesc.getFields();
+ FieldDescriptor[] xmlFields = xmlClassDesc.getFields();
// Attributes
XMLFieldDescriptor[] introFields = referenceDesc.getAttributeDescriptors();
@@ -285,7 +354,7 @@
// Attributes
XMLFieldDescriptor[] introFields = referenceDesc.getAttributeDescriptors();
for (int i = 0; i