001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package com.tc.objectserver.managedobject;
006:
007: import com.tc.exception.ImplementMe;
008: import com.tc.io.serializer.TCObjectInputStream;
009: import com.tc.io.serializer.TCObjectOutputStream;
010: import com.tc.object.ObjectID;
011: import com.tc.object.dna.api.DNACursor;
012: import com.tc.object.dna.api.DNAWriter;
013: import com.tc.object.dna.api.DNAEncoding;
014: import com.tc.object.dna.api.LiteralAction;
015: import com.tc.object.dna.api.LogicalAction;
016: import com.tc.object.dna.api.PhysicalAction;
017: import com.tc.objectserver.core.api.ManagedObjectState;
018: import com.tc.objectserver.persistence.impl.InMemoryPersistor;
019: import com.tc.util.Assert;
020:
021: import java.io.ByteArrayInputStream;
022: import java.io.ByteArrayOutputStream;
023: import java.lang.reflect.InvocationHandler;
024: import java.lang.reflect.Method;
025: import java.util.ArrayList;
026: import java.util.Arrays;
027: import java.util.HashMap;
028: import java.util.Iterator;
029: import java.util.List;
030: import java.util.Map;
031:
032: import junit.framework.TestCase;
033:
034: public abstract class AbstractTestManagedObjectState extends TestCase {
035: protected static final String loaderDesc = "System.loader";
036: protected ObjectID objectID;
037: protected ManagedObjectChangeListenerProvider listenerProvider;
038:
039: public void setUp() throws Exception {
040: super .setUp();
041: listenerProvider = new NullManagedObjectChangeListenerProvider();
042: ManagedObjectStateFactory.disableSingleton(true);
043: ManagedObjectStateFactory.createInstance(listenerProvider,
044: new InMemoryPersistor());
045: objectID = new ObjectID(2000);
046: }
047:
048: protected void tearDown() throws Exception {
049: super .tearDown();
050: ManagedObjectStateFactory.disableSingleton(false);
051: objectID = null;
052: listenerProvider = null;
053: }
054:
055: protected ManagedObjectState createManagedObjectState(
056: String className, TestDNACursor cursor) throws Exception {
057: ManagedObjectState state = ManagedObjectStateFactory
058: .getInstance()
059: .createState(new ObjectID(1), ObjectID.NULL_ID,
060: className, loaderDesc, cursor);
061: return state;
062: }
063:
064: public void basicTestUnit(String className, final byte type,
065: TestDNACursor cursor, int objCount) throws Exception {
066: ManagedObjectState state = createManagedObjectState(className,
067: cursor);
068: state.apply(objectID, cursor, new BackReferences());
069:
070: // API verification
071: basicAPI(className, type, cursor, objCount, state);
072:
073: // dehydrate
074: basicDehydrate(cursor, objCount, state);
075:
076: // writeTo, readFrom and equal
077: basicReadWriteEqual(type, state);
078: }
079:
080: protected void basicAPI(String className, final byte type,
081: TestDNACursor cursor, int objCount, ManagedObjectState state) {
082: Assert.assertEquals("BackReferences object size", objCount,
083: state.getObjectReferences().size());
084: Assert.assertTrue(state.getType() == type);
085: Assert.assertTrue("ClassName:" + state.getClassName(), state
086: .getClassName().equals(className));
087:
088: }
089:
090: protected void basicDehydrate(TestDNACursor cursor, int objCount,
091: ManagedObjectState state) {
092: TestDNAWriter dnaWriter = new TestDNAWriter();
093: state.dehydrate(objectID, dnaWriter);
094: cursor.reset();
095: cursor.next();
096: while (cursor.next()) {
097: Object action = cursor.getAction();
098: Assert.assertTrue(dnaWriter.containsAction(action));
099: }
100: }
101:
102: protected void basicReadWriteEqual(final byte type,
103: ManagedObjectState state) throws Exception {
104: ByteArrayOutputStream bout = new ByteArrayOutputStream();
105: TCObjectOutputStream out = new TCObjectOutputStream(bout);
106: state.writeTo(out);
107: ByteArrayInputStream bin = new ByteArrayInputStream(bout
108: .toByteArray());
109: TCObjectInputStream in = new TCObjectInputStream(bin);
110: ManagedObjectState state2 = ManagedObjectStateFactory
111: .getInstance().readManagedObjectStateFrom(in, type);
112: Assert.assertTrue(state.equals(state2));
113: }
114:
115: public class TestDNAWriter implements DNAWriter {
116: private List physicalActions = new ArrayList();
117: private List logicalActions = new ArrayList();
118: private List literalActions = new ArrayList();
119:
120: public TestDNAWriter() {
121: //
122: }
123:
124: public void addLogicalAction(int method, Object[] parameters) {
125: logicalActions.add(new LogicalAction(method, parameters));
126: }
127:
128: public void addPhysicalAction(String field, Object value) {
129: addPhysicalAction(field, value, value instanceof ObjectID);
130: }
131:
132: public void finalizeDNA(boolean isDeltaDNA) {
133: //
134: }
135:
136: public void addArrayElementAction(int index, Object value) {
137: //
138: }
139:
140: public void addEntireArray(Object value) {
141: physicalActions.add(new PhysicalAction(value));
142: }
143:
144: public void addLiteralValue(Object value) {
145: literalActions.add(new LiteralAction(value));
146: }
147:
148: public void setParentObjectID(ObjectID id) {
149: //
150: }
151:
152: public void setArrayLength(int length) {
153: //
154: }
155:
156: public void addPhysicalAction(String fieldName, Object value,
157: boolean canBeReference) {
158: physicalActions.add(new PhysicalAction(fieldName, value,
159: canBeReference));
160: }
161:
162: public int getActionCount() {
163: return logicalActions.size() + physicalActions.size()
164: + literalActions.size();
165: }
166:
167: protected boolean containsAction(Object targetAction) {
168: if (targetAction instanceof LogicalAction) {
169: return containsLogicalAction((LogicalAction) targetAction);
170: } else if (targetAction instanceof PhysicalAction) {
171: return containsPhysicalAction((PhysicalAction) targetAction);
172: } else if (targetAction instanceof LiteralAction) {
173: return containsLiteralAction((LiteralAction) targetAction);
174: }
175:
176: return false;
177: }
178:
179: private boolean containsLogicalAction(LogicalAction targetAction) {
180: for (Iterator i = logicalActions.iterator(); i.hasNext();) {
181: LogicalAction action = (LogicalAction) i.next();
182: if (identicalLogicalAction(targetAction, action)) {
183: return true;
184: }
185: }
186: return false;
187: }
188:
189: private boolean containsPhysicalAction(
190: PhysicalAction targetAction) {
191: for (Iterator i = physicalActions.iterator(); i.hasNext();) {
192: PhysicalAction action = (PhysicalAction) i.next();
193: if (identicalPhysicalAction(targetAction, action)) {
194: return true;
195: }
196: }
197: return false;
198: }
199:
200: private boolean containsLiteralAction(LiteralAction targetAction) {
201: for (Iterator i = literalActions.iterator(); i.hasNext();) {
202: LiteralAction action = (LiteralAction) i.next();
203: if (identicalLiteralAction(targetAction, action)) {
204: return true;
205: }
206: }
207: return false;
208: }
209:
210: private boolean identicalLiteralAction(LiteralAction a1,
211: LiteralAction a2) {
212: if (a1 == null || a2 == null) {
213: return false;
214: }
215: if (a1.getObject() == null || a2.getObject() == null) {
216: return false;
217: }
218:
219: return a1.getObject().equals(a2.getObject());
220: }
221:
222: private boolean identicalPhysicalAction(PhysicalAction a1,
223: PhysicalAction a2) {
224: if (a1 == null || a2 == null) {
225: return false;
226: }
227:
228: if (!a1.isEntireArray() && !a2.isEntireArray()) {
229: if (a1.getFieldName() == null
230: || a2.getFieldName() == null) {
231: return false;
232: }
233: }
234:
235: if (a1.isEntireArray() != a2.isEntireArray()) {
236: return false;
237: }
238:
239: if (a1.getObject() == null && a2.getObject() == null) {
240: return true;
241: }
242: if (a1.getObject() == null && a2.getObject() != null) {
243: return false;
244: }
245: if (a1.getObject() != null && a2.getObject() == null) {
246: return false;
247: }
248:
249: if (a1.isEntireArray()) {
250: return Arrays.equals((Object[]) a1.getObject(),
251: (Object[]) a2.getObject());
252: } else if (a1.getObject() instanceof Object[]
253: && a2.getObject() instanceof Object[]) {
254: return Arrays.equals((Object[]) a1.getObject(),
255: (Object[]) a2.getObject());
256: } else {
257: if (a1.getFieldName().equals(a2.getFieldName())) {
258: return (a1.getObject().equals(a2.getObject()));
259: }
260: }
261: return false;
262: }
263:
264: private boolean identicalLogicalAction(LogicalAction a1,
265: LogicalAction a2) {
266: if (a1 == null || a2 == null) {
267: return false;
268: }
269: if (a1.getParameters() == null
270: || a2.getParameters() == null) {
271: return false;
272: }
273:
274: if (a1.getMethod() == a2.getMethod()) {
275: if (a1.getParameters().length == a2.getParameters().length) {
276: for (int i = 0; i < a1.getParameters().length; i++) {
277: if (!a1.getParameters()[i].equals(a2
278: .getParameters()[i])) {
279: return false;
280: }
281: }
282: return true;
283: }
284: }
285: return false;
286: }
287:
288: public void addClassLoaderAction(String classLoaderFieldName,
289: Object value) {
290: //
291:
292: }
293:
294: public void addSubArrayAction(int start, Object array,
295: int length) {
296: //
297: }
298: }
299:
300: public class TestDNACursor implements DNACursor {
301: private List actions = new ArrayList();
302: private int current = -1;
303:
304: public void addPhysicalAction(String addFieldName,
305: Object addObj, boolean isref) {
306: actions
307: .add(new PhysicalAction(addFieldName, addObj, isref));
308: }
309:
310: public void addLogicalAction(int method, Object params[]) {
311: actions.add(new LogicalAction(method, params));
312: }
313:
314: public void addArrayAction(Object[] objects) {
315: actions.add(new PhysicalAction(objects));
316: }
317:
318: public void addLiteralAction(Object value) {
319: actions.add(new LiteralAction(value));
320: }
321:
322: public boolean next() {
323: return actions.size() > ++current;
324: }
325:
326: public LogicalAction getLogicalAction() {
327: return (LogicalAction) actions.get(current);
328: }
329:
330: public Object getAction() {
331: return actions.get(current);
332: }
333:
334: public PhysicalAction getPhysicalAction() {
335: return (PhysicalAction) actions.get(current);
336: }
337:
338: public boolean next(DNAEncoding encoding) {
339: throw new ImplementMe();
340: }
341:
342: public int getActionCount() {
343: return actions.size();
344: }
345:
346: public void reset() throws UnsupportedOperationException {
347: current = -1;
348: }
349: }
350:
351: public interface MyProxyInf1 {
352: public int getValue();
353:
354: public void setValue(int i);
355: }
356:
357: public interface MyProxyInf2 {
358: public String getStringValue();
359:
360: public void setStringValue(String str);
361: }
362:
363: public static class MyInvocationHandler implements
364: InvocationHandler {
365: private Map values = new HashMap();
366: private Map stringValues = new HashMap();
367:
368: public Object invoke(Object proxy, Method method, Object[] args)
369: throws Throwable {
370: if (method.getName().equals("getValue")) {
371: return values.get(proxy);
372: } else if (method.getName().equals("setValue")) {
373: values.put(proxy, args[0]);
374: return null;
375: } else if (method.getName().equals("setStringValue")) {
376: stringValues.put(proxy, args[0]);
377: return null;
378: } else if (method.getName().equals("getStringValue")) {
379: return stringValues.get(proxy);
380: } else if (method.getName().equals("hashCode")) {
381: return new Integer(System.identityHashCode(proxy));
382: }
383: return null;
384: }
385: }
386: }
|