Index: src/main/org/castor/persist/TransactionContext.java
===================================================================
RCS file: /scm/castor/castor/src/main/org/castor/persist/TransactionContext.java,v
retrieving revision 1.1
diff -u -r1.1 TransactionContext.java
--- src/main/org/castor/persist/TransactionContext.java 20 Jun 2005 12:00:59 -0000 1.1
+++ src/main/org/castor/persist/TransactionContext.java 21 Jun 2005 07:38:21 -0000
@@ -45,6 +45,7 @@
import org.exolab.castor.persist.ObjectDeletedWaitingForLockException;
import org.exolab.castor.persist.ObjectLock;
import org.exolab.castor.persist.PersistenceInfoGroup;
+import org.exolab.castor.persist.ProposedObject;
import org.exolab.castor.persist.QueryResults;
import org.exolab.castor.persist.TxSynchronizable;
import org.exolab.castor.persist.spi.InstanceFactory;
@@ -548,10 +549,10 @@
public synchronized Object load(final LockEngine engine,
final ClassMolder molder,
final Object identity,
- Object objectToBeLoaded,
+ ProposedObject proposedObject,
final AccessMode suggestedAccessMode)
throws ObjectNotFoundException, LockNotGrantedException, PersistenceException {
- return load(engine, molder, identity, objectToBeLoaded,
+ return load(engine, molder, identity, proposedObject,
suggestedAccessMode, null);
}
@@ -571,7 +572,7 @@
* The class persistence molder
* @param identity
* The object's identity
- * @param objectToBeLoaded
+ * @param proposedObject
* The object to fetch (single instance per transaction)
* @param suggestedAccessMode
* The access mode (see {@link AccessMode}) the values in
@@ -590,7 +591,7 @@
public synchronized Object load(final LockEngine engine,
final ClassMolder molder,
final Object identity,
- Object objectToBeLoaded,
+ ProposedObject proposedObject,
final AccessMode suggestedAccessMode,
QueryResults results)
throws ObjectNotFoundException, LockNotGrantedException, PersistenceException {
@@ -605,12 +606,11 @@
// Test that the object to be loaded (which we will fill in) is of an
// appropriate type for our molder.
- if (objectToBeLoaded != null
+ if (proposedObject.getObject() != null
&& !molder.getJavaClass(_db.getClassLoader()).isAssignableFrom(
- objectToBeLoaded.getClass())) {
+ proposedObject.getProposedClass())) {
throw new PersistenceException(Messages.format(
- "persist.typeMismatch", molder.getName(), objectToBeLoaded
- .getClass()));
+ "persist.typeMismatch", molder.getName(), proposedObject.getProposedClass()));
}
oid = new OID(engine, molder, identity);
@@ -627,8 +627,10 @@
// If the object has been loaded, but the instance sugguested to
// be loaded into is not the same as the loaded instance,
// error is reported.
- if (objectToBeLoaded != null
- && objectToBeLoaded != objectInTransaction) {
+
+ // TODO [WG]: could read && propsedObject != objectInTransaction
+ if (proposedObject.getObject() != null
+ && proposedObject.getObject() != objectInTransaction) {
throw new PersistenceException(Messages.format(
"persist.multipleLoad", molder.getName(), identity));
}
@@ -687,13 +689,13 @@
return objectInTransaction;
}
- // Load (or reload) the object through the persistence engine with the
- // requested lock. This might report failure (object no longer exists),
- // hold until a suitable lock is granted (or fail to grant), or
+ // Load (or reload, in case the object is stored in a acache) the object through the
+ // persistence engine with the requested lock. This might report failure (object no
+ // longer exists), hold until a suitable lock is granted (or fail to grant), or
// report error with the persistence engine.
try {
- if (objectToBeLoaded != null) {
- objectInTransaction = objectToBeLoaded;
+ if (proposedObject.getObject() != null) {
+ objectInTransaction = proposedObject.getObject();
} else {
// ssa, multi classloader feature
// ssa, FIXME : No better way to do that ?
@@ -705,15 +707,31 @@
objectInTransaction = molder.newInstance(_db
.getClassLoader());
}
+
+
+ proposedObject.setProposedClass(objectInTransaction.getClass());
+ proposedObject.setActualClass(objectInTransaction.getClass());
+ proposedObject.setObject(objectInTransaction);
}
_tracker.trackObject(engine, molder, oid, objectInTransaction);
- OID newoid = engine.load(this, oid, objectInTransaction,
- suggestedAccessMode, _lockTimeout, results);
-
- // rehash the object entry, because oid might have changed!
- _tracker.trackOIDChange(objectInTransaction, engine, oid, newoid);
+ // load object through LockEngine
+ OID newoid = engine.load( this, oid, proposedObject, suggestedAccessMode, _lockTimeout, results );
+ if (proposedObject.isExpanded()) {
+ _log.debug ("Proposed object = " + proposedObject);
+ _log.debug("Removing entry for OID " + oid);
+ _tracker.untrackObject(objectInTransaction);
+ _log.debug("Creating new OID for " + proposedObject.getActualClass().getName());
+ OID newOID = new OID (engine, proposedObject.getActualClassMolder(), identity);
+ _log.debug ("Creating ObjectEntry for OID " + newOID);
+ _tracker.trackObject(engine, molder, oid, proposedObject.getObject());
+ objectInTransaction = proposedObject.getObject();
+ } else {
+ // rehash the object entry, because oid might have changed!
+ _tracker.trackOIDChange(objectInTransaction, engine, oid, newoid);
+ }
+
} catch (ObjectNotFoundException except) {
_tracker.untrackObject(objectInTransaction);
throw except;
Index: src/main/org/exolab/castor/jdo/drivers/MultiRSCallQuery.java
===================================================================
RCS file: /scm/castor/castor/src/main/org/exolab/castor/jdo/drivers/MultiRSCallQuery.java,v
retrieving revision 1.4
diff -u -r1.4 MultiRSCallQuery.java
--- src/main/org/exolab/castor/jdo/drivers/MultiRSCallQuery.java 25 Mar 2004 12:31:06 -0000 1.4
+++ src/main/org/exolab/castor/jdo/drivers/MultiRSCallQuery.java 21 Jun 2005 07:38:22 -0000
@@ -59,6 +59,7 @@
import org.exolab.castor.jdo.QueryException;
import org.exolab.castor.jdo.engine.SQLTypes;
import org.exolab.castor.mapping.AccessMode;
+import org.exolab.castor.persist.ProposedObject;
import org.exolab.castor.persist.spi.Complex;
import org.exolab.castor.persist.spi.PersistenceQuery;
import org.exolab.castor.util.Messages;
@@ -235,10 +236,12 @@
}
- public Object fetch(Object[] fields,Object identity) throws ObjectNotFoundException, PersistenceException
+ public Object fetch(ProposedObject proposedObject, Object identity) throws ObjectNotFoundException, PersistenceException
{
Object stamp = null;
+ Object[] fields = proposedObject.getFields();
+
try {
// Load all the fields of the object including one-one relations
// index 0 belongs to the identity
Index: src/main/org/exolab/castor/jdo/drivers/PostgreSQLCallQuery.java
===================================================================
RCS file: /scm/castor/castor/src/main/org/exolab/castor/jdo/drivers/PostgreSQLCallQuery.java,v
retrieving revision 1.4
diff -u -r1.4 PostgreSQLCallQuery.java
--- src/main/org/exolab/castor/jdo/drivers/PostgreSQLCallQuery.java 25 Mar 2004 12:32:01 -0000 1.4
+++ src/main/org/exolab/castor/jdo/drivers/PostgreSQLCallQuery.java 21 Jun 2005 07:38:22 -0000
@@ -60,6 +60,7 @@
import org.exolab.castor.jdo.engine.JDBCSyntax;
import org.exolab.castor.jdo.engine.SQLTypes;
import org.exolab.castor.mapping.AccessMode;
+import org.exolab.castor.persist.ProposedObject;
import org.exolab.castor.persist.spi.Complex;
import org.exolab.castor.persist.spi.PersistenceQuery;
import org.exolab.castor.util.Messages;
@@ -248,10 +249,10 @@
}
- public Object fetch(Object[] fields,Object identity) throws ObjectNotFoundException, PersistenceException
+ public Object fetch(ProposedObject proposedObject, Object identity) throws ObjectNotFoundException, PersistenceException
{
Object stamp = null;
-
+ Object[] fields = proposedObject.getFields();
try {
// Load all the fields of the object including one-one relations
Index: src/main/org/exolab/castor/jdo/drivers/ReturnedRSCallQuery.java
===================================================================
RCS file: /scm/castor/castor/src/main/org/exolab/castor/jdo/drivers/ReturnedRSCallQuery.java,v
retrieving revision 1.3
diff -u -r1.3 ReturnedRSCallQuery.java
--- src/main/org/exolab/castor/jdo/drivers/ReturnedRSCallQuery.java 25 Mar 2004 12:24:22 -0000 1.3
+++ src/main/org/exolab/castor/jdo/drivers/ReturnedRSCallQuery.java 21 Jun 2005 07:38:22 -0000
@@ -59,6 +59,7 @@
import org.exolab.castor.jdo.QueryException;
import org.exolab.castor.jdo.engine.SQLTypes;
import org.exolab.castor.mapping.AccessMode;
+import org.exolab.castor.persist.ProposedObject;
import org.exolab.castor.persist.spi.Complex;
import org.exolab.castor.persist.spi.PersistenceQuery;
import org.exolab.castor.util.Messages;
@@ -228,10 +229,10 @@
}
- public Object fetch(Object[] fields,Object identity) throws ObjectNotFoundException, PersistenceException
+ public Object fetch(ProposedObject proposedObject, Object identity) throws ObjectNotFoundException, PersistenceException
{
Object stamp = null;
-
+ Object[] fields = proposedObject.getFields();
try {
// Load all the fields of the object including one-one relations
Index: src/main/org/exolab/castor/jdo/engine/DatabaseImpl.java
===================================================================
RCS file: /scm/castor/castor/src/main/org/exolab/castor/jdo/engine/DatabaseImpl.java,v
retrieving revision 1.25
diff -u -r1.25 DatabaseImpl.java
--- src/main/org/exolab/castor/jdo/engine/DatabaseImpl.java 20 Jun 2005 12:00:55 -0000 1.25
+++ src/main/org/exolab/castor/jdo/engine/DatabaseImpl.java 21 Jun 2005 07:38:22 -0000
@@ -343,9 +343,12 @@
TransactionContext tx = getTransaction();
PersistenceInfo info = _scope.getPersistenceInfo(type);
- return tx.load(info.engine, info.molder, identity, object, mode);
+ ProposedObject proposedObject = new ProposedObject();
+ proposedObject.setObject(null);
+ proposedObject.setProposedClass(null);
+
+ return tx.load( info.engine, info.molder, identity, proposedObject, mode );
}
-
public void create( Object object )
throws ClassNotPersistenceCapableException, DuplicateIdentityException,
TransactionNotInProgressException, PersistenceException {
Index: src/main/org/exolab/castor/jdo/engine/OQLQueryImpl.java
===================================================================
RCS file: /scm/castor/castor/src/main/org/exolab/castor/jdo/engine/OQLQueryImpl.java,v
retrieving revision 1.15
diff -u -r1.15 OQLQueryImpl.java
--- src/main/org/exolab/castor/jdo/engine/OQLQueryImpl.java 20 Jun 2005 12:00:55 -0000 1.15
+++ src/main/org/exolab/castor/jdo/engine/OQLQueryImpl.java 21 Jun 2005 07:38:23 -0000
@@ -47,6 +47,8 @@
package org.exolab.castor.jdo.engine;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.castor.persist.TransactionContext;
import org.exolab.castor.jdo.*;
import org.exolab.castor.jdo.oql.*;
@@ -75,6 +77,7 @@
implements Query, OQLQuery
{
+ private final static Log log = LogFactory.getLog (OQLQueryImpl.class);
private LockEngine _dbEngine;
@@ -249,7 +252,9 @@
_objClass = walker.getObjClass();
_clsDesc = walker.getClassDescriptor();
+ log.debug ("class descriptor = " + _clsDesc);
_expr = walker.getQueryExpression();
+ log.debug ("sql expression = " + _expr);
_paramInfo = walker.getParamInfo();
_projectionType = walker.getProjectionType();
_pathInfo = walker.getPathInfo();
Index: src/main/org/exolab/castor/jdo/engine/SQLEngine.java
===================================================================
RCS file: /scm/castor/castor/src/main/org/exolab/castor/jdo/engine/SQLEngine.java,v
retrieving revision 1.31
diff -u -r1.31 SQLEngine.java
--- src/main/org/exolab/castor/jdo/engine/SQLEngine.java 16 Jun 2005 12:14:28 -0000 1.31
+++ src/main/org/exolab/castor/jdo/engine/SQLEngine.java 21 Jun 2005 07:38:24 -0000
@@ -53,6 +53,7 @@
import org.exolab.castor.jdo.drivers.PreparedStatementProxy;
import org.exolab.castor.mapping.*;
import org.exolab.castor.mapping.loader.FieldHandlerImpl;
+import org.exolab.castor.persist.ProposedObject;
import org.exolab.castor.persist.spi.*;
import org.exolab.castor.util.Messages;
import org.exolab.castor.util.SqlBindParser;
@@ -117,7 +118,7 @@
private ColumnInfo[] _ids;
private SQLEngine _extends;
-
+
private QueryExpression _sqlFinder;
private PersistenceFactory _factory;
@@ -327,6 +328,10 @@
}
}
+ public Persistence.ColumnInfo[] getColumnInfoForIdentities() {
+ return _ids;
+ }
+
public Persistence.FieldInfo[] getInfo() {
return _fields;
}
@@ -964,15 +969,21 @@
for(int i = 0; i < fields.length; i++){
currentField = toJava(i, 0, res.getObject(_fields[i].columns[0].name));
- if ( currentField != null &&
- _fields[i].tableName.compareTo(_mapTo) == 0 &&
- !original[i].equals(currentField) ) {
- if (numberOfFieldsNotMatching >= 1) {
- enlistFieldsNotMatching.append (", ");
+ if (_fields[i].tableName.compareTo(_mapTo) == 0) {
+
+ if ((original[i] == null && currentField != null) ||
+ (currentField == null && original[i] != null) ||
+ (original[i] == null && currentField == null)) {
+ enlistFieldsNotMatching.append ("(" + _clsDesc.getJavaClass().getName() + ")." + _fields[i].columns[0].name + ": ");
+ enlistFieldsNotMatching.append ("[" + original[i] + "/" + currentField + "]");
+ } else if (!original[i].equals(currentField) ) {
+ if (numberOfFieldsNotMatching >= 1) {
+ enlistFieldsNotMatching.append (", ");
+ }
+ enlistFieldsNotMatching.append ("(" + _clsDesc.getJavaClass().getName() + ")." + _fields[i].columns[0].name + ": ");
+ enlistFieldsNotMatching.append ("[" + original[i] + "/" + currentField + "]");
+ numberOfFieldsNotMatching++;
}
- enlistFieldsNotMatching.append ("(" + _clsDesc.getJavaClass().getName() + ")." + _fields[i].columns[0].name + ": ");
- enlistFieldsNotMatching.append ("[" + original[i] + "/" + currentField + "]");
- numberOfFieldsNotMatching++;
}
}
throw new ObjectModifiedException( Messages.format("persist.objectModified", _clsDesc.getJavaClass().getName(), identity, enlistFieldsNotMatching.toString()) );
@@ -1106,25 +1117,46 @@
}
- public Object load( Object conn, Object[] fields, Object identity, AccessMode accessMode )
- throws ObjectNotFoundException, PersistenceException {
-
+ /**
+ * Loads the object from persistence storage. This method will load
+ * the object fields from persistence storage based on the object's
+ * identity. This method may return a stamp which can be used at a
+ * later point to determine whether the copy of the object in
+ * persistence storage is newer than the cached copy (see {@link
+ * #store}). If lock is true the object must be
+ * locked in persistence storage to prevent concurrent updates.
+ *
+ * @param conn An open connection
+ * @param fields An Object[] to load field values into
+ * @param identity Identity of the object to load.
+ * @param accessMode The access mode (null equals shared)
+ * @return The object's stamp, or null
+ * @throws ObjectNotFoundException The object was not found in persistent storage
+ * @throws PersistenceException A persistence error occured
+ */
+ public Object load( Object conn, ProposedObject proposedObject, Object identity, AccessMode accessMode )
+ throws ObjectNotFoundException, PersistenceException
+ {
PreparedStatement stmt = null;
ResultSet rs = null;
Object stamp = null;
boolean notNull;
+
+ Object[] fields = proposedObject.getFields();
+ int originalNumberOfFields = fields.length;
+
+ _log.debug ("number of fields to load from persistence store: " + fields.length);
+
try {
- String sql = ( accessMode == AccessMode.DbLocked ) ? _sqlLoadLock : _sqlLoad;
- stmt = ( (Connection) conn ).prepareStatement(sql);
-
+ String sqlString = ( accessMode == AccessMode.DbLocked ) ? _sqlLoadLock : _sqlLoad;
+ stmt = ( (Connection) conn ).prepareStatement(sqlString);
+
if (_log.isDebugEnabled()) {
- String generatedSQL = ( accessMode == AccessMode.DbLocked ) ? _sqlLoadLock : _sqlLoad;
-// _log.debug( Messages.format( "jdo.loading", _clsDesc.getJavaClass().getName(), generatedSQL ) );
- _log.debug( Messages.format( "jdo.loading", _clsDesc.getJavaClass().getName(), stmt.toString()) );
- }
+ _log.debug( Messages.format("jdo.loading", _clsDesc.getJavaClass().getName(), sqlString)); }
int count = 1;
+ int fieldIndex = 1;
// bind the identity of the preparedStatement
if ( identity instanceof Complex ) {
Complex id = (Complex) identity;
@@ -1132,37 +1164,76 @@
throw new PersistenceException( "Size of complex field mismatched! expected: "+_ids.length+" found: "+id.size() );
for ( int i=0; i<_ids.length; i++ )
- stmt.setObject( count++, idToSQL( i, id.get(i) ) );
-
+ stmt.setObject( fieldIndex++, idToSQL( i, id.get(i) ) );
} else {
if ( _ids.length != 1 )
throw new PersistenceException( "Complex field expected!" );
- stmt.setObject( count++, idToSQL( 0, identity ) );
+ stmt.setObject( fieldIndex++, idToSQL( 0, identity ) );
}
if (_log.isDebugEnabled()) {
_log.debug( Messages.format( "jdo.loading", _clsDesc.getJavaClass().getName(), stmt.toString()) );
}
- // query the object
+ // execute the SQL query
rs = stmt.executeQuery();
if ( ! rs.next() )
throw new ObjectNotFoundException( Messages.format("persist.objectNotFound", _clsDesc.getJavaClass().getName(), identity) );
+ int numberOfFields = _fields.length;
+ int numberOfIdentityColumns = _ids.length;
+
+ int numberOfExtendLevels = numberOfExtendingClassDescriptors (getDescriptor());
+
+ Collection extendingClassDescriptors = this.getDescriptor().getExtendedBy();
+
+ if (extendingClassDescriptors.size() > 0) {
+ Object[] returnValues =
+ calculateNumberOfFields(extendingClassDescriptors,
+ _ids.length, _fields.length, numberOfExtendLevels, rs);
+ JDOClassDescriptor potentialLeafDescriptor = (JDOClassDescriptor) returnValues[0];
+
+
+ if (potentialLeafDescriptor != null &&
+ !potentialLeafDescriptor.getJavaClass().getName().equals (getDescriptor().getJavaClass().getName())) {
+ Object[] expandedFields = new Object[potentialLeafDescriptor.getFields().length];
+
+ fields = expandedFields;
+ proposedObject.setFields (expandedFields);
+ proposedObject.setActualClass (potentialLeafDescriptor.getJavaClass());
+ proposedObject.setExpanded(true);
+ }
+
+ return null;
+ }
+
// Load all the fields of the object including one-one relations
- count = 1;
+ int columnIndex = 1; // index to use during ResultSet.getXXX()
+ fieldIndex = 1; // index in fields[] for storing result of SQLTypes.getObject()
+ String tableName = null;
+ String tableNameOld = tableName;
Object[] temp = new Object[10]; // assume complex field max at 10
for ( int i = 0 ; i < _fields.length ; ++i ) {
+
+ tableName = _fields[i].tableName;
+ if (!tableName.equals (tableNameOld) && !_fields[i].joined) {
+ for (int j = 0; j < _ids.length; j++) {
+ columnIndex = columnIndex + 1;
+ }
+ }
+
if ( !_fields[i].load )
continue;
if ( !_fields[i].multi ) {
notNull = false;
if ( _fields[i].columns.length == 1 ) {
- fields[i] = toJava( i, 0, SQLTypes.getObject( rs, count++, _fields[i].columns[0].sqlType ) );
+ fields[i] = toJava( i, 0, SQLTypes.getObject( rs, columnIndex++, _fields[i].columns[0].sqlType ) );
+ fieldIndex += 1;
} else {
for ( int j=0; j<_fields[i].columns.length; j++ ) {
- temp[j] = toJava( i, j, SQLTypes.getObject( rs, count++, _fields[i].columns[j].sqlType ) );
+ temp[j] = toJava( i, j, SQLTypes.getObject( rs, columnIndex++, _fields[i].columns[j].sqlType ) );
+ fieldIndex += 1;
if ( temp[j] != null ) {
notNull = true;
}
@@ -1176,11 +1247,12 @@
ArrayList res = new ArrayList();
notNull = false;
for ( int j=0; j<_fields[i].columns.length; j++ ) {
- temp[j] = toJava( i, j, SQLTypes.getObject( rs, count, _fields[i].columns[j].sqlType ) );
+ temp[j] = toJava( i, j, SQLTypes.getObject( rs, columnIndex, _fields[i].columns[j].sqlType ) );
if ( temp[j] != null ) {
notNull = true;
}
- count++;
+ fieldIndex++;
+ columnIndex += 1;
}
if ( notNull ) {
if ( _fields[i].columns.length == 1 )
@@ -1190,24 +1262,40 @@
}
fields[i] = res;
}
+
+ tableNameOld = tableName;
}
while ( rs.next() ) {
- count = 1;
+ fieldIndex = 1;
+ columnIndex = 1;
+
+ tableName = null;
+ tableNameOld = tableName;
+
for ( int i = 0; i < _fields.length ; ++i ) {
- if ( !_fields[i].load )
+
+ tableName = _fields[i].tableName;
+ if (!tableName.equals (tableNameOld) && !_fields[i].joined) {
+ for (int j = 0; j < _ids.length; j++) {
+ columnIndex = columnIndex + 1;
+ }
+ }
+
+ if ( !_fields[i].load )
continue;
if ( _fields[i].multi ) {
ArrayList res = (ArrayList)fields[i];
notNull = false;
for ( int j=0; j<_fields[i].columns.length; j++ ) {
- temp[j] = toJava( i, j, SQLTypes.getObject( rs, count, _fields[i].columns[j].sqlType ) );
+ temp[j] = toJava( i, j, SQLTypes.getObject( rs, columnIndex, _fields[i].columns[j].sqlType ) );
if ( temp[j] != null ) {
notNull = true;
}
- count++;
+ columnIndex += 1;
}
+ fieldIndex++;
if ( notNull ) {
if ( _fields[i].columns.length == 1 ) {
if ( !res.contains( temp[0] ) )
@@ -1219,9 +1307,13 @@
}
}
} else {
- count += _fields[i].columns.length;
+ fieldIndex += 1;
+ columnIndex += _fields[i].columns.length;
}
+ tableNameOld = tableName;
}
+
+ proposedObject.setFields (fields);
}
} catch ( SQLException except ) {
_log.fatal( Messages.format( "jdo.loadFatal", _type, (( accessMode == AccessMode.DbLocked ) ? _sqlLoadLock : _sqlLoad ) ), except );
@@ -1241,7 +1333,105 @@
}
return stamp;
}
-
+
+ private int numberOfExtendingClassDescriptors (JDOClassDescriptor classDescriptor) {
+ int numberOfExtendLevels = 1;
+ JDOClassDescriptor currentClassDescriptor = getDescriptor();
+ while (currentClassDescriptor.getExtends() != null) {
+ currentClassDescriptor = (JDOClassDescriptor) currentClassDescriptor.getExtends();
+ numberOfExtendLevels += 1;
+ }
+ return numberOfExtendLevels;
+ }
+
+ private Object[] calculateNumberOfFields (Collection extendingClassDescriptors,
+ int numberOfIdentityColumns,
+ int numberOfFields,
+ int numberOfExtendLevels,
+ ResultSet rs)
+ throws SQLException
+ {
+ JDOClassDescriptor potentialLeafDescriptor = null;
+ int suggestedNumberOfFields = numberOfFields;
+ Collection potentialActualClassDescriptor = new LinkedList();
+ int numberOfIdentitiesToAnalyze = 0;
+ addExtendingClassDescriptors(potentialActualClassDescriptor, extendingClassDescriptors);
+
+ JDOClassDescriptor potentialClassDescriptor = null;
+ JDOClassDescriptor potentialClassDescriptorPrevious = null;
+ int initialColumnIndex = numberOfFields + numberOfIdentityColumns * numberOfExtendLevels + 1;
+ int columnIndex = initialColumnIndex;
+ int numberOfExtendingClassDescriptors = 0;
+ for (Iterator iter = potentialActualClassDescriptor.iterator(); iter.hasNext(); ) {
+ potentialClassDescriptor = (JDOClassDescriptor) iter.next();
+ numberOfExtendingClassDescriptors += 1;
+ _log.debug ("Potential extending class descriptor: " + potentialClassDescriptor.getJavaClass().getName());
+ FieldDescriptor[] identityDescriptors = potentialClassDescriptor.getIdentities();
+ boolean isNull = true;
+
+ for (int i = 0; i < identityDescriptors.length; i++) {
+ Object temp;
+ Object[] temps;
+ JDOFieldDescriptor jdoFieldDescriptor = (JDOFieldDescriptor) identityDescriptors[i];
+ if (jdoFieldDescriptor.getSQLName().length == 1 ) {
+ temp = SQLTypes.getObject( rs, columnIndex++, java.sql.Types.JAVA_OBJECT);
+ isNull = (temp == null);
+ } else {
+ temps = new Object[jdoFieldDescriptor.getSQLName().length];
+ for ( int j=0; j 0) {
+ potentialLeafDescriptor = potentialClassDescriptor;
+ suggestedNumberOfFields += potentialClassDescriptor.getFields().length;
+ } else if (!iter.hasNext() && isNull && numberOfIdentitiesToAnalyze > 0){
+ potentialLeafDescriptor = potentialClassDescriptorPrevious;
+ // suggestedNumberOfFields += potentialClassDescriptor.getFields().length;
+ } else {
+ FieldDescriptor[] potentialFields =
+ (FieldDescriptor[]) potentialClassDescriptor.getFields();
+ for (int i = 0; i < potentialFields.length; i++) {
+ JDOFieldDescriptor jdoFieldDescriptor = (JDOFieldDescriptor) potentialFields[i];
+ String[] columnNames = jdoFieldDescriptor.getSQLName();
+ for (int j = 0; j < columnNames.length; j++) {
+ columnIndex = columnIndex + 1;
+ }
+ }
+
+ // the JDOClassDescriptor we just looked at is definitely part of the extends hierarchy,
+ // and as such we need to increase the number of potential fields
+ if (!isNull) {
+ suggestedNumberOfFields += potentialClassDescriptor.getFields().length;
+ }
+ }
+ }
+
+ _log.debug ("In total " + numberOfIdentitiesToAnalyze + " (extending) identities analyzed.");
+
+ if (potentialLeafDescriptor != null) {
+ _log.debug ("Most likely of type " + potentialLeafDescriptor.getJavaClass().getName());
+ _log.debug ("After analysis, " + suggestedNumberOfFields + " fields need to be loaded.");
+ }
+
+ return new Object[] {potentialLeafDescriptor, new Integer (suggestedNumberOfFields) };
+
+ }
private void buildSqlCreate () throws QueryException {
StringBuffer sql;
@@ -1399,7 +1589,8 @@
}
- private void buildFinder( JDOClassDescriptor clsDesc ) throws QueryException {
+ // private void buildFinder(JDOClassDescriptor clsDesc, ColumnInfo[] ids, FieldInfo[] fields, String mapTo) throws QueryException {
+ private void buildFinder(JDOClassDescriptor clsDesc) throws QueryException {
QueryExpression expr;
QueryExpression find;
@@ -1426,15 +1617,41 @@
find.addInnerJoin(curDesc.getTableName(), curDesc.getIdentityColumnNames(),
baseDesc.getTableName(), baseDesc.getIdentityColumnNames());
curDesc = baseDesc;
+
+ // add identity column names to SELECT statement
+// String[] identityColumnNames = baseDesc.getIdentityColumnNames();
+// for (int j = 0; j < identityColumnNames.length; j++) {
+// expr.addColumn (baseDesc.getTableName(), identityColumnNames[j]);
+// }
}
+
for ( int i=0; i<_ids.length; i++ ) {
- find.addColumn( _mapTo, idnames[i] );
+ // find.addColumn(_mapTo, idnames[i]);
+ // expr.addColumn(_mapTo, idnames[i]);
}
// join all the related/depended table
Vector joinTables = new Vector();
+ String aliasOld = null;
+ String alias = null;
+
for ( int i=0; i<_fields.length; i++ ) {
- String alias = _fields[i].tableName;
+ if (i > 0) {
+ aliasOld = alias;
+ }
+ alias = _fields[i].tableName;
+
+ // add id columns to select statement
+ if (!alias.equals (aliasOld) && !_fields[i].joined) {
+ JDOClassDescriptor classDescriptor = (JDOClassDescriptor)
+ _fields[i].fieldDescriptor.getContainingClassDescriptor();
+ String[] ids = classDescriptor.getIdentityColumnNames();
+ for (int j = 0; j < ids.length; j++) {
+ expr.addColumn (alias, ids[j]);
+ find.addColumn (alias, ids[j]);
+ }
+ }
+
if ( _fields[i].load ) {
if ( _fields[i].joined /*&& !joinTables.contains( _fields[i].tableName )*/ ) {
int offset = 0;
@@ -1458,10 +1675,71 @@
expr.addColumn( alias, _fields[i].columns[j].name );
find.addColumn( alias, _fields[i].columns[j].name );
}
+
expr.addTable(_fields[i].tableName, alias);
find.addTable(_fields[i].tableName, alias);
}
+
+
}
+
+ // 'join' all the extending tables
+ curDesc = clsDesc;
+ List classDescriptorsToAdd = new LinkedList();
+ JDOClassDescriptor classDescriptor = null;
+ addExtendingClassDescriptors(classDescriptorsToAdd, curDesc.getExtendedBy());
+
+ if (classDescriptorsToAdd.size() > 0) {
+ for (Iterator iter = classDescriptorsToAdd.iterator(); iter.hasNext(); ) {
+ classDescriptor = (JDOClassDescriptor) iter.next();
+ _log.debug ("Adding outer left join for " + classDescriptor.getJavaClass().getName() +
+ " on table " + classDescriptor.getTableName());
+ expr.addOuterJoin( _mapTo,
+ curDesc.getIdentityColumnNames(),
+ classDescriptor.getTableName(),
+ classDescriptor.getIdentityColumnNames());
+ find.addOuterJoin( _mapTo,
+ curDesc.getIdentityColumnNames(),
+ classDescriptor.getTableName(),
+ classDescriptor.getIdentityColumnNames());
+
+ Persistence persistenceEngine;
+ try {
+ persistenceEngine = _factory.getPersistence (classDescriptor);
+ } catch (MappingException e) {
+ throw new QueryException ("Problem obtaining persistence engine for ClassDescriptor " + classDescriptor.getJavaClass().getName(), e);
+ }
+
+ SQLEngine.ColumnInfo[] idInfos =
+ (SQLEngine.ColumnInfo[]) persistenceEngine.getColumnInfoForIdentities();
+ for (int i = 0; i < idInfos.length; i++) {
+ _log.debug ("Adding column " + idInfos[i].name + " for table " + classDescriptor.getTableName());
+ expr.addColumn (classDescriptor.getTableName(), idInfos[i].name);
+ find.addColumn (classDescriptor.getTableName(), idInfos[i].name);
+ }
+
+ SQLEngine.FieldInfo[] fieldInfos = (SQLEngine.FieldInfo[]) persistenceEngine.getInfo();
+ for (int i = 0; i < fieldInfos.length; i++) {
+ boolean hasFieldToAdd = false;
+ SQLEngine.ColumnInfo[] columnInfos = fieldInfos[i].columns;
+ if (classDescriptor.getTableName().equals(fieldInfos[i].tableName)) {
+ for ( int j = 0; j < columnInfos.length; j++ ) {
+ _log.debug ("Adding column " + fieldInfos[i].columns[j].name + " for table " + classDescriptor.getTableName());
+ expr.addColumn (classDescriptor.getTableName(), fieldInfos[i].columns[j].name);
+ find.addColumn (classDescriptor.getTableName(), fieldInfos[i].columns[j].name);
+ }
+ hasFieldToAdd = true;
+ }
+
+ if (hasFieldToAdd) {
+ expr.addTable(classDescriptor.getTableName());
+ find.addTable(classDescriptor.getTableName());
+ }
+ }
+ }
+ }
+
+
_sqlLoad = expr.getStatement( false );
_sqlLoadLock = expr.getStatement( true );
@@ -1469,9 +1747,21 @@
if(_log.isDebugEnabled()) {
_log.debug( Messages.format( "jdo.loading", _type, _sqlLoad ) );
+ _log.debug( Messages.format( "jdo.loading.with.lock", _type, _sqlLoadLock ) );
+ _log.debug( Messages.format( "jdo.finding", _type, _sqlFinder ) );
}
}
+
+ private void addExtendingClassDescriptors (Collection classDescriptorsToAdd, Collection extendingClassDescriptors) {
+ JDOClassDescriptor classDescriptor = null;
+ for (Iterator iter = extendingClassDescriptors.iterator(); iter.hasNext(); ) {
+ classDescriptor = (JDOClassDescriptor) iter.next();
+ classDescriptorsToAdd.add (classDescriptor);
+ addExtendingClassDescriptors(classDescriptorsToAdd, classDescriptor.getExtendedBy());
+ }
+
+ }
public String toString() {
@@ -1497,10 +1787,17 @@
final String[] joinFields;
ColumnInfo[] columns;
+
+ final FieldDescriptor fieldDescriptor;
+
+ final ClassDescriptor classDescriptor;
FieldInfo( JDOClassDescriptor clsDesc, FieldDescriptor fieldDesc, String classTable, boolean ext )
throws MappingException{
+ fieldDescriptor = fieldDesc;
+ classDescriptor = clsDesc;
+
// for readability
final int FIELD_TYPE = 0;
@@ -1645,16 +1942,31 @@
}
}
- static final class ColumnInfo {
+ static final class ColumnInfo implements Persistence.ColumnInfo{
+ /**
+ * Name of the column
+ */
final String name;
+ /**
+ * SQL type of teh coplumn
+ */
final int sqlType;
+ /**
+ * TypeConvertor to use when converting to the SQLType of this column.
+ */
final TypeConvertor convertTo;
+ /**
+ * TypeConvertor to use when converting from the SQLType of this column.
+ */
final TypeConvertor convertFrom;
+ /**
+ * Type conversion parameters
+ */
final String convertParam;
ColumnInfo( String name, int type, TypeConvertor convertTo,
@@ -1665,6 +1977,41 @@
this.convertFrom = convertFrom;
this.convertParam = convertParam;
}
+
+ /* (non-Javadoc)
+ * @see org.exolab.castor.persist.spi.Persistence.ColumnInfo#getName()
+ */
+ public String getName() {
+ return name;
+ }
+
+ /* (non-Javadoc)
+ * @see org.exolab.castor.persist.spi.Persistence.ColumnInfo#getSqlType()
+ */
+ public int getSqlType() {
+ return sqlType;
+ }
+
+ /* (non-Javadoc)
+ * @see org.exolab.castor.persist.spi.Persistence.ColumnInfo#getConvertTo()
+ */
+ public TypeConvertor getConvertTo() {
+ return convertTo;
+ }
+
+ /* (non-Javadoc)
+ * @see org.exolab.castor.persist.spi.Persistence.ColumnInfo#getConvertFrom()
+ */
+ public TypeConvertor getConvertFrom() {
+ return convertFrom;
+ }
+
+ /* (non-Javadoc)
+ * @see org.exolab.castor.persist.spi.Persistence.ColumnInfo#getConvertParam()
+ */
+ public String getConvertParam() {
+ return convertParam;
+ }
}
static final class SQLQuery implements PersistenceQuery {
@@ -1673,7 +2020,8 @@
private ResultSet _rs;
- private final SQLEngine _engine;
+ private /*final*/ SQLEngine _engine;
+ private SQLEngine _requestedEngine;
private final Class[] _types;
@@ -1692,6 +2040,7 @@
SQLQuery( SQLEngine engine, String sql, Class[] types )
{
_engine = engine;
+ _requestedEngine = engine;
_types = types;
_values = new Object[ _types.length ];
_sql = sql;
@@ -1749,7 +2098,7 @@
}
catch (SQLException e)
{
- throw new PersistenceException(e.getMessage());
+ throw new PersistenceException(e.getMessage(), e);
}
return retval;
}
@@ -1956,19 +2305,43 @@
}
- private Object loadSingleField( int i, int count ) throws SQLException, PersistenceException
+ private Object loadSingleField( int i, CounterRef counterReference) throws SQLException, PersistenceException
{
+ String currentTableName = counterReference.getTableName();
+ int count = counterReference.getCounter();
Object[] temp = new Object[_engine._fields[i].columns.length];
boolean notNull = false;
Object field;
+
+ String fieldTableName = _engine._fields[i].tableName;
+
+ ResultSetMetaData metaData = _rs.getMetaData();
+ String columnTableName = metaData.getTableName(count);
+ _log.debug("Current column: " + columnTableName + "." + metaData.getColumnName(count) + "/" + metaData.getColumnLabel(count));
+
+ while (!columnTableName.equals(fieldTableName)) {
+ _log.debug("Skipping " + metaData.getTableName(count) + "." + metaData.getColumnName(count) + " due to wrong table name.");
+ count++;
+ columnTableName = metaData.getTableName(count);
+ }
+ String firstColumnOfField = _engine._fields[i].columns[0].name;
+ while (!metaData.getColumnName(count).equals(firstColumnOfField)) {
+ _log.debug("Skipping " + metaData.getTableName(count) + "." + metaData.getColumnName(count));
+ count++;
+ }
+
if ( _engine._fields[i].columns.length == 1 ) {
- field = _engine.toJava( i, 0, SQLTypes.getObject( _rs, count++,
+ field = _engine.toJava( i, 0, SQLTypes.getObject( _rs, count,
_engine._fields[i].columns[0].sqlType ) );
+ _log.debug ("Got value for " + metaData.getTableName(count) + "." + metaData.getColumnName(count) + ": " + field);
+ count++;
} else {
for ( int j=0; j<_engine._fields[i].columns.length; j++ ) {
- temp[j] = _engine.toJava( i, j, SQLTypes.getObject( _rs, count++,
+ temp[j] = _engine.toJava( i, j, SQLTypes.getObject( _rs, count,
_engine._fields[i].columns[j].sqlType ) );
+ _log.debug ("Got value for " + metaData.getTableName(count) + "." + metaData.getColumnName(count) + ": " + temp[j]);
+ count++;
if ( temp[j] != null ) {
notNull = true;
}
@@ -1978,16 +2351,40 @@
else
field = null;
}
+ _log.debug("Loaded field " + _engine._fields[i].getFieldName() + ": " + field);
+ counterReference.setCounter(count);
+ counterReference.setTableName(currentTableName);
return field;
}
- private Object loadMultiField( int i, int count, Object field ) throws SQLException, PersistenceException
+ private Object loadMultiField( int i, CounterRef counterReference, Object field ) throws SQLException, PersistenceException
{
+ int count = counterReference.getCounter();
Object[] temp = new Object[_engine._fields[i].columns.length];
boolean notNull = false;
ArrayList res;
+ String fieldTableName = _engine._fields[i].tableName;
+
+ _log.debug("Loading value for field " + _engine._fields[i].getFieldName() + " from " + _engine._fields[i].tableName);
+
+ ResultSetMetaData metaData = _rs.getMetaData();
+ String columnTableName = metaData.getTableName(count);
+ _log.debug("Current column: " + columnTableName + "." + metaData.getColumnName(count) + "/" + metaData.getColumnLabel(count));
+
+ while (!columnTableName.equals(fieldTableName)) {
+ _log.debug("Skipping " + metaData.getTableName(count) + "." + metaData.getColumnName(count) + " due to wrong table name.");
+ count++;
+ columnTableName = metaData.getTableName(count);
+ }
+
+ String firstColumnOfField = _engine._fields[i].columns[0].name;
+ while (!metaData.getColumnName(count).equals(firstColumnOfField)) {
+ _log.debug("Skipping " + metaData.getTableName(count) + "." + metaData.getColumnName(count));
+ count++;
+ }
+
if( field == null )
res = new ArrayList();
else
@@ -1996,6 +2393,7 @@
for ( int j=0; j<_engine._fields[i].columns.length; j++ ) {
temp[j] = _engine.toJava( i, j,
SQLTypes.getObject( _rs, count, _engine._fields[i].columns[j].sqlType ) );
+ _log.debug ("Got value for " + metaData.getTableName(count) + "." + metaData.getColumnName(count) + ": " + temp[j]);
if ( temp[j] != null ) {
notNull = true;
}
@@ -2011,27 +2409,43 @@
res.add( com );
}
}
+ counterReference.setCounter(count);
+
return res;
}
- private int loadRow( Object[] fields, boolean isFirst ) throws SQLException, PersistenceException
+ private int loadRow( Object[] fields, int numberOfFields, boolean isFirst ) throws SQLException, PersistenceException
{
int count = _engine._ids.length + 1;
+ String tableName = null;
+
+ // TODO: wrong, as it could be that the first field is not part of the root class.
+ tableName = _engine._fields[0].tableName;
+
// Load all the fields.
- for ( int i = 0 ; i < _engine._fields.length ; ++i ) {
+ CounterRef counterReference = new CounterRef ();
+ counterReference.setCounter(count);
+ counterReference.setTableName(tableName);
+
+ for ( int i = 0 ; i < numberOfFields ; ++i ) {
+
if ( !_engine._fields[i].load )
continue;
if ( _engine._fields[i].multi ) {
- fields[i] = loadMultiField( i, count, fields[i] );
+ counterReference.setCounter(count);
+ fields[i] = loadMultiField( i, counterReference, fields[i] );
+ count = counterReference.getCounter();
} else if( isFirst ) {
// Non-multi fields have to be done one only once, so this is skipped
// if we have already read the first row.
- fields[i] = loadSingleField( i, count );
+ counterReference.setCounter (count);
+ fields[i] = loadSingleField( i, counterReference);
+ count = counterReference.getCounter();
}
- count += _engine._fields[i].columns.length;
+ // count += _engine._fields[i].columns.length;
}
return count;
}
@@ -2064,12 +2478,19 @@
}
- // Fill the given fields[] with the "cached" stuff from our _fields[] .
- public Object fetch( Object[] fields, Object identity ) throws ObjectNotFoundException, PersistenceException
+ /**
+ * @see org.exolab.castor.persist.spi.PersistenceQuery#fetch(org.exolab.castor.persist.ProposedObject, java.lang.Object)
+ */
+ public Object fetch( ProposedObject proposedObject, Object identity )
+ throws ObjectNotFoundException, PersistenceException
{
+ Object[] fields = proposedObject.getFields();
+
+ // Fill the given fields[] with the "cached" stuff from our _fields[] .
for( int i = 0; i < _fields.length; i++ ) {
fields[i] = _fields[i];
}
+
return null;
}
@@ -2079,7 +2500,48 @@
// maybe we can optimize a little bit here when we have time.
// Instead of creating new Object[] and ArrayList for each
// "multi field" each fetchRaw is called, we might reuse them.
- _fields = new Object[_engine._fields.length];
+
+ SQLEngine oldEngine = null;
+ int originalFieldNumber = _requestedEngine._fields.length;
+ if (_requestedEngine.getDescriptor().isExtended()) {
+ Collection extendingClassDescriptors = _requestedEngine.getDescriptor().getExtendedBy();
+ int numberOfExtendLevels = _requestedEngine.numberOfExtendingClassDescriptors(_requestedEngine.getDescriptor());
+ JDOClassDescriptor leafDescriptor = null;
+ Object[] returnValues = null;
+ try {
+ returnValues =_requestedEngine.calculateNumberOfFields(extendingClassDescriptors, _requestedEngine._ids.length, _requestedEngine._fields.length, numberOfExtendLevels, this._rs);
+ }
+ catch (SQLException e) {
+ _log.error ("Problem calculating number of concrete fields.", e);
+ throw new PersistenceException ("Problem calculating number of concrete fields.", e);
+ }
+
+ leafDescriptor = (JDOClassDescriptor) returnValues[0];
+
+ if (leafDescriptor != null) {
+ _log.debug("potential leaf descriptor = " + leafDescriptor.getJavaClass().getName());
+
+
+ if (!leafDescriptor.getJavaClass().getName().equals(_requestedEngine.getDescriptor().getJavaClass().getName())) {
+ _log.debug ("Increasing number of fields to load from " + originalFieldNumber + " to "
+ + ((Integer) returnValues[1]).intValue());
+ originalFieldNumber = ((Integer) returnValues[1]).intValue();
+
+ Persistence newEngine =null;
+ try {
+ newEngine = _requestedEngine._factory.getPersistence(leafDescriptor);
+ } catch (MappingException e) {
+ _log.error ("Problem obtaining persistence engine for " + leafDescriptor.getJavaClass().getName(), e);
+ throw new PersistenceException ("Problem obtaining persistence engine for " + leafDescriptor.getJavaClass().getName(), e);
+ }
+ _log.debug ("About to start using persistence engine for " + ((SQLEngine) newEngine).getDescriptor());
+ _engine = (SQLEngine) newEngine;
+ }
+ }
+ }
+
+
+ _fields = new Object[originalFieldNumber];
// It would prove a little difficult to fetch if we don't have any rows with data left :-)
if ( _resultSetDone )
@@ -2102,7 +2564,7 @@
// As we assume that we have called fetch() immediatly after nextIdentity(),
// we can be sure that it belongs to the object we want. This is probably not the
// safest programming style, but has to suffice currently :-)
- loadRow( _fields, true );
+ loadRow( _fields, originalFieldNumber, true );
// We move forward in the ResultSet, until we see another identity or run out of rows.
while ( _rs.next() ) {
@@ -2114,7 +2576,7 @@
if( identitiesEqual( wantedIdentity, currentIdentity ) ) {
// Load next row of object data from _rs into <_fields> array.
- loadRow( _fields, false );
+ loadRow( _fields, originalFieldNumber, false );
} else {
// We are done with all the rows for our obj. and still have rows left.
@@ -2129,7 +2591,7 @@
// We are done with all the rows for our obj. and don't have any rows left.
_resultSetDone = true;
_lastIdentity = null;
-
+
} catch ( SQLException except ) {
throw new PersistenceException( Messages.format("persist.nested", except), except );
}
Index: src/main/org/exolab/castor/jdo/engine/SQLTypes.java
===================================================================
RCS file: /scm/castor/castor/src/main/org/exolab/castor/jdo/engine/SQLTypes.java,v
retrieving revision 1.11
diff -u -r1.11 SQLTypes.java
--- src/main/org/exolab/castor/jdo/engine/SQLTypes.java 24 Mar 2005 10:44:57 -0000 1.11
+++ src/main/org/exolab/castor/jdo/engine/SQLTypes.java 21 Jun 2005 07:38:25 -0000
@@ -363,7 +363,6 @@
return java.toString();
}
-
public static Object getObject( ResultSet rs, int index, int sqlType )
throws SQLException
{
Index: src/main/org/exolab/castor/mapping/loader/ClassDescriptorImpl.java
===================================================================
RCS file: /scm/castor/castor/src/main/org/exolab/castor/mapping/loader/ClassDescriptorImpl.java,v
retrieving revision 1.2
diff -u -r1.2 ClassDescriptorImpl.java
--- src/main/org/exolab/castor/mapping/loader/ClassDescriptorImpl.java 5 Mar 2005 13:41:52 -0000 1.2
+++ src/main/org/exolab/castor/mapping/loader/ClassDescriptorImpl.java 21 Jun 2005 07:38:26 -0000
@@ -47,6 +47,12 @@
package org.exolab.castor.mapping.loader;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedList;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.exolab.castor.mapping.ValidityException;
import org.exolab.castor.mapping.ClassDescriptor;
import org.exolab.castor.mapping.FieldDescriptor;
@@ -66,7 +72,7 @@
public class ClassDescriptorImpl
implements ClassDescriptor
{
-
+ private static final Log _log = LogFactory.getLog (ClassDescriptorImpl.class);
private ClassMapping _map;
/**
@@ -85,6 +91,12 @@
* 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 _extendedBy = new LinkedList();
private final ClassDescriptor _depends;
@@ -166,6 +178,13 @@
throw new MappingException( "mapping.classDoesNotExtend",
_javaClass.getName(), extend.getJavaClass().getName() );
_extends = extend;
+
+ _log.debug (_extends.getClass().getName());
+ 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
@@ -232,6 +251,31 @@
public ClassDescriptor getExtends()
{
return _extends;
+ }
+
+ public boolean isExtending()
+ {
+ return (_extends != null);
+ }
+
+ /**
+ * Returns a collection of class descriptors that extend this class descriptor.
+ * @return A collection of class descriptors.
+ */
+ public Collection getExtendedBy()
+ {
+ return _extendedBy;
+ }
+
+ public boolean isExtended()
+ {
+ return (_extendedBy.size() > 0);
+ }
+
+ public void addExtendedBy (ClassDescriptor classDesc)
+ {
+ _log.debug ("Adding ClassDescriptor of type " + classDesc.getClass().getName());
+ _extendedBy.add (classDesc);
}
public ClassDescriptor getDepends() {
Index: src/main/org/exolab/castor/persist/ClassMolder.java
===================================================================
RCS file: /scm/castor/castor/src/main/org/exolab/castor/persist/ClassMolder.java,v
retrieving revision 1.24
diff -u -r1.24 ClassMolder.java
--- src/main/org/exolab/castor/persist/ClassMolder.java 20 Jun 2005 12:00:50 -0000 1.24
+++ src/main/org/exolab/castor/persist/ClassMolder.java 21 Jun 2005 07:38:28 -0000
@@ -65,6 +65,7 @@
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
@@ -487,17 +488,31 @@
extendFields = getFullFields( extend );
thisFields = clsMap.getFieldMapping();
- fieldList = new ArrayList(extendFields.length + thisFields.length);
+ fieldList = new ArrayList(extendFields.length + thisFields.length - identities.length);
for (int i = 0; i < extendFields.length; i++) {
fieldList.add(extendFields[i]);
}
- for ( int i=0; i";
+ }
+}
Index: src/examples/polymorphism/Computer.java
===================================================================
RCS file: src/examples/polymorphism/Computer.java
diff -N src/examples/polymorphism/Computer.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/examples/polymorphism/Computer.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,24 @@
+package polymorphism;
+
+/**
+ * @author werner.guttmann
+ *
+ * This is a type.
+ */
+public class Computer extends Product {
+
+ private String cpu;
+
+ /**
+ * @return Returns the cpu.
+ */
+ public String getCpu() {
+ return this.cpu;
+ }
+ /**
+ * @param cpu The cpu to set.
+ */
+ public void setCpu(String cpu) {
+ this.cpu = cpu;
+ }
+}
Index: src/examples/polymorphism/ComputerMulti.java
===================================================================
RCS file: src/examples/polymorphism/ComputerMulti.java
diff -N src/examples/polymorphism/ComputerMulti.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/examples/polymorphism/ComputerMulti.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,24 @@
+package polymorphism;
+
+/**
+ * @author werner.guttmann
+ *
+ * This is a type.
+ */
+public class ComputerMulti extends ProductMulti {
+
+ private String cpu;
+
+ /**
+ * @return Returns the cpu.
+ */
+ public String getCpu() {
+ return this.cpu;
+ }
+ /**
+ * @param cpu The cpu to set.
+ */
+ public void setCpu(String cpu) {
+ this.cpu = cpu;
+ }
+}
Index: src/examples/polymorphism/Container.java
===================================================================
RCS file: src/examples/polymorphism/Container.java
diff -N src/examples/polymorphism/Container.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/examples/polymorphism/Container.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,16 @@
+package polymorphism;
+
+public class Container {
+ private String id;
+ private Base reference;
+
+ public String getId() { return this.id; }
+ public void setId(String id) { this.id = id; }
+
+ public Base getReference() { return this.reference; }
+ public void setReference(Base reference) { this.reference = reference; }
+
+ public String toString(){
+ return super.toString() + "Container: id =" + this.id + ",reference=[" + this.reference + "]";
+ }
+}
Index: src/examples/polymorphism/Craft.java
===================================================================
RCS file: src/examples/polymorphism/Craft.java
diff -N src/examples/polymorphism/Craft.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/examples/polymorphism/Craft.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,5 @@
+package polymorphism;
+
+import org.exolab.castor.jdo.TimeStampable;
+
+public class Craft extends Product1893 implements TimeStampable { }
Index: src/examples/polymorphism/Culture.java
===================================================================
RCS file: src/examples/polymorphism/Culture.java
diff -N src/examples/polymorphism/Culture.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/examples/polymorphism/Culture.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,5 @@
+package polymorphism;
+
+import org.exolab.castor.jdo.TimeStampable;
+
+public class Culture extends Product1893 implements TimeStampable { }
Index: src/examples/polymorphism/Derived.java
===================================================================
RCS file: src/examples/polymorphism/Derived.java
diff -N src/examples/polymorphism/Derived.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/examples/polymorphism/Derived.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,12 @@
+package polymorphism;
+
+public class Derived extends Base {
+ private String scent;
+
+ public String getScent() { return this.scent; }
+ public void setScent(String scent) { this.scent = scent; }
+
+ public String toString(){
+ return super.toString() + ", Derived: scent=" + this.scent;
+ }
+}
Index: src/examples/polymorphism/Laptop.java
===================================================================
RCS file: src/examples/polymorphism/Laptop.java
diff -N src/examples/polymorphism/Laptop.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/examples/polymorphism/Laptop.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,36 @@
+package polymorphism;
+
+
+/**
+ * @author werner.guttmann
+ */
+public class Laptop extends Computer {
+
+ private int weight;
+ private String resolution;
+
+ /**
+ * @return Returns the resolution.
+ */
+ public String getResolution() {
+ return this.resolution;
+ }
+ /**
+ * @param resolution The resolution to set.
+ */
+ public void setResolution(String resolution) {
+ this.resolution = resolution;
+ }
+ /**
+ * @return Returns the weight.
+ */
+ public int getWeight() {
+ return this.weight;
+ }
+ /**
+ * @param weight The weight to set.
+ */
+ public void setWeight(int weight) {
+ this.weight = weight;
+ }
+}
Index: src/examples/polymorphism/LaptopMulti.java
===================================================================
RCS file: src/examples/polymorphism/LaptopMulti.java
diff -N src/examples/polymorphism/LaptopMulti.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/examples/polymorphism/LaptopMulti.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,36 @@
+package polymorphism;
+
+
+/**
+ * @author werner.guttmann
+ */
+public class LaptopMulti extends ComputerMulti {
+
+ private int weight;
+ private String resolution;
+
+ /**
+ * @return Returns the resolution.
+ */
+ public String getResolution() {
+ return this.resolution;
+ }
+ /**
+ * @param resolution The resolution to set.
+ */
+ public void setResolution(String resolution) {
+ this.resolution = resolution;
+ }
+ /**
+ * @return Returns the weight.
+ */
+ public int getWeight() {
+ return this.weight;
+ }
+ /**
+ * @param weight The weight to set.
+ */
+ public void setWeight(int weight) {
+ this.weight = weight;
+ }
+}
Index: src/examples/polymorphism/M.java
===================================================================
RCS file: src/examples/polymorphism/M.java
diff -N src/examples/polymorphism/M.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/examples/polymorphism/M.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,34 @@
+package polymorphism;
+
+import java.util.Collection;
+
+/**
+ * @author werner.guttmann
+ *
+ * This is a type.
+ */
+public class M {
+
+ private int id;
+ private String name;
+ private Collection ns;
+
+ public int getId() {
+ return this.id;
+ }
+ public void setId(int id) {
+ this.id = id;
+ }
+ public String getName() {
+ return this.name;
+ }
+ public void setName(String name) {
+ this.name = name;
+ }
+ public Collection getNs() {
+ return this.ns;
+ }
+ public void setNs(Collection ns) {
+ this.ns = ns;
+ }
+}
Index: src/examples/polymorphism/N.java
===================================================================
RCS file: src/examples/polymorphism/N.java
diff -N src/examples/polymorphism/N.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/examples/polymorphism/N.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,34 @@
+package polymorphism;
+
+import java.util.Collection;
+
+/**
+ * @author werner.guttmann
+ *
+ * This is a type.
+ */
+public class N {
+
+ private int id;
+ private String name;
+ private Collection ms;
+
+ public Collection getMs() {
+ return this.ms;
+ }
+ public void setMs(Collection ms) {
+ this.ms = ms;
+ }
+ public int getId() {
+ return this.id;
+ }
+ public void setId(int id) {
+ this.id = id;
+ }
+ public String getName() {
+ return this.name;
+ }
+ public void setName(String name) {
+ this.name = name;
+ }
+}
Index: src/examples/polymorphism/Order.java
===================================================================
RCS file: src/examples/polymorphism/Order.java
diff -N src/examples/polymorphism/Order.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/examples/polymorphism/Order.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,34 @@
+package polymorphism;
+
+import java.util.Collection;
+
+/**
+ * @author werner.guttmann
+ *
+ * This is a type.
+ */
+public class Order {
+
+ private int id;
+ private String name;
+ private Collection products;
+
+ public int getId() {
+ return this.id;
+ }
+ public void setId(int id) {
+ this.id = id;
+ }
+ public String getName() {
+ return this.name;
+ }
+ public void setName(String name) {
+ this.name = name;
+ }
+ public Collection getProducts() {
+ return this.products;
+ }
+ public void setProducts(Collection products) {
+ this.products = products;
+ }
+}
Index: src/examples/polymorphism/Owner.java
===================================================================
RCS file: src/examples/polymorphism/Owner.java
diff -N src/examples/polymorphism/Owner.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/examples/polymorphism/Owner.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,31 @@
+package polymorphism;
+
+/**
+ * @author werner.guttmann
+ */
+public class Owner {
+
+ private int id;
+ private String name;
+ private Product product;
+
+ public int getId() {
+ return this.id;
+ }
+ public void setId(int id) {
+ this.id = id;
+ }
+ public String getName() {
+ return this.name;
+ }
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Product getProduct() {
+ return this.product;
+ }
+ public void setProduct(Product product) {
+ this.product = product;
+ }
+}
Index: src/examples/polymorphism/PolymorphismTest.java
===================================================================
RCS file: src/examples/polymorphism/PolymorphismTest.java
diff -N src/examples/polymorphism/PolymorphismTest.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/examples/polymorphism/PolymorphismTest.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,556 @@
+package polymorphism;
+
+import java.util.Collection;
+import java.util.LinkedList;
+
+import org.exolab.castor.jdo.Database;
+import org.exolab.castor.jdo.JDOManager;
+import org.exolab.castor.jdo.OQLQuery;
+import org.exolab.castor.jdo.ObjectNotFoundException;
+import org.exolab.castor.jdo.QueryResults;
+import org.exolab.castor.persist.spi.Complex;
+
+import junit.framework.TestCase;
+
+/**
+ * @author werner.guttmann
+ *
+ * This is a type.
+ */
+public class PolymorphismTest extends TestCase {
+
+ private static final String DATABASE_NAME = "1018";
+ /**
+ * Castor JDO manager
+ */
+ private JDOManager jdo = null;
+
+ /*
+ * @see TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ JDOManager.loadConfiguration (getClass().getResource("jdo-conf.xml").toString());
+ this.jdo = JDOManager.createInstance(DATABASE_NAME);
+
+ }
+
+ public void testLoadLaptop() throws Exception {
+
+ Database database = null;
+
+ database = this.jdo.getDatabase();
+
+ database.begin();
+ Laptop laptop = (Laptop) database.load (Laptop.class, new Integer (1));
+ database.commit();
+
+ assertNotNull (laptop);
+ assertEquals ("polymorphism.Laptop", laptop.getClass().getName());
+ assertEquals (1, laptop.getId());
+ assertEquals ("laptop 1", laptop.getName());
+
+ database.close();
+
+ }
+
+ public void testCreateAndLoadLaptop() throws Exception {
+
+ Database database = null;
+
+ database = this.jdo.getDatabase();
+
+ database.begin();
+ ProductDetail detail = new ProductDetail();
+ detail.setId(10);
+ detail.setCategory("category 10");
+ detail.setLocation("location 10");
+ database.create(detail);
+ database.commit();
+
+ database.begin();
+ Laptop laptop = new Laptop();
+ laptop.setId(10);
+ laptop.setName("laptop 10");
+ laptop.setCpu("centrino");
+ laptop.setResolution("1600");
+ laptop.setWeight(2750);
+ laptop.setDetail((ProductDetail) database.load(ProductDetail.class, new Integer (10)));
+ database.create(laptop);
+ database.commit();
+
+ database.begin();
+ laptop = (Laptop) database.load (Laptop.class, new Integer (10));
+ database.commit();
+
+ assertNotNull (laptop);
+ assertEquals ("polymorphism.Laptop", laptop.getClass().getName());
+ assertEquals (10, laptop.getId());
+ assertEquals ("laptop 10", laptop.getName());
+
+ database.begin();
+ database.remove (database.load(Laptop.class, new Integer (10)));
+ database.remove (database.load (ProductDetail.class, new Integer (10)));
+ database.commit();
+
+ database.begin();
+ try {
+ laptop = (Laptop) database.load(Laptop.class, new Integer (10));
+ fail ("Laptop with id 10 still exists.");
+ }
+ catch (ObjectNotFoundException e) {
+ assertEquals ("The object of type polymorphism.Laptop with identity 10 was not found in persistent storage", e.getMessage());
+ }
+
+ database.commit();
+
+ database.close();
+
+ }
+
+ public void testLoadLaptopMulti() throws Exception {
+
+ Database database = null;
+
+ database = this.jdo.getDatabase();
+
+ database.begin();
+ LaptopMulti laptop = (LaptopMulti) database.load (LaptopMulti.class, new Complex (new Integer (1), new Integer(1)));
+ database.commit();
+
+ assertNotNull (laptop);
+ assertEquals ("polymorphism.LaptopMulti", laptop.getClass().getName());
+ assertEquals ("laptop 1", laptop.getName());
+ assertEquals (1, laptop.getId1());
+ assertEquals (1, laptop.getId2());
+
+ database.close();
+
+ }
+
+ public void testLoadServer() throws Exception {
+
+ Database database = null;
+
+ database = this.jdo.getDatabase();
+
+ database.begin();
+ Server server = (Server) database.load (Server.class, new Integer (3));
+ database.commit();
+
+ assertNotNull (server);
+ assertEquals ("polymorphism.Server", server.getClass().getName());
+ assertEquals (3, server.getId());
+ assertEquals ("server 3", server.getName());
+
+ database.close();
+
+ }
+
+ public void testLoadServerMulti() throws Exception {
+
+ Database database = null;
+
+ database = this.jdo.getDatabase();
+
+ database.begin();
+ ServerMulti server = (ServerMulti) database.load (ServerMulti.class, new Complex (new Integer (3), new Integer(3)));
+ database.commit();
+
+ assertNotNull (server);
+ assertEquals ("polymorphism.ServerMulti", server.getClass().getName());
+ assertEquals (3, server.getId1());
+ assertEquals (3, server.getId2());
+ assertEquals ("server 3", server.getName());
+
+ database.close();
+
+ }
+
+ public void testLoadComputer() throws Exception {
+
+ Database database = null;
+
+ database = this.jdo.getDatabase();
+
+ database.begin();
+ Computer computer = (Computer) database.load (Computer.class, new Integer (2));
+ database.commit();
+
+ assertNotNull (computer);
+ assertEquals ("polymorphism.Laptop", computer.getClass().getName());
+ assertEquals (2, computer.getId());
+ assertEquals ("laptop 2", computer.getName());
+
+ database.close();
+
+ }
+
+ public void testCreateAndLoadComputer() throws Exception {
+
+ Database database = null;
+
+ database = this.jdo.getDatabase();
+
+ database.begin();
+ Order order = new Order();
+ order.setId(12);
+ order.setName("order 12");
+ database.create(order);
+ database.commit();
+
+ database.begin();
+ ProductDetail detail = new ProductDetail();
+ detail.setId(12);
+ detail.setCategory("category 12");
+ detail.setLocation("location 12");
+ database.create(detail);
+ database.commit();
+
+ database.begin();
+ Laptop laptop = new Laptop();
+ laptop.setId(12);
+ laptop.setName("laptop 12");
+ laptop.setCpu("centrino");
+ laptop.setResolution("1600");
+ laptop.setWeight(2450);
+ laptop.setDetail((ProductDetail) database.load(ProductDetail.class, new Integer (12)));
+ database.create(laptop);
+ Collection orders = new LinkedList();
+ orders.add(database.load (Order.class, new Integer (12)));;
+ laptop.setOrders(orders);
+ database.commit();
+
+ database.begin();
+ Computer computer = (Computer) database.load (Computer.class, new Integer (12));
+ database.commit();
+
+ assertNotNull (computer);
+ assertEquals ("polymorphism.Laptop", computer.getClass().getName());
+ assertEquals (12, computer.getId());
+ assertEquals ("laptop 12", computer.getName());
+
+ database.begin();
+ database.remove (database.load(Computer.class, new Integer (12)));
+ database.remove (database.load (ProductDetail.class, new Integer (12)));
+ database.remove (database.load(Order.class, new Integer (12)));
+ database.commit();
+
+
+ database.close();
+
+ }
+
+
+ public void testLoadComputerMulti() throws Exception {
+
+ Database database = null;
+
+ database = this.jdo.getDatabase();
+
+ database.begin();
+ ComputerMulti computer = (LaptopMulti) database.load (ComputerMulti.class, new Complex (new Integer (1), new Integer (1)));
+ database.commit();
+
+ assertNotNull (computer);
+ assertEquals (1, computer.getId1());
+ assertEquals (1, computer.getId2());
+ assertEquals ("laptop 1", computer.getName());
+
+ database.close();
+
+ }
+
+ public void testLoadTruck() throws Exception {
+
+ Database database = null;
+
+ database = this.jdo.getDatabase();
+
+ database.begin();
+ Truck truck = (Truck) database.load (Truck.class, new Integer (5));
+ database.commit();
+
+ assertNotNull (truck);
+ assertEquals (5, truck.getId());
+
+ database.close();
+
+ }
+
+ public void testLoadCar() throws Exception {
+
+ Database database = null;
+
+ database = this.jdo.getDatabase();
+
+ database.begin();
+ Object object = database.load (Car.class, new Integer (5));
+ assertNotNull (object);
+ assertEquals ("polymorphism.Truck", object.getClass().getName());
+ Truck truck = (Truck) object;
+ database.commit();
+
+ assertNotNull (truck);
+ assertEquals (5, truck.getId());
+
+ database.close();
+
+ }
+
+ public void testCreateAndLoadCar() throws Exception {
+
+ Database database = null;
+
+ database = this.jdo.getDatabase();
+
+ database.begin();
+ Order order = new Order();
+ order.setId(11);
+ order.setName("order 11");
+ database.create(order);
+ database.commit();
+
+ database.begin();
+ ProductDetail detail = new ProductDetail();
+ detail.setId(11);
+ detail.setCategory("category 11");
+ detail.setLocation("location 11");
+ database.create(detail);
+ database.commit();
+
+ database.begin();
+ Truck truck = new Truck();
+ truck.setId(11);
+ truck.setName("truck 11");
+ truck.setKw(112);
+ truck.setMake("Fiat");
+ truck.setMaxWeight(3750);
+ truck.setDetail((ProductDetail) database.load(ProductDetail.class, new Integer (11)));
+ database.create(truck);
+ Collection orders = new LinkedList();
+ orders.add(database.load (Order.class, new Integer (11)));;
+ truck.setOrders(orders);
+ database.commit();
+
+ database.begin();
+ Object object = database.load (Car.class, new Integer (11));
+ assertNotNull (object);
+ assertEquals ("polymorphism.Truck", object.getClass().getName());
+ Truck loadedTruck = (Truck) object;
+ database.commit();
+
+ assertNotNull (loadedTruck);
+ assertEquals (11, loadedTruck.getId());
+
+ database.begin();
+ database.remove (database.load (Car.class, new Integer (11)));
+ database.remove (database.load (ProductDetail.class, new Integer (11)));
+ database.remove(database.load(Order.class, new Integer (11)));
+ database.commit();
+
+ database.close();
+
+ }
+
+
+ public void testLoadOwner() throws Exception {
+
+ Database database = null;
+
+ database = this.jdo.getDatabase();
+
+ database.begin();
+ Owner owner = (Owner) database.load (Owner.class, new Integer (1));
+ database.commit();
+
+ assertNotNull (owner);
+ assertEquals (1, owner.getId());
+ assertEquals ("owner 1", owner.getName());
+
+ Product product = owner.getProduct();
+ assertNotNull (product);
+ assertEquals (1, product.getId());
+ assertEquals ("polymorphism.Laptop", product.getClass().getName());
+
+ database.close();
+
+ }
+
+ public void testLoadM() throws Exception {
+
+ Database database = null;
+
+ database = this.jdo.getDatabase();
+
+ database.begin();
+ M m = (M) database.load (M.class, new Integer (1));
+ database.commit();
+
+ assertNotNull (m);
+ assertEquals (1, m.getId());
+ assertEquals ("m1", m.getName());
+
+ Collection ns = m.getNs();
+ assertNotNull (ns);
+ assertEquals (2, ns.size());
+
+ database.close();
+
+ }
+
+ public void testQueryOwner () throws Exception {
+
+ Database database = this.jdo.getDatabase();
+
+ database.begin();
+ OQLQuery query = database.getOQLQuery("select owner from polymorphism.Owner as owner");
+ QueryResults results = query.execute();
+
+ if (results.hasMore()) {
+ int counter = 1;
+ while (results.hasMore()) {
+ Owner owner = (Owner) results.next();
+ assertNotNull (owner);
+ assertEquals (counter, owner.getId());
+
+ counter += 1;
+ }
+ } else {
+ fail ("Query does not return any Computer instances.");
+ }
+ database.commit();
+
+ database.close();
+ }
+
+ public void testQueryComputers () throws Exception {
+
+ Database database;
+
+ String[] classNames =
+ {
+ "polymorphism.Laptop",
+ "polymorphism.Laptop",
+ "polymorphism.Server",
+ "polymorphism.Server"
+ };
+
+ database = this.jdo.getDatabase();
+
+ database.begin();
+ OQLQuery query = database.getOQLQuery("select computer from polymorphism.Computer as computer");
+ QueryResults results = query.execute();
+
+ if (results.hasMore()) {
+ int counter = 1;
+ while (results.hasMore()) {
+ Computer computer = (Computer) results.next();
+ assertNotNull (computer);
+ assertEquals (counter, computer.getId());
+ assertEquals (classNames[counter - 1], computer.getClass().getName());
+
+ counter += 1;
+ }
+ } else {
+ fail ("Query does not return any Computer instances.");
+ }
+ database.commit();
+
+ database.close();
+ }
+
+ public void testQueryLaptops () throws Exception {
+
+ Database database;
+
+ database = this.jdo.getDatabase();
+
+ database.begin();
+ OQLQuery query = database.getOQLQuery("select l from polymorphism.Laptop as l");
+ QueryResults results = query.execute();
+
+ if (results.hasMore()) {
+ int counter = 1;
+ Laptop laptop = null;
+ while (results.hasMore()) {
+ laptop = (Laptop) results.next();
+ assertNotNull (laptop);
+ assertEquals (counter, laptop.getId());
+
+ counter += 1;
+ }
+ } else {
+ fail ("Query does not return any Laptop instances.");
+ }
+ database.commit();
+
+ database.close();
+ }
+
+ public void testQueryServers () throws Exception {
+
+ Database database;
+
+ database = this.jdo.getDatabase();
+
+ database.begin();
+ OQLQuery query = database.getOQLQuery("select l from polymorphism.Server as l");
+ QueryResults results = query.execute();
+
+ if (results.hasMore()) {
+ int counter = 3;
+ while (results.hasMore()) {
+ Server server = (Server) results.next();
+ assertNotNull (server);
+ assertEquals (counter, server.getId());
+
+ counter += 1;
+ }
+ } else {
+ fail ("Query does not return any Laptop instances.");
+ }
+ database.commit();
+
+ database.close();
+ }
+
+ public void testQueryProducts () throws Exception {
+
+ Database database;
+
+ String[] classNames =
+ {
+ "polymorphism.Laptop",
+ "polymorphism.Laptop",
+ "polymorphism.Server",
+ "polymorphism.Server",
+ "polymorphism.Truck"
+ };
+
+ database = this.jdo.getDatabase();
+
+ database.begin();
+ OQLQuery query = database.getOQLQuery("select product from polymorphism.Product as product");
+ QueryResults results = query.execute();
+
+ if (results.hasMore()) {
+ int counter = 1;
+ while (results.hasMore()) {
+ Product product = (Product) results.next();
+ assertNotNull (product);
+ assertEquals (counter, product.getId());
+ assertEquals (classNames[counter - 1], product.getClass().getName());
+
+ counter += 1;
+ }
+ } else {
+ fail ("Query does not return any Product instances.");
+ }
+ database.commit();
+
+ database.close();
+ }
+
+}
Index: src/examples/polymorphism/Product.java
===================================================================
RCS file: src/examples/polymorphism/Product.java
diff -N src/examples/polymorphism/Product.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/examples/polymorphism/Product.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,51 @@
+package polymorphism;
+
+import java.util.Collection;
+
+/**
+ * @author werner.guttmann
+ */
+public class Product {
+
+ private int id;
+ private String name;
+ private ProductDetail detail;
+ private Collection orders;
+
+ public ProductDetail getDetail() {
+ return this.detail;
+ }
+ public void setDetail(ProductDetail detail) {
+ this.detail = detail;
+ }
+ /**
+ * @return Returns the id.
+ */
+ public int getId() {
+ return this.id;
+ }
+ /**
+ * @param id The id to set.
+ */
+ public void setId(int id) {
+ this.id = id;
+ }
+ /**
+ * @return Returns the name.
+ */
+ public String getName() {
+ return this.name;
+ }
+ /**
+ * @param name The name to set.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+ public Collection getOrders() {
+ return this.orders;
+ }
+ public void setOrders(Collection orders) {
+ this.orders = orders;
+ }
+}
Index: src/examples/polymorphism/Product1893.java
===================================================================
RCS file: src/examples/polymorphism/Product1893.java
diff -N src/examples/polymorphism/Product1893.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/examples/polymorphism/Product1893.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,49 @@
+package polymorphism;
+
+import java.util.Iterator;
+import java.util.Vector;
+
+import org.exolab.castor.jdo.TimeStampable;
+
+public class Product1893 implements TimeStampable {
+ private int _id;
+ private String _name;
+ private String _desc;
+ private Vector _composition = new Vector();
+
+ private long _timeStamp;
+
+ public int getId() { return _id; }
+ public void setId( int id ) { _id = id; }
+
+ public String getName() { return _name; }
+ public void setName( String name ) { _name = name; }
+
+ public String getDescription() { return _desc; }
+ public void setDescription( String desc ) { _desc = desc; }
+
+ public Vector getCompositions() { return _composition; }
+ public void setCompositions( Vector products ) {
+ Iterator iter = products.iterator();
+ while( iter.hasNext() ) {
+ ComposedProduct cp = (ComposedProduct)iter.next();
+ if ( ! _composition.contains( cp ) ) {
+ _composition.add( cp );
+ cp.addSubProduct( this );
+ }
+ }
+ }
+ public void addComposition( ComposedProduct product ) {
+ if ( ! _composition.contains( product ) ) {
+ _composition.addElement( product );
+ product.addSubProduct( this );
+ }
+ }
+
+ public void jdoSetTimeStamp( long timeStamp ) { _timeStamp = timeStamp; }
+ public long jdoGetTimeStamp() { return _timeStamp; }
+
+ public String toString() {
+ return "";
+ }
+}
Index: src/examples/polymorphism/ProductDetail.java
===================================================================
RCS file: src/examples/polymorphism/ProductDetail.java
diff -N src/examples/polymorphism/ProductDetail.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/examples/polymorphism/ProductDetail.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,33 @@
+package polymorphism;
+
+/**
+ * @author werner.guttmann
+ *
+ * This is a type.
+ */
+public class ProductDetail {
+
+ private int id;
+ private String category;
+ private String location;
+
+
+ public String getCategory() {
+ return this.category;
+ }
+ public void setCategory(String category) {
+ this.category = category;
+ }
+ public int getId() {
+ return this.id;
+ }
+ public void setId(int id) {
+ this.id = id;
+ }
+ public String getLocation() {
+ return this.location;
+ }
+ public void setLocation(String location) {
+ this.location = location;
+ }
+}
Index: src/examples/polymorphism/ProductMulti.java
===================================================================
RCS file: src/examples/polymorphism/ProductMulti.java
diff -N src/examples/polymorphism/ProductMulti.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/examples/polymorphism/ProductMulti.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,49 @@
+package polymorphism;
+
+/**
+ * @author werner.guttmann
+ */
+public class ProductMulti {
+
+ private int id1;
+ private int id2;
+ private String name;
+ private ProductDetail detail;
+
+ public ProductDetail getDetail() {
+ return this.detail;
+ }
+ public void setDetail(ProductDetail detail) {
+ this.detail = detail;
+ }
+ /**
+ * @return Returns the id.
+ */
+ public int getId1() {
+ return this.id1;
+ }
+ /**
+ * @param id The id to set.
+ */
+ public void setId1(int id1) {
+ this.id1 = id1;
+ }
+ /**
+ * @return Returns the name.
+ */
+ public String getName() {
+ return this.name;
+ }
+ /**
+ * @param name The name to set.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+ public int getId2() {
+ return this.id2;
+ }
+ public void setId2(int id2) {
+ this.id2 = id2;
+ }
+}
Index: src/examples/polymorphism/Server.java
===================================================================
RCS file: src/examples/polymorphism/Server.java
diff -N src/examples/polymorphism/Server.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/examples/polymorphism/Server.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,35 @@
+package polymorphism;
+
+/**
+ * @author werner.guttmann
+ */
+public class Server extends Computer {
+
+ private int numberOfCPUs;
+ private int supportInYears;
+
+ /**
+ * @return Returns the numberOfCPUs.
+ */
+ public int getNumberOfCPUs() {
+ return this.numberOfCPUs;
+ }
+ /**
+ * @param numberOfCPUs The numberOfCPUs to set.
+ */
+ public void setNumberOfCPUs(int numberOfCPUs) {
+ this.numberOfCPUs = numberOfCPUs;
+ }
+ /**
+ * @return Returns the supportInYears.
+ */
+ public int getSupportInYears() {
+ return this.supportInYears;
+ }
+ /**
+ * @param supportInYears The supportInYears to set.
+ */
+ public void setSupportInYears(int supportInYears) {
+ this.supportInYears = supportInYears;
+ }
+}
Index: src/examples/polymorphism/ServerMulti.java
===================================================================
RCS file: src/examples/polymorphism/ServerMulti.java
diff -N src/examples/polymorphism/ServerMulti.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/examples/polymorphism/ServerMulti.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,35 @@
+package polymorphism;
+
+/**
+ * @author werner.guttmann
+ */
+public class ServerMulti extends ComputerMulti{
+
+ private int numberOfCPUs;
+ private int supportInYears;
+
+ /**
+ * @return Returns the numberOfCPUs.
+ */
+ public int getNumberOfCPUs() {
+ return this.numberOfCPUs;
+ }
+ /**
+ * @param numberOfCPUs The numberOfCPUs to set.
+ */
+ public void setNumberOfCPUs(int numberOfCPUs) {
+ this.numberOfCPUs = numberOfCPUs;
+ }
+ /**
+ * @return Returns the supportInYears.
+ */
+ public int getSupportInYears() {
+ return this.supportInYears;
+ }
+ /**
+ * @param supportInYears The supportInYears to set.
+ */
+ public void setSupportInYears(int supportInYears) {
+ this.supportInYears = supportInYears;
+ }
+}
Index: src/examples/polymorphism/Test1197.java
===================================================================
RCS file: src/examples/polymorphism/Test1197.java
diff -N src/examples/polymorphism/Test1197.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/examples/polymorphism/Test1197.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,203 @@
+package polymorphism;
+
+import junit.framework.TestCase;
+
+import org.exolab.castor.jdo.Database;
+import org.exolab.castor.jdo.JDOManager;
+import org.exolab.castor.jdo.OQLQuery;
+import org.exolab.castor.jdo.QueryResults;
+import org.exolab.castor.mapping.Mapping;
+
+public class Test1197 extends TestCase {
+ private static final String DATABASE_NAME = "1018";
+ private static final String JdoConfFile = "jdo-conf.xml";
+ private static final String MappingFile = "mapping.xml";
+ private static final int REPS = 100;
+
+ private Mapping mapping;
+ private JDOManager jdo;
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run( Test1197.class );
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ this.mapping = new Mapping( getClass().getClassLoader() );
+ this.mapping.loadMapping( getClass().getResource( MappingFile ) );
+
+ JDOManager.loadConfiguration( getClass().getResource( JdoConfFile ).toString() );
+ this.jdo = JDOManager.createInstance( DATABASE_NAME );
+
+ Database db = this.jdo.getDatabase();
+
+ db.begin();
+ OQLQuery query = db.getOQLQuery( "select c from " + Container.class.getName() + " c" );
+ QueryResults results = query.execute();
+ while (results.hasMore()) { db.remove(results.next()); }
+ db.commit();
+
+ db.begin();
+ query = db.getOQLQuery( "select d from " + Derived.class.getName() + " d" );
+ results = query.execute();
+ while (results.hasMore()) { db.remove(results.next()); }
+ db.commit();
+
+ db.begin();
+ query = db.getOQLQuery( "select d from " + Base.class.getName() + " d" );
+ results = query.execute();
+ while (results.hasMore()) { db.remove(results.next()); }
+ db.commit();
+
+ db.begin();
+ try{
+ Derived d = new Derived();
+ d.setId( "100" );
+ d.setColor( "blue" );
+ d.setScent( "parsimmon" );
+ db.create( d );
+
+ Container c = new Container();
+ c.setId( "200" );
+ c.setReference( d );
+ db.create( c );
+
+ db.commit();
+ } catch ( Exception ex ){
+ ex.printStackTrace();
+ db.rollback();
+ throw ex;
+ }
+
+ db.close();
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ protected Container loadContainer() throws Exception{
+ Database db = this.jdo.getDatabase();
+ db.begin();
+ Container container;
+ try {
+ container = (Container) db.load( Container.class, "200" );
+ db.commit();
+ } catch ( Exception ex ) {
+ db.rollback();
+ throw ex;
+ } finally {
+ db.close();
+ }
+ return container;
+ }
+
+ private Derived loadDerived() throws Exception{
+ Database db = this.jdo.getDatabase();
+ db.begin();
+ Derived derived;
+ try {
+ derived = (Derived) db.load( Derived.class, "100" );
+ db.commit();
+ } catch ( Exception ex ) {
+ db.rollback();
+ throw ex;
+ } finally {
+ db.close();
+ }
+ return derived;
+ }
+
+ private Container loadContainerThenDerived() throws Exception {
+ Database db = this.jdo.getDatabase();
+ db.begin();
+ Container container = null;
+ Derived derived = null;
+ try {
+ container = (Container) db.load( Container.class, "200" );
+ derived = (Derived) db.load( Derived.class, "100" );
+ db.commit();
+ } catch ( Exception ex ) {
+ db.rollback();
+ throw ex;
+ } finally {
+ db.close();
+ }
+ return container;
+ }
+
+ public void testLoadContainer() {
+ try {
+ System.out.println( "First we load a Container in its own transaction" );
+ System.out.flush();
+ Object o = loadContainer();
+ System.out.println( "loadContainer: " + o );
+ } catch ( Exception ex ) {
+ ex.printStackTrace();
+ }
+ }
+
+ public void testLoadDerived() {
+ try {
+ System.out.println( "Second we load a Derived in its own transaction" );
+ System.out.flush();
+ Object o = loadDerived();
+ System.out.println( "loadDerived: " + o );
+ } catch ( Exception ex ) {
+ ex.printStackTrace();
+ }
+ }
+
+ public void testLoadContainerThenDerived() {
+ try {
+ System.out.println( "Third we load a Container and a Derived in one transaction" );
+ System.out.flush();
+ Object o = loadContainerThenDerived();
+ System.out.println( "loadContainerThenDerived: " + o);
+ } catch ( Exception ex ) {
+ ex.printStackTrace();
+ }
+ }
+
+ public void testLoadContainerAndDerivedThreaded() {
+ int count = 0;
+ try {
+ System.out.println( "Forth we load Container and Derived in seperate "
+ + "threads in their own transactions" );
+ System.out.flush();
+
+ Thread thread = new Thread ( new TreadedContainerLoader() );
+ thread.start();
+
+ for ( int i = 0; i < REPS; i++ ) {
+ count = i;
+ loadDerived();
+ }
+ System.out.println( "First thread successfully loaded " + (count + 1) + " Derived" );
+
+ thread.join();
+ } catch ( Exception ex ) {
+ System.err.println( "Exception on first thread loading Derived on " + (count + 1) + "th try" );
+ System.out.flush();
+ ex.printStackTrace();
+ }
+ }
+
+ class TreadedContainerLoader implements Runnable {
+ public void run() {
+ int count = 0;
+ try {
+ for ( int i = 0; i < REPS; i++ ) {
+ count = i;
+ loadContainer();
+ }
+ System.out.println( "Second thread successfully loaded " + (count + 1) + " Containers" );
+ } catch ( Exception ex ) {
+ System.err.println( "Exception on second thread loading Container on " + (count + 1) + "th try" );
+ System.out.flush();
+ ex.printStackTrace();
+ }
+ }
+ }
+}
Index: src/examples/polymorphism/Test1893.java
===================================================================
RCS file: src/examples/polymorphism/Test1893.java
diff -N src/examples/polymorphism/Test1893.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/examples/polymorphism/Test1893.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,166 @@
+package polymorphism;
+
+import junit.framework.TestCase;
+
+import org.exolab.castor.jdo.Database;
+import org.exolab.castor.jdo.JDOManager;
+import org.exolab.castor.mapping.Mapping;
+
+public class Test1893 extends TestCase {
+
+ private static final String DATABASE_NAME = "1018";
+ public static final String JdoConfFile = "jdo-conf.xml";
+ public static final String MappingFile = "mapping.xml";
+
+ private Mapping mapping;
+ private JDOManager jdo;
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run( Test1893.class );
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ this.mapping = new Mapping( getClass().getClassLoader() );
+ this.mapping.loadMapping( getClass().getResource( MappingFile ) );
+
+ JDOManager.loadConfiguration( getClass().getResource( JdoConfFile ).toString() );
+ this.jdo = JDOManager.createInstance( DATABASE_NAME );
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testCreateProd() throws Exception
+ {
+ Database db = this.jdo.getDatabase();
+ db.setAutoStore( true );
+ db.begin();
+
+ Product1893 pd1 = new Product1893();
+ pd1.setName( "Product-1" );
+ pd1.setDescription( "Product-1: <30" );
+ db.create( pd1 );
+
+ Product1893 pd2 = new Product1893();
+ pd2.setName( "Product-2" );
+ pd2.setDescription( "Product-2: <30" );
+ db.create( pd2 );
+
+ db.commit();
+ db.close();
+ }
+
+ public void testCreateCrafts() throws Exception
+ {
+ Database db = this.jdo.getDatabase();
+ db.setAutoStore( true );
+ db.begin();
+
+ Craft crf1 = new Craft();
+ crf1.setName( "Craft-1" );
+ crf1.setDescription( "Craft-1: <30" );
+ db.create( crf1 );
+
+ Craft crf2 = new Craft();
+ crf2.setName( "Craft-2" );
+ crf2.setDescription( "Craft-2: <30" );
+ db.create( crf2 );
+
+ db.commit();
+ db.close();
+ }
+
+ public void testCreateCulture() throws Exception {
+ Database db = this.jdo.getDatabase();
+ db.setAutoStore( true );
+ db.begin();
+
+ Culture cult1 = new Culture();
+ cult1.setName( "Culture-1" );
+ cult1.setDescription( "Culture-1: <30" );
+ db.create( cult1 );
+
+ Culture cult2 = new Culture();
+ cult2.setName( "Culture-2" );
+ cult2.setDescription( "Culture-2: <30" );
+ db.create( cult2 );
+
+ db.commit();
+ db.close();
+ }
+
+ public void testCreateAccomodation() throws Exception {
+ Database db = this.jdo.getDatabase();
+ db.setAutoStore( true );
+ db.begin();
+
+ Accommodation acc1 = new Accommodation();
+ acc1.setName( "Accommodation-1" );
+ acc1.setDescription( "Accommodation-1: <30" );
+ acc1.setBestSeason( "Season-1" );
+ db.create( acc1 );
+
+ Accommodation acc2 = new Accommodation();
+ acc2.setName( "Accommodation-2" );
+ acc2.setDescription( "Accommodation-2: <30" );
+ acc2.setBestSeason( "Season-2" );
+ db.create( acc2 );
+
+ db.commit();
+ db.close();
+ }
+
+ public void testCreateComposed() throws Exception {
+ Database db = this.jdo.getDatabase();
+ db.setAutoStore( true );
+ db.begin();
+
+ ComposedProduct compp1 = new ComposedProduct();
+ compp1.setName( "Composition-1" );
+ compp1.setExtraName( "Xtra-Composition-1" );
+ compp1.setDescription( "Composition-1: <30" );
+ compp1.setExtraDescription( "Xtra-Composition-1: <30" );
+ db.create( compp1 );
+
+ ComposedProduct compp2 = new ComposedProduct();
+ compp2.setName( "Composition-2" );
+ compp2.setExtraName( "Xtra-Composition-2" );
+ compp2.setDescription( "Composition-2: <30" );
+ compp2.setExtraDescription( "Xtra-Composition-2: <30" );
+ db.create( compp2 );
+
+ db.commit();
+ db.close();
+ }
+
+ public void testComposeOffer() throws Exception {
+ Database db = this.jdo.getDatabase();
+ db.setAutoStore( true );
+ db.begin();
+
+ Product1893 pd1 = new Product1893();
+ pd1.setName( "Just product" );
+ db.create( pd1 );
+
+ Accommodation acc1 = new Accommodation();
+ acc1.setName( "Comp-Accommodation-2" );
+ acc1.setDescription( "Comp-Accommodation-2: <30" );
+ acc1.setBestSeason( "Comp-Season-2" );
+ db.create( acc1 );
+
+ ComposedProduct compp1 = new ComposedProduct();
+ compp1.setName( "Composition-3" );
+ compp1.setExtraName( "Xtra-Composition-3" );
+ compp1.setDescription( "Composition-3: <30" );
+ compp1.setExtraDescription( "Xtra-Composition-3: <30" );
+ compp1.addSubProduct( pd1 );
+ compp1.addSubProduct( acc1 );
+ db.create( compp1 );
+
+ db.commit();
+ db.close();
+ }
+}
Index: src/examples/polymorphism/Truck.java
===================================================================
RCS file: src/examples/polymorphism/Truck.java
diff -N src/examples/polymorphism/Truck.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/examples/polymorphism/Truck.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,22 @@
+package polymorphism;
+
+/**
+ * @author Administrator
+ */
+public class Truck extends Car {
+
+ private int maxWeight;
+
+ /**
+ * @return Returns the maxWeight.
+ */
+ public int getMaxWeight() {
+ return maxWeight;
+ }
+ /**
+ * @param maxWeight The maxWeight to set.
+ */
+ public void setMaxWeight(int maxWeight) {
+ this.maxWeight = maxWeight;
+ }
+}
Index: src/examples/polymorphism/ddl.sql
===================================================================
RCS file: src/examples/polymorphism/ddl.sql
diff -N src/examples/polymorphism/ddl.sql
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/examples/polymorphism/ddl.sql 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,229 @@
+drop table if exists ordr;
+create table ordr (
+ id int not null,
+ name varchar (20) not null
+);
+
+drop table if exists detail;
+create table detail (
+ id int not null,
+ category varchar (20) not null,
+ location varchar (20) not null
+);
+
+drop table if exists owner;
+create table owner (
+ id int not null,
+ name varchar (20) not null,
+ product int not null
+);
+
+drop table if exists prod;
+create table prod (
+ id int not null,
+ name varchar(200) not null,
+ detail int not null
+);
+
+drop table if exists computer;
+create table computer (
+ id int not null,
+ cpu varchar(200) not null
+);
+
+drop table if exists laptop;
+create table laptop (
+ id int not null,
+ weight int not null,
+ resolution varchar(19) not null
+);
+
+drop table if exists server;
+create table server (
+ id int not null,
+ numberOfCPUs int not null,
+ support int not null
+);
+
+drop table if exists car;
+create table car (
+ id int not null,
+ kw int not null,
+ make varchar(200) not null
+);
+
+drop table if exists truck;
+create table truck (
+ id int not null,
+ max_weight int not null
+);
+
+drop table if exists prod_multi;
+create table prod_multi (
+ id1 int not null,
+ id2 int not null,
+ name varchar(200) not null,
+ detail int not null
+);
+
+drop table if exists computer_multi;
+create table computer_multi (
+ id1 int not null,
+ id2 int not null,
+ cpu varchar(200) not null
+);
+
+drop table if exists laptop_multi;
+create table laptop_multi (
+ id1 int not null,
+ id2 int not null,
+ weight int not null,
+ resolution varchar(19) not null
+);
+
+drop table if exists server_multi;
+create table server_multi (
+ id1 int not null,
+ id2 int not null,
+ numberOfCPUs int not null,
+ support int not null
+);
+
+drop table if exists order_product;
+create table order_product (
+ order_id int not null,
+ product_id int not null
+);
+
+drop table if exists table_m;
+create table table_m (
+ id int not null,
+ name varchar(20) not null
+);
+
+drop table if exists table_n;
+create table table_n (
+ id int not null,
+ name varchar(20) not null
+);
+
+drop table if exists m_n;
+create table m_n (
+ m_id int not null,
+ n_id int not null
+);
+
+
+insert into detail (id, category, location) values (1, 'category 1', 'location 1');
+insert into detail (id, category, location) values (2, 'category 2', 'location 2');
+insert into detail (id, category, location) values (3, 'category 3', 'location 3');
+insert into detail (id, category, location) values (4, 'category 4', 'location 4');
+insert into detail (id, category, location) values (5, 'category 5', 'location 5');
+
+insert into prod (id, name, detail) values (1, 'laptop 1', 1);
+insert into computer (id, cpu) values (1, 'centrino');
+insert into laptop (id, weight, resolution) values (1, 2800, '1280');
+
+insert into prod (id, name, detail) values (2, 'laptop 2', 2);
+insert into computer (id, cpu) values (2, 'centrino');
+insert into laptop (id, weight, resolution) values (2, 2700, '1024');
+
+insert into prod (id, name, detail) values (3, 'server 3', 3);
+insert into computer (id, cpu) values (3, 'pentium 4');
+insert into server (id, numberOfCPUs, support) values (3, 4, 3);
+
+insert into prod (id, name, detail) values (4, 'server 4', 4);
+insert into computer (id, cpu) values (4, 'pentium 4');
+insert into server (id, numberOfCPUs, support) values (4, 16,5);
+
+insert into prod (id, name, detail) values (5, 'truck 5', 5);
+insert into car (id, kw, make) values (5, 60, 'make 5');
+insert into truck (id, max_weight) values (5, 4);
+
+insert into prod_multi (id1, id2, name, detail) values (1, 1, 'laptop 1', 1);
+insert into computer_multi (id1, id2, cpu) values (1, 1, 'centrino');
+insert into laptop_multi (id1, id2, weight, resolution) values (1, 1, 2800, '1280');
+
+insert into prod_multi (id1, id2, name, detail) values (2, 2, 'laptop 2', 2);
+insert into computer_multi (id1, id2, cpu) values (2, 2, 'centrino');
+insert into laptop_multi (id1, id2, weight, resolution) values (2, 2, 2700, '1024');
+
+insert into prod_multi (id1, id2, name, detail) values (3, 3, 'server 3', 3);
+insert into computer_multi (id1, id2, cpu) values (3, 3, 'pentium 4');
+insert into server_multi (id1, id2, numberOfCPUs, support) values (3, 3, 4, 3);
+
+insert into prod_multi (id1, id2, name, detail) values (4, 4, 'server 4', 4);
+insert into computer_multi (id1, id2, cpu) values (4, 4, 'pentium 4');
+insert into server_multi (id1, id2, numberOfCPUs, support) values (4, 4, 16,5);
+
+insert into owner (id, name, product) values (1, 'owner 1', 1);
+
+insert into ordr (id, name) values (1, 'order 1');
+
+insert into order_product (order_id, product_id) values (1, 1);
+insert into order_product (order_id, product_id) values (1, 2);
+
+insert into m_n (m_id, n_id) values (1, 1);
+insert into m_n (m_id, n_id) values (1, 2);
+
+insert into table_m (id, name) values (1, "m1");
+insert into table_m (id, name) values (2, "m2");
+
+insert into table_n (id, name) values (1, "n1");
+insert into table_n (id, name) values (2, "n2");
+
+
+/*
+* Two objects, a Derived and a Container.
+* Since Derived derives from Base there is a row in Base too.
+* The Container id = 200
+* The Derived id = 100
+*/
+DROP TABLE IF EXISTS base;
+CREATE TABLE base (
+ id varchar(64) NOT NULL default '',
+ color varchar(64) default NULL,
+ PRIMARY KEY (ID)
+) ;
+
+INSERT INTO base VALUES ('100','red');
+
+DROP TABLE IF EXISTS derived;
+CREATE TABLE derived (
+ id varchar(64) NOT NULL default '',
+ scent varchar(64) default NULL,
+ PRIMARY KEY (ID)
+) ;
+INSERT INTO derived VALUES ('100','vanilla');
+
+
+DROP TABLE IF EXISTS container;
+CREATE TABLE container (
+ id varchar(64) NOT NULL default '',
+ reference varchar(64) default NULL,
+ PRIMARY KEY (ID)
+) ;
+INSERT INTO container VALUES ('200','100');
+
+-- 1893
+
+CREATE TABLE Product(
+ IdProd NUMERIC(10) PRIMARY KEY,
+ NameProd VARCHAR(30) NULL,
+ DescProd VARCHAR(30) NULL);
+
+CREATE TABLE ActProduct(
+ IdAct NUMERIC(10) PRIMARY KEY REFERENCES Product (IdProd),
+ BestSeason VARCHAR(30) NULL);
+
+CREATE TABLE ComposedOffer(
+ IdCOffer NUMERIC(10) PRIMARY KEY REFERENCES Product (IdProd),
+ NameCO VARCHAR(30) NULL,
+ DescCO VARCHAR(30) NULL);
+
+CREATE TABLE OfferComposition(
+ Offer NUMERIC(10),
+ Product NUMERIC(10),
+ CONSTRAINT unique_rel UNIQUE (Offer, Product) );
+
+
Index: src/examples/polymorphism/jdo-conf.xml
===================================================================
RCS file: src/examples/polymorphism/jdo-conf.xml
diff -N src/examples/polymorphism/jdo-conf.xml
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/examples/polymorphism/jdo-conf.xml 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: src/examples/polymorphism/mapping.xml
===================================================================
RCS file: src/examples/polymorphism/mapping.xml
diff -N src/examples/polymorphism/mapping.xml
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/examples/polymorphism/mapping.xml 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,381 @@
+
+
+
+
+
+ Product definition
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Computer definition, extends generic product
+
+
+
+
+
+
+
+
+
+
+
+
+ Laptop definition, extends generic computer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Server definition, extends generic computer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Car definition, extends generic product
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Truck definition, extends generic car
+
+
+
+
+
+
+
+
+
+
+
+
+ ProductMulti definition
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ComputerMulti definition, extends generic product
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ LaptopMulti definition, extends generic computer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ServerMulti definition, extends generic computer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Owner definition
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Product detail definition
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Order definition
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ M definition
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ N definition
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: src/main/org/exolab/castor/jdo/engine/CounterRef.java
===================================================================
RCS file: src/main/org/exolab/castor/jdo/engine/CounterRef.java
diff -N src/main/org/exolab/castor/jdo/engine/CounterRef.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/main/org/exolab/castor/jdo/engine/CounterRef.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,34 @@
+/**
+ * Created on 11.03.2005 at 15:42:46
+ *
+ * TODO Insert class description here
+ *
+ * @author werner.guttmann
+ *
+ * Copyright (c) Vector SW DV GmbH, 2005
+ */
+package org.exolab.castor.jdo.engine;
+
+/**
+ * @author werner.guttmann
+ *
+ * This is a type.
+ */
+public class CounterRef {
+
+ private int counter;
+ private String tableName;
+
+ public String getTableName() {
+ return this.tableName;
+ }
+ public void setTableName(String tableName) {
+ this.tableName = tableName;
+ }
+ public int getCounter() {
+ return this.counter;
+ }
+ public void setCounter(int counter) {
+ this.counter = counter;
+ }
+}
Index: src/main/org/exolab/castor/persist/ProposedObject.java
===================================================================
RCS file: src/main/org/exolab/castor/persist/ProposedObject.java
diff -N src/main/org/exolab/castor/persist/ProposedObject.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/main/org/exolab/castor/persist/ProposedObject.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,123 @@
+/*
+ * Created on 25.02.2005
+ *
+ * To change the template for this generated file go to
+ * Window - Preferences - Java - Code Generation - Code and Comments
+ */
+package org.exolab.castor.persist;
+
+/**
+ * @author Administrator
+ *
+ * To change the template for this generated type comment go to
+ * Window - Preferences - Java - Code Generation - Code and Comments
+ */
+public class ProposedObject {
+
+ private Class proposedClass;
+ private Class actualClass;
+ private Object object;
+ private Object[] fields;
+
+ boolean isExpanded = false;
+ private ClassMolder actualClassMolder;
+
+ /**
+ * @return Returns the fields.
+ */
+ public Object[] getFields() {
+ return this.fields;
+ }
+ /**
+ * @param fields The fields to set.
+ */
+ public void setFields(Object[] fields) {
+ this.fields = fields;
+ }
+ /**
+ * @return Returns the object.
+ */
+ public Object getObject() {
+ return this.object;
+ }
+ /**
+ * @param object The object to set.
+ */
+ public void setObject(Object object) {
+ this.object = object;
+ }
+ /**
+ * @return Returns the proposedClass.
+ */
+ public Class getProposedClass() {
+ return this.proposedClass;
+ }
+ /**
+ * @param proposedClass The proposedClass to set.
+ */
+ public void setProposedClass(Class proposedClass) {
+ this.proposedClass = proposedClass;
+ }
+ /**
+ *
+ */
+ public ProposedObject() {
+ super();
+ }
+
+ /**
+ * @return Returns the isExpanded.
+ */
+ public boolean isExpanded() {
+ return this.isExpanded;
+ }
+ /**
+ * @param isExpanded The isExpanded to set.
+ */
+ public void setExpanded(boolean isExpanded) {
+ this.isExpanded = isExpanded;
+ }
+ /**
+ * @return Returns the actualClass.
+ */
+ public Class getActualClass() {
+ return this.actualClass;
+ }
+ /**
+ * @param actualClass The actualClass to set.
+ */
+ public void setActualClass(Class actualClass) {
+ this.actualClass = actualClass;
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append ("<");
+ buffer.append ("proposedClass=" + this.proposedClass);
+ buffer.append ("; actualClass=" + this.actualClass);
+ buffer.append ("; object=" + this.object);
+ buffer.append ("; actual classmolder=" + this.actualClassMolder + "; ");
+ if (this.fields != null) {
+ for (int i = 0; i < this.fields.length; i++) {
+ buffer.append("fields[" + i + "]='" + this.fields[i] + "':");
+ }
+ }
+ buffer.append (">");
+ return buffer.toString();
+ }
+
+ /**
+ * @return
+ */
+ public ClassMolder getActualClassMolder() {
+ return this.actualClassMolder;
+ }
+
+ public void setActualClassMolder(ClassMolder actualClassMolder) {
+ this.actualClassMolder = actualClassMolder;
+ }
+}