| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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 |
| <<<<<<< Updated upstream |
| * |
| * 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 |
| ======= |
| * |
| * https://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 |
| >>>>>>> Stashed changes |
| * limitations under the License. |
| */ |
| |
| package org.apache.jdo.tck.api.instancecallbacks; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| import javax.jdo.JDOHelper; |
| import javax.jdo.listener.AttachLifecycleListener; |
| import javax.jdo.listener.ClearLifecycleListener; |
| import javax.jdo.listener.CreateLifecycleListener; |
| import javax.jdo.listener.DeleteLifecycleListener; |
| import javax.jdo.listener.DetachLifecycleListener; |
| import javax.jdo.listener.DirtyLifecycleListener; |
| import javax.jdo.listener.InstanceLifecycleEvent; |
| import javax.jdo.listener.LoadLifecycleListener; |
| import javax.jdo.listener.StoreLifecycleListener; |
| import org.apache.jdo.tck.JDO_Test; |
| |
| /** |
| * <B>Title:</B> Abstract test AbstractInstanceLifecycleListener <br> |
| * <B>Keywords:</B> LifeCycleListener lifecycle listener callback <br> |
| * <B>Assertion IDs:</B> A12.15-1, A12.15-2, A12.15-3, A12.15-4, A12.15-5, A12.15-6, A12.15-7, |
| * A12.15-8, A12.15-9, A12.15-10, A12.15-11, A12.15-12, A12.15-13, A12.15-14, <br> |
| * <B>Assertion Description: </B> A12.15-1 void postCreate(InstanceLifecycleEvent event); This |
| * method is called whenever a persistent instance is created, during makePersistent. It is called |
| * after the instance transitions to persistent-new. A12.15-2 void postLoad(InstanceLifecycleEvent |
| * event); This method is called whenever a persistent instance is loaded. It is called after the |
| * jdoPostLoad method is invoked on the instance. A12.15-3 void preStore(InstanceLifecycleEvent |
| * event); This method is called whenever a persistent instance is stored, for example during flush |
| * or commit. It is called before the jdoPreStore method is invoked on the instance. A12.15-4 void |
| * postStore(InstanceLifecycleEvent event); This method is called whenever a persistent instance is |
| * stored, for example during flush or commit. It is called after the jdoPreStore method is invoked |
| * on the instance. An object identity for a per?sistent-new instance must have been assigned to the |
| * instance when this callback is invoked. A12.15-5 void preClear(InstanceLifecycleEvent event); |
| * This method is called whenever a persistent instance is cleared, for example during |
| * afterCompletion. It is called before the jdoPreClear method is invoked on the instance. A12.15-6 |
| * void postClear(InstanceLifecycleEvent event); This method is called whenever a persistent |
| * instance is cleared, for example during afterCom?pletion. It is called after the jdoPreClear |
| * method is invoked on the instance and the fields have been cleared by the JDO implementation. |
| * A12.15-7 void preDelete(InstanceLifecycleEvent event); This method is called whenever a |
| * persistent instance is deleted, during deletePersistent. It is called before the state transition |
| * and before the jdoPreDelete method is invoked on the instance. A12.15-8 void |
| * postDelete(InstanceLifecycleEvent event); This method is called whenever a persistent instance is |
| * deleted, during deletePersistent. It is called after the jdoPreDelete method is invoked on the |
| * instance and after the state transition. A12.15-9 void preDirty(InstanceLifecycleEvent event); |
| * This method is called whenever a persistent clean instance is first made dirty, during an |
| * operation that modifies the value of a persistent or transactional field. It is called before the |
| * field value is changed. A12.15-10 void postDirty(InstanceLifecycleEvent event); This method is |
| * called whenever a persistent clean instance is first made dirty, during an operation that |
| * modifies the value of a persistent or transactional field. It is called after the field value was |
| * changed. A12.15-11 void preDetach(InstanceLifecycleEvent event); This method is called before a |
| * persistent instance is copied for detachment. A12.15-12 void postDetach(InstanceLifecycleEvent |
| * event); This method is called whenever a persistent instance is copied for detachment. The source |
| * instance is the detached copy; the target instance is the persistent instance. A12.15-13 void |
| * preAttach(InstanceLifecycleEvent event); This method is called before a detached instance is |
| * attached. The source instance is the detached instance]. A12.15-14 void |
| * postAttach(InstanceLifecycleEvent event); This method is called after a detached instance is |
| * attached. The source instance is the corresponding persistent instance in the cache; the target |
| * instance is the detached instance. |
| * |
| * <p>This is the abstract base class for the lifecycle listener test classes. It contains |
| * constants, variables, and methods used by each listener test class. This class implements the |
| * setup and teardown methods used by each concrete test class. |
| * |
| * <p>This class also includes the listener base class that is extended by each specific listener. |
| * |
| * <p>The strategy of each test case is the same. A specific listener is implemented that responds |
| * only to events for that specific test; a specific persistence-capable class is also implemented, |
| * that responds only to callbacks for the specific test. A sequence of operations that stimulates |
| * the callbacks is executed. During these operations, listener events and callbacks are collected |
| * by the listener instance. Finally, the actual events and callbacks that were collected are |
| * analyzed and differences are reported. |
| */ |
| public abstract class AbstractInstanceLifecycleListener extends JDO_Test { |
| |
| /** */ |
| protected static final String ASSERTION1_FAILED = |
| "Assertion A12.15-1 (TestInstanceLifecycleListenerCreate) failed: "; |
| |
| protected static final String ASSERTION2_FAILED = |
| "Assertion A12.15-2 (TestInstanceLifecycleListener) failed: "; |
| protected static final String ASSERTION3_FAILED = |
| "Assertion A12.15-3 (TestInstanceLifecycleListener) failed: "; |
| protected static final String ASSERTION4_FAILED = |
| "Assertion A12.15-4 (TestInstanceLifecycleListener) failed: "; |
| protected static final String ASSERTION5_FAILED = |
| "Assertion A12.15-5 (TestInstanceLifecycleListener) failed: "; |
| protected static final String ASSERTION6_FAILED = |
| "Assertion A12.15-6 (TestInstanceLifecycleListener) failed: "; |
| protected static final String ASSERTION7_FAILED = |
| "Assertion A12.15-7 (TestInstanceLifecycleListenerDelete) failed: "; |
| protected static final String ASSERTION8_FAILED = |
| "Assertion A12.15-8 (TestInstanceLifecycleListenerDelete) failed: "; |
| protected static final String ASSERTION9_FAILED = |
| "Assertion A12.15-9 (TestInstanceLifecycleListener) failed: "; |
| protected static final String ASSERTION10_FAILED = |
| "Assertion A12.15-10 (TestInstanceLifecycleListener) failed: "; |
| protected static final String ASSERTION11_FAILED = |
| "Assertion A12.15-11 (TestInstanceLifecycleListener) failed: "; |
| protected static final String ASSERTION12_FAILED = |
| "Assertion A12.15-12 (TestInstanceLifecycleListener) failed: "; |
| protected static final String ASSERTION13_FAILED = |
| "Assertion A12.15-13 (TestInstanceLifecycleListener) failed: "; |
| protected static final String ASSERTION14_FAILED = |
| "Assertion A12.15-14 (TestInstanceLifecycleListener) failed: "; |
| |
| /** |
| * The listener to be used for the test. This method is implemented by the subclasses to use the |
| * proper listener. |
| * |
| * @return listener |
| */ |
| protected abstract InstanceLifecycleListenerImpl getListener(); |
| |
| /** |
| * The classes to be used for the test. This method is implemented by the subclasses to use the |
| * proper classes. The classes returned by this method are used for two purposes: they are used to |
| * register listeners; and they are used as the teardown classes whose instances are removed from |
| * the datastore at the end of the test. |
| * |
| * @return classes |
| */ |
| protected abstract Class<?>[] getPersistentClasses(); |
| |
| /** Register a new InstanceLifecycleListenerImpl with the PersistenceManager. */ |
| protected void addListener() { |
| getPM(); |
| pm.addInstanceLifecycleListener(getListener(), getPersistentClasses()); |
| } |
| |
| /** Unregister the InstanceLifecycleListenerImpl with the PersistenceManager. */ |
| protected void removeListener() { |
| getPM(); |
| pm.removeInstanceLifecycleListener(getListener()); |
| } |
| |
| /** Set up for lifecycle tests: Register the LifecycleListener; add PCPoint to tearDownClasses. */ |
| @Override |
| protected void localSetUp() { |
| addListener(); |
| addTearDownClass(getPersistentClasses()); |
| } |
| |
| /** Clean up after lifecycle tests: Unregister the LifecycleListener. */ |
| @Override |
| protected void localTearDown() { |
| removeListener(); // no callbacks for teardown |
| super.localTearDown(); |
| } |
| |
| /** |
| * The LifeCycleListener to be registered with the PersistenceManager. This is the base class that |
| * is extended by each test. |
| */ |
| protected abstract static class InstanceLifecycleListenerImpl |
| implements AttachLifecycleListener, |
| ClearLifecycleListener, |
| CreateLifecycleListener, |
| DeleteLifecycleListener, |
| DetachLifecycleListener, |
| DirtyLifecycleListener, |
| LoadLifecycleListener, |
| StoreLifecycleListener { |
| |
| protected InstanceLifecycleListenerImpl() {} |
| |
| protected Object expectedSource = null; |
| protected Object expectedTarget = null; |
| |
| public void setExpectedSource(Object source) { |
| expectedSource = source; |
| } |
| |
| public void setExpectedTarget(Object target) { |
| expectedTarget = target; |
| } |
| |
| /** |
| * This is the list names of locations for listener events and callbacks. Each instance of an |
| * event or callback has a specific name that is associated with the value. The values are used |
| * during collection of events and both names and values are used for reporting results. |
| */ |
| private static final List<String> locations = new ArrayList<>(); |
| |
| /** |
| * These are indexes into the sequence array. Each index represents the position in the sequence |
| * array for the corresponding callback or listener event. |
| */ |
| public static final int PRE_ATTACH_CALLBACK; |
| |
| public static final int POST_ATTACH_CALLBACK; |
| public static final int PRE_ATTACH_LISTENER; |
| public static final int POST_ATTACH_LISTENER; |
| public static final int PRE_CLEAR_CALLBACK; |
| public static final int PRE_CLEAR_LISTENER; |
| public static final int POST_CLEAR_LISTENER; |
| public static final int POST_CREATE_LISTENER; |
| public static final int PRE_DELETE_CALLBACK; |
| public static final int PRE_DELETE_LISTENER; |
| public static final int POST_DELETE_LISTENER; |
| public static final int PRE_DETACH_CALLBACK; |
| public static final int POST_DETACH_CALLBACK; |
| public static final int PRE_DETACH_LISTENER; |
| public static final int POST_DETACH_LISTENER; |
| public static final int PRE_DIRTY_LISTENER; |
| public static final int POST_DIRTY_LISTENER; |
| public static final int POST_LOAD_CALLBACK; |
| public static final int POST_LOAD_LISTENER; |
| public static final int PRE_STORE_CALLBACK; |
| public static final int PRE_STORE_LISTENER; |
| public static final int POST_STORE_LISTENER; |
| |
| /* |
| * Initialize the list of names and the associated values. For each |
| * listener event and callback, add the name and then assign the value. |
| */ |
| static { |
| int index = 0; |
| locations.add("PRE_ATTACH_LISTENER"); |
| PRE_ATTACH_LISTENER = index++; |
| locations.add("PRE_ATTACH_CALLBACK"); |
| PRE_ATTACH_CALLBACK = index++; |
| locations.add("POST_ATTACH_CALLBACK"); |
| POST_ATTACH_CALLBACK = index++; |
| locations.add("POST_ATTACH_LISTENER"); |
| POST_ATTACH_LISTENER = index++; |
| locations.add("PRE_CLEAR_LISTENER"); |
| PRE_CLEAR_LISTENER = index++; |
| locations.add("PRE_CLEAR_CALLBACK"); |
| PRE_CLEAR_CALLBACK = index++; |
| locations.add("POST_CLEAR_LISTENER"); |
| POST_CLEAR_LISTENER = index++; |
| locations.add("POST_CREATE_LISTENER"); |
| POST_CREATE_LISTENER = index++; |
| locations.add("PRE_DELETE_LISTENER"); |
| PRE_DELETE_LISTENER = index++; |
| locations.add("PRE_DELETE_CALLBACK"); |
| PRE_DELETE_CALLBACK = index++; |
| locations.add("POST_DELETE_LISTENER"); |
| POST_DELETE_LISTENER = index++; |
| locations.add("POST_DETACH_CALLBACK"); |
| POST_DETACH_CALLBACK = index++; |
| locations.add("PRE_DETACH_LISTENER"); |
| PRE_DETACH_LISTENER = index++; |
| locations.add("PRE_DETACH_CALLBACK"); |
| PRE_DETACH_CALLBACK = index++; |
| locations.add("POST_DETACH_LISTENER"); |
| POST_DETACH_LISTENER = index++; |
| locations.add("PRE_DIRTY_LISTENER"); |
| PRE_DIRTY_LISTENER = index++; |
| locations.add("POST_DIRTY_LISTENER"); |
| POST_DIRTY_LISTENER = index++; |
| locations.add("POST_LOAD_CALLBACK"); |
| POST_LOAD_CALLBACK = index++; |
| locations.add("POST_LOAD_LISTENER"); |
| POST_LOAD_LISTENER = index++; |
| locations.add("PRE_STORE_LISTENER"); |
| PRE_STORE_LISTENER = index++; |
| locations.add("PRE_STORE_CALLBACK"); |
| PRE_STORE_CALLBACK = index++; |
| locations.add("POST_STORE_LISTENER"); |
| POST_STORE_LISTENER = index++; |
| } |
| |
| private final int[] actual = new int[locations.size()]; |
| |
| /** Track the current sequence of callbacks. */ |
| private int current = 0; |
| |
| public void notifyEvent(int event) { |
| actual[event] = ++current; |
| } |
| |
| /** |
| * Initialize the expected ordering of callbacks and listeners. Each entry in the sequence is |
| * one of the PRE_ or POST_XXX_LISTENER or _CALLBACK above. The order in the sequence is the |
| * expected calling order. |
| */ |
| private static int[] newExpected(int[] sequence) { |
| int order = 0; |
| int[] result = new int[locations.size()]; |
| for (int j : sequence) { |
| result[j] = ++order; |
| } |
| return result; |
| } |
| |
| /** The error message buffer to report exceptions. */ |
| protected final StringBuffer messages = new StringBuffer(); |
| |
| protected void checkEventType(String where, int expected, int actual) { |
| if (expected != actual) { |
| messages.append( |
| where |
| + "wrong event type: " |
| + "expected <" |
| + expected |
| + ">, actual <" |
| + actual |
| + ">\n"); |
| } |
| } |
| |
| protected void checkEventSource(String where, Object eventSource) { |
| if (expectedSource != eventSource) { |
| messages.append( |
| where |
| + "wrong event source: " |
| + "expected <" |
| + expectedSource |
| + ">, actual <" |
| + eventSource |
| + ">\n"); |
| } |
| } |
| |
| protected void checkEventTarget(String where, Object eventTarget) { |
| if (expectedTarget != eventTarget) { |
| messages.append( |
| where |
| + "wrong event target: " |
| + "expected <" |
| + expectedTarget |
| + ">, actual <" |
| + eventTarget |
| + ">\n"); |
| } |
| } |
| |
| protected void checkTrue(String where, boolean condition) { |
| if (!condition) { |
| messages.append(where + "was not true.\n"); |
| } |
| } |
| |
| protected void checkSame(String where, Object expected, Object actual) { |
| if (expected != actual) { |
| messages.append(where + "expected <" + expected + ">, actual <" + actual + ">\n"); |
| } |
| } |
| |
| protected void checkPersistent(String where, Object obj) { |
| if (!JDOHelper.isPersistent(obj)) { |
| messages.append(where + "object should be persistent.\n"); |
| } |
| } |
| |
| protected void checkNotPersistent(String where, Object obj) { |
| if (JDOHelper.isPersistent(obj)) { |
| messages.append(where + "object should not be persistent.\n"); |
| } |
| } |
| |
| protected void checkDirty(String where, Object obj) { |
| if (!JDOHelper.isDirty(obj)) { |
| messages.append(where + "object should be dirty.\n"); |
| } |
| } |
| |
| protected void checkNotDirty(String where, Object obj) { |
| if (JDOHelper.isDirty(obj)) { |
| messages.append(where + "object should not be dirty.\n"); |
| } |
| } |
| |
| protected void checkNew(String where, Object obj) { |
| if (!JDOHelper.isNew(obj)) { |
| messages.append(where + "object should be new.\n"); |
| } |
| } |
| |
| protected void checkNotNew(String where, Object obj) { |
| if (JDOHelper.isNew(obj)) { |
| messages.append(where + "object should not be new.\n"); |
| } |
| } |
| |
| protected void checkDeleted(String where, Object obj) { |
| if (!JDOHelper.isDeleted(obj)) { |
| messages.append(where + "object should be deleted.\n"); |
| } |
| } |
| |
| protected void checkNotDeleted(String where, Object obj) { |
| if (JDOHelper.isDeleted(obj)) { |
| messages.append(where + "object should not be deleted.\n"); |
| } |
| } |
| |
| /** |
| * Verify the actual sequence of callbacks and listeners against the expected. Each of the |
| * expected and actual are int arrays in which each listener and callback have one position in |
| * the array and the value of the array at that position is the order, starting with 1, of the |
| * callback. If the callback or listener was never invoked, the value is 0. |
| * |
| * @param where where |
| * @param expected expected |
| */ |
| public void verifyCallbacks(String where, int[] expected) { |
| int[] expectedSequence = newExpected(expected); |
| for (int index = 0; index < locations.size(); ++index) { |
| if (expectedSequence[index] != actual[index]) { |
| messages.append( |
| "\nSequence verification failed for " |
| + locations.get(index) |
| + "; expected: <" |
| + expectedSequence[index] |
| + "> actual: <" |
| + actual[index] |
| + ">\n"); |
| } |
| } |
| if (messages.length() > 0) { |
| fail(where + "\n" + messages); |
| } |
| } |
| |
| public void postAttach(InstanceLifecycleEvent event) {} |
| |
| public void postClear(InstanceLifecycleEvent event) {} |
| |
| public void postCreate(InstanceLifecycleEvent event) {} |
| |
| public void postDelete(InstanceLifecycleEvent event) {} |
| |
| public void postDetach(InstanceLifecycleEvent event) {} |
| |
| public void postDirty(InstanceLifecycleEvent event) {} |
| |
| public void postLoad(InstanceLifecycleEvent event) {} |
| |
| public void postStore(InstanceLifecycleEvent event) {} |
| |
| public void preAttach(InstanceLifecycleEvent event) {} |
| |
| public void preClear(InstanceLifecycleEvent event) {} |
| |
| public void preDelete(InstanceLifecycleEvent event) {} |
| |
| public void preDetach(InstanceLifecycleEvent event) {} |
| |
| public void preDirty(InstanceLifecycleEvent event) {} |
| |
| public void preStore(InstanceLifecycleEvent event) {} |
| } |
| } |