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