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