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 () {
59                  public Object 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 testBadStringConstructorNullClass() {
146         try {
147             ObjectIdentity c1 = new ObjectIdentity(null, "1");
148         } catch (NullPointerException ex) {
149             return;
150         }
151         fail ("Failed to catch expected exception.");
152     }
153     
154     public void testBadStringConstructorNullParam() {
155         try {
156             ObjectIdentity c1 = new ObjectIdentity(Object.class, null);
157         } catch (JDONullIdentityException ex) {
158             return;
159         }
160         fail ("Failed to catch expected exception.");
161     }
162     
163     public void testBadStringConstructorTooShort() {
164         try {
165             ObjectIdentity c1 = new ObjectIdentity(Object.class, "xx");
166         } catch (JDOUserException ex) {
167             return;
168         }
169         fail ("Failed to catch expected exception.");
170     }
171     
172     public void testBadStringConstructorNoDelimiter() {
173         try {
174             ObjectIdentity c1 = new ObjectIdentity(Object.class, "xxxxxxxxx");
175         } catch (JDOUserException ex) {
176             return;
177         }
178         fail ("Failed to catch expected exception.");
179     }
180     
181     public void testBadStringConstructorBadClassName() {
182         try {
183             ObjectIdentity c1 = new ObjectIdentity(Object.class, "xx:yy");
184         } catch (JDOUserException ex) {
185             validateNestedException(ex, ClassNotFoundException.class);
186             return;
187         }
188         fail ("Failed to catch expected ClassNotFoundException.");
189     }
190     
191     public void testBadStringConstructorNoStringConstructor() {
192         try {
193             ObjectIdentity c1 = new ObjectIdentity(Object.class, 
194                     "javax.jdo.identity.ObjectIdentityTest$BadIdClassNoStringConstructor:yy");
195         } catch (JDOUserException ex) {
196             validateNestedException(ex, NoSuchMethodException.class);
197             return;
198         }
199         fail ("Failed to catch expected NoSuchMethodException.");
200     }
201     
202     public void testBadStringConstructorNoPublicStringConstructor() {
203         try {
204             ObjectIdentity c1 = new ObjectIdentity(Object.class, 
205                     "javax.jdo.identity.ObjectIdentityTest$BadIdClassNoPublicStringConstructor: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 testBadStringConstructorIllegalArgument() {
214         try {
215             ObjectIdentity c1 = new ObjectIdentity(Object.class, 
216                     "javax.jdo.identity.ObjectIdentityTest$IdClass:yy");
217         } catch (JDOUserException ex) {
218             validateNestedException(ex, InvocationTargetException.class);
219             return;
220         }
221         fail ("Failed to catch expected InvocationTargetException.");
222     }
223 
224     public void testStringDateConstructor() {
225         SimpleDateFormat usDateFormat = new SimpleDateFormat
226                 ("MMM dd, yyyy hh:mm:ss a", Locale.US);
227         helper.registerDateFormat(usDateFormat);
228         Object c1 = new ObjectIdentity(Object.class, 
229             "java.util.Date:Jan 01, 1970 00:00:00 AM");
230         helper.registerDateFormat(DateFormat.getDateTimeInstance());
231     }
232 
233     public void testStringDefaultDateConstructor() {
234         DateFormat dateFormat = DateFormat.getDateTimeInstance();
235         String rightNow = dateFormat.format(new Date());
236         Object c1 = new ObjectIdentity(Object.class, 
237             "java.util.Date:" + rightNow);
238     }
239 
240     public void testBadStringDateConstructor() {
241         try {
242             ObjectIdentity c1 = new ObjectIdentity(Object.class, 
243                 "java.util.Date:Jop 1, 1970 00:00:00");
244         } catch (JDOUserException ex) {
245             return;
246         }
247         fail ("Failed to catch expected Exception.");
248     }
249 
250     public void testStringLocaleConstructorLanguage() {
251         if (!isClassLoadable("java.util.Currency")) return;
252         SingleFieldIdentity c1 = new ObjectIdentity(Object.class, 
253                     "java.util.Locale:en");
254         assertEquals(new Locale("en"), c1.getKeyAsObject());
255     }
256 
257     public void testStringLocaleConstructorCountry() {
258         SingleFieldIdentity c1 = new ObjectIdentity(Object.class, 
259                     "java.util.Locale:_US");
260         assertEquals(new Locale("","US"), c1.getKeyAsObject());
261     }
262 
263     public void testStringLocaleConstructorLanguageCountry() {
264         SingleFieldIdentity c1 = new ObjectIdentity(Object.class, 
265                     "java.util.Locale:en_US");
266         assertEquals(new Locale("en","US"), c1.getKeyAsObject());
267     }
268 
269     public void testStringLocaleConstructorLanguageCountryVariant() {
270         SingleFieldIdentity c1 = new ObjectIdentity(Object.class, 
271                     "java.util.Locale:en_US_MAC");
272         assertEquals(new Locale("en","US","MAC"), c1.getKeyAsObject());
273     }
274 
275     public void testStringCurrencyConstructor() {
276         if (!isClassLoadable("java.util.Currency")) return;
277         SingleFieldIdentity c1 = new ObjectIdentity(Object.class, 
278                     "java.util.Currency:USD");
279     }
280 
281     public void testBadStringCurrencyConstructor() {
282         if (!isClassLoadable("java.util.Currency")) return;
283         try {
284             ObjectIdentity c1 = new ObjectIdentity(Object.class, 
285                     "java.util.Currency:NowhereInTheWorld");
286         } catch (JDOUserException ex) {
287             validateNestedException(ex, IllegalArgumentException.class);
288             return;
289         }
290         fail ("Failed to catch expected IllegalArgumentException.");
291     }
292 
293     public void testSerializedIdClass() {
294         ObjectIdentity c1 = new ObjectIdentity(Object.class, new IdClass(1));
295         ObjectIdentity c2 = new ObjectIdentity(Object.class, new IdClass(1));
296         ObjectIdentity c3 = new ObjectIdentity(Object.class, new IdClass(2));
297         Object[] scis = writeReadSerialized(new Object[] {c1, c2, c3});
298         Object sc1 = scis[0];
299         Object sc2 = scis[1];
300         Object sc3 = scis[2];
301         assertEquals ("Equal ObjectIdentity instances compare not equal.", c1, sc1);
302         assertEquals ("Equal ObjectIdentity instances compare not equal.", c2, sc2);
303         assertEquals ("Equal ObjectIdentity instances compare not equal.", sc1, c2);
304         assertEquals ("Equal ObjectIdentity instances compare not equal.", sc2, c1);
305         assertFalse ("Not equal ObjectIdentity instances compare equal.", c1.equals(sc3));
306         assertFalse ("Not equal ObjectIdentity instances compare equal.", sc1.equals(c3));
307         assertFalse ("Not equal ObjectIdentity instances compare equal.", sc1.equals(sc3));
308         assertFalse ("Not equal ObjectIdentity instances compare equal.", sc3.equals(sc1));
309     }
310     
311     public void testSerializedBigDecimal() {
312         ObjectIdentity c1 = new ObjectIdentity(Object.class, new BigDecimal("123456789.012"));
313         ObjectIdentity c2 = new ObjectIdentity(Object.class, new BigDecimal("123456789.012"));
314         ObjectIdentity c3 = new ObjectIdentity(Object.class, new BigDecimal("123456789.01"));
315         Object[] scis = writeReadSerialized(new Object[] {c1, c2, c3});
316         Object sc1 = scis[0];
317         Object sc2 = scis[1];
318         Object sc3 = scis[2];
319         assertEquals ("Equal ObjectIdentity instances compare not equal.", c1, sc1);
320         assertEquals ("Equal ObjectIdentity instances compare not equal.", c2, sc2);
321         assertEquals ("Equal ObjectIdentity instances compare not equal.", sc1, c2);
322         assertEquals ("Equal ObjectIdentity instances compare not equal.", sc2, c1);
323         assertFalse ("Not equal ObjectIdentity instances compare equal.", c1.equals(sc3));
324         assertFalse ("Not equal ObjectIdentity instances compare equal.", sc1.equals(c3));
325         assertFalse ("Not equal ObjectIdentity instances compare equal.", sc1.equals(sc3));
326         assertFalse ("Not equal ObjectIdentity instances compare equal.", sc3.equals(sc1));
327     }
328     
329     public void testSerializedCurrency() {
330         if (!isClassLoadable("java.util.Currency")) return;
331         ObjectIdentity c1 = new ObjectIdentity(Object.class, Currency.getInstance(Locale.US));
332         ObjectIdentity c2 = new ObjectIdentity(Object.class, Currency.getInstance(Locale.US));
333         ObjectIdentity c3 = new ObjectIdentity(Object.class, Currency.getInstance(Locale.GERMANY));
334         Object[] scis = writeReadSerialized(new Object[] {c1, c2, c3});
335         Object sc1 = scis[0];
336         Object sc2 = scis[1];
337         Object sc3 = scis[2];
338         assertEquals ("Equal ObjectIdentity instances compare not equal.", c1, sc1);
339         assertEquals ("Equal ObjectIdentity instances compare not equal.", c2, sc2);
340         assertEquals ("Equal ObjectIdentity instances compare not equal.", sc1, c2);
341         assertEquals ("Equal ObjectIdentity instances compare not equal.", sc2, c1);
342         assertFalse ("Not equal ObjectIdentity instances compare equal.", c1.equals(sc3));
343         assertFalse ("Not equal ObjectIdentity instances compare equal.", sc1.equals(c3));
344         assertFalse ("Not equal ObjectIdentity instances compare equal.", sc1.equals(sc3));
345         assertFalse ("Not equal ObjectIdentity instances compare equal.", sc3.equals(sc1));
346     }
347     
348     public void testSerializedDate() {
349         ObjectIdentity c1 = new ObjectIdentity(Object.class, new Date(1));
350         ObjectIdentity c2 = new ObjectIdentity(Object.class, "java.util.Date:1");
351         ObjectIdentity c3 = new ObjectIdentity(Object.class, new Date(2));
352         Object[] scis = writeReadSerialized(new Object[] {c1, c2, c3});
353         Object sc1 = scis[0];
354         Object sc2 = scis[1];
355         Object sc3 = scis[2];
356         assertEquals ("Equal ObjectIdentity instances compare not equal.", c1, sc1);
357         assertEquals ("Equal ObjectIdentity instances compare not equal.", c2, sc2);
358         assertEquals ("Equal ObjectIdentity instances compare not equal.", sc1, c2);
359         assertEquals ("Equal ObjectIdentity instances compare not equal.", sc2, c1);
360         assertFalse ("Not equal ObjectIdentity instances compare equal.", c1.equals(sc3));
361         assertFalse ("Not equal ObjectIdentity instances compare equal.", sc1.equals(c3));
362         assertFalse ("Not equal ObjectIdentity instances compare equal.", sc1.equals(sc3));
363         assertFalse ("Not equal ObjectIdentity instances compare equal.", sc3.equals(sc1));
364     }
365     
366     public void testSerializedLocale() {
367         ObjectIdentity c1 = new ObjectIdentity(Object.class, Locale.US);
368         ObjectIdentity c2 = new ObjectIdentity(Object.class, Locale.US);
369         ObjectIdentity c3 = new ObjectIdentity(Object.class, Locale.GERMANY);
370         Object[] scis = writeReadSerialized(new Object[] {c1, c2, c3});
371         Object sc1 = scis[0];
372         Object sc2 = scis[1];
373         Object sc3 = scis[2];
374         assertEquals ("Equal ObjectIdentity instances compare not equal.", c1, sc1);
375         assertEquals ("Equal ObjectIdentity instances compare not equal.", c2, sc2);
376         assertEquals ("Equal ObjectIdentity instances compare not equal.", sc1, c2);
377         assertEquals ("Equal ObjectIdentity instances compare not equal.", sc2, c1);
378         assertFalse ("Not equal ObjectIdentity instances compare equal.", c1.equals(sc3));
379         assertFalse ("Not equal ObjectIdentity instances compare equal.", sc1.equals(c3));
380         assertFalse ("Not equal ObjectIdentity instances compare equal.", sc1.equals(sc3));
381         assertFalse ("Not equal ObjectIdentity instances compare equal.", sc3.equals(sc1));
382     }
383     
384     public void testGetKeyAsObject() {
385         ObjectIdentity c1 = new ObjectIdentity(Object.class, new IdClass(1));
386         assertEquals("keyAsObject doesn't match.", c1.getKeyAsObject(), new IdClass(1));
387     }
388 
389     private void validateNestedException(JDOUserException ex, Class expected) {
390         Throwable[] nesteds = ex.getNestedExceptions();
391         if (nesteds == null || nesteds.length == 0) {
392             fail ("Nested exception is null or length 0");
393         }
394         Throwable nested = nesteds[0];
395         if (!(expected.isAssignableFrom(nested.getClass()))) {
396             fail ("Wrong nested exception. Expected ClassNotFoundException, got "
397                     + nested.toString());
398         }
399         return;
400     }
401     public static class IdClass implements Serializable {
402         public int value;
403         public IdClass() {value = 0;}
404         public IdClass(int value) {this.value = value;}
405         public IdClass(String str) {this.value = Integer.parseInt(str);}
406         public String toString() {return Integer.toString(value);}
407         public int hashCode() {
408             return value;
409         }
410         public boolean equals (Object obj) {
411             if (this == obj) {
412                 return true;
413             } else {
414                 IdClass other = (IdClass) obj;
415                 return value == other.value;
416             }
417         }
418     }
419     
420     public static class BadIdClassNoStringConstructor {
421     }
422     
423     public static class BadIdClassNoPublicStringConstructor {
424         private BadIdClassNoPublicStringConstructor(String str) {}
425     }
426 }