### Eclipse Workspace Patch 1.0
#P jdo-tck
Index: src/java/org/apache/jdo/tck/lifecycle/StateTransitions.java
===================================================================
--- src/java/org/apache/jdo/tck/lifecycle/StateTransitions.java (revision 1740768)
+++ src/java/org/apache/jdo/tck/lifecycle/StateTransitions.java (working copy)
@@ -24,6 +24,9 @@
import javax.jdo.Extent;
import javax.jdo.JDOFatalException;
+import javax.jdo.JDOHelper;
+import javax.jdo.ObjectState;
+import javax.jdo.PersistenceManager;
import javax.jdo.Transaction;
import org.apache.jdo.tck.JDO_Test;
@@ -37,7 +40,7 @@
*
*Assertion IDs: A5.9-1 through A5.9-190
*Assertion Description:
- All possible state transistions are being tested in this test.
+ * All possible state transitions are being tested in this test.
*/
public class StateTransitions extends JDO_Test {
@@ -92,8 +95,13 @@
private static final int SERIALIZEOUTSIDETX = 24;
private static final int SERIALIZEDATASTORE = 25;
private static final int SERIALIZEOPTIMISTIC = 26;
+ private static final int REFRESH_REMOTELY_MODIFIED = 27;
+ private static final int REFRESH_REMOTELY_DELETED = 28;
+ //The optimistic test allows additional scenarios without causing locking problems
+ private static final int REFRESH_REMOTELY_MODIFIED_OPT = 29;
+ private static final int REFRESH_REMOTELY_DELETED_OPT = 30;
- private static final int NUM_OPERATIONS = 27;
+ private static final int NUM_OPERATIONS = 31;
private static final String[] operations = {
"makePersistent",
@@ -122,7 +130,11 @@
"detachCopy with active optimistic tx",
"serialize outside tx",
"serialize with active datastore tx",
- "serialize with active optimistic tx"
+ "serialize with active optimistic tx",
+ "refresh remotely modified, datastore tx",
+ "refresh remotely deleted, datastore tx",
+ "refresh remotely modified, optimistic tx",
+ "refresh remotely deleted, optimistic tx"
};
/**
@@ -350,6 +362,40 @@
UNCHANGED, UNCHANGED, UNCHANGED,
UNCHANGED, UNCHANGED, UNCHANGED,
UNCHANGED},
+
+ // TRANSIENT, PERSISTENT_NEW, PERSISTENT_CLEAN,
+ // PERSISTENT_DIRTY, HOLLOW, TRANSIENT_CLEAN,
+ // TRANSIENT_DIRTY, PERSISTENT_NEW_DELETED, PERSISTENT_DELETED,
+ // PERSISTENT_NONTRANSACTIONAL, PERSISTENT_NONTRANSACTIONAL_DIRTY, DETACHED_CLEAN,
+ // DETACHED_DIRTY
+
+ // refresh after remote modification - normal tx
+ { UNCHANGED, PERSISTENT_CLEAN, UNCHANGED,
+ PERSISTENT_CLEAN, UNCHANGED, UNCHANGED,
+ UNCHANGED, PERSISTENT_CLEAN, UNCHANGED,
+ UNCHANGED, PERSISTENT_NONTRANSACTIONAL, ERROR,
+ ERROR},
+
+ // refresh after remote deletion - normal tx
+ { UNCHANGED, UNCHANGED, TRANSIENT,
+ TRANSIENT, UNCHANGED, UNCHANGED,
+ UNCHANGED, TRANSIENT, TRANSIENT,
+ TRANSIENT, TRANSIENT, ERROR,
+ ERROR},
+
+ // refresh after remote modification - optimistic
+ { UNCHANGED, PERSISTENT_NONTRANSACTIONAL, UNCHANGED,
+ PERSISTENT_NONTRANSACTIONAL, UNCHANGED, UNCHANGED,
+ UNCHANGED, PERSISTENT_NONTRANSACTIONAL, UNCHANGED,
+ UNCHANGED, PERSISTENT_NONTRANSACTIONAL, ERROR,
+ ERROR},
+
+ // refresh after remote deletion - optimistic
+ { UNCHANGED, UNCHANGED, TRANSIENT,
+ TRANSIENT, UNCHANGED, UNCHANGED,
+ UNCHANGED, TRANSIENT, TRANSIENT,
+ TRANSIENT, TRANSIENT, ERROR,
+ ERROR},
};
private static final int DATASTORE_TX = 0;
@@ -388,12 +434,17 @@
{ false, true, false }, // detachCopy with active optimistic tx
{ false, false, true }, // serialize outside tx
{ true, false, false }, // serialize with active datastore tx
- { false, true, false } // serialize with active optimistic tx
+ { false, true, false }, // serialize with active optimistic tx
+ { true, false, false }, // refresh remotely modified, datastore tx
+ { true, false, false }, // refresh remotely deleted, datastore tx
+ { false, true, false }, // refresh remotely modified, optimistic tx
+ { false, true, false } // refresh remotely deleted, optimistix tx
};
/**
* @see JDO_Test#localSetUp()
*/
+ @Override
protected void localSetUp() {
pm = getPM();
addTearDownClass(StateTransitionObj.class);
@@ -487,6 +538,7 @@
{
for( operation = 0; operation < NUM_OPERATIONS; ++operation ){
// rule out situations that do not apply
+ appendMessage("TZ-Checking: " + scenario + " / " + operation); //TODO
if( !applies_to_scenario[operation][scenario] ) continue;
if( (operation == READOUTSIDETX ||
operation == RETRIEVEOUTSIDETX ||
@@ -586,6 +638,8 @@
if( transaction.isActive() ) transaction.rollback();
}
catch(Exception unexpected_exception) {
+ appendMessage("TZ-Failing: " + scenario + " / " + operation); //TODO
+ unexpected_exception.printStackTrace(); //TODO
if (debug) {
unexpected_exception.printStackTrace();
}
@@ -776,6 +830,26 @@
}
break;
}
+ case REFRESH_REMOTELY_MODIFIED:
+ case REFRESH_REMOTELY_MODIFIED_OPT:
+ {
+ //This test only applies to persistent objects
+ if (JDOHelper.isPersistent(obj)) {
+ modifyRemotely(obj, false);
+ pm.refresh(obj);
+ }
+ break;
+ }
+ case REFRESH_REMOTELY_DELETED:
+ case REFRESH_REMOTELY_DELETED_OPT:
+ {
+ //This test only applies to persistent objects
+ if (JDOHelper.isPersistent(obj)) {
+ modifyRemotely(obj, true);
+ pm.refresh(obj);
+ }
+ break;
+ }
default:
{
appendMessage(ASSERTION_FAILED + NL +
@@ -1079,4 +1153,82 @@
}
return obj;
}
+
+ /** Modify or delete an object in a separate PM. */
+ private void modifyRemotely(StateTransitionObj objLocal, boolean deleteRemotely)
+ {
+ //First ensure that the object is in the DB and PERSISTENT_CLEAN (has no locks in DB)
+ ObjectState state = JDOHelper.getObjectState(objLocal);
+ if (ObjectState.TRANSIENT == state
+ || ObjectState.TRANSIENT_CLEAN == state
+ || ObjectState.TRANSIENT_DIRTY == state) {
+ pm.makePersistent(objLocal);
+ }
+ if (JDOHelper.isNew(objLocal)) {
+ boolean isRV = pm.currentTransaction().getRetainValues();
+ //ensure non-hollow after commit
+ pm.currentTransaction().setRetainValues(true);
+ pm.currentTransaction().commit();
+ pm.currentTransaction().begin();
+ pm.currentTransaction().setRetainValues(isRV);
+ } else {
+ pm.refresh(objLocal);
+ }
+
+ //apply changes in concurrent transaction
+ Object oid = pm.getObjectId(objLocal);
+ PersistenceManager pm = getPMF().getPersistenceManager();
+ pm.currentTransaction().begin();
+ StateTransitionObj objRemote = (StateTransitionObj) pm.getObjectById(oid);
+ if (deleteRemotely) {
+ pm.deletePersistent(objRemote);
+ } else {
+ objRemote.writeField(objRemote.readField() + 1);
+ }
+ pm.currentTransaction().commit();
+ pm.close();
+
+ //recreate desired object state
+ switch (state) {
+ case DETACHED_CLEAN:
+ case DETACHED_DIRTY:
+ case HOLLOW_PERSISTENT_NONTRANSACTIONAL:
+ throw new IllegalStateException("State is not applicable: " + state);
+ case PERSISTENT_CLEAN:
+ break;
+ case PERSISTENT_DELETED:
+ pm.deletePersistent(objLocal);
+ break;
+ case PERSISTENT_DIRTY:
+ objLocal.writeField(objLocal.readField() + 23);
+ break;
+ case PERSISTENT_NEW:
+ pm.makeTransient(objLocal); //make it TRANSIENT
+ pm.makePersistent(objLocal); // make it p-new
+ break;
+ case PERSISTENT_NEW_DELETED:
+ pm.makeTransient(objLocal); //make it TRANSIENT
+ pm.makePersistent(objLocal); // make it p-new
+ pm.deletePersistent(objLocal);
+ break;
+ case PERSISTENT_NONTRANSACTIONAL_DIRTY:
+ pm.makeNontransactional(objLocal);
+ objLocal.writeField(objLocal.readField() + 23);
+ break;
+ case TRANSIENT:
+ pm.makeTransient(objLocal);
+ break;
+ case TRANSIENT_CLEAN:
+ pm.makeTransient(objLocal);
+ pm.makeTransactional(objLocal);
+ break;
+ case TRANSIENT_DIRTY:
+ pm.makeTransient(objLocal);
+ pm.makeTransactional(objLocal);
+ objLocal.writeField(objLocal.readField() + 23);
+ break;
+ default:
+ throw new IllegalStateException("State is not applicable: " + state);
+ }
+ }
}