1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package javax.jdo.spi;
19
20 import java.lang.reflect.InvocationHandler;
21 import java.lang.reflect.Proxy;
22
23 import javax.jdo.JDOHelper;
24 import javax.jdo.PersistenceManager;
25
26 import javax.jdo.util.AbstractTest;
27 import javax.jdo.util.BatchTestRunner;
28
29 /**
30 * This class tests the StateInterrogation interface. The test is in
31 * several parts:
32 * <ul><li> Add and remove the StateInterrogation instance
33 * </li><li> test interrogatives to return the correct answer
34 * </li><li> test getters to return the correct answer
35 * </li><li> test makeDirty to return.
36 * </li></ul>
37 * We use an mock implementation of StateInterrogation interface to
38 * log when calls are received and to return the correct replies.
39 * We use a java.lang.reflect.Proxy for the getPersistenceManager call
40 * because it's too much work to mock it.
41 */
42 public class StateInterrogationTest extends AbstractTest {
43
44 private JDOImplHelper implHelper = JDOImplHelper.getInstance();
45
46 private JDOHelper helper = new JDOHelper();
47
48 /** Creates a new instance of StateInterrogationTest */
49 public StateInterrogationTest() {
50 }
51
52 /**
53 * @param args the command line arguments
54 */
55 public static void main(String[] args) {
56 BatchTestRunner.run(StateInterrogationTest.class);
57 }
58
59 public void testGetObjectIdNull() {
60 Object id2 = helper.getObjectId(nbcpc2);
61 assertNull("ObjectId should be null before addStateInterrogations",
62 id2);
63 addStateInterrogations();
64 Object id = helper.getObjectId(Boolean.TRUE);
65 assertNull("ObjectId should be null for non-pc instances",
66 id);
67 }
68
69 public void testGetObjectId() {
70 addStateInterrogations();
71 Object id2 = helper.getObjectId(nbcpc2);
72 assertNotNull("ObjectId should not be null",
73 id2);
74 assertEquals("ObjectId should be 2",
75 2, id2.hashCode());
76 Object id20 = helper.getObjectId(nbcpc2);
77 assertEquals("ObjectIds from same object should be equal",
78 id2, id20);
79 }
80
81 public void testRemoveStateInterrogation() {
82 addStateInterrogations();
83 Object id2 = helper.getObjectId(nbcpc2);
84 assertNotNull("ObjectId should not be null",
85 id2);
86 assertEquals("ObjectId should be 2",
87 2, id2.hashCode());
88 implHelper.removeStateInterrogation(si2);
89 implHelper.removeStateInterrogation(si0);
90 Object id21 = helper.getObjectId(nbcpc2);
91 assertNull("ObjectId should be null after RemoveStateInterrogation",
92 id21);
93 Object id1 = helper.getObjectId(nbcpc1);
94 assertNotNull("ObjectId should not be null",
95 id1);
96 assertEquals("ObjectId should be 1",
97 1, id1.hashCode());
98 }
99
100 public void testGetTransactionalObjectIdNull() {
101 Object id2 = helper.getTransactionalObjectId(nbcpc2);
102 assertNull("TransactionalObjectId should be null before addStateInterrogations",
103 id2);
104 addStateInterrogations();
105 Object id = helper.getTransactionalObjectId(Boolean.TRUE);
106 assertNull("TransactionalObjectId should be null for non-pc instances",
107 id);
108 }
109
110 public void testGetTransactionalObjectId() {
111 addStateInterrogations();
112 Object id2 = helper.getTransactionalObjectId(nbcpc2);
113 assertNotNull("TransactionalObjectId should not be null",
114 id2);
115 assertEquals("TransactionalObjectId should be 2",
116 2, id2.hashCode());
117 Object id20 = helper.getTransactionalObjectId(nbcpc2);
118 assertEquals("TransactionalObjectIds from same object should be equal",
119 id2, id20);
120 }
121
122 public void testGetPersistenceManagerNull() {
123 Object pm2 = helper.getPersistenceManager(nbcpc2);
124 assertNull("PersistenceManager should be null before addStateInterrogations",
125 pm2);
126 addStateInterrogations();
127 Object pm = helper.getPersistenceManager(Boolean.TRUE);
128 assertNull("PersistenceManager should be null for non-pc instances",
129 pm);
130 }
131
132 public void testGetPersistenceManager() {
133 addStateInterrogations();
134 Object pm2 = helper.getPersistenceManager(nbcpc2);
135 assertNotNull("PersistenceManager should not be null",
136 pm2);
137 assertEquals("PersistenceManager should be 2",
138 2, pm2.hashCode());
139 Object pm20 = helper.getPersistenceManager(nbcpc2);
140 assertEquals("PersistenceManagers from same object should be equal",
141 pm2, pm20);
142 }
143
144 public void testGetVersionNull() {
145 Object id2 = helper.getVersion(nbcpc2);
146 assertNull("Version should be null before addStateInterrogations",
147 id2);
148 addStateInterrogations();
149 Object id = helper.getVersion(Boolean.TRUE);
150 assertNull("Version should be null for non-pc instances",
151 id);
152 }
153
154 public void testGetVersion() {
155 addStateInterrogations();
156 Object id2 = helper.getVersion(nbcpc2);
157 assertNotNull("Version should not be null",
158 id2);
159 assertEquals("Version should be 2",
160 2, id2.hashCode());
161 Object id20 = helper.getVersion(nbcpc2);
162 assertEquals("Versions from same object should be equal",
163 id2, id20);
164 }
165
166 public void testIsDeletedFalse() {
167 assertFalse("IsDeleted should be false before addStateInterrogations",
168 helper.isDeleted(nbcpc2));
169 addStateInterrogations();
170 assertFalse("IsDeleted should be false for non-pc instances",
171 helper.isDeleted(Boolean.TRUE));
172 implHelper.removeStateInterrogation(si2);
173 assertFalse("IsDeleted should be false after removeStateInterrogations",
174 helper.isDeleted(nbcpc2));
175 }
176
177 public void testIsDeletedMine() {
178 addStateInterrogations();
179 assertTrue("IsDeleted should be true for nbcpc1",
180 helper.isDeleted(nbcpc1));
181 assertFalse("IsDeleted should be false for nbcpc2",
182 helper.isDeleted(nbcpc2));
183 }
184
185 public void testIsDetachedFalse() {
186 assertFalse("IsDetached should be false before addStateInterrogations",
187 helper.isDetached(nbcpc2));
188 addStateInterrogations();
189 assertFalse("IsDetached should be false for non-pc instances",
190 helper.isDetached(Boolean.TRUE));
191 implHelper.removeStateInterrogation(si2);
192 assertFalse("IsDetached should be false after removeStateInterrogations",
193 helper.isDetached(nbcpc2));
194 }
195
196 public void testIsDetachedMine() {
197 addStateInterrogations();
198 assertTrue("IsDetached should be true for nbcpc1",
199 helper.isDetached(nbcpc1));
200 assertFalse("IsDetached should be false for nbcpc2",
201 helper.isDetached(nbcpc2));
202 }
203
204 public void testIsDirtyFalse() {
205 assertFalse("IsDirty should be false before addStateInterrogations",
206 helper.isDirty(nbcpc2));
207 addStateInterrogations();
208 assertFalse("IsDirty should be false for non-pc instances",
209 helper.isDirty(Boolean.TRUE));
210 implHelper.removeStateInterrogation(si2);
211 nbcpc2.setDirty(true);
212 assertFalse("IsDirty should be false after removeStateInterrogations",
213 helper.isDirty(nbcpc2));
214 nbcpc2.setDirty(false);
215 }
216
217 public void testIsDirtyMine() {
218 addStateInterrogations();
219 nbcpc1.setDirty(true);
220 assertTrue("IsDirty should be true for nbcpc1 after setDirty(true)",
221 helper.isDirty(nbcpc1));
222 nbcpc1.setDirty(false);
223 assertFalse("IsDirty should be false for nbcpc1 after setDirty(false)",
224 helper.isDirty(nbcpc1));
225 assertFalse("IsDirty should be false for nbcpc2",
226 helper.isDirty(nbcpc2));
227 }
228
229 public void testIsNewFalse() {
230 assertFalse("IsNew should be false before addStateInterrogations",
231 helper.isNew(nbcpc2));
232 addStateInterrogations();
233 assertFalse("IsNew should be false for non-pc instances",
234 helper.isNew(Boolean.TRUE));
235 implHelper.removeStateInterrogation(si2);
236 assertFalse("IsNew should be false after removeStateInterrogations",
237 helper.isNew(nbcpc2));
238 }
239
240 public void testIsNewMine() {
241 addStateInterrogations();
242 assertTrue("IsNew should be true for nbcpc1",
243 helper.isNew(nbcpc1));
244 assertFalse("IsNew should be false for nbcpc2",
245 helper.isNew(nbcpc2));
246 }
247
248 public void testIsPersistentFalse() {
249 assertFalse("IsPersistent should be false before addStateInterrogations",
250 helper.isPersistent(nbcpc2));
251 addStateInterrogations();
252 assertFalse("IsPersistent should be false for non-pc instances",
253 helper.isPersistent(Boolean.TRUE));
254 implHelper.removeStateInterrogation(si2);
255 assertFalse("IsPersistent should be false after removeStateInterrogations",
256 helper.isPersistent(nbcpc2));
257 }
258
259 public void testIsPersistentMine() {
260 addStateInterrogations();
261 assertTrue("IsPersistent should be true for nbcpc1",
262 helper.isPersistent(nbcpc1));
263 assertFalse("IsPersistent should be false for nbcpc2",
264 helper.isPersistent(nbcpc2));
265 }
266
267 public void testIsTransactionalFalse() {
268 assertFalse("IsTransactional should be false before addStateInterrogations",
269 helper.isTransactional(nbcpc2));
270 addStateInterrogations();
271 assertFalse("IsTransactional should be false for non-pc instances",
272 helper.isTransactional(Boolean.TRUE));
273 implHelper.removeStateInterrogation(si2);
274 assertFalse("IsTransactional should be false after removeStateInterrogations",
275 helper.isTransactional(nbcpc2));
276 }
277
278 public void testIsTransactionalMine() {
279 addStateInterrogations();
280 assertTrue("IsTransactional should be true for nbcpc1",
281 helper.isTransactional(nbcpc1));
282 assertFalse("IsTransactional should be false for nbcpc2",
283 helper.isTransactional(nbcpc2));
284 }
285
286 public void testMakeDirtyFalse() {
287 helper.makeDirty(nbcpc2, "");
288 nbcpc2.setDirty(true);
289 assertFalse("IsDirty should be false before addStateInterrogations",
290 helper.isDirty(nbcpc2));
291 addStateInterrogations();
292 implHelper.removeStateInterrogation(si2);
293 nbcpc2.setDirty(false);
294 helper.makeDirty(nbcpc2, "");
295 assertFalse("IsDirty should be false after removeStateInterrogations",
296 helper.isDirty(nbcpc2));
297 }
298
299 public void testMakeDirtyMine() {
300 addStateInterrogations();
301 helper.makeDirty(nbcpc1, "");
302 assertTrue("IsDirty should be true for nbcpc1",
303 helper.isDirty(nbcpc1));
304 nbcpc1.setDirty(false);
305 assertFalse("IsDirty should be false after setDirty(false)",
306 helper.isDirty(nbcpc1));
307 }
308
309 public void tearDown() {
310 removeStateInterrogations();
311 }
312
313 public void addStateInterrogations() {
314 implHelper.addStateInterrogation(si0);
315 implHelper.addStateInterrogation(si1);
316 implHelper.addStateInterrogation(si2);
317 }
318
319 public void removeStateInterrogations() {
320 implHelper.removeStateInterrogation(si0);
321 implHelper.removeStateInterrogation(si1);
322 implHelper.removeStateInterrogation(si2);
323 }
324
325 /**
326 * The non-binary-compatible PersistenceManager class instances.
327 */
328 static private PersistenceManager pmProxy0 = (PersistenceManager)
329 Proxy.newProxyInstance(
330 PersistenceManager.class.getClassLoader(),
331 new Class[] {PersistenceManager.class},
332 new InvocationHandlerImpl(0));
333
334 /**
335 * The non-binary-compatible PersistenceManager class instances.
336 */
337 static private PersistenceManager pmProxy1 = (PersistenceManager)
338 Proxy.newProxyInstance(
339 PersistenceManager.class.getClassLoader(),
340 new Class[] {PersistenceManager.class},
341 new InvocationHandlerImpl(1));
342
343 /**
344 * The non-binary-compatible PersistenceManager class instances.
345 */
346 static private PersistenceManager pmProxy2 = (PersistenceManager)
347 Proxy.newProxyInstance(
348 PersistenceManager.class.getClassLoader(),
349 new Class[] {PersistenceManager.class},
350 new InvocationHandlerImpl(2));
351
352 /**
353 * The array of PersistenceManager proxies
354 */
355 static PersistenceManager[] pmProxies = {pmProxy0, pmProxy1, pmProxy2};
356
357 /**
358 * The array of NonBinaryCompatiblePersistenceCapable instances.
359 */
360 NonBinaryCompatiblePersistenceCapable nbcpc0 =
361 new NonBinaryCompatiblePersistenceCapable(0);
362 NonBinaryCompatiblePersistenceCapable nbcpc1 =
363 new NonBinaryCompatiblePersistenceCapable(1);
364 NonBinaryCompatiblePersistenceCapable nbcpc2 =
365 new NonBinaryCompatiblePersistenceCapable(2);
366
367 NonBinaryCompatiblePersistenceCapable[] nbcpcs = {nbcpc0, nbcpc1, nbcpc2};
368
369 /**
370 * The array of StateInterrogations
371 */
372 static StateInterrogation si0 = new StateInterrogationImpl(0);
373 static StateInterrogation si1 = new StateInterrogationImpl(1);
374 static StateInterrogation si2 = new StateInterrogationImpl(2);
375 static StateInterrogation[] sis = {si0, si1, si2};
376
377 /**
378 * The StateInterrogation implementation manages
379 * NonBinaryCompatiblePersistenceCapable instances that have a
380 * hashCode equal to their own.
381 *
382 * <P>For the methods returning Object, return null if the object
383 * is not managed by this StateInterrogation.
384 *
385 * <P>For the methods returning Boolean, return null if the object
386 * is not managed by this StateInterrogation.
387 *
388 * <P>For the makeDirty method, return false if the object
389 * is not managed by this StateInterrogation.
390 */
391 private static class StateInterrogationImpl implements StateInterrogation {
392
393 private int id;
394
395 public int hashCode() {
396 return id;
397 }
398
399 private StateInterrogationImpl(int id) {
400 this.id = id;
401 }
402
403 public boolean equals(Object other) {
404 if (other.getClass() != StateInterrogationImpl.class) return false;
405 return (other.hashCode() == id);
406 }
407
408 private boolean isMine(Object pc) {
409 return pc.hashCode() == id;
410 }
411
412 public javax.jdo.PersistenceManager getPersistenceManager(Object pc) {
413 return isMine(pc)?pmProxies[id]:null;
414 }
415
416 public Object getObjectId(Object pc) {
417 return isMine(pc)?new ObjectIdImpl(id):null;
418 }
419
420 public Object getTransactionalObjectId(Object pc) {
421 return isMine(pc)?new ObjectIdImpl(id):null;
422 }
423
424 public Object getVersion(Object pc) {
425 return isMine(pc)?new ObjectIdImpl(id):null;
426 }
427
428 public Boolean isDeleted(Object pc) {
429 if (isMine(pc)) {
430 return (pc.hashCode()==1)?Boolean.TRUE:Boolean.FALSE;
431 } else return null;
432 }
433
434 public Boolean isDetached(Object pc) {
435 if (isMine(pc)) {
436 return (pc.hashCode()==1)?Boolean.TRUE:Boolean.FALSE;
437 } else return null;
438 }
439
440 public Boolean isDirty(Object pc) {
441 if (isMine(pc)) {
442 return ((NonBinaryCompatiblePersistenceCapable)pc).isDirty()
443 ?Boolean.TRUE:Boolean.FALSE;
444 } else return null;
445 }
446
447 public Boolean isNew(Object pc) {
448 if (isMine(pc)) {
449 return (pc.hashCode()==1)?Boolean.TRUE:Boolean.FALSE;
450 } else return null;
451 }
452
453 public Boolean isPersistent(Object pc) {
454 if (isMine(pc)) {
455 return (pc.hashCode()==1)?Boolean.TRUE:Boolean.FALSE;
456 } else return null;
457 }
458
459 public Boolean isTransactional(Object pc) {
460 if (isMine(pc)) {
461 return (pc.hashCode()==1)?Boolean.TRUE:Boolean.FALSE;
462 } else return null;
463 }
464
465 public boolean makeDirty(Object pc, String fieldName) {
466 if (isMine(pc)) {
467 ((NonBinaryCompatiblePersistenceCapable)pc).setDirty(true);
468 return true;
469 } else return false;
470 }
471 }
472
473 /**
474 * The non-binary-compatible PersistenceCapable class.
475 */
476 public static class NonBinaryCompatiblePersistenceCapable {
477 private int id;
478 private boolean dirty = false;
479 private NonBinaryCompatiblePersistenceCapable(int id) {
480 this.id = id;
481 }
482 public int hashCode() {
483 return id;
484 }
485 public void setDirty(boolean dirty) {
486 this.dirty = dirty;
487 }
488 public boolean isDirty() {
489 return dirty;
490 }
491 }
492
493 /**
494 * The non-binary-compatible object id class.
495 */
496 public static class ObjectIdImpl {
497 private int id;
498 private ObjectIdImpl(int id) {
499 this.id = id;
500 }
501 public int hashCode() {
502 return id;
503 }
504 public boolean equals(Object other) {
505 if (other.getClass() != ObjectIdImpl.class) return false;
506 return (other.hashCode() == id);
507 }
508 }
509
510 /**
511 * The non-binary-compatible InvocationHandler class
512 * for PersistenceManager proxy.
513 */
514 private static class InvocationHandlerImpl implements InvocationHandler {
515 private int id;
516 private InvocationHandlerImpl(int id) {
517 this.id = id;
518 }
519 public int hashCode() {
520 return id;
521 }
522 public boolean equals(Object other) {
523 if (other.getClass() != ObjectIdImpl.class) return false;
524 return (other.hashCode() == id);
525 }
526 public Object invoke(Object obj, java.lang.reflect.Method method,
527 Object[] params) throws Throwable {
528 String name = method.getName();
529 if (name == "hashCode") {
530 return new Integer(id);
531 } else if (name == "equals") {
532 Object other = params[0];
533 if (!(other instanceof PersistenceManager)) return Boolean.FALSE;
534 int otherid = Proxy.getInvocationHandler(other).hashCode();
535 if (otherid == id) return Boolean.TRUE;
536 return Boolean.FALSE;
537 }
538 return null;
539 }
540 }
541 }