1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software 
12   * distributed under the License is distributed on an "AS IS" BASIS, 
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
14   * See the License for the specific language governing permissions and 
15   * limitations under the License.
16   */
17  
18  /*
19   * ObjectIdentityTest.java
20   *
21   */
22  
23  package javax.jdo.identity;
24  
25  import java.lang.reflect.Constructor;
26  import java.lang.reflect.InvocationTargetException;
27  
28  import java.io.Serializable;
29  
30  import java.math.BigDecimal;
31  
32  import java.security.AccessController;
33  import java.security.PrivilegedAction;
34  
35  import java.text.SimpleDateFormat;
36  import java.text.DateFormat;
37  
38  import java.util.Currency;
39  import java.util.Date;
40  import java.util.Locale;
41  
42  import javax.jdo.JDOUserException;
43  import javax.jdo.JDONullIdentityException;
44  
45  import javax.jdo.spi.JDOImplHelper;
46  
47  import javax.jdo.util.BatchTestRunner;
48  
49  /**
50   *
51   */
52  public class ObjectIdentityTest extends SingleFieldIdentityTest {
53      
54      /** The JDOImplHelper instance used for Date formatting.
55       */
56      private static JDOImplHelper helper = (JDOImplHelper)
57          AccessController.doPrivileged(
58              new PrivilegedAction<JDOImplHelper> () {
59                  public JDOImplHelper run () {
60                      return JDOImplHelper.getInstance();
61                  }
62              }
63          );
64      
65      /** Creates a new instance of ObjectIdentityTest */
66      public ObjectIdentityTest() {
67      }
68      
69      /**
70       * @param args the command line arguments
71       */
72      public static void main(String[] args) {
73          BatchTestRunner.run(ObjectIdentityTest.class);
74      }
75      
76      public void testConstructor() {
77          ObjectIdentity c1 = new ObjectIdentity(Object.class, new IdClass(1));
78          ObjectIdentity c2 = new ObjectIdentity(Object.class, new IdClass(1));
79          ObjectIdentity c3 = new ObjectIdentity(Object.class, new IdClass(2));
80          assertEquals("Equal ObjectIdentity instances compare not equal.", c1, c2);
81          assertFalse ("Not equal ObjectIdentity instances compare equal", c1.equals(c3));
82      }
83      
84      public void testIntegerConstructor() {
85          ObjectIdentity c1 = new ObjectIdentity(Object.class, new Integer(1));
86          ObjectIdentity c2 = new ObjectIdentity(Object.class, new Integer(1));
87          ObjectIdentity c3 = new ObjectIdentity(Object.class, new Integer(2));
88          assertEquals("Equal ObjectIdentity instances compare not equal.", c1, c2);
89          assertFalse ("Not equal ObjectIdentity instances compare equal", c1.equals(c3));
90      }
91      
92      public void testLongConstructor() {
93          ObjectIdentity c1 = new ObjectIdentity(Object.class, new Long(1));
94          ObjectIdentity c2 = new ObjectIdentity(Object.class, new Long(1));
95          ObjectIdentity c3 = new ObjectIdentity(Object.class, new Long(2));
96          assertEquals("Equal ObjectIdentity instances compare not equal.", c1, c2);
97          assertFalse ("Not equal ObjectIdentity instances compare equal", c1.equals(c3));
98      }
99      
100     public void testDateConstructor() {
101         ObjectIdentity c1 = new ObjectIdentity(Object.class, new Date(1));
102         ObjectIdentity c2 = new ObjectIdentity(Object.class, new Date(1));
103         ObjectIdentity c3 = new ObjectIdentity(Object.class, new Date(2));
104         assertEquals("Equal ObjectIdentity instances compare not equal.", c1, c2);
105         assertFalse ("Not equal ObjectIdentity instances compare equal", c1.equals(c3));
106     }
107     
108     public void testLocaleConstructor() {
109         ObjectIdentity c1 = new ObjectIdentity(Object.class, Locale.US);
110         ObjectIdentity c2 = new ObjectIdentity(Object.class, Locale.US);
111         ObjectIdentity c3 = new ObjectIdentity(Object.class, Locale.GERMANY);
112         assertEquals("Equal ObjectIdentity instances compare not equal.", c1, c2);
113         assertFalse ("Not equal ObjectIdentity instances compare equal", c1.equals(c3));
114     }
115     
116     public void testCurrencyConstructor() {
117         if (!isClassLoadable("java.util.Currency")) return;
118         ObjectIdentity c1 = new ObjectIdentity(Object.class, 
119                 Currency.getInstance(Locale.US));
120         ObjectIdentity c2 = new ObjectIdentity(Object.class, 
121                 Currency.getInstance(Locale.US));
122         ObjectIdentity c3 = new ObjectIdentity(Object.class, 
123                 Currency.getInstance(Locale.GERMANY));
124         assertEquals("Equal ObjectIdentity instances compare not equal.", c1, c2);
125         assertFalse ("Not equal ObjectIdentity instances compare equal", c1.equals(c3));
126     }
127     
128     public void testStringConstructor() {
129         ObjectIdentity c1 = new ObjectIdentity(Object.class, 
130                 "javax.jdo.identity.ObjectIdentityTest$IdClass:1");        
131         ObjectIdentity c2 = new ObjectIdentity(Object.class, 
132                 "javax.jdo.identity.ObjectIdentityTest$IdClass:1");        
133         ObjectIdentity c3 = new ObjectIdentity(Object.class, 
134                 "javax.jdo.identity.ObjectIdentityTest$IdClass:2");        
135         assertEquals("Equal ObjectIdentity instances compare not equal.", c1, c2);
136         assertFalse ("Not equal ObjectIdentity instances compare equal", c1.equals(c3));
137     }
138     
139     public void testToStringConstructor() {
140         ObjectIdentity c1 = new ObjectIdentity(Object.class, new IdClass(1));
141         ObjectIdentity c2 = new ObjectIdentity(Object.class, c1.toString());
142         assertEquals ("Equal ObjectIdentity instances compare not equal.", c1, c2);
143     }
144 
145     public void testDateCompareTo() {
146     	ObjectIdentity c1 = new ObjectIdentity(Object.class, new Date(1));
147     	ObjectIdentity c2 = new ObjectIdentity(Object.class, new Date(1));
148     	ObjectIdentity c3 = new ObjectIdentity(Object.class, new Date(2));
149         ObjectIdentity c4 = new ObjectIdentity(Class.class, new Date(1));
150         assertEquals("Equal ObjectIdentity instances compare not equal.", 0, c1.compareTo(c2));
151         assertTrue("Not equal ObjectIdentity instances have wrong compareTo result", c1.compareTo(c3) < 0);
152         assertTrue("Not equal ObjectIdentity instances have wrong compareTo result", c3.compareTo(c1) > 0); 
153         assertTrue("Not equal ObjectIdentity instances have wrong compareTo result", c1.compareTo(c4) > 0);
154     }
155 
156     public void testBadStringConstructorNullClass() {
157         try {
158             ObjectIdentity c1 = new ObjectIdentity(null, "1");
159         } catch (NullPointerException ex) {
160             return;
161         }
162         fail ("Failed to catch expected exception.");
163     }
164     
165     public void testBadStringConstructorNullParam() {
166         try {
167             ObjectIdentity c1 = new ObjectIdentity(Object.class, null);
168         } catch (JDONullIdentityException ex) {
169             return;
170         }
171         fail ("Failed to catch expected exception.");
172     }
173     
174     public void testBadStringConstructorTooShort() {
175         try {
176             ObjectIdentity c1 = new ObjectIdentity(Object.class, "xx");
177         } catch (JDOUserException ex) {
178             return;
179         }
180         fail ("Failed to catch expected exception.");
181     }
182     
183     public void testBadStringConstructorNoDelimiter() {
184         try {
185             ObjectIdentity c1 = new ObjectIdentity(Object.class, "xxxxxxxxx");
186         } catch (JDOUserException ex) {
187             return;
188         }
189         fail ("Failed to catch expected exception.");
190     }
191     
192     public void testBadStringConstructorBadClassName() {
193         try {
194             ObjectIdentity c1 = new ObjectIdentity(Object.class, "xx:yy");
195         } catch (JDOUserException ex) {
196             validateNestedException(ex, ClassNotFoundException.class);
197             return;
198         }
199         fail ("Failed to catch expected ClassNotFoundException.");
200     }
201     
202     public void testBadStringConstructorNoStringConstructor() {
203         try {
204             ObjectIdentity c1 = new ObjectIdentity(Object.class, 
205                     "javax.jdo.identity.ObjectIdentityTest$BadIdClassNoStringConstructor:yy");
206         } catch (JDOUserException ex) {
207             validateNestedException(ex, NoSuchMethodException.class);
208             return;
209         }
210         fail ("Failed to catch expected NoSuchMethodException.");
211     }
212     
213     public void testBadStringConstructorNoPublicStringConstructor() {
214         try {
215             ObjectIdentity c1 = new ObjectIdentity(Object.class, 
216                     "javax.jdo.identity.ObjectIdentityTest$BadIdClassNoPublicStringConstructor:yy");
217         } catch (JDOUserException ex) {
218             validateNestedException(ex, NoSuchMethodException.class);
219             return;
220         }
221         fail ("Failed to catch expected NoSuchMethodException.");
222     }
223     
224     public void testBadStringConstructorIllegalArgument() {
225         try {
226             ObjectIdentity c1 = new ObjectIdentity(Object.class, 
227                     "javax.jdo.identity.ObjectIdentityTest$IdClass:yy");
228         } catch (JDOUserException ex) {
229             validateNestedException(ex, InvocationTargetException.class);
230             return;
231         }
232         fail ("Failed to catch expected InvocationTargetException.");
233     }
234 
235     public void testStringDateConstructor() {
236         SimpleDateFormat usDateFormat = new SimpleDateFormat
237                 ("MMM dd, yyyy hh:mm:ss a", Locale.US);
238         helper.registerDateFormat(usDateFormat);
239         Object c1 = new ObjectIdentity(Object.class, 
240             "java.util.Date:Jan 01, 1970 00:00:00 AM");
241         helper.registerDateFormat(DateFormat.getDateTimeInstance());
242     }
243 
244     public void testStringDefaultDateConstructor() {
245         DateFormat dateFormat = DateFormat.getDateTimeInstance();
246         String rightNow = dateFormat.format(new Date());
247         Object c1 = new ObjectIdentity(Object.class, 
248             "java.util.Date:" + rightNow);
249     }
250 
251     public void testBadStringDateConstructor() {
252         try {
253             ObjectIdentity c1 = new ObjectIdentity(Object.class, 
254                 "java.util.Date:Jop 1, 1970 00:00:00");
255         } catch (JDOUserException ex) {
256             return;
257         }
258         fail ("Failed to catch expected Exception.");
259     }
260 
261     public void testStringLocaleConstructorLanguage() {
262         if (!isClassLoadable("java.util.Currency")) return;
263         SingleFieldIdentity c1 = new ObjectIdentity(Object.class, 
264                     "java.util.Locale:en");
265         assertEquals(new Locale("en"), c1.getKeyAsObject());
266     }
267 
268     public void testStringLocaleConstructorCountry() {
269         SingleFieldIdentity c1 = new ObjectIdentity(Object.class, 
270                     "java.util.Locale:_US");
271         assertEquals(new Locale("","US"), c1.getKeyAsObject());
272     }
273 
274     public void testStringLocaleConstructorLanguageCountry() {
275         SingleFieldIdentity c1 = new ObjectIdentity(Object.class, 
276                     "java.util.Locale:en_US");
277         assertEquals(new Locale("en","US"), c1.getKeyAsObject());
278     }
279 
280     public void testStringLocaleConstructorLanguageCountryVariant() {
281         SingleFieldIdentity c1 = new ObjectIdentity(Object.class, 
282                     "java.util.Locale:en_US_MAC");
283         assertEquals(new Locale("en","US","MAC"), c1.getKeyAsObject());
284     }
285 
286     public void testStringCurrencyConstructor() {
287         if (!isClassLoadable("java.util.Currency")) return;
288         SingleFieldIdentity c1 = new ObjectIdentity(Object.class, 
289                     "java.util.Currency:USD");
290     }
291 
292     public void testBadStringCurrencyConstructor() {
293         if (!isClassLoadable("java.util.Currency")) return;
294         try {
295             ObjectIdentity c1 = new ObjectIdentity(Object.class, 
296                     "java.util.Currency:NowhereInTheWorld");
297         } catch (JDOUserException ex) {
298             validateNestedException(ex, IllegalArgumentException.class);
299             return;
300         }
301         fail ("Failed to catch expected IllegalArgumentException.");
302     }
303 
304     public void testSerializedIdClass() {
305         ObjectIdentity c1 = new ObjectIdentity(Object.class, new IdClass(1));
306         ObjectIdentity c2 = new ObjectIdentity(Object.class, new IdClass(1));
307         ObjectIdentity c3 = new ObjectIdentity(Object.class, new IdClass(2));
308         Object[] scis = writeReadSerialized(new Object[] {c1, c2, c3});
309         Object sc1 = scis[0];
310         Object sc2 = scis[1];
311         Object sc3 = scis[2];
312         assertEquals ("Equal ObjectIdentity instances compare not equal.", c1, sc1);
313         assertEquals ("Equal ObjectIdentity instances compare not equal.", c2, sc2);
314         assertEquals ("Equal ObjectIdentity instances compare not equal.", sc1, c2);
315         assertEquals ("Equal ObjectIdentity instances compare not equal.", sc2, c1);
316         assertFalse ("Not equal ObjectIdentity instances compare equal.", c1.equals(sc3));
317         assertFalse ("Not equal ObjectIdentity instances compare equal.", sc1.equals(c3));
318         assertFalse ("Not equal ObjectIdentity instances compare equal.", sc1.equals(sc3));
319         assertFalse ("Not equal ObjectIdentity instances compare equal.", sc3.equals(sc1));
320     }
321     
322     public void testSerializedBigDecimal() {
323         ObjectIdentity c1 = new ObjectIdentity(Object.class, new BigDecimal("123456789.012"));
324         ObjectIdentity c2 = new ObjectIdentity(Object.class, new BigDecimal("123456789.012"));
325         ObjectIdentity c3 = new ObjectIdentity(Object.class, new BigDecimal("123456789.01"));
326         Object[] scis = writeReadSerialized(new Object[] {c1, c2, c3});
327         Object sc1 = scis[0];
328         Object sc2 = scis[1];
329         Object sc3 = scis[2];
330         assertEquals ("Equal ObjectIdentity instances compare not equal.", c1, sc1);
331         assertEquals ("Equal ObjectIdentity instances compare not equal.", c2, sc2);
332         assertEquals ("Equal ObjectIdentity instances compare not equal.", sc1, c2);
333         assertEquals ("Equal ObjectIdentity instances compare not equal.", sc2, c1);
334         assertFalse ("Not equal ObjectIdentity instances compare equal.", c1.equals(sc3));
335         assertFalse ("Not equal ObjectIdentity instances compare equal.", sc1.equals(c3));
336         assertFalse ("Not equal ObjectIdentity instances compare equal.", sc1.equals(sc3));
337         assertFalse ("Not equal ObjectIdentity instances compare equal.", sc3.equals(sc1));
338     }
339     
340     public void testSerializedCurrency() {
341         if (!isClassLoadable("java.util.Currency")) return;
342         ObjectIdentity c1 = new ObjectIdentity(Object.class, Currency.getInstance(Locale.US));
343         ObjectIdentity c2 = new ObjectIdentity(Object.class, Currency.getInstance(Locale.US));
344         ObjectIdentity c3 = new ObjectIdentity(Object.class, Currency.getInstance(Locale.GERMANY));
345         Object[] scis = writeReadSerialized(new Object[] {c1, c2, c3});
346         Object sc1 = scis[0];
347         Object sc2 = scis[1];
348         Object sc3 = scis[2];
349         assertEquals ("Equal ObjectIdentity instances compare not equal.", c1, sc1);
350         assertEquals ("Equal ObjectIdentity instances compare not equal.", c2, sc2);
351         assertEquals ("Equal ObjectIdentity instances compare not equal.", sc1, c2);
352         assertEquals ("Equal ObjectIdentity instances compare not equal.", sc2, c1);
353         assertFalse ("Not equal ObjectIdentity instances compare equal.", c1.equals(sc3));
354         assertFalse ("Not equal ObjectIdentity instances compare equal.", sc1.equals(c3));
355         assertFalse ("Not equal ObjectIdentity instances compare equal.", sc1.equals(sc3));
356         assertFalse ("Not equal ObjectIdentity instances compare equal.", sc3.equals(sc1));
357     }
358     
359     public void testSerializedDate() {
360         ObjectIdentity c1 = new ObjectIdentity(Object.class, new Date(1));
361         ObjectIdentity c2 = new ObjectIdentity(Object.class, "java.util.Date:1");
362         ObjectIdentity c3 = new ObjectIdentity(Object.class, new Date(2));
363         Object[] scis = writeReadSerialized(new Object[] {c1, c2, c3});
364         Object sc1 = scis[0];
365         Object sc2 = scis[1];
366         Object sc3 = scis[2];
367         assertEquals ("Equal ObjectIdentity instances compare not equal.", c1, sc1);
368         assertEquals ("Equal ObjectIdentity instances compare not equal.", c2, sc2);
369         assertEquals ("Equal ObjectIdentity instances compare not equal.", sc1, c2);
370         assertEquals ("Equal ObjectIdentity instances compare not equal.", sc2, c1);
371         assertFalse ("Not equal ObjectIdentity instances compare equal.", c1.equals(sc3));
372         assertFalse ("Not equal ObjectIdentity instances compare equal.", sc1.equals(c3));
373         assertFalse ("Not equal ObjectIdentity instances compare equal.", sc1.equals(sc3));
374         assertFalse ("Not equal ObjectIdentity instances compare equal.", sc3.equals(sc1));
375     }
376     
377     public void testSerializedLocale() {
378         ObjectIdentity c1 = new ObjectIdentity(Object.class, Locale.US);
379         ObjectIdentity c2 = new ObjectIdentity(Object.class, Locale.US);
380         ObjectIdentity c3 = new ObjectIdentity(Object.class, Locale.GERMANY);
381         Object[] scis = writeReadSerialized(new Object[] {c1, c2, c3});
382         Object sc1 = scis[0];
383         Object sc2 = scis[1];
384         Object sc3 = scis[2];
385         assertEquals ("Equal ObjectIdentity instances compare not equal.", c1, sc1);
386         assertEquals ("Equal ObjectIdentity instances compare not equal.", c2, sc2);
387         assertEquals ("Equal ObjectIdentity instances compare not equal.", sc1, c2);
388         assertEquals ("Equal ObjectIdentity instances compare not equal.", sc2, c1);
389         assertFalse ("Not equal ObjectIdentity instances compare equal.", c1.equals(sc3));
390         assertFalse ("Not equal ObjectIdentity instances compare equal.", sc1.equals(c3));
391         assertFalse ("Not equal ObjectIdentity instances compare equal.", sc1.equals(sc3));
392         assertFalse ("Not equal ObjectIdentity instances compare equal.", sc3.equals(sc1));
393     }
394     
395     public void testGetKeyAsObject() {
396         ObjectIdentity c1 = new ObjectIdentity(Object.class, new IdClass(1));
397         assertEquals("keyAsObject doesn't match.", c1.getKeyAsObject(), new IdClass(1));
398     }
399 
400     private <T> void validateNestedException(JDOUserException ex, Class<T> expected) {
401         Throwable[] nesteds = ex.getNestedExceptions();
402         if (nesteds == null || nesteds.length != 1) {
403             fail ("Nested exception is null or length 0");
404         }
405         Throwable nested = nesteds[0];
406         if (nested != ex.getCause()) {
407             fail ("Nested exception is not == getCause()");
408         }
409         if (!(expected.isAssignableFrom(nested.getClass()))) {
410             fail ("Wrong nested exception. Expected "
411                     + expected.getName() + ", got "
412                     + nested.toString());
413         }
414         return;
415     }
416     public static class IdClass implements Serializable {
417         public int value;
418         public IdClass() {value = 0;}
419         public IdClass(int value) {this.value = value;}
420         public IdClass(String str) {this.value = Integer.parseInt(str);}
421         public String toString() {return Integer.toString(value);}
422         public int hashCode() {
423             return value;
424         }
425         public boolean equals (Object obj) {
426             if (this == obj) {
427                 return true;
428             } else {
429                 IdClass other = (IdClass) obj;
430                 return value == other.value;
431             }
432         }
433     }
434     
435     public static class BadIdClassNoStringConstructor {
436     }
437     
438     public static class BadIdClassNoPublicStringConstructor {
439         private BadIdClassNoPublicStringConstructor(String str) {}
440     }
441 }