Added: incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/lifecycle/StateTransitions.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/lifecycle/StateTransitions.java?view=auto&rev=158179 ============================================================================== --- incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/lifecycle/StateTransitions.java (added) +++ incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/lifecycle/StateTransitions.java Fri Mar 18 17:07:39 2005 @@ -0,0 +1,768 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.tck.lifecycle; + +import java.util.Iterator; + +import javax.jdo.Extent; +import javax.jdo.PersistenceManager; +import javax.jdo.PersistenceManagerFactory; +import javax.jdo.Transaction; + +import org.apache.jdo.tck.JDO_Test; +import org.apache.jdo.tck.pc.lifecycle.StateTransitionObj; +import org.apache.jdo.tck.util.BatchTestRunner; + +/** + *<B>Title:</B> Test State Transitions + *<BR> + *<B>Keywords:</B> lifecycle + *<BR> + *<B>Assertion IDs:</B> A5.9-1 through A5.9-190 + *<B>Assertion Description: </B> + All possible state transistions are being tested in this test. + */ + +public class StateTransitions extends JDO_Test { + + /** */ + private static final String ASSERTION_FAILED = + "Assertions A5.9-1 through A5.9-190 (StateTransitions) failed: "; + + /** + * The <code>main</code> is called when the class + * is directly executed from the command line. + * @param args The arguments passed to the program. + */ + public static void main(String[] args) { + BatchTestRunner.run(StateTransitions.class); + } + + private Transaction transaction; + private int scenario; + private int operation; + private int current_state; + private int expected_state; + private int new_state; + +/** + * Operations that cause state changes + */ + private static final int MAKEPERSISTENT = 0; + private static final int DELETEPERSISTENT = 1; + private static final int MAKETRANSACTIONAL = 2; + private static final int MAKENONTRANSACTIONAL = 3; + private static final int MAKETRANSIENT = 4; + private static final int COMMITNORETAINVALUES = 5; + private static final int COMMITRETAINVALUES = 6; + private static final int ROLLBACKNORESTOREVALUES = 7; + private static final int ROLLBACKRESTOREVALUES = 8; + private static final int REFRESHDATASTORE = 9; + private static final int REFRESHOPTIMISTIC = 10; + private static final int EVICT = 11; + private static final int READOUTSIDETX = 12; + private static final int READOPTIMISTIC = 13; + private static final int READDATASTORE = 14; + private static final int WRITEOUTSIDETX = 15; + private static final int WRITEINSIDETX = 16; + private static final int RETRIEVEOUTSIDETX = 17; + private static final int RETRIEVEINSIDETX = 18; + + private static final String[] operations = { + "makePersistent", + "deletePersistent", + "makeTransactional", + "makeNontransactional", + "makeTransient", + "commit, retainValues=false", + "commit, retainValues=true", + "rollback, restoreValues=false", + "rollback, restoreValues=true", + "refresh with active datastore tx", + "refresh with active optimistic tx", + "evict", + "read field outside tx", + "read field with active optimistic tx", + "read field with active datastore tx", + "write field outside tx", + "write field with active tx", + "retrieve outside tx", + "retrieve with active tx" + }; + private static final int NUM_OPERATIONS = 19; + + private static final boolean[] closes_transaction = + { false, false, false, false, false, true, true, true, true, false, + false, false, false, false, false, false, false, false, false }; + + /** + * Illegal state transitions + */ + private static final int UNCHANGED = -1; + private static final int ERROR = -2; + private static final int IMPOSSIBLE = -3; + private static final int NOT_APPLICABLE = -4; + + /** + * State transitions + */ + public static final int[][] transitions = { // [operation] [current state] = new state + // makePersistent + { PERSISTENT_NEW, UNCHANGED, UNCHANGED, UNCHANGED, UNCHANGED, PERSISTENT_NEW, + PERSISTENT_NEW, UNCHANGED, UNCHANGED, UNCHANGED}, + + // deletePersistent + { ERROR, PERSISTENT_NEW_DELETED, PERSISTENT_DELETED, PERSISTENT_DELETED, + PERSISTENT_DELETED, ERROR, ERROR, UNCHANGED, UNCHANGED, PERSISTENT_DELETED}, + + // makeTransactional + { TRANSIENT_CLEAN, UNCHANGED, UNCHANGED, UNCHANGED, PERSISTENT_CLEAN, + UNCHANGED, UNCHANGED, UNCHANGED, UNCHANGED, PERSISTENT_CLEAN}, + + // makeNontransactional + { ERROR, ERROR, PERSISTENT_NONTRANSACTIONAL, ERROR, UNCHANGED, + TRANSIENT, ERROR, ERROR, ERROR, UNCHANGED}, + + // makeTransient + { UNCHANGED, ERROR, TRANSIENT, ERROR, TRANSIENT, + UNCHANGED, UNCHANGED, ERROR, ERROR, TRANSIENT}, + + // commit, retainValues = false + { UNCHANGED, HOLLOW, HOLLOW, HOLLOW, UNCHANGED, UNCHANGED, + TRANSIENT_CLEAN, TRANSIENT, TRANSIENT, UNCHANGED}, + + // commit, retainValues = true + { UNCHANGED, PERSISTENT_NONTRANSACTIONAL, PERSISTENT_NONTRANSACTIONAL, + PERSISTENT_NONTRANSACTIONAL, UNCHANGED, UNCHANGED, TRANSIENT_CLEAN, + TRANSIENT, TRANSIENT, UNCHANGED}, + + // rollback, restoreValues = false + { UNCHANGED, TRANSIENT, HOLLOW, HOLLOW, UNCHANGED, UNCHANGED, + TRANSIENT_CLEAN, TRANSIENT, HOLLOW, UNCHANGED}, + + // rollback, restoreValues = true + { UNCHANGED, TRANSIENT, PERSISTENT_NONTRANSACTIONAL, PERSISTENT_NONTRANSACTIONAL, + UNCHANGED, UNCHANGED, TRANSIENT_CLEAN, TRANSIENT, PERSISTENT_NONTRANSACTIONAL, UNCHANGED}, + + // refresh with active datastore transaction + { UNCHANGED, UNCHANGED, UNCHANGED, PERSISTENT_CLEAN, UNCHANGED, + UNCHANGED, UNCHANGED, UNCHANGED, UNCHANGED, UNCHANGED}, + + // refresh with active optimistic transaction + { UNCHANGED, UNCHANGED, UNCHANGED, PERSISTENT_NONTRANSACTIONAL, UNCHANGED, + UNCHANGED, UNCHANGED, UNCHANGED, UNCHANGED, UNCHANGED}, + + // evict + { NOT_APPLICABLE, UNCHANGED, HOLLOW, UNCHANGED, UNCHANGED, + UNCHANGED, UNCHANGED, UNCHANGED, UNCHANGED, HOLLOW}, + + // read field outside transaction + { UNCHANGED, IMPOSSIBLE, IMPOSSIBLE, IMPOSSIBLE, PERSISTENT_NONTRANSACTIONAL, + UNCHANGED, IMPOSSIBLE, IMPOSSIBLE, IMPOSSIBLE, UNCHANGED}, + + // read field with active optimistic transaction + { UNCHANGED, UNCHANGED, UNCHANGED, UNCHANGED, PERSISTENT_NONTRANSACTIONAL, + UNCHANGED, UNCHANGED, ERROR, ERROR, UNCHANGED}, + + // read field with active datastore transaction + { UNCHANGED, UNCHANGED, UNCHANGED, UNCHANGED, PERSISTENT_CLEAN, + UNCHANGED, UNCHANGED, ERROR, ERROR, PERSISTENT_CLEAN}, + + // write field outside transaction + { UNCHANGED, IMPOSSIBLE, IMPOSSIBLE, IMPOSSIBLE, PERSISTENT_NONTRANSACTIONAL, + UNCHANGED, IMPOSSIBLE, IMPOSSIBLE, IMPOSSIBLE, UNCHANGED}, + + // write field with active transaction + { UNCHANGED, UNCHANGED, PERSISTENT_DIRTY, UNCHANGED, PERSISTENT_DIRTY, + TRANSIENT_DIRTY, UNCHANGED, ERROR, ERROR, PERSISTENT_DIRTY}, + + // retrieve outside transaction + { UNCHANGED, IMPOSSIBLE, IMPOSSIBLE, IMPOSSIBLE, PERSISTENT_NONTRANSACTIONAL, + UNCHANGED, IMPOSSIBLE, IMPOSSIBLE, IMPOSSIBLE, UNCHANGED}, + + // retrieve with active transaction + { UNCHANGED, UNCHANGED, UNCHANGED, UNCHANGED, PERSISTENT_CLEAN, + UNCHANGED, UNCHANGED, UNCHANGED, UNCHANGED, PERSISTENT_CLEAN} + }; + + private static final int DATASTORE_TX = 0; + private static final int OPTIMISTIC_TX = 1; + private static final int NO_TX = 2; + + private static final String[] scenario_string = { + "datastore transaction", "optimistic transaction", "no transaction" + }; + + private static final boolean[][] applies_to_scenario = { + // Datastore Optimistic No tx + { true, true, false }, // makePersistent + { true, true, false }, // deletePersistent + { true, true, false }, // makeTransactional + { true, true, false }, // makeNontransactional + { true, true, false }, // makeTransient + { true, true, false }, // commit RetainValues = false + { true, true, false }, // commit RetainValues = true + { true, true, false }, // rollback RestoreValues = false + { true, true, false }, // rollback RestoreValues = true + { true, false, false }, // refresh with active datastore transaction + { false, true, false }, // refresh with active optimistic transaction + { true, true, false }, // evict + { false, false, true }, // read field outside of a transaction + { false, true, false }, // read field with active optimistic transaction + { true, false, false }, // read field with active datastore transaction + { false, false, true }, // write field or makeDirty outside of a transaction + { true, true, false }, // write field or makeDirty with active transaction + { false, true, true }, // retrieve outside of a transaction or with active optimistic transaction + { true, false, false } // retrieve with active datastore transaction + }; + + public StateTransitions() + { + } + + public void test() { + pm = getPM(); + generatePersistentInstances(); + + scenario = DATASTORE_TX; + checkTransitions(); + + if( isOptimisticSupported() ){ + scenario = OPTIMISTIC_TX; + checkTransitions(); + } + + scenario = NO_TX; + checkTransitions(); + } + + /** */ + private void generatePersistentInstances() + { + if( doPersistentInstancesExist() ) return; + int i; + Transaction t = pm.currentTransaction(); + t.begin(); + for( i = 0; i < 50; ++i ){ + StateTransitionObj sto = new StateTransitionObj(i); + sto.writeField(i); + pm.makePersistent(sto); + } + t.commit(); + if( !doPersistentInstancesExist() ) + if (debug) + logger.debug("StateTransitions unable to create instances of StateTransitionsObj"); + } + + /** */ + private boolean doPersistentInstancesExist() + { + boolean ret; + Transaction t = pm.currentTransaction(); + t.begin(); + Extent e = pm.getExtent(StateTransitionObj.class, false); + Iterator iter = e.iterator(); + ret = iter.hasNext(); + t.rollback(); + return ret; + } + + /** */ + void checkTransitions() + { + for( operation = 0; operation < NUM_OPERATIONS; ++operation ){ + // rule out situations that do not apply + if( ! applies_to_scenario[operation][scenario] ) continue; + if( operation == READOUTSIDETX && !isNontransactionalReadSupported() ) continue; + if( operation == WRITEOUTSIDETX && !isNontransactionalWriteSupported() ) continue; + if( operation == COMMITRETAINVALUES && !isRetainValuesSupported() ) continue; + if( operation == MAKENONTRANSACTIONAL && + !(isNontransactionalReadSupported() || isNontransactionalWriteSupported()) ) + continue; + + for( current_state = 0; current_state < NUM_STATES; ++current_state){ + if( scenario == OPTIMISTIC_TX && current_state == PERSISTENT_CLEAN ) continue; + if( (current_state == TRANSIENT_CLEAN || current_state == TRANSIENT_DIRTY) && + !isTransientTransactionalSupported() ) + continue; // this state is not supported by implementation + if( current_state == PERSISTENT_NONTRANSACTIONAL && + !(isNontransactionalReadSupported() || isNontransactionalWriteSupported()) ) + continue; // this state is not supported by implementation + + expected_state = transitions[operation][current_state]; + if( expected_state == IMPOSSIBLE ) continue; + if( expected_state == NOT_APPLICABLE ) continue; + if( expected_state == UNCHANGED ) expected_state = current_state; + try { + transaction = pm.currentTransaction(); + if( transaction.isActive()){ + if (debug) + logger.debug("Transaction is active (but should not be), rolling back"); + transaction.rollback(); + } + + if( scenario != NO_TX ){ + if( operation == COMMITNORETAINVALUES ) + transaction.setRetainValues(false); + if( operation == COMMITRETAINVALUES ) + transaction.setRetainValues(true); + if( operation == ROLLBACKNORESTOREVALUES ) + transaction.setRestoreValues(false); + if( operation == ROLLBACKRESTOREVALUES ) + transaction.setRestoreValues(true); + + transaction.setOptimistic(scenario == OPTIMISTIC_TX); + transaction.begin(); + if( !transaction.isActive() ) + if (debug) + logger.debug("StateTransitions: Transaction should be active, but it is not"); + } + + StateTransitionObj obj = getInstanceInState(current_state); + if( obj == null ){ // could not get object in state + if( transaction.isActive() ) transaction.rollback(); + continue; + } + + // Apply operation, catching possible exception + Exception e = null; + try { + applyOperation(operation, obj); + } catch( Exception excep ){ + if( excep instanceof javax.jdo.JDOUserException ){ + e = excep; + } else { + printSituation(); + fail(ASSERTION_FAILED, + "StateTransitions: Unexpected exception:" + excep); + continue; + } + } + + // Get new state, verify correct transition and exceptions occurred + new_state = currentState(obj); + if( expected_state == ERROR ){ + if( e == null ){ + printSituation(); + fail(ASSERTION_FAILED, + "StateTransitions: JDOUserException should have been thrown"); + } else { + if( new_state != current_state ){ + printSituation(); + fail(ASSERTION_FAILED, + "StateTransitions: " + + " JDOUserException properly thrown, but instance should remain in current state," + + "instance changed state to " + states[new_state]); + } + } + } + if( expected_state >= 0 && new_state != expected_state && + !((new_state == HOLLOW && expected_state == PERSISTENT_NONTRANSACTIONAL) || + (new_state == PERSISTENT_NONTRANSACTIONAL && expected_state == HOLLOW)) ) { + // status interrogation gives same values for PERSISTENT_NONTRANSACTIONAL and HOLLOW + printSituation(); + fail(ASSERTION_FAILED, + "StateTransitions: Invalid state transition to " + + states[new_state] + ", new state should be " + + states[expected_state]); + } + if( transaction.isActive() ) transaction.rollback(); + } + catch(Exception unexpected_exception) { + printSituation(); + if (transaction.isActive()) + transaction.rollback(); + fail(ASSERTION_FAILED, + "Unexpected exception caught in StateTransitions " + unexpected_exception); + } + } + } + } + + /** */ + void printSituation() + { + if (debug) { + logger.debug(" (" + scenario_string[scenario] + + ", initial state=" + states[current_state] + + ", operation=" + operations[operation] + ")"); + } + } + + /** */ + void applyOperation(int operation, StateTransitionObj stobj) + { + StateTransitionObj obj = (StateTransitionObj) stobj; + switch( operation ){ + case MAKEPERSISTENT: + { + pm.makePersistent(obj); + break; + } + case DELETEPERSISTENT: + { + pm.deletePersistent(obj); + break; + } + case MAKETRANSACTIONAL: + { + pm.makeTransactional(obj); + break; + } + case MAKENONTRANSACTIONAL: + { + pm.makeNontransactional(obj); + break; + } + case MAKETRANSIENT: + { + pm.makeTransient(obj); + break; + } + case COMMITNORETAINVALUES: + { + pm.currentTransaction().commit(); + break; + } + case COMMITRETAINVALUES: + { + pm.currentTransaction().commit(); + break; + } + case ROLLBACKNORESTOREVALUES: + { + pm.currentTransaction().rollback(); + break; + } + case ROLLBACKRESTOREVALUES: + { + pm.currentTransaction().rollback(); + break; + } + case REFRESHDATASTORE: + { + pm.refresh(obj); + break; + } + case REFRESHOPTIMISTIC: + { + pm.refresh(obj); + break; + } + case EVICT: + { + pm.evict(obj); + break; + } + case READOUTSIDETX: + { + int val = obj.readField(); + break; + } + case READOPTIMISTIC: + { + int val = obj.readField(); + break; + } + case READDATASTORE: + { + int val = obj.readField(); + break; + } + case WRITEOUTSIDETX: + { + obj.writeField(42); + break; + } + case WRITEINSIDETX: + { + obj.writeField(42); + break; + } + case RETRIEVEOUTSIDETX: + { + pm.retrieve(obj); + break; + } + case RETRIEVEINSIDETX: + { + pm.retrieve(obj); + break; + } + default: + { + fail(ASSERTION_FAILED, + "StateTransitions internal error, illegal operation " + operation); + } + } + } + + /** + * Get an instance in the specified state. + */ + private StateTransitionObj getInstanceInState(int state) + { + switch(state) { + case TRANSIENT: + return getTransientInstance(); + case PERSISTENT_NEW: + return getPersistentNewInstance(); + case PERSISTENT_CLEAN: + return getPersistentCleanInstance(); + case PERSISTENT_DIRTY: + return getPersistentDirtyInstance(); + case HOLLOW: + return getHollowInstance(); + case TRANSIENT_CLEAN: + return getTransientCleanInstance(); + case TRANSIENT_DIRTY: + return getTransientDirtyInstance(); + case PERSISTENT_NEW_DELETED: + return getPersistentNewDeletedInstance(); + case PERSISTENT_DELETED: + return getPersistentDeletedInstance(); + case PERSISTENT_NONTRANSACTIONAL: + return getPersistentNontransactionalInstance(); + default: + { + return null; + } + } + } + + /** */ + private StateTransitionObj getTransientInstance() + { + StateTransitionObj obj = new StateTransitionObj(23); + int curr = currentState(obj); + if( curr != TRANSIENT ) { + if (debug) { + logger.debug("StateTransitions: Unable to create transient instance, state is " + + states[curr]); + } + printSituation(); + return null; + } + return obj; + } + + /** */ + private StateTransitionObj getPersistentNewInstance() + { + StateTransitionObj obj = getTransientInstance(); + if( obj == null ) return null; + pm.makePersistent(obj); // should transition to persistent-new + int curr = currentState(obj); + if( curr != PERSISTENT_NEW ) { + if (debug) { + logger.debug("StateTransitions: Unable to create persistent-new instance" + + " from transient instance via makePersistent(), state is " + + states[curr]); + } + printSituation(); + return null; + } + return obj; + } + + /** */ + public StateTransitionObj getPersistentCleanInstance() + { + StateTransitionObj obj = getHollowInstance(); + if( obj == null ) return null; + StateTransitionObj sto = (StateTransitionObj) obj; + int val = sto.readField(); + int curr = currentState(sto); + if( curr != PERSISTENT_CLEAN ) { + if (debug) { + logger.debug("StateTransition: Unable to create persistent-clean instance" + + " from a hollow instance by reading a field, state is " + + states[curr]); + } + printSituation(); + return null; + } + return obj; + } + + /** */ + public StateTransitionObj getPersistentDirtyInstance() + { + StateTransitionObj obj = getHollowInstance(); + if( obj == null ) return null; + StateTransitionObj pcobj = (StateTransitionObj) obj; + pcobj.writeField(23); + int curr = currentState(obj); + if( curr != PERSISTENT_DIRTY ) { + if (debug) { + logger.debug("StateTransition: Unable to create persistent-dirty instance" + + " from a hollow instance by writing a field, state is " + + states[curr]); + } + printSituation(); + return null; + } + return obj; + } + + /** */ + public StateTransitionObj getHollowInstance() + { + Extent extent = pm.getExtent(StateTransitionObj.class, false); + Iterator iter = extent.iterator(); + if( !iter.hasNext() ){ + if (debug) + logger.debug("Extent for StateTransitionObj should not be empty"); + return null; + } + StateTransitionObj obj = (StateTransitionObj) iter.next(); + + transaction.setRetainValues(false); + if ( !transaction.isActive() ) + transaction.begin(); + if( !transaction.isActive() ) + if (debug) + logger.debug("getHollowInstance: Transaction should be active, but it is not"); + + transaction.commit(); // This should put the instance in the HOLLOW state + + if( scenario != NO_TX ){ + if( operation == COMMITNORETAINVALUES ) + transaction.setRetainValues(false); + if( operation == COMMITRETAINVALUES ) + transaction.setRetainValues(true); + if( operation == ROLLBACKNORESTOREVALUES ) + transaction.setRestoreValues(false); + if( operation == ROLLBACKRESTOREVALUES ) + transaction.setRestoreValues(true); + + transaction.setOptimistic(scenario == OPTIMISTIC_TX); + transaction.begin(); + if( !transaction.isActive() ) + if (debug) + logger.debug("getHollowInstance: Transaction should be active, but it is not"); + } + + int curr = currentState(obj); + if( curr != HOLLOW && curr != PERSISTENT_NONTRANSACTIONAL ){ + if (debug) { + logger.debug("StateTransition: Attempt to get hollow instance via accessing extent failed, state is " + + states[curr]); + } + printSituation(); + return null; + } + return obj; + } + + /** */ + public StateTransitionObj getTransientCleanInstance() + { + StateTransitionObj obj = getTransientInstance(); + if( obj == null ) return null; + pm.makeTransactional(obj); + int curr = currentState(obj); + if( curr != TRANSIENT_CLEAN ) { + if (debug) { + logger.debug("StateTransition: Unable to create transient-clean instance" + + " from a transient instance via makeTransactional(), state is " + + states[curr]); + } + printSituation(); + return null; + } + return obj; + } + + /** */ + public StateTransitionObj getTransientDirtyInstance() + { + StateTransitionObj obj = getTransientCleanInstance(); + if( obj == null ) return null; + StateTransitionObj pcobj = (StateTransitionObj) obj; + pcobj.writeField(23); + int curr = currentState(obj); + if( curr != TRANSIENT_DIRTY ) { + if (debug) { + logger.debug("StateTransition: Unable to create transient-dirty instance" + + " from a transient-clean instance via modifying a field, state is " + + states[curr]); + } + printSituation(); + return null; + } + return obj; + } + + /** */ + public StateTransitionObj getPersistentNewDeletedInstance() + { + StateTransitionObj obj = getPersistentNewInstance(); + if( obj == null ) return null; + pm.deletePersistent(obj); // should transition to persistent-new-deleted + int curr = currentState(obj); + if( curr != PERSISTENT_NEW_DELETED) { + if (debug) { + logger.debug("StateTransition: Unable to create persistent-new-deleted instance" + + " from a persistent-new instance via deletePersistent, state is " + + states[curr]); + } + printSituation(); + return null; + } + return obj; + } + + /** */ + public StateTransitionObj getPersistentDeletedInstance() + { + StateTransitionObj obj = getHollowInstance(); + if( obj == null ) return null; + pm.deletePersistent(obj); + int curr = currentState(obj); + if( curr != PERSISTENT_DELETED ) { + if (debug) { + logger.debug("StateTransition: Unable to create persistent-deleted instance" + + " from a persistent instance via deletePersistent(), state is " + + states[curr]); + } + printSituation(); + return null; + } + return obj; + } + + /** */ + public StateTransitionObj getPersistentNontransactionalInstance() + { + StateTransitionObj obj = getHollowInstance(); + if( obj == null ) return null; + pm.makeNontransactional(obj); + int curr = currentState(obj); + if( curr != PERSISTENT_NONTRANSACTIONAL && curr != HOLLOW ) { + if (debug) { + logger.debug("StateTransition: Unable to create persistent-nontransactional instance" + + " from a persistent-clean instance via makeNontransactional(), state is " + + states[curr]); + } + printSituation(); + return null; + } + return null; + } + +}
Added: incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/lifecycle/TransientTransactionalStateCommit.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/lifecycle/TransientTransactionalStateCommit.java?view=auto&rev=158179 ============================================================================== --- incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/lifecycle/TransientTransactionalStateCommit.java (added) +++ incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/lifecycle/TransientTransactionalStateCommit.java Fri Mar 18 17:07:39 2005 @@ -0,0 +1,122 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.tck.lifecycle; + +import java.util.Iterator; + +import javax.jdo.Extent; +import javax.jdo.PersistenceManager; +import javax.jdo.PersistenceManagerFactory; +import javax.jdo.Transaction; + +import org.apache.jdo.tck.JDO_Test; +import org.apache.jdo.tck.pc.lifecycle.StateTransitionObj; +import org.apache.jdo.tck.util.BatchTestRunner; + +/** + *<B>Title:</B> Test Transient Transactional Commit + *<BR> + *<B>Keywords:</B> lifecycle transienttransactional commit + *<BR> + *<B>Assertion IDs:</B> A5.1-3 + *<BR> + *<B>Assertion Description: </B> + If <code>TransientTransactional</code> is supported, a transient transactional instance + will have its state preserved when its associated transaction commits. +*/ + + +public class TransientTransactionalStateCommit extends JDO_Test { + + /** */ + private static final String ASSERTION_FAILED = + "Assertion A5.1-3 (TransientTransactionalStateCommit) failed: "; + + private static final int CLEAN_VALUE = 12; + private static final int DIRTY_VALUE = 123; + + /** + * The <code>main</code> is called when the class + * is directly executed from the command line. + * @param args The arguments passed to the program. + */ + public static void main(String[] args) { + BatchTestRunner.run(TransientTransactionalStateCommit.class); + } + + /** */ + public void test() { + if (!isTransientTransactionalSupported()) { + logger.debug("Transient transactional instances are not supported"); + } + else { + pm = getPM(); + + StateTransitionObj obj = getTransientInstance(); + + pm.currentTransaction().begin(); + + makeTransientDirty(obj); + + int beforeValue=obj.readField(); + pm.currentTransaction().commit(); + int afterValue=obj.readField(); + if (beforeValue!=afterValue) + { + fail(ASSERTION_FAILED, + "Field value incorrect after commit. Expected: " + + beforeValue + " Found: " + afterValue); + } + } + } + + protected StateTransitionObj getTransientInstance() { + StateTransitionObj obj = new StateTransitionObj(CLEAN_VALUE); + int curr = currentState(obj); + if( curr != TRANSIENT ){ + fail(ASSERTION_FAILED, + "Unable to create transient instance, state is " + + states[curr]); + } + return obj; + } + + protected void makeTransientClean(StateTransitionObj obj) { + if( obj == null ) return; + pm.makeTransactional(obj); + int curr = currentState(obj); + if( curr != TRANSIENT_CLEAN ){ + fail(ASSERTION_FAILED, + "Unable to create transient-clean instance " + + "from a transient instance via makeTransactional(), state is " + + states[curr]); + } + } + + protected void makeTransientDirty(StateTransitionObj obj) { + if( obj == null ) return; + makeTransientClean(obj); + obj.writeField(DIRTY_VALUE); + int curr = currentState(obj); + if( curr != TRANSIENT_DIRTY ){ + fail(ASSERTION_FAILED, + "Unable to create transient-dirty instance " + + "from a transient-clean instance via modifying a field, state is " + + states[curr]); + } + } +} Added: incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/lifecycle/TransientTransactionalStateRollback.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/lifecycle/TransientTransactionalStateRollback.java?view=auto&rev=158179 ============================================================================== --- incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/lifecycle/TransientTransactionalStateRollback.java (added) +++ incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/lifecycle/TransientTransactionalStateRollback.java Fri Mar 18 17:07:39 2005 @@ -0,0 +1,131 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.tck.lifecycle; + +import java.util.Iterator; + +import javax.jdo.Extent; +import javax.jdo.PersistenceManager; +import javax.jdo.PersistenceManagerFactory; +import javax.jdo.Transaction; + +import org.apache.jdo.tck.JDO_Test; +import org.apache.jdo.tck.pc.lifecycle.StateTransitionObj; +import org.apache.jdo.tck.util.BatchTestRunner; + +/** + *<B>Title:</B> Test Transient Transactional Rollback + *<BR> + *<B>Keywords:</B> lifecycle transienttransactional rollback + *<BR> + *<B>Assertion IDs:</B> A5.1-4 + *<B>Assertion Description: </B> + If <code>TransientTransactional</code> is supported, a transient transactional instance + will have its state restored to its state prior to becoming transactional when + its associated transaction aborts or on rollback. + */ + +public class TransientTransactionalStateRollback extends JDO_Test { + + /** */ + private static final String ASSERTION_FAILED = + "Assertion A5.1-4 (TransientTransactionalStateRollback) failed: "; + + private static final int CLEAN_VALUE = 12; + private static final int DIRTY_VALUE = 123; + + /** + * The <code>main</code> is called when the class + * is directly executed from the command line. + * @param args The arguments passed to the program. + */ + public static void main(String[] args) { + BatchTestRunner.run(TransientTransactionalStateRollback.class); + } + + /** */ + public void test() { + if (!isTransientTransactionalSupported()) { + logger.debug("Transient transactional instances are not supported"); + } + else { + pm = getPM(); + + // Get transient instance and read field value + StateTransitionObj obj = getTransientInstance(); + + int beforeValue=obj.readField(); + + // Start transaction + Transaction tx = pm.currentTransaction(); + tx.begin(); + + // Get transient dirty instance + makeTransientDirty(obj); + + // Rollback + tx.rollback(); + int curr = currentState(obj); + if( curr != TRANSIENT_CLEAN ){ + fail(ASSERTION_FAILED, + "StateTransition: Unable to create transient-clean instance " + + "from a transient-dirty instance via tx.rollback(), state is " + states[curr]); + } + + // Check that field value has been rolled back + int afterValue=obj.readField(); + if (beforeValue!=afterValue) + { + fail(ASSERTION_FAILED, + "Field value incorrect after rollback. Expected: "+beforeValue+" Found: "+afterValue); + } + } + } + + protected StateTransitionObj getTransientInstance() { + StateTransitionObj obj = new StateTransitionObj(CLEAN_VALUE); + int curr = currentState(obj); + if( curr != TRANSIENT ){ + fail(ASSERTION_FAILED, + "Unable to create transient instance, state is " + states[curr]); + } + return obj; + } + + protected void makeTransientClean(StateTransitionObj obj) { + if( obj == null ) return; + pm.makeTransactional(obj); + int curr = currentState(obj); + if( curr != TRANSIENT_CLEAN ){ + fail(ASSERTION_FAILED, + "Unable to create transient-clean instance " + + "from a transient instance via makeTransactional(), state is " + states[curr]); + } + } + + protected void makeTransientDirty(StateTransitionObj obj) { + if( obj == null ) return; + makeTransientClean(obj); + obj.writeField(DIRTY_VALUE); + int curr = currentState(obj); + if( curr != TRANSIENT_DIRTY ){ + fail(ASSERTION_FAILED, + "Unable to create transient-dirty instance " + + "from a transient-clean instance via modifying a field, state is " + states[curr]); + } + } +} Added: incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/lifecycle/nontransactional/ModificationOfNontransactionalInstanceOutsideTransaction.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/lifecycle/nontransactional/ModificationOfNontransactionalInstanceOutsideTransaction.java?view=auto&rev=158179 ============================================================================== --- incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/lifecycle/nontransactional/ModificationOfNontransactionalInstanceOutsideTransaction.java (added) +++ incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/lifecycle/nontransactional/ModificationOfNontransactionalInstanceOutsideTransaction.java Fri Mar 18 17:07:39 2005 @@ -0,0 +1,202 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.tck.lifecycle.nontransactional; + +import java.util.Iterator; + +import javax.jdo.PersistenceManager; +import javax.jdo.Extent; + +import org.apache.jdo.tck.JDO_Test; +import org.apache.jdo.tck.pc.lifecycle.StateTransitionObj; +import org.apache.jdo.tck.util.BatchTestRunner; + +/** + *<B>Title:</B> Modification of Nontransactional Persistent Instance Outside a Transaction + *<BR> + *<B>Keywords:</B> nontransactionalwrite + *<BR> + *<B>Assertion ID:</B> A5.6-9. + *<BR> + *<B>Assertion Description: </B> + * With <code>NontransactionalWrite</code> set to <code>true</code>, + * modification of nontransactional persistent instances is permitted outside + * a transaction. The changes do not participate in any subsequent transaction. + */ + +public class ModificationOfNontransactionalInstanceOutsideTransaction extends JDO_Test { + + /** */ + private static final String ASSERTION_FAILED = + "Assertion A5.6-9 (ModificationOfNontransactionalInstanceOutsideTransaction) failed: "; + + /** + * The <code>main</code> is called when the class + * is directly executed from the command line. + * @param args The arguments passed to the program. + */ + public static void main(String[] args) { + BatchTestRunner.run(ModificationOfNontransactionalInstanceOutsideTransaction.class); + } + + /** + * The pc instance, set by method createAndModifyInstance. + */ + private StateTransitionObj object; + + /** + * The ObjectId of the pc instance, set by method + * createAndModifyInstance. + */ + private Object oid; + + /** + * The original value of the int field of the pc instance, + * set by method createAndModifyInstance. + */ + private int originalValue; + + /** */ + public void testDifferentPM() { + if (!isNontransactionalWriteSupported()) { + printUnsupportedOptionalFeatureNotTested( + "NontransactionalWrite", "testDifferentPM"); + } + else { + pm = getPM(); + createAndModifyInstance(); + + int value=object.readField(); + if (value!=999){ + fail(ASSERTION_FAILED, + "Unable to write value to field with setNontransactionalWrite==true"); + } + + // begin new transaction, read instance from datastore and + // verify that old value is still there + PersistenceManager pm2 = null; + try { + pm2 = getPMF().getPersistenceManager(); + pm2.currentTransaction().begin(); + StateTransitionObj object2 = + (StateTransitionObj)pm2.getObjectById(oid,true); + if (object2 == null){ + fail(ASSERTION_FAILED, + "Failed to read instance from datastore via pm.getObjectById(...)"); + } + + int value2 = object2.readField(); + if (value2 != originalValue){ + fail(ASSERTION_FAILED, + "Value has been changed with setNontransactionalWrite==true. " + + "New value is " + value2 + " ... Old value was " + originalValue); + } + pm2.currentTransaction().commit(); + } + finally { + if ((pm2 != null) && !pm2.isClosed()) { + if (pm2.currentTransaction().isActive()) + pm2.currentTransaction().rollback(); + pm2.close(); + } + } + } + } + + /** */ + public void testSameInstance() { + if (!isNontransactionalWriteSupported()) { + printUnsupportedOptionalFeatureNotTested( + "NontransactionalWrite", "testDifferentPM"); + } + else { + pm = getPM(); + createAndModifyInstance(); + + // use the object in a new datastore transaction + pm.currentTransaction().setOptimistic(false); + pm.currentTransaction().begin(); + int value = object.readField(); + if (value != originalValue){ + fail(ASSERTION_FAILED, + "Value has been changed with setNontransactionalWrite==true. " + + "New value is " + value + " ... Old value was " + originalValue); + } + pm.currentTransaction().commit(); + } + } + + /** */ + public void testIterateExtent() { + if (!isNontransactionalWriteSupported()) { + printUnsupportedOptionalFeatureNotTested( + "NontransactionalWrite", "testDifferentPM"); + } + else { + pm = getPM(); + createAndModifyInstance(); + + // iterate the extent and use the object in a new datastore transaction + pm.currentTransaction().setOptimistic(false); + pm.currentTransaction().begin(); + Extent e = pm.getExtent(StateTransitionObj.class, false); + for (Iterator i = e.iterator(); i.hasNext();) { + StateTransitionObj next = (StateTransitionObj)i.next(); + if (oid.equals(pm.getObjectId(next))) { + // found instance + int value = next.readField(); + if (value != originalValue){ + fail(ASSERTION_FAILED, + "Value has been changed with setNontransactionalWrite==true. " + + "New value is " + value + " ... Old value was " + originalValue); + } + } + } + pm.currentTransaction().commit(); + } + } + + /** */ + private void createAndModifyInstance() { + pm.currentTransaction().begin(); + // create and save the pc instance + object = getPersistentNewInstance(); + // save the ObjectId + oid = pm.getObjectId(object); + // save the value of the int field + originalValue = object.readField(); + pm.currentTransaction().commit(); + + // change field outside of transaction + pm.currentTransaction().setNontransactionalWrite(true); + object.writeField(999); + } + + /** */ + private StateTransitionObj getPersistentNewInstance() { + StateTransitionObj obj = new StateTransitionObj(); + pm.makePersistent(obj); // obj should transition to PERSISTENT_NEW + int curr = currentState(obj); + if (curr != PERSISTENT_NEW) { + fail(ASSERTION_FAILED, + "Unable to create persistent-new instance " + + "from transient instance via makePersistent(), state is " + + getStateOfInstance(obj)); + } + return obj; + } +} Added: incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/models/embedded/SecondClassObjectsTrackTheirChanges.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/models/embedded/SecondClassObjectsTrackTheirChanges.java?view=auto&rev=158179 ============================================================================== --- incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/models/embedded/SecondClassObjectsTrackTheirChanges.java (added) +++ incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/models/embedded/SecondClassObjectsTrackTheirChanges.java Fri Mar 18 17:07:39 2005 @@ -0,0 +1,135 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package org.apache.jdo.tck.models.embedded; + +import javax.jdo.PersistenceManager; +import java.util.Date; +import java.util.Set; + +import org.apache.jdo.tck.JDO_Test; +import org.apache.jdo.tck.util.BatchTestRunner; +import org.apache.jdo.tck.pc.company.Company; +import org.apache.jdo.tck.pc.company.Address; +import org.apache.jdo.tck.pc.company.Department; + +/** + *<B>Title:</B> Embedded Objects Track Their Changes + *<BR> + *<B>Keywords:</B> embedded lifecycle + *<BR> + *<B>Assertion ID:</B> A6.3-1. + *<BR> + *<B>Assertion Description: </B> +Second Class Objects track changes made to themselves and notify their owning +First Class Object that they have changed, and the change is reflected as a +change to that First Class Object (e.g. the owning instance changes state from +persistent-clean to persistent-dirty). + + */ + +public class SecondClassObjectsTrackTheirChanges extends JDO_Test { + + /** */ + private static final String ASSERTION_FAILED = + "Assertion A6.3-1 (SecondClassObjectsTrackTheirChanges) failed: "; + + /** + * The <code>main</code> is called when the class + * is directly executed from the command line. + * @param args The arguments passed to the program. + */ + public static void main(String[] args) { + BatchTestRunner.run(SecondClassObjectsTrackTheirChanges.class); + } + + /** This tests that persistence-capable instances track changes or notify their owning instance that they are dirty */ + public void testPCInstance() { + pm = getPM(); + pm.currentTransaction().begin(); + Company comp = getPersistentNewInstance(0); + pm.currentTransaction().commit(); // obj should transition to hollow + testHollowInstance(comp); + pm.currentTransaction().begin(); + makePersistentCleanInstance(comp); + + Address addr = comp.getAddress(); + addr.setStreet("200 Orange Street"); // comp or addr should transition to persistent-dirty + int currComp = currentState(comp); + int currAddr = currentState(addr); + if ((currComp != PERSISTENT_DIRTY) && (currAddr != PERSISTENT_DIRTY)){ + fail(ASSERTION_FAILED, + "Unable to create persistent-dirty instance " + + "from persistent-clean instance via changing Address instance, state of Company instance is " + states[currComp] + " and state of Address instance is " + states[currAddr]); + } + } + + /** This tests that mutable system class instances track changes or notify their owning instance that they are dirty */ + public void testMutableSystemClass() { + pm = getPM(); + pm.currentTransaction().begin(); + Company comp = getPersistentNewInstance(1); + pm.currentTransaction().commit(); // obj should transition to hollow + testHollowInstance(comp); + pm.currentTransaction().begin(); + makePersistentCleanInstance(comp); + + Set depts = comp.getDepartments(); + comp.addDepartment(new Department(0,"HR",comp)); // comp or depts should transition to persistent-dirty + int currComp = currentState(comp); + int currDepts = currentState(depts); + if ((currComp != PERSISTENT_DIRTY) && (currDepts != PERSISTENT_DIRTY)){ + fail(ASSERTION_FAILED, + "Unable to create persistent-dirty instance " + + "from persistent-clean instance via changing Departments instance, state of Company instance is " + states[currComp] + " and state of Departments instance is " + states[currDepts]); + } + } + + public Company getPersistentNewInstance(long companyid) + { + Company obj = new Company(companyid, "MyCompany", new Date(), new Address(0,"","","","","")); + pm.makePersistent(obj); // obj should transition to persistent-new + int curr = currentState(obj); + if( curr != PERSISTENT_NEW ){ + fail(ASSERTION_FAILED, + "Unable to create persistent-new instance " + + "from transient instance via makePersistent(), state is " + states[curr]); + } + return obj; + } + + public void testHollowInstance(Company obj) + { + int curr = currentState(obj); + if( curr != HOLLOW ){ + fail(ASSERTION_FAILED, + "Unable to create hollow instance " + + "from persistent-new instance via commit(), state is " + states[curr]); + } + } + + public void makePersistentCleanInstance(Company obj) + { + pm.makeTransactional(obj); // obj should transition to persistent-clean + int curr = currentState(obj); + if( curr != PERSISTENT_CLEAN ){ + fail(ASSERTION_FAILED, + "Unable to create persistent-clean instance " + + "from hollow instance via makeTransactional(obj), state is " + states[curr]); + } + } +} Added: incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/models/fieldtypes/FirstSetOfTestValuesForCollection.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/models/fieldtypes/FirstSetOfTestValuesForCollection.java?view=auto&rev=158179 ============================================================================== --- incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/models/fieldtypes/FirstSetOfTestValuesForCollection.java (added) +++ incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/models/fieldtypes/FirstSetOfTestValuesForCollection.java Fri Mar 18 17:07:39 2005 @@ -0,0 +1,141 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.tck.models.fieldtypes; + +import java.util.*; +import java.math.*; + +import org.apache.jdo.tck.pc.fieldtypes.SimpleClass; + +public class FirstSetOfTestValuesForCollection extends Hashtable { + + public FirstSetOfTestValuesForCollection() { + String [] elementTypes = {"Object", "SimpleClass", "SimpleInterface", + "String", "Date", "Locale", "BigDecimal", + "BigInteger", "Byte", "Double", "Float", + "Integer", "Long", "Short"}; + + Vector objectVector = new Vector(); + objectVector.add(0, new SimpleClass(1, "Hello World")); + objectVector.add(1, new SimpleClass(2, "Java Data Objects")); + objectVector.add(2, new SimpleClass(2, "Java")); + objectVector.add(3, new SimpleClass(4, "Origami")); + objectVector.add(4, new SimpleClass(5, "watch")); + put("Object", objectVector); + + Vector simpleClassVector = new Vector(); + simpleClassVector.add(0, new SimpleClass(1, "Welcome")); + simpleClassVector.add(1, new SimpleClass(2, "To")); + simpleClassVector.add(2, new SimpleClass(3, "The")); + simpleClassVector.add(3, new SimpleClass(4, "Beautiful")); + simpleClassVector.add(4, new SimpleClass(5, "World")); + put("SimpleClass", simpleClassVector); + put("SimpleInterface", simpleClassVector); + + + Vector stringVector = new Vector(); + stringVector.add(0, new String("Hello")); + stringVector.add(1, new String("Welcome")); + stringVector.add(2, new String("To The")); + stringVector.add(3, new String("Beautiful")); + stringVector.add(4, new String("World")); + put("String", stringVector); + + Vector dateVector = new Vector(); + dateVector.add(0, new Date(2007908)); + dateVector.add(1, new Date(89067382l)); + dateVector.add(2, new Date(890673822)); + dateVector.add(3, new Date(890673823)); + dateVector.add(4, new Date(890673824)); + put("Date", dateVector); + + Vector localeVector = new Vector(); + localeVector.add(0, Locale.CHINA); + localeVector.add(1, Locale.FRANCE); + localeVector.add(2, Locale.GERMANY); + localeVector.add(3, Locale.JAPAN); + localeVector.add(4, Locale.ITALY); + put("Locale", localeVector); + + + Vector bigDecVector = new Vector(); + bigDecVector.add(0, new BigDecimal("2007908.54548")); + bigDecVector.add(1, new BigDecimal("0.544")); + bigDecVector.add(2, new BigDecimal("3002323232.545454")); + bigDecVector.add(3, new BigDecimal("64564645656.78657")); + bigDecVector.add(4, new BigDecimal("4564565465.2342")); + put("BigDecimal", bigDecVector); + + Vector bigIntVector = new Vector(); + bigIntVector.add(0, new BigInteger("2007908")); + bigIntVector.add(1, new BigInteger("767575")); + bigIntVector.add(2, new BigInteger("3002323232")); + bigIntVector.add(3, new BigInteger("64564645656")); + bigIntVector.add(4, new BigInteger("456445645")); + put("BigInteger", bigIntVector); + + Vector byteVector = new Vector(); + byteVector.add(0, new Byte((byte)Byte.MIN_VALUE)); + byteVector.add(1, new Byte((byte)Byte.MAX_VALUE)); + byteVector.add(2, new Byte((byte)(Byte.MAX_VALUE- 20))); + byteVector.add(3, new Byte((byte)(Byte.MAX_VALUE - 50))); + byteVector.add(4, new Byte((byte)(Byte.MAX_VALUE - 75))); + put("Byte", byteVector); + + Vector doubleVector = new Vector(); + doubleVector.add(0, new Double(Double.MIN_VALUE)); + doubleVector.add(1, new Double(Double.MAX_VALUE)); + doubleVector.add(2, new Double(Double.MAX_VALUE - 20000)); + doubleVector.add(3, new Double(Double.MAX_VALUE - 454545.436664)); + doubleVector.add(4, new Double(Double.MAX_VALUE - 2323235.76764677)); + put("Double", doubleVector); + + Vector floatVector = new Vector(); + floatVector.add(0, new Float(Float.MIN_VALUE)); + floatVector.add(1, new Float(Float.MAX_VALUE)); + floatVector.add(2, new Float(Float.MAX_VALUE - 20000)); + floatVector.add(3, new Float(Float.MAX_VALUE - 454545.434)); + floatVector.add(4, new Float(Float.MAX_VALUE - 565656.43434)); + put("Float", floatVector); + + Vector integerVector = new Vector(); + integerVector.add(0, new Integer(Integer.MIN_VALUE)); + integerVector.add(1, new Integer(Integer.MAX_VALUE)); + integerVector.add(2, new Integer(Integer.MAX_VALUE - 20000)); + integerVector.add(3, new Integer(Integer.MAX_VALUE - 343434343)); + integerVector.add(4, new Integer(Integer.MAX_VALUE - 565656)); + put("Integer", integerVector); + + + Vector longVector = new Vector(); + longVector.add(0, new Long(Long.MIN_VALUE)); + longVector.add(1, new Long(Long.MAX_VALUE)); + longVector.add(2, new Long(Long.MAX_VALUE - 20000)); + longVector.add(3, new Long(Long.MAX_VALUE - 343434343)); + longVector.add(4, new Long(Long.MAX_VALUE - 565656)); + put("Long", longVector); + + Vector shortVector = new Vector(); + shortVector.add(0, new Short(Short.MIN_VALUE)); + shortVector.add(1, new Short(Short.MAX_VALUE)); + shortVector.add(2, new Short((short)(Short.MAX_VALUE - 20000))); + shortVector.add(3, new Short((short)(Short.MAX_VALUE - 343))); + shortVector.add(4, new Short((short)(Short.MAX_VALUE - 5656))); + put("Short", shortVector); + } + +} Added: incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/models/fieldtypes/SecondSetOfTestValuesForCollection.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/models/fieldtypes/SecondSetOfTestValuesForCollection.java?view=auto&rev=158179 ============================================================================== --- incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/models/fieldtypes/SecondSetOfTestValuesForCollection.java (added) +++ incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/models/fieldtypes/SecondSetOfTestValuesForCollection.java Fri Mar 18 17:07:39 2005 @@ -0,0 +1,141 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.tck.models.fieldtypes; + +import java.util.*; +import java.math.*; + +import org.apache.jdo.tck.pc.fieldtypes.SimpleClass; + +public class SecondSetOfTestValuesForCollection extends Hashtable { + + public SecondSetOfTestValuesForCollection() { + String [] elementTypes = {"Object", "SimpleClass", "SimpleInterface", + "String", "Date", "Locale", "BigDecimal", + "BigInteger", "Byte", "Double", "Float", + "Integer", "Long", "Short"}; + + Vector objectVector = new Vector(); + objectVector.add(0, new SimpleClass(1, "Hi There")); + objectVector.add(1, new SimpleClass(1, "Hi")); + objectVector.add(2, new SimpleClass(2, "Object")); + objectVector.add(3, new SimpleClass(0, "Relational")); + objectVector.add(4, new SimpleClass(3, "Hi There")); + put("Object", objectVector); + + Vector simpleClassVector = new Vector(); + simpleClassVector.add(0, new SimpleClass(1, "Peaches")); + simpleClassVector.add(1, new SimpleClass(2, "Oranges")); + simpleClassVector.add(2, new SimpleClass(3, "Blue Berries")); + simpleClassVector.add(3, new SimpleClass(4, "Apples")); + simpleClassVector.add(4, new SimpleClass(5, "Strawberries")); + put("SimpleClass", simpleClassVector); + put("SimpleInterface", simpleClassVector); + + + Vector stringVector = new Vector(); + stringVector.add(0, new String("Peaches")); + stringVector.add(1, new String("Oranges")); + stringVector.add(2, new String("Blue Berries")); + stringVector.add(3, new String("Apples")); + stringVector.add(4, new String("Strawberries")); + put("String", stringVector); + + Vector dateVector = new Vector(); + dateVector.add(0, new Date(54545)); + dateVector.add(1, new Date(8905454l)); + dateVector.add(2, new Date(323545445)); + dateVector.add(3, new Date(890748967382l)); + dateVector.add(4, new Date(954545)); + put("Date", dateVector); + + Vector localeVector = new Vector(); + localeVector.add(0, Locale.ENGLISH); + localeVector.add(1, Locale.JAPANESE); + localeVector.add(2, Locale.CANADA_FRENCH); + localeVector.add(3, Locale.KOREA); + localeVector.add(4, Locale.UK); + put("Locale", localeVector); + + + Vector bigDecVector = new Vector(); + bigDecVector.add(0, new BigDecimal("434238.5454898989")); +// bigDecVector.add(1, new BigDecimal("8348967382l.544")); + bigDecVector.add(1, new BigDecimal("6.544")); + bigDecVector.add(2, new BigDecimal("55552323232.545454")); + bigDecVector.add(3, new BigDecimal("6456456.7543543534865785")); + bigDecVector.add(4, new BigDecimal("456456.4353452342")); + put("BigDecimal", bigDecVector); + + Vector bigIntVector = new Vector(); + bigIntVector.add(0, new BigInteger("345345345")); + bigIntVector.add(1, new BigInteger("543543543543544")); + bigIntVector.add(2, new BigInteger("65323423432423423")); + bigIntVector.add(3, new BigInteger("87845634534543")); + bigIntVector.add(4, new BigInteger("53452567766657567")); + put("BigInteger", bigIntVector); + + Vector byteVector = new Vector(); + byteVector.add(0, new Byte((byte)(Byte.MAX_VALUE-34))); + byteVector.add(1, new Byte((byte)Byte.MIN_VALUE)); + byteVector.add(2, new Byte((byte)(Byte.MAX_VALUE- 76))); + byteVector.add(3, new Byte((byte)Byte.MAX_VALUE)); + byteVector.add(4, new Byte((byte)(Byte.MAX_VALUE - 12))); + put("Byte", byteVector); + + Vector doubleVector = new Vector(); + doubleVector.add(0, new Double(Double.MAX_VALUE - 343434)); + doubleVector.add(1, new Double(Double.MIN_VALUE)); + doubleVector.add(2, new Double(Double.MAX_VALUE)); + doubleVector.add(3, new Double(Double.MAX_VALUE - 65423445.436664)); + doubleVector.add(4, new Double(Double.MAX_VALUE - 7235.236764677)); + put("Double", doubleVector); + + Vector floatVector = new Vector(); + floatVector.add(0, new Float(Float.MAX_VALUE - 5452)); + floatVector.add(1, new Float(Float.MIN_VALUE)); + floatVector.add(2, new Float(Float.MAX_VALUE - 6564560.54)); + floatVector.add(3, new Float(Float.MAX_VALUE)); + floatVector.add(4, new Float(Float.MAX_VALUE - 9756.634)); + put("Float", floatVector); + + Vector integerVector = new Vector(); + integerVector.add(0, new Integer(Integer.MAX_VALUE - 54454)); + integerVector.add(1, new Integer(Integer.MIN_VALUE)); + integerVector.add(2, new Integer(Integer.MAX_VALUE)); + integerVector.add(3, new Integer(Integer.MAX_VALUE - 767234)); + integerVector.add(4, new Integer(Integer.MAX_VALUE - 23673446)); + put("Integer", integerVector); + + + Vector longVector = new Vector(); + longVector.add(0, new Long(Long.MAX_VALUE - 545345454)); + longVector.add(1, new Long(Long.MIN_VALUE)); + longVector.add(2, new Long(Long.MAX_VALUE)); + longVector.add(3, new Long(Long.MAX_VALUE - 3543343)); + longVector.add(4, new Long(Long.MAX_VALUE - 556)); + put("Long", longVector); + + Vector shortVector = new Vector(); + shortVector.add(0, new Short((short)(Short.MAX_VALUE - 3434))); + shortVector.add(1, new Short(Short.MIN_VALUE)); + shortVector.add(2, new Short((short)(Short.MAX_VALUE))); + shortVector.add(3, new Short((short)(Short.MAX_VALUE - 23344))); + shortVector.add(4, new Short((short)(Short.MAX_VALUE - 723))); + put("Short", shortVector); + } +} Added: incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/models/fieldtypes/TestArrayCollections.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/models/fieldtypes/TestArrayCollections.java?view=auto&rev=158179 ============================================================================== --- incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/models/fieldtypes/TestArrayCollections.java (added) +++ incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/models/fieldtypes/TestArrayCollections.java Fri Mar 18 17:07:39 2005 @@ -0,0 +1,174 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.tck.models.fieldtypes; + +import java.util.Arrays; +import java.util.Hashtable; +import java.util.Vector; + +import javax.jdo.PersistenceManager; +import javax.jdo.Transaction; + +import org.apache.jdo.tck.JDO_Test; +import org.apache.jdo.tck.pc.fieldtypes.ArrayCollections; +import org.apache.jdo.tck.util.BatchTestRunner; + +/** + *<B>Title:</B> Support of field type array. + *<BR> + *<B>Keywords:</B> model + *<BR> + *<B>Assertion ID:</B> A6.4.3-39. + *<BR> + *<B>Assertion Description: </B> +JDO implementations may optionally support fields of array types. + */ + +public class TestArrayCollections extends JDO_Test { + + /** */ + private static final String ASSERTION_FAILED = + "Assertion (TestArrayCollections) failed: "; + + /** + * The <code>main</code> is called when the class + * is directly executed from the command line. + * @param args The arguments passed to the program. + */ + public static void main(String[] args) { + BatchTestRunner.run(TestArrayCollections.class); + } + + /** */ + public void test() { + pm = getPM(); + + runTest(pm); + + pm.close(); + pm = null; + } + + /** */ + void runTest(PersistenceManager pm) + { + if (!isArraySupported()) { + if (debug) + logger.debug("JDO Implementation does not support optional feature Array"); + return; + } + + Transaction tx = pm.currentTransaction(); + try { + int i, n; + FirstSetOfTestValuesForCollection firstSetOfValues = + new FirstSetOfTestValuesForCollection(); + SecondSetOfTestValuesForCollection secondSetOfValues = + new SecondSetOfTestValuesForCollection(); + + // turn on datastore transactions + tx.setOptimistic(false); + tx.begin(); + ArrayCollections pi = new ArrayCollections(); + pi.identifier = 1; + pm.makePersistent(pi); + Object oid = pm.getObjectId(pi); + n = pi.getLength(); + // Provide initial set of values + for(i = 0; i < n; ++i){ + String valueType = TestUtil.getFieldSpecs( + ArrayCollections.fieldSpecs[i]); + //create an array of initial values for each value type + Object[] firstValueArray = null; + Vector firstValueVector = (Vector)firstSetOfValues.get(valueType); + firstValueArray = (Object[])java.lang.reflect.Array.newInstance(firstValueVector.get(0).getClass(), + firstValueVector.size()); + for (int j=0; j<firstValueVector.size(); j++) { + firstValueArray[j] = firstValueVector.get(j); + } + + //set the initial set of values + pi.set( i, firstValueArray); + } + tx.commit(); + // cache will be flushed + pi = null; + System.gc(); + + tx.begin(); + + checkValues(oid, firstSetOfValues); // check if persistent fields have values set + pi = (ArrayCollections) pm.getObjectById(oid, true); + + // Provide new set of values + for( i = 0; i < n; ++i){ + String valueType = TestUtil.getFieldSpecs(ArrayCollections.fieldSpecs[i]); + //create an array of second set of values for each value type + Object[] secondValueArray = null; + Vector secondValueVector = (Vector)secondSetOfValues.get(valueType); + secondValueArray = (Object[])java.lang.reflect.Array.newInstance(secondValueVector.get(0).getClass(), + secondValueVector.size()); + for (int j=0; j<secondValueVector.size(); j++) { + secondValueArray[j] = secondValueVector.get(j); + } + pi.set( i, secondValueArray); + } + tx.commit(); + // cache will be flushed + pi = null; + System.gc(); + + tx.begin(); + // check new values + checkValues(oid, secondSetOfValues); + pi = (ArrayCollections) pm.getObjectById(oid, true); + pm.deletePersistent(pi); + tx.commit(); + tx = null; + } + finally { + if ((tx != null) && tx.isActive()) + tx.rollback(); + } + } + + /** */ + private void checkValues(Object oid, Hashtable startValue) + { + int i; + ArrayCollections pi = (ArrayCollections) pm.getObjectById(oid, true); + int n = pi.getLength(); + for (i = 0; i < n; ++i) { + String valueType = TestUtil.getFieldSpecs(ArrayCollections.fieldSpecs[i]); + //build the compareWith array + Object[] compareWith = null; + Vector compareWithVector = (Vector)startValue.get(valueType); + compareWith = (Object[])java.lang.reflect.Array.newInstance(compareWithVector.get(0).getClass(), + compareWithVector.size()); + for (int j=0; j<compareWithVector.size(); j++) { + compareWith[j] = compareWithVector.get(j); + } + + Object[] val = pi.get(i); + + if(!Arrays.equals(val, compareWith)){ + fail(ASSERTION_FAILED, + "Incorrect value for " + ArrayCollections.fieldSpecs[i]); + } + } + } +} Added: incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/models/fieldtypes/TestArrayListCollections.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/models/fieldtypes/TestArrayListCollections.java?view=auto&rev=158179 ============================================================================== --- incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/models/fieldtypes/TestArrayListCollections.java (added) +++ incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/models/fieldtypes/TestArrayListCollections.java Fri Mar 18 17:07:39 2005 @@ -0,0 +1,150 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.tck.models.fieldtypes; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Hashtable; + +import javax.jdo.PersistenceManager; +import javax.jdo.Transaction; + +import org.apache.jdo.tck.JDO_Test; +import org.apache.jdo.tck.pc.fieldtypes.ArrayListCollections; +import org.apache.jdo.tck.util.BatchTestRunner; + +/** + *<B>Title:</B> Support of field type ArrayList. + *<BR> + *<B>Keywords:</B> model + *<BR> + *<B>Assertion ID:</B> A6.4.3-23. + *<BR> + *<B>Assertion Description: </B> + If the ArrayList optional feature is supported, then JDO implementation must + support fields of the mutable object class <code>ArrayList</code>, + supporting them as Second Class Objects or First Class Objects. + */ + +public class TestArrayListCollections extends JDO_Test { + + /** */ + private static final String ASSERTION_FAILED = + "Assertion A6.4.3-23 (TestArrayListCollections) failed: "; + + /** + * The <code>main</code> is called when the class + * is directly executed from the command line. + * @param args The arguments passed to the program. + */ + public static void main(String[] args) { + BatchTestRunner.run(TestArrayListCollections.class); + } + + /** */ + public void test() { + pm = getPM(); + + runTest(pm); + + pm.close(); + pm = null; + } + + /** */ + void runTest(PersistenceManager pm) + { + if (!isArrayListSupported()) { + if (debug) + logger.debug("JDO Implementation does not support optional feature ArrayList"); + return; + } + + Transaction tx = pm.currentTransaction(); + try { + int i, n; + FirstSetOfTestValuesForCollection firstValue = + new FirstSetOfTestValuesForCollection(); + SecondSetOfTestValuesForCollection secondValue = + new SecondSetOfTestValuesForCollection(); + + // turn on datastore transactions + tx.setOptimistic(false); + tx.begin(); + ArrayListCollections pi = new ArrayListCollections(); + pi.identifier = 1; + pm.makePersistent(pi); + Object oid = pm.getObjectId(pi); + n = pi.getLength(); + // Provide initial set of values + for(i = 0; i < n; ++i){ + String valueType = TestUtil.getFieldSpecs(ArrayListCollections.fieldSpecs[i]); + pi.set( i, new ArrayList((Collection)firstValue.get(valueType))); + } + tx.commit(); + // cache will be flushed + pi = null; + System.gc(); + + tx.begin(); + + checkValues(oid, firstValue); // check if persistent fields have values set + pi = (ArrayListCollections) pm.getObjectById(oid, true); + + // Provide new set of values + for( i = 0; i < n; ++i){ + String valueType = TestUtil.getFieldSpecs(ArrayListCollections.fieldSpecs[i]); + pi.set( i, new ArrayList((Collection)secondValue.get(valueType))); + } + tx.commit(); + // cache will be flushed + pi = null; + System.gc(); + + tx.begin(); + // check new values + checkValues(oid, secondValue); + pi = (ArrayListCollections) pm.getObjectById(oid, true); + pm.deletePersistent(pi); + tx.commit(); + tx = null; + } + finally { + if ((tx != null) && tx.isActive()) + tx.rollback(); + } + } + + /** */ + private void checkValues(Object oid, Hashtable startValue) + { + int i; + ArrayListCollections pi = (ArrayListCollections) pm.getObjectById(oid, true); + int n = pi.getLength(); + for( i = 0; i < n; ++i){ + String valueType = TestUtil.getFieldSpecs(ArrayListCollections.fieldSpecs[i]); + ArrayList compareWith = new ArrayList((Collection)startValue.get(valueType)); + + ArrayList val = pi.get(i); + + if(!val.equals(compareWith)){ + fail(ASSERTION_FAILED, + "Incorrect value for " + ArrayListCollections.fieldSpecs[i]); + } + } + } +} Added: incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/models/fieldtypes/TestCollectionCollections.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/models/fieldtypes/TestCollectionCollections.java?view=auto&rev=158179 ============================================================================== --- incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/models/fieldtypes/TestCollectionCollections.java (added) +++ incubator/jdo/trunk/tck11/test/java/org/apache/jdo/tck/models/fieldtypes/TestCollectionCollections.java Fri Mar 18 17:07:39 2005 @@ -0,0 +1,144 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.tck.models.fieldtypes; + +import java.util.Collection; +import java.util.Hashtable; + +import javax.jdo.PersistenceManager; +import javax.jdo.Transaction; + +import org.apache.jdo.tck.JDO_Test; +import org.apache.jdo.tck.pc.fieldtypes.CollectionCollections; +import org.apache.jdo.tck.util.BatchTestRunner; + +/** + *<B>Title:</B> Support of field type Collection. + *<BR> + *<B>Keywords:</B> model + *<BR> + *<B>Assertion ID:</B> A6.4.3-33. + *<BR> + *<B>Assertion Description: </B> + JDO implementations must support fields of the interface type + <code>java.util.Collection</code>, and may choose to support them + as Second Class Objects or First Class Objects. + */ + + +public class TestCollectionCollections extends JDO_Test { + + /** */ + private static final String ASSERTION_FAILED = + "Assertion A6.4.3-33 (TestCollectionCollections) failed: "; + + /** + * The <code>main</code> is called when the class + * is directly executed from the command line. + * @param args The arguments passed to the program. + */ + public static void main(String[] args) { + BatchTestRunner.run(TestCollectionCollections.class); + } + + /** */ + public void test() { + pm = getPM(); + + runTest(pm); + + pm.close(); + pm = null; + } + + /** */ + void runTest(PersistenceManager pm) + { + Transaction tx = pm.currentTransaction(); + try { + int i, n; + FirstSetOfTestValuesForCollection firstValue = new FirstSetOfTestValuesForCollection(); + SecondSetOfTestValuesForCollection secondValue = new SecondSetOfTestValuesForCollection(); + + // turn on datastore transactions + tx.setOptimistic(false); + tx.begin(); + CollectionCollections pi = new CollectionCollections(); + pi.identifier = 1; + pm.makePersistent(pi); + Object oid = pm.getObjectId(pi); + n = pi.getLength(); + // Provide initial set of values + for(i = 0; i < n; ++i){ + String valueType = TestUtil.getFieldSpecs(CollectionCollections.fieldSpecs[i]); + pi.set( i, (Collection)firstValue.get(valueType)); + } + tx.commit(); + // cache will be flushed + pi = null; + System.gc(); + + tx.begin(); + + checkValues(oid, firstValue); // check if persistent fields have values set + pi = (CollectionCollections) pm.getObjectById(oid, true); + + // Provide new set of values + for( i = 0; i < n; ++i){ + String valueType = TestUtil.getFieldSpecs(CollectionCollections.fieldSpecs[i]); + pi.set( i, (Collection)secondValue.get(valueType)); + + } + tx.commit(); + // cache will be flushed + pi = null; + System.gc(); + + tx.begin(); + // check new values + checkValues(oid, secondValue); + pi = (CollectionCollections) pm.getObjectById(oid, true); + pm.deletePersistent(pi); + tx.commit(); + tx = null; + } + finally { + if ((tx != null) && tx.isActive()) + tx.rollback(); + } + } + + /** */ + private void checkValues(Object oid, Hashtable startValue) + { + int ret = 0; + int i; + Collection value; + CollectionCollections pi = (CollectionCollections) pm.getObjectById(oid, true); + int n = pi.getLength(); + for( i = 0; i < n; ++i){ + String valueType = TestUtil.getFieldSpecs(CollectionCollections.fieldSpecs[i]); + Collection compareWith = (Collection)startValue.get(valueType); + + Collection val = pi.get(i); + if(! val.equals(compareWith) ){ + fail(ASSERTION_FAILED, + "Incorrect value for " + CollectionCollections.fieldSpecs[i]); + } + } + } +}