001    /*
002     *  Copyright 2001-2006 Stephen Colebourne
003     *
004     *  Licensed under the Apache License, Version 2.0 (the "License");
005     *  you may not use this file except in compliance with the License.
006     *  You may obtain a copy of the License at
007     *
008     *      http://www.apache.org/licenses/LICENSE-2.0
009     *
010     *  Unless required by applicable law or agreed to in writing, software
011     *  distributed under the License is distributed on an "AS IS" BASIS,
012     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     *  See the License for the specific language governing permissions and
014     *  limitations under the License.
015     */
016    package org.joda.time.convert;
017    
018    import java.io.Serializable;
019    import java.lang.reflect.Constructor;
020    import java.lang.reflect.Field;
021    import java.lang.reflect.Modifier;
022    import java.security.AllPermission;
023    import java.security.CodeSource;
024    import java.security.Permission;
025    import java.security.PermissionCollection;
026    import java.security.Permissions;
027    import java.security.Policy;
028    import java.security.ProtectionDomain;
029    import java.util.Calendar;
030    import java.util.Date;
031    import java.util.GregorianCalendar;
032    
033    import junit.framework.TestCase;
034    import junit.framework.TestSuite;
035    
036    import org.joda.time.Chronology;
037    import org.joda.time.DateTime;
038    import org.joda.time.DateTimeZone;
039    import org.joda.time.Duration;
040    import org.joda.time.ReadablePartial;
041    import org.joda.time.ReadablePeriod;
042    import org.joda.time.Period;
043    import org.joda.time.PeriodType;
044    import org.joda.time.Interval;
045    import org.joda.time.JodaTimePermission;
046    import org.joda.time.ReadWritablePeriod;
047    import org.joda.time.ReadWritableInterval;
048    import org.joda.time.ReadableDateTime;
049    import org.joda.time.ReadableDuration;
050    import org.joda.time.ReadableInstant;
051    import org.joda.time.ReadableInterval;
052    import org.joda.time.TimeOfDay;
053    import org.joda.time.format.DateTimeFormatter;
054    
055    /**
056     * This class is a JUnit test for ConverterManager.
057     *
058     * @author Stephen Colebourne
059     */
060    public class TestConverterManager extends TestCase {
061        private static final boolean OLD_JDK;
062        static {
063            String str = System.getProperty("java.version");
064            boolean old = true;
065            if (str.length() > 3 &&
066                str.charAt(0) == '1' &&
067                str.charAt(1) == '.' &&
068                (str.charAt(2) == '4' || str.charAt(2) == '5' || str.charAt(2) == '6')) {
069                old = false;
070            }
071            OLD_JDK = old;
072        }
073    
074        private static final Policy RESTRICT;
075        private static final Policy ALLOW;
076        static {
077            // don't call Policy.getPolicy()
078            RESTRICT = new Policy() {
079                public PermissionCollection getPermissions(CodeSource codesource) {
080                    Permissions p = new Permissions();
081                    p.add(new AllPermission());  // enable everything
082                    return p;
083                }
084                public void refresh() {
085                }
086                public boolean implies(ProtectionDomain domain, Permission permission) {
087                    if (permission instanceof JodaTimePermission) {
088                        return false;
089                    }
090                    return true;
091    //                return super.implies(domain, permission);
092                }
093            };
094            ALLOW = new Policy() {
095                public PermissionCollection getPermissions(CodeSource codesource) {
096                    Permissions p = new Permissions();
097                    p.add(new AllPermission());  // enable everything
098                    return p;
099                }
100                public void refresh() {
101                }
102            };
103        }
104    
105        public static void main(String[] args) {
106            junit.textui.TestRunner.run(suite());
107        }
108    
109        public static TestSuite suite() {
110            return new TestSuite(TestConverterManager.class);
111        }
112    
113        public TestConverterManager(String name) {
114            super(name);
115        }
116    
117        //-----------------------------------------------------------------------
118        public void testSingleton() throws Exception {
119            Class cls = ConverterManager.class;
120            assertEquals(true, Modifier.isPublic(cls.getModifiers()));
121            
122            Constructor con = cls.getDeclaredConstructor((Class[]) null);
123            assertEquals(1, cls.getDeclaredConstructors().length);
124            assertEquals(true, Modifier.isProtected(con.getModifiers()));
125            
126            Field fld = cls.getDeclaredField("INSTANCE");
127            assertEquals(true, Modifier.isPrivate(fld.getModifiers()));
128        }
129    
130        //-----------------------------------------------------------------------
131        public void testGetInstantConverter() {
132            InstantConverter c = ConverterManager.getInstance().getInstantConverter(new Long(0L));
133            assertEquals(Long.class, c.getSupportedType());
134            
135            c = ConverterManager.getInstance().getInstantConverter(new DateTime());
136            assertEquals(ReadableInstant.class, c.getSupportedType());
137            
138            c = ConverterManager.getInstance().getInstantConverter("");
139            assertEquals(String.class, c.getSupportedType());
140            
141            c = ConverterManager.getInstance().getInstantConverter(new Date());
142            assertEquals(Date.class, c.getSupportedType());
143            
144            c = ConverterManager.getInstance().getInstantConverter(new GregorianCalendar());
145            assertEquals(Calendar.class, c.getSupportedType());
146            
147            c = ConverterManager.getInstance().getInstantConverter(null);
148            assertEquals(null, c.getSupportedType());
149            
150            try {
151                ConverterManager.getInstance().getInstantConverter(Boolean.TRUE);
152                fail();
153            } catch (IllegalArgumentException ex) {}
154        }
155    
156        public void testGetInstantConverterRemovedNull() {
157            try {
158                ConverterManager.getInstance().removeInstantConverter(NullConverter.INSTANCE);
159                try {
160                    ConverterManager.getInstance().getInstantConverter(null);
161                    fail();
162                } catch (IllegalArgumentException ex) {}
163            } finally {
164                ConverterManager.getInstance().addInstantConverter(NullConverter.INSTANCE);
165            }
166            assertEquals(6, ConverterManager.getInstance().getInstantConverters().length);
167        }
168    
169        public void testGetInstantConverterOKMultipleMatches() {
170            InstantConverter c = new InstantConverter() {
171                public long getInstantMillis(Object object, Chronology chrono) {return 0;}
172                public Chronology getChronology(Object object, DateTimeZone zone) {return null;}
173                public Chronology getChronology(Object object, Chronology chrono) {return null;}
174                public Class getSupportedType() {return ReadableDateTime.class;}
175            };
176            try {
177                ConverterManager.getInstance().addInstantConverter(c);
178                InstantConverter ok = ConverterManager.getInstance().getInstantConverter(new DateTime());
179                // ReadableDateTime and ReadableInstant both match, but RI discarded as less specific
180                assertEquals(ReadableDateTime.class, ok.getSupportedType());
181            } finally {
182                ConverterManager.getInstance().removeInstantConverter(c);
183            }
184            assertEquals(6, ConverterManager.getInstance().getInstantConverters().length);
185        }
186    
187        public void testGetInstantConverterBadMultipleMatches() {
188            InstantConverter c = new InstantConverter() {
189                public long getInstantMillis(Object object, Chronology chrono) {return 0;}
190                public Chronology getChronology(Object object, DateTimeZone zone) {return null;}
191                public Chronology getChronology(Object object, Chronology chrono) {return null;}
192                public Class getSupportedType() {return Serializable.class;}
193            };
194            try {
195                ConverterManager.getInstance().addInstantConverter(c);
196                try {
197                    ConverterManager.getInstance().getInstantConverter(new DateTime());
198                    fail();
199                } catch (IllegalStateException ex) {
200                    // Serializable and ReadableInstant both match, so cannot pick
201                }
202            } finally {
203                ConverterManager.getInstance().removeInstantConverter(c);
204            }
205            assertEquals(6, ConverterManager.getInstance().getInstantConverters().length);
206        }
207    
208        //-----------------------------------------------------------------------
209        public void testGetInstantConverters() {
210            InstantConverter[] array = ConverterManager.getInstance().getInstantConverters();
211            assertEquals(6, array.length);
212        }
213    
214        //-----------------------------------------------------------------------
215        public void testAddInstantConverter1() {
216            InstantConverter c = new InstantConverter() {
217                public long getInstantMillis(Object object, Chronology chrono) {return 0;}
218                public Chronology getChronology(Object object, DateTimeZone zone) {return null;}
219                public Chronology getChronology(Object object, Chronology chrono) {return null;}
220                public Class getSupportedType() {return Boolean.class;}
221            };
222            try {
223                InstantConverter removed = ConverterManager.getInstance().addInstantConverter(c);
224                assertEquals(null, removed);
225                assertEquals(Boolean.class, ConverterManager.getInstance().getInstantConverter(Boolean.TRUE).getSupportedType());
226                assertEquals(7, ConverterManager.getInstance().getInstantConverters().length);
227            } finally {
228                ConverterManager.getInstance().removeInstantConverter(c);
229            }
230            assertEquals(6, ConverterManager.getInstance().getInstantConverters().length);
231        }
232    
233        public void testAddInstantConverter2() {
234            InstantConverter c = new InstantConverter() {
235                public long getInstantMillis(Object object, Chronology chrono) {return 0;}
236                public Chronology getChronology(Object object, DateTimeZone zone) {return null;}
237                public Chronology getChronology(Object object, Chronology chrono) {return null;}
238                public Class getSupportedType() {return String.class;}
239            };
240            try {
241                InstantConverter removed = ConverterManager.getInstance().addInstantConverter(c);
242                assertEquals(StringConverter.INSTANCE, removed);
243                assertEquals(String.class, ConverterManager.getInstance().getInstantConverter("").getSupportedType());
244                assertEquals(6, ConverterManager.getInstance().getInstantConverters().length);
245            } finally {
246                ConverterManager.getInstance().addInstantConverter(StringConverter.INSTANCE);
247            }
248            assertEquals(6, ConverterManager.getInstance().getInstantConverters().length);
249        }
250    
251        public void testAddInstantConverter3() {
252            InstantConverter removed = ConverterManager.getInstance().addInstantConverter(StringConverter.INSTANCE);
253            assertEquals(null, removed);
254            assertEquals(6, ConverterManager.getInstance().getInstantConverters().length);
255        }
256    
257        public void testAddInstantConverter4() {
258            InstantConverter removed = ConverterManager.getInstance().addInstantConverter(null);
259            assertEquals(null, removed);
260            assertEquals(6, ConverterManager.getInstance().getInstantConverters().length);
261        }
262    
263        public void testAddInstantConverterSecurity() {
264            if (OLD_JDK) {
265                return;
266            }
267            try {
268                Policy.setPolicy(RESTRICT);
269                System.setSecurityManager(new SecurityManager());
270                ConverterManager.getInstance().addInstantConverter(StringConverter.INSTANCE);
271                fail();
272            } catch (SecurityException ex) {
273                // ok
274            } finally {
275                System.setSecurityManager(null);
276                Policy.setPolicy(ALLOW);
277            }
278            assertEquals(6, ConverterManager.getInstance().getInstantConverters().length);
279        }
280    
281        //-----------------------------------------------------------------------
282        public void testRemoveInstantConverter1() {
283            try {
284                InstantConverter removed = ConverterManager.getInstance().removeInstantConverter(StringConverter.INSTANCE);
285                assertEquals(StringConverter.INSTANCE, removed);
286                assertEquals(5, ConverterManager.getInstance().getInstantConverters().length);
287            } finally {
288                ConverterManager.getInstance().addInstantConverter(StringConverter.INSTANCE);
289            }
290            assertEquals(6, ConverterManager.getInstance().getInstantConverters().length);
291        }
292    
293        public void testRemoveInstantConverter2() {
294            InstantConverter c = new InstantConverter() {
295                public long getInstantMillis(Object object, Chronology chrono) {return 0;}
296                public Chronology getChronology(Object object, DateTimeZone zone) {return null;}
297                public Chronology getChronology(Object object, Chronology chrono) {return null;}
298                public Class getSupportedType() {return Boolean.class;}
299            };
300            InstantConverter removed = ConverterManager.getInstance().removeInstantConverter(c);
301            assertEquals(null, removed);
302            assertEquals(6, ConverterManager.getInstance().getInstantConverters().length);
303        }
304    
305        public void testRemoveInstantConverter3() {
306            InstantConverter removed = ConverterManager.getInstance().removeInstantConverter(null);
307            assertEquals(null, removed);
308            assertEquals(6, ConverterManager.getInstance().getInstantConverters().length);
309        }
310    
311        public void testRemoveInstantConverterSecurity() {
312            if (OLD_JDK) {
313                return;
314            }
315            try {
316                Policy.setPolicy(RESTRICT);
317                System.setSecurityManager(new SecurityManager());
318                ConverterManager.getInstance().removeInstantConverter(StringConverter.INSTANCE);
319                fail();
320            } catch (SecurityException ex) {
321                // ok
322            } finally {
323                System.setSecurityManager(null);
324                Policy.setPolicy(ALLOW);
325            }
326            assertEquals(6, ConverterManager.getInstance().getInstantConverters().length);
327        }
328    
329        //-----------------------------------------------------------------------
330        //-----------------------------------------------------------------------
331        private static final int PARTIAL_SIZE = 7;
332        
333        public void testGetPartialConverter() {
334            PartialConverter c = ConverterManager.getInstance().getPartialConverter(new Long(0L));
335            assertEquals(Long.class, c.getSupportedType());
336            
337            c = ConverterManager.getInstance().getPartialConverter(new TimeOfDay());
338            assertEquals(ReadablePartial.class, c.getSupportedType());
339            
340            c = ConverterManager.getInstance().getPartialConverter(new DateTime());
341            assertEquals(ReadableInstant.class, c.getSupportedType());
342            
343            c = ConverterManager.getInstance().getPartialConverter("");
344            assertEquals(String.class, c.getSupportedType());
345            
346            c = ConverterManager.getInstance().getPartialConverter(new Date());
347            assertEquals(Date.class, c.getSupportedType());
348            
349            c = ConverterManager.getInstance().getPartialConverter(new GregorianCalendar());
350            assertEquals(Calendar.class, c.getSupportedType());
351            
352            c = ConverterManager.getInstance().getPartialConverter(null);
353            assertEquals(null, c.getSupportedType());
354            
355            try {
356                ConverterManager.getInstance().getPartialConverter(Boolean.TRUE);
357                fail();
358            } catch (IllegalArgumentException ex) {}
359        }
360    
361        public void testGetPartialConverterRemovedNull() {
362            try {
363                ConverterManager.getInstance().removePartialConverter(NullConverter.INSTANCE);
364                try {
365                    ConverterManager.getInstance().getPartialConverter(null);
366                    fail();
367                } catch (IllegalArgumentException ex) {}
368            } finally {
369                ConverterManager.getInstance().addPartialConverter(NullConverter.INSTANCE);
370            }
371            assertEquals(PARTIAL_SIZE, ConverterManager.getInstance().getPartialConverters().length);
372        }
373    
374        public void testGetPartialConverterOKMultipleMatches() {
375            PartialConverter c = new PartialConverter() {
376                public int[] getPartialValues(ReadablePartial partial, Object object, Chronology chrono) {return null;}
377                public int[] getPartialValues(ReadablePartial partial, Object object, Chronology chrono, DateTimeFormatter parser) {return null;}
378                public Chronology getChronology(Object object, DateTimeZone zone) {return null;}
379                public Chronology getChronology(Object object, Chronology chrono) {return null;}
380                public Class getSupportedType() {return ReadableDateTime.class;}
381            };
382            try {
383                ConverterManager.getInstance().addPartialConverter(c);
384                PartialConverter ok = ConverterManager.getInstance().getPartialConverter(new DateTime());
385                // ReadableDateTime and ReadablePartial both match, but RI discarded as less specific
386                assertEquals(ReadableDateTime.class, ok.getSupportedType());
387            } finally {
388                ConverterManager.getInstance().removePartialConverter(c);
389            }
390            assertEquals(PARTIAL_SIZE, ConverterManager.getInstance().getPartialConverters().length);
391        }
392    
393        public void testGetPartialConverterBadMultipleMatches() {
394            PartialConverter c = new PartialConverter() {
395                public int[] getPartialValues(ReadablePartial partial, Object object, Chronology chrono) {return null;}
396                public int[] getPartialValues(ReadablePartial partial, Object object, Chronology chrono, DateTimeFormatter parser) {return null;}
397                public Chronology getChronology(Object object, DateTimeZone zone) {return null;}
398                public Chronology getChronology(Object object, Chronology chrono) {return null;}
399                public Class getSupportedType() {return Serializable.class;}
400            };
401            try {
402                ConverterManager.getInstance().addPartialConverter(c);
403                try {
404                    ConverterManager.getInstance().getPartialConverter(new DateTime());
405                    fail();
406                } catch (IllegalStateException ex) {
407                    // Serializable and ReadablePartial both match, so cannot pick
408                }
409            } finally {
410                ConverterManager.getInstance().removePartialConverter(c);
411            }
412            assertEquals(PARTIAL_SIZE, ConverterManager.getInstance().getPartialConverters().length);
413        }
414    
415        //-----------------------------------------------------------------------
416        public void testGetPartialConverters() {
417            PartialConverter[] array = ConverterManager.getInstance().getPartialConverters();
418            assertEquals(PARTIAL_SIZE, array.length);
419        }
420    
421        //-----------------------------------------------------------------------
422        public void testAddPartialConverter1() {
423            PartialConverter c = new PartialConverter() {
424                public int[] getPartialValues(ReadablePartial partial, Object object, Chronology chrono) {return null;}
425                public int[] getPartialValues(ReadablePartial partial, Object object, Chronology chrono, DateTimeFormatter parser) {return null;}
426                public Chronology getChronology(Object object, DateTimeZone zone) {return null;}
427                public Chronology getChronology(Object object, Chronology chrono) {return null;}
428                public Class getSupportedType() {return Boolean.class;}
429            };
430            try {
431                PartialConverter removed = ConverterManager.getInstance().addPartialConverter(c);
432                assertEquals(null, removed);
433                assertEquals(Boolean.class, ConverterManager.getInstance().getPartialConverter(Boolean.TRUE).getSupportedType());
434                assertEquals(PARTIAL_SIZE + 1, ConverterManager.getInstance().getPartialConverters().length);
435            } finally {
436                ConverterManager.getInstance().removePartialConverter(c);
437            }
438            assertEquals(PARTIAL_SIZE, ConverterManager.getInstance().getPartialConverters().length);
439        }
440    
441        public void testAddPartialConverter2() {
442            PartialConverter c = new PartialConverter() {
443                public int[] getPartialValues(ReadablePartial partial, Object object, Chronology chrono) {return null;}
444                public int[] getPartialValues(ReadablePartial partial, Object object, Chronology chrono, DateTimeFormatter parser) {return null;}
445                public Chronology getChronology(Object object, DateTimeZone zone) {return null;}
446                public Chronology getChronology(Object object, Chronology chrono) {return null;}
447                public Class getSupportedType() {return String.class;}
448            };
449            try {
450                PartialConverter removed = ConverterManager.getInstance().addPartialConverter(c);
451                assertEquals(StringConverter.INSTANCE, removed);
452                assertEquals(String.class, ConverterManager.getInstance().getPartialConverter("").getSupportedType());
453                assertEquals(PARTIAL_SIZE, ConverterManager.getInstance().getPartialConverters().length);
454            } finally {
455                ConverterManager.getInstance().addPartialConverter(StringConverter.INSTANCE);
456            }
457            assertEquals(PARTIAL_SIZE, ConverterManager.getInstance().getPartialConverters().length);
458        }
459    
460        public void testAddPartialConverter3() {
461            PartialConverter removed = ConverterManager.getInstance().addPartialConverter(StringConverter.INSTANCE);
462            assertEquals(null, removed);
463            assertEquals(PARTIAL_SIZE, ConverterManager.getInstance().getPartialConverters().length);
464        }
465    
466        public void testAddPartialConverter4() {
467            PartialConverter removed = ConverterManager.getInstance().addPartialConverter(null);
468            assertEquals(null, removed);
469            assertEquals(PARTIAL_SIZE, ConverterManager.getInstance().getPartialConverters().length);
470        }
471    
472        public void testAddPartialConverterSecurity() {
473            if (OLD_JDK) {
474                return;
475            }
476            try {
477                Policy.setPolicy(RESTRICT);
478                System.setSecurityManager(new SecurityManager());
479                ConverterManager.getInstance().addPartialConverter(StringConverter.INSTANCE);
480                fail();
481            } catch (SecurityException ex) {
482                // ok
483            } finally {
484                System.setSecurityManager(null);
485                Policy.setPolicy(ALLOW);
486            }
487            assertEquals(PARTIAL_SIZE, ConverterManager.getInstance().getPartialConverters().length);
488        }
489    
490        //-----------------------------------------------------------------------
491        public void testRemovePartialConverter1() {
492            try {
493                PartialConverter removed = ConverterManager.getInstance().removePartialConverter(StringConverter.INSTANCE);
494                assertEquals(StringConverter.INSTANCE, removed);
495                assertEquals(PARTIAL_SIZE - 1, ConverterManager.getInstance().getPartialConverters().length);
496            } finally {
497                ConverterManager.getInstance().addPartialConverter(StringConverter.INSTANCE);
498            }
499            assertEquals(PARTIAL_SIZE, ConverterManager.getInstance().getPartialConverters().length);
500        }
501    
502        public void testRemovePartialConverter2() {
503            PartialConverter c = new PartialConverter() {
504                public int[] getPartialValues(ReadablePartial partial, Object object, Chronology chrono) {return null;}
505                public int[] getPartialValues(ReadablePartial partial, Object object, Chronology chrono, DateTimeFormatter parser) {return null;}
506                public Chronology getChronology(Object object, DateTimeZone zone) {return null;}
507                public Chronology getChronology(Object object, Chronology chrono) {return null;}
508                public Class getSupportedType() {return Boolean.class;}
509            };
510            PartialConverter removed = ConverterManager.getInstance().removePartialConverter(c);
511            assertEquals(null, removed);
512            assertEquals(PARTIAL_SIZE, ConverterManager.getInstance().getPartialConverters().length);
513        }
514    
515        public void testRemovePartialConverter3() {
516            PartialConverter removed = ConverterManager.getInstance().removePartialConverter(null);
517            assertEquals(null, removed);
518            assertEquals(PARTIAL_SIZE, ConverterManager.getInstance().getPartialConverters().length);
519        }
520    
521        public void testRemovePartialConverterSecurity() {
522            if (OLD_JDK) {
523                return;
524            }
525            try {
526                Policy.setPolicy(RESTRICT);
527                System.setSecurityManager(new SecurityManager());
528                ConverterManager.getInstance().removeInstantConverter(StringConverter.INSTANCE);
529                fail();
530            } catch (SecurityException ex) {
531                // ok
532            } finally {
533                System.setSecurityManager(null);
534                Policy.setPolicy(ALLOW);
535            }
536            assertEquals(PARTIAL_SIZE, ConverterManager.getInstance().getPartialConverters().length);
537        }
538    
539        //-----------------------------------------------------------------------
540        //-----------------------------------------------------------------------
541        private static int DURATION_SIZE = 5;
542        
543        public void testGetDurationConverter() {
544            DurationConverter c = ConverterManager.getInstance().getDurationConverter(new Long(0L));
545            assertEquals(Long.class, c.getSupportedType());
546            
547            c = ConverterManager.getInstance().getDurationConverter(new Duration(123L));
548            assertEquals(ReadableDuration.class, c.getSupportedType());
549            
550            c = ConverterManager.getInstance().getDurationConverter(new Interval(0L, 1000L));
551            assertEquals(ReadableInterval.class, c.getSupportedType());
552            
553            c = ConverterManager.getInstance().getDurationConverter("");
554            assertEquals(String.class, c.getSupportedType());
555            
556            c = ConverterManager.getInstance().getDurationConverter(null);
557            assertEquals(null, c.getSupportedType());
558            
559            try {
560                ConverterManager.getInstance().getDurationConverter(Boolean.TRUE);
561                fail();
562            } catch (IllegalArgumentException ex) {}
563        }
564    
565        public void testGetDurationConverterRemovedNull() {
566            try {
567                ConverterManager.getInstance().removeDurationConverter(NullConverter.INSTANCE);
568                try {
569                    ConverterManager.getInstance().getDurationConverter(null);
570                    fail();
571                } catch (IllegalArgumentException ex) {}
572            } finally {
573                ConverterManager.getInstance().addDurationConverter(NullConverter.INSTANCE);
574            }
575            assertEquals(DURATION_SIZE, ConverterManager.getInstance().getDurationConverters().length);
576        }
577    
578        //-----------------------------------------------------------------------
579        public void testGetDurationConverters() {
580            DurationConverter[] array = ConverterManager.getInstance().getDurationConverters();
581            assertEquals(DURATION_SIZE, array.length);
582        }
583    
584        //-----------------------------------------------------------------------
585        public void testAddDurationConverter1() {
586            DurationConverter c = new DurationConverter() {
587                public long getDurationMillis(Object object) {return 0;}
588                public Class getSupportedType() {return Boolean.class;}
589            };
590            try {
591                DurationConverter removed = ConverterManager.getInstance().addDurationConverter(c);
592                assertEquals(null, removed);
593                assertEquals(Boolean.class, ConverterManager.getInstance().getDurationConverter(Boolean.TRUE).getSupportedType());
594                assertEquals(DURATION_SIZE + 1, ConverterManager.getInstance().getDurationConverters().length);
595            } finally {
596                ConverterManager.getInstance().removeDurationConverter(c);
597            }
598            assertEquals(DURATION_SIZE, ConverterManager.getInstance().getDurationConverters().length);
599        }
600    
601        public void testAddDurationConverter2() {
602            DurationConverter c = new DurationConverter() {
603                public long getDurationMillis(Object object) {return 0;}
604                public Class getSupportedType() {return String.class;}
605            };
606            try {
607                DurationConverter removed = ConverterManager.getInstance().addDurationConverter(c);
608                assertEquals(StringConverter.INSTANCE, removed);
609                assertEquals(String.class, ConverterManager.getInstance().getDurationConverter("").getSupportedType());
610                assertEquals(DURATION_SIZE, ConverterManager.getInstance().getDurationConverters().length);
611            } finally {
612                ConverterManager.getInstance().addDurationConverter(StringConverter.INSTANCE);
613            }
614            assertEquals(DURATION_SIZE, ConverterManager.getInstance().getDurationConverters().length);
615        }
616    
617        public void testAddDurationConverter3() {
618            DurationConverter removed = ConverterManager.getInstance().addDurationConverter(null);
619            assertEquals(null, removed);
620            assertEquals(DURATION_SIZE, ConverterManager.getInstance().getDurationConverters().length);
621        }
622    
623        public void testAddDurationConverterSecurity() {
624            if (OLD_JDK) {
625                return;
626            }
627            try {
628                Policy.setPolicy(RESTRICT);
629                System.setSecurityManager(new SecurityManager());
630                ConverterManager.getInstance().addDurationConverter(StringConverter.INSTANCE);
631                fail();
632            } catch (SecurityException ex) {
633                // ok
634            } finally {
635                System.setSecurityManager(null);
636                Policy.setPolicy(ALLOW);
637            }
638            assertEquals(DURATION_SIZE, ConverterManager.getInstance().getDurationConverters().length);
639        }
640    
641        //-----------------------------------------------------------------------
642        public void testRemoveDurationConverter1() {
643            try {
644                DurationConverter removed = ConverterManager.getInstance().removeDurationConverter(StringConverter.INSTANCE);
645                assertEquals(StringConverter.INSTANCE, removed);
646                assertEquals(DURATION_SIZE - 1, ConverterManager.getInstance().getDurationConverters().length);
647            } finally {
648                ConverterManager.getInstance().addDurationConverter(StringConverter.INSTANCE);
649            }
650            assertEquals(DURATION_SIZE, ConverterManager.getInstance().getDurationConverters().length);
651        }
652    
653        public void testRemoveDurationConverter2() {
654            DurationConverter c = new DurationConverter() {
655                public long getDurationMillis(Object object) {return 0;}
656                public Class getSupportedType() {return Boolean.class;}
657            };
658            DurationConverter removed = ConverterManager.getInstance().removeDurationConverter(c);
659            assertEquals(null, removed);
660            assertEquals(DURATION_SIZE, ConverterManager.getInstance().getDurationConverters().length);
661        }
662    
663        public void testRemoveDurationConverter3() {
664            DurationConverter removed = ConverterManager.getInstance().removeDurationConverter(null);
665            assertEquals(null, removed);
666            assertEquals(DURATION_SIZE, ConverterManager.getInstance().getDurationConverters().length);
667        }
668    
669        public void testRemoveDurationConverterSecurity() {
670            if (OLD_JDK) {
671                return;
672            }
673            try {
674                Policy.setPolicy(RESTRICT);
675                System.setSecurityManager(new SecurityManager());
676                ConverterManager.getInstance().removeDurationConverter(StringConverter.INSTANCE);
677                fail();
678            } catch (SecurityException ex) {
679                // ok
680            } finally {
681                System.setSecurityManager(null);
682                Policy.setPolicy(ALLOW);
683            }
684            assertEquals(DURATION_SIZE, ConverterManager.getInstance().getDurationConverters().length);
685        }
686    
687        //-----------------------------------------------------------------------
688        //-----------------------------------------------------------------------
689        private static int PERIOD_SIZE = 5;
690        
691        public void testGetPeriodConverter() {
692            PeriodConverter c = ConverterManager.getInstance().getPeriodConverter(new Period(1, 2, 3, 4, 5, 6, 7, 8));
693            assertEquals(ReadablePeriod.class, c.getSupportedType());
694            
695            c = ConverterManager.getInstance().getPeriodConverter(new Duration(123L));
696            assertEquals(ReadableDuration.class, c.getSupportedType());
697            
698            c = ConverterManager.getInstance().getPeriodConverter(new Interval(0L, 1000L));
699            assertEquals(ReadableInterval.class, c.getSupportedType());
700            
701            c = ConverterManager.getInstance().getPeriodConverter("");
702            assertEquals(String.class, c.getSupportedType());
703            
704            c = ConverterManager.getInstance().getPeriodConverter(null);
705            assertEquals(null, c.getSupportedType());
706            
707            try {
708                ConverterManager.getInstance().getPeriodConverter(Boolean.TRUE);
709                fail();
710            } catch (IllegalArgumentException ex) {}
711        }
712    
713        public void testGetPeriodConverterRemovedNull() {
714            try {
715                ConverterManager.getInstance().removePeriodConverter(NullConverter.INSTANCE);
716                try {
717                    ConverterManager.getInstance().getPeriodConverter(null);
718                    fail();
719                } catch (IllegalArgumentException ex) {}
720            } finally {
721                ConverterManager.getInstance().addPeriodConverter(NullConverter.INSTANCE);
722            }
723            assertEquals(PERIOD_SIZE, ConverterManager.getInstance().getPeriodConverters().length);
724        }
725    
726        //-----------------------------------------------------------------------
727        public void testGetPeriodConverters() {
728            PeriodConverter[] array = ConverterManager.getInstance().getPeriodConverters();
729            assertEquals(PERIOD_SIZE, array.length);
730        }
731    
732        //-----------------------------------------------------------------------
733        public void testAddPeriodConverter1() {
734            PeriodConverter c = new PeriodConverter() {
735                public void setInto(ReadWritablePeriod duration, Object object, Chronology c) {}
736                public PeriodType getPeriodType(Object object) {return null;}
737                public Class getSupportedType() {return Boolean.class;}
738            };
739            try {
740                PeriodConverter removed = ConverterManager.getInstance().addPeriodConverter(c);
741                assertEquals(null, removed);
742                assertEquals(Boolean.class, ConverterManager.getInstance().getPeriodConverter(Boolean.TRUE).getSupportedType());
743                assertEquals(PERIOD_SIZE + 1, ConverterManager.getInstance().getPeriodConverters().length);
744            } finally {
745                ConverterManager.getInstance().removePeriodConverter(c);
746            }
747            assertEquals(PERIOD_SIZE, ConverterManager.getInstance().getPeriodConverters().length);
748        }
749    
750        public void testAddPeriodConverter2() {
751            PeriodConverter c = new PeriodConverter() {
752                public void setInto(ReadWritablePeriod duration, Object object, Chronology c) {}
753                public PeriodType getPeriodType(Object object) {return null;}
754                public Class getSupportedType() {return String.class;}
755            };
756            try {
757                PeriodConverter removed = ConverterManager.getInstance().addPeriodConverter(c);
758                assertEquals(StringConverter.INSTANCE, removed);
759                assertEquals(String.class, ConverterManager.getInstance().getPeriodConverter("").getSupportedType());
760                assertEquals(PERIOD_SIZE, ConverterManager.getInstance().getPeriodConverters().length);
761            } finally {
762                ConverterManager.getInstance().addPeriodConverter(StringConverter.INSTANCE);
763            }
764            assertEquals(PERIOD_SIZE, ConverterManager.getInstance().getPeriodConverters().length);
765        }
766    
767        public void testAddPeriodConverter3() {
768            PeriodConverter removed = ConverterManager.getInstance().addPeriodConverter(null);
769            assertEquals(null, removed);
770            assertEquals(PERIOD_SIZE, ConverterManager.getInstance().getPeriodConverters().length);
771        }
772    
773        public void testAddPeriodConverterSecurity() {
774            if (OLD_JDK) {
775                return;
776            }
777            try {
778                Policy.setPolicy(RESTRICT);
779                System.setSecurityManager(new SecurityManager());
780                ConverterManager.getInstance().addPeriodConverter(StringConverter.INSTANCE);
781                fail();
782            } catch (SecurityException ex) {
783                // ok
784            } finally {
785                System.setSecurityManager(null);
786                Policy.setPolicy(ALLOW);
787            }
788            assertEquals(PERIOD_SIZE, ConverterManager.getInstance().getPeriodConverters().length);
789        }
790    
791        //-----------------------------------------------------------------------
792        public void testRemovePeriodConverter1() {
793            try {
794                PeriodConverter removed = ConverterManager.getInstance().removePeriodConverter(StringConverter.INSTANCE);
795                assertEquals(StringConverter.INSTANCE, removed);
796                assertEquals(PERIOD_SIZE - 1, ConverterManager.getInstance().getPeriodConverters().length);
797            } finally {
798                ConverterManager.getInstance().addPeriodConverter(StringConverter.INSTANCE);
799            }
800            assertEquals(PERIOD_SIZE, ConverterManager.getInstance().getPeriodConverters().length);
801        }
802    
803        public void testRemovePeriodConverter2() {
804            PeriodConverter c = new PeriodConverter() {
805                public void setInto(ReadWritablePeriod duration, Object object, Chronology c) {}
806                public PeriodType getPeriodType(Object object) {return null;}
807                public Class getSupportedType() {return Boolean.class;}
808            };
809            PeriodConverter removed = ConverterManager.getInstance().removePeriodConverter(c);
810            assertEquals(null, removed);
811            assertEquals(PERIOD_SIZE, ConverterManager.getInstance().getPeriodConverters().length);
812        }
813    
814        public void testRemovePeriodConverter3() {
815            PeriodConverter removed = ConverterManager.getInstance().removePeriodConverter(null);
816            assertEquals(null, removed);
817            assertEquals(PERIOD_SIZE, ConverterManager.getInstance().getPeriodConverters().length);
818        }
819    
820        public void testRemovePeriodConverterSecurity() {
821            if (OLD_JDK) {
822                return;
823            }
824            try {
825                Policy.setPolicy(RESTRICT);
826                System.setSecurityManager(new SecurityManager());
827                ConverterManager.getInstance().removePeriodConverter(StringConverter.INSTANCE);
828                fail();
829            } catch (SecurityException ex) {
830                // ok
831            } finally {
832                System.setSecurityManager(null);
833                Policy.setPolicy(ALLOW);
834            }
835            assertEquals(PERIOD_SIZE, ConverterManager.getInstance().getPeriodConverters().length);
836        }
837    
838        //-----------------------------------------------------------------------
839        //-----------------------------------------------------------------------
840        private static int INTERVAL_SIZE = 3;
841    
842        public void testGetIntervalConverter() {
843            IntervalConverter c = ConverterManager.getInstance().getIntervalConverter(new Interval(0L, 1000L));
844            assertEquals(ReadableInterval.class, c.getSupportedType());
845            
846            c = ConverterManager.getInstance().getIntervalConverter("");
847            assertEquals(String.class, c.getSupportedType());
848            
849            c = ConverterManager.getInstance().getIntervalConverter(null);
850            assertEquals(null, c.getSupportedType());
851            
852            try {
853                ConverterManager.getInstance().getIntervalConverter(Boolean.TRUE);
854                fail();
855            } catch (IllegalArgumentException ex) {}
856            try {
857                ConverterManager.getInstance().getIntervalConverter(new Long(0));
858                fail();
859            } catch (IllegalArgumentException ex) {}
860        }
861    
862        public void testGetIntervalConverterRemovedNull() {
863            try {
864                ConverterManager.getInstance().removeIntervalConverter(NullConverter.INSTANCE);
865                try {
866                    ConverterManager.getInstance().getIntervalConverter(null);
867                    fail();
868                } catch (IllegalArgumentException ex) {}
869            } finally {
870                ConverterManager.getInstance().addIntervalConverter(NullConverter.INSTANCE);
871            }
872            assertEquals(INTERVAL_SIZE, ConverterManager.getInstance().getIntervalConverters().length);
873        }
874    
875        //-----------------------------------------------------------------------
876        public void testGetIntervalConverters() {
877            IntervalConverter[] array = ConverterManager.getInstance().getIntervalConverters();
878            assertEquals(INTERVAL_SIZE, array.length);
879        }
880    
881        //-----------------------------------------------------------------------
882        public void testAddIntervalConverter1() {
883            IntervalConverter c = new IntervalConverter() {
884                public boolean isReadableInterval(Object object, Chronology chrono) {return false;}
885                public void setInto(ReadWritableInterval interval, Object object, Chronology chrono) {}
886                public Class getSupportedType() {return Boolean.class;}
887            };
888            try {
889                IntervalConverter removed = ConverterManager.getInstance().addIntervalConverter(c);
890                assertEquals(null, removed);
891                assertEquals(Boolean.class, ConverterManager.getInstance().getIntervalConverter(Boolean.TRUE).getSupportedType());
892                assertEquals(INTERVAL_SIZE + 1, ConverterManager.getInstance().getIntervalConverters().length);
893            } finally {
894                ConverterManager.getInstance().removeIntervalConverter(c);
895            }
896            assertEquals(INTERVAL_SIZE, ConverterManager.getInstance().getIntervalConverters().length);
897        }
898    
899        public void testAddIntervalConverter2() {
900            IntervalConverter c = new IntervalConverter() {
901                public boolean isReadableInterval(Object object, Chronology chrono) {return false;}
902                public void setInto(ReadWritableInterval interval, Object object, Chronology chrono) {}
903                public Class getSupportedType() {return String.class;}
904            };
905            try {
906                IntervalConverter removed = ConverterManager.getInstance().addIntervalConverter(c);
907                assertEquals(StringConverter.INSTANCE, removed);
908                assertEquals(String.class, ConverterManager.getInstance().getIntervalConverter("").getSupportedType());
909                assertEquals(INTERVAL_SIZE, ConverterManager.getInstance().getIntervalConverters().length);
910            } finally {
911                ConverterManager.getInstance().addIntervalConverter(StringConverter.INSTANCE);
912            }
913            assertEquals(INTERVAL_SIZE, ConverterManager.getInstance().getIntervalConverters().length);
914        }
915    
916        public void testAddIntervalConverter3() {
917            IntervalConverter removed = ConverterManager.getInstance().addIntervalConverter(null);
918            assertEquals(null, removed);
919            assertEquals(INTERVAL_SIZE, ConverterManager.getInstance().getIntervalConverters().length);
920        }
921    
922        public void testAddIntervalConverterSecurity() {
923            if (OLD_JDK) {
924                return;
925            }
926            try {
927                Policy.setPolicy(RESTRICT);
928                System.setSecurityManager(new SecurityManager());
929                ConverterManager.getInstance().addIntervalConverter(StringConverter.INSTANCE);
930                fail();
931            } catch (SecurityException ex) {
932                // ok
933            } finally {
934                System.setSecurityManager(null);
935                Policy.setPolicy(ALLOW);
936            }
937            assertEquals(INTERVAL_SIZE, ConverterManager.getInstance().getIntervalConverters().length);
938        }
939    
940        //-----------------------------------------------------------------------
941        public void testRemoveIntervalConverter1() {
942            try {
943                IntervalConverter removed = ConverterManager.getInstance().removeIntervalConverter(StringConverter.INSTANCE);
944                assertEquals(StringConverter.INSTANCE, removed);
945                assertEquals(INTERVAL_SIZE - 1, ConverterManager.getInstance().getIntervalConverters().length);
946            } finally {
947                ConverterManager.getInstance().addIntervalConverter(StringConverter.INSTANCE);
948            }
949            assertEquals(INTERVAL_SIZE, ConverterManager.getInstance().getIntervalConverters().length);
950        }
951    
952        public void testRemoveIntervalConverter2() {
953            IntervalConverter c = new IntervalConverter() {
954                public boolean isReadableInterval(Object object, Chronology chrono) {return false;}
955                public void setInto(ReadWritableInterval interval, Object object, Chronology chrono) {}
956                public Class getSupportedType() {return Boolean.class;}
957            };
958            IntervalConverter removed = ConverterManager.getInstance().removeIntervalConverter(c);
959            assertEquals(null, removed);
960            assertEquals(INTERVAL_SIZE, ConverterManager.getInstance().getIntervalConverters().length);
961        }
962    
963        public void testRemoveIntervalConverter3() {
964            IntervalConverter removed = ConverterManager.getInstance().removeIntervalConverter(null);
965            assertEquals(null, removed);
966            assertEquals(INTERVAL_SIZE, ConverterManager.getInstance().getIntervalConverters().length);
967        }
968    
969        public void testRemoveIntervalConverterSecurity() {
970            if (OLD_JDK) {
971                return;
972            }
973            try {
974                Policy.setPolicy(RESTRICT);
975                System.setSecurityManager(new SecurityManager());
976                ConverterManager.getInstance().removeIntervalConverter(StringConverter.INSTANCE);
977                fail();
978            } catch (SecurityException ex) {
979                // ok
980            } finally {
981                System.setSecurityManager(null);
982                Policy.setPolicy(ALLOW);
983            }
984            assertEquals(INTERVAL_SIZE, ConverterManager.getInstance().getIntervalConverters().length);
985        }
986    
987        //-----------------------------------------------------------------------
988        public void testToString() {
989            assertEquals("ConverterManager[6 instant,7 partial,5 duration,5 period,3 interval]", ConverterManager.getInstance().toString());
990        }
991    
992    }