001 /*
002 * Copyright 2001-2005 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;
017
018 import java.io.ByteArrayInputStream;
019 import java.io.ByteArrayOutputStream;
020 import java.io.FileInputStream;
021 import java.io.FileOutputStream;
022 import java.io.ObjectInputStream;
023 import java.io.ObjectOutputStream;
024 import java.io.Serializable;
025 import java.util.Locale;
026 import java.util.TimeZone;
027
028 import junit.framework.TestCase;
029 import junit.framework.TestSuite;
030
031 import org.joda.time.chrono.BuddhistChronology;
032 import org.joda.time.chrono.CopticChronology;
033 import org.joda.time.chrono.GJChronology;
034 import org.joda.time.chrono.GregorianChronology;
035 import org.joda.time.chrono.ISOChronology;
036 import org.joda.time.chrono.JulianChronology;
037 import org.joda.time.field.DelegatedDurationField;
038 import org.joda.time.field.MillisDurationField;
039 import org.joda.time.field.UnsupportedDateTimeField;
040 import org.joda.time.field.UnsupportedDurationField;
041
042 /**
043 * This class is a Junit unit test for serialization.
044 *
045 * @author Stephen Colebourne
046 */
047 public class TestSerialization extends TestCase {
048 // Test in 2002/03 as time zones are more well known
049 // (before the late 90's they were all over the place)
050
051 private static final DateTimeZone PARIS = DateTimeZone.forID("Europe/Paris");
052 private static final DateTimeZone LONDON = DateTimeZone.forID("Europe/London");
053 private static final DateTimeZone TOKYO = DateTimeZone.forID("Asia/Tokyo");
054
055 long y2002days = 365 + 365 + 366 + 365 + 365 + 365 + 366 + 365 + 365 + 365 +
056 366 + 365 + 365 + 365 + 366 + 365 + 365 + 365 + 366 + 365 +
057 365 + 365 + 366 + 365 + 365 + 365 + 366 + 365 + 365 + 365 +
058 366 + 365;
059 long y2003days = 365 + 365 + 366 + 365 + 365 + 365 + 366 + 365 + 365 + 365 +
060 366 + 365 + 365 + 365 + 366 + 365 + 365 + 365 + 366 + 365 +
061 365 + 365 + 366 + 365 + 365 + 365 + 366 + 365 + 365 + 365 +
062 366 + 365 + 365;
063
064 // 2002-06-09
065 private long TEST_TIME_NOW =
066 (y2002days + 31L + 28L + 31L + 30L + 31L + 9L -1L) * DateTimeConstants.MILLIS_PER_DAY;
067
068 // 2002-04-05
069 private long TEST_TIME1 =
070 (y2002days + 31L + 28L + 31L + 5L -1L) * DateTimeConstants.MILLIS_PER_DAY
071 + 12L * DateTimeConstants.MILLIS_PER_HOUR
072 + 24L * DateTimeConstants.MILLIS_PER_MINUTE;
073
074 // 2003-05-06
075 private long TEST_TIME2 =
076 (y2003days + 31L + 28L + 31L + 30L + 6L -1L) * DateTimeConstants.MILLIS_PER_DAY
077 + 14L * DateTimeConstants.MILLIS_PER_HOUR
078 + 28L * DateTimeConstants.MILLIS_PER_MINUTE;
079
080 private static class MockDelegatedDurationField extends DelegatedDurationField implements Serializable {
081 private static final long serialVersionUID = 1878496002811998493L;
082 public MockDelegatedDurationField() {
083 super(MillisDurationField.INSTANCE);
084 }
085 }
086
087 private DateTimeZone originalDateTimeZone = null;
088 private TimeZone originalTimeZone = null;
089 private Locale originalLocale = null;
090
091 public static void main(String[] args) {
092 junit.textui.TestRunner.run(suite());
093 }
094
095 public static TestSuite suite() {
096 return new TestSuite(TestSerialization.class);
097 }
098
099 public TestSerialization(String name) {
100 super(name);
101 }
102
103 protected void setUp() throws Exception {
104 DateTimeUtils.setCurrentMillisFixed(TEST_TIME_NOW);
105 originalDateTimeZone = DateTimeZone.getDefault();
106 originalTimeZone = TimeZone.getDefault();
107 originalLocale = Locale.getDefault();
108 DateTimeZone.setDefault(LONDON);
109 TimeZone.setDefault(TimeZone.getTimeZone("Europe/London"));
110 Locale.setDefault(Locale.UK);
111 }
112
113 protected void tearDown() throws Exception {
114 DateTimeUtils.setCurrentMillisSystem();
115 DateTimeZone.setDefault(originalDateTimeZone);
116 TimeZone.setDefault(originalTimeZone);
117 Locale.setDefault(originalLocale);
118 originalDateTimeZone = null;
119 originalTimeZone = null;
120 originalLocale = null;
121 }
122
123 //-----------------------------------------------------------------------
124 public void testTest() {
125 assertEquals("2002-06-09T00:00:00.000Z", new Instant(TEST_TIME_NOW).toString());
126 assertEquals("2002-04-05T12:24:00.000Z", new Instant(TEST_TIME1).toString());
127 assertEquals("2003-05-06T14:28:00.000Z", new Instant(TEST_TIME2).toString());
128 }
129
130 //-----------------------------------------------------------------------
131 public void testSerializedInstant() throws Exception {
132 Instant test = new Instant();
133 loadAndCompare(test, "Instant", false);
134 inlineCompare(test, false);
135 }
136
137 public void testSerializedDateTime() throws Exception {
138 DateTime test = new DateTime();
139 loadAndCompare(test, "DateTime", false);
140 inlineCompare(test, false);
141 }
142
143 public void testSerializedDateTimeProperty() throws Exception {
144 DateTime.Property test = new DateTime().hourOfDay();
145 loadAndCompare(test, "DateTimeProperty", false);
146 inlineCompare(test, false);
147 }
148
149 public void testSerializedMutableDateTime() throws Exception {
150 MutableDateTime test = new MutableDateTime();
151 loadAndCompare(test, "MutableDateTime", false);
152 inlineCompare(test, false);
153 }
154
155 public void testSerializedMutableDateTimeProperty() throws Exception {
156 MutableDateTime.Property test = new MutableDateTime().hourOfDay();
157 loadAndCompare(test, "MutableDateTimeProperty", false);
158 inlineCompare(test, false);
159 }
160
161 public void testSerializedDateMidnight() throws Exception {
162 DateMidnight test = new DateMidnight();
163 loadAndCompare(test, "DateMidnight", false);
164 inlineCompare(test, false);
165 }
166
167 public void testSerializedDateMidnightProperty() throws Exception {
168 DateMidnight.Property test = new DateMidnight().monthOfYear();
169 loadAndCompare(test, "DateMidnightProperty", false);
170 inlineCompare(test, false);
171 }
172
173 public void testSerializedLocalDate() throws Exception {
174 LocalDate test = new LocalDate();
175 loadAndCompare(test, "LocalDate", false);
176 inlineCompare(test, false);
177 }
178
179 public void testSerializedLocalDateBuddhist() throws Exception {
180 LocalDate test = new LocalDate(BuddhistChronology.getInstanceUTC());
181 loadAndCompare(test, "LocalDateBuddhist", false);
182 inlineCompare(test, false);
183 }
184
185 public void testSerializedLocalTime() throws Exception {
186 LocalTime test = new LocalTime();
187 loadAndCompare(test, "LocalTime", false);
188 inlineCompare(test, false);
189 }
190
191 public void testSerializedLocalDateTime() throws Exception {
192 LocalDateTime test = new LocalDateTime();
193 loadAndCompare(test, "LocalDateTime", false);
194 inlineCompare(test, false);
195 }
196
197 public void testSerializedYearMonthDay() throws Exception {
198 YearMonthDay test = new YearMonthDay();
199 loadAndCompare(test, "YearMonthDay", false);
200 inlineCompare(test, false);
201 }
202
203 public void testSerializedTimeOfDay() throws Exception {
204 TimeOfDay test = new TimeOfDay();
205 loadAndCompare(test, "TimeOfDay", false);
206 inlineCompare(test, false);
207 }
208
209 public void testSerializedDateTimeZoneUTC() throws Exception {
210 DateTimeZone test = DateTimeZone.UTC;
211 loadAndCompare(test, "DateTimeZoneUTC", true);
212 inlineCompare(test, true);
213 }
214
215 public void testSerializedDateTimeZone() throws Exception {
216 // have to re-get the zone, as TestDateTimeZone may have
217 // changed the cache, or a SoftReference may have got cleared
218 DateTimeZone test = DateTimeZone.forID("Europe/Paris");
219 loadAndCompare(test, "DateTimeZone", true);
220 inlineCompare(test, true);
221 }
222
223 public void testDuration() throws Exception {
224 Duration test = Duration.millis(12345);
225 loadAndCompare(test, "Duration", false);
226 inlineCompare(test, false);
227 }
228
229 public void testSerializedCopticChronology() throws Exception {
230 CopticChronology test = CopticChronology.getInstance(LONDON);
231 loadAndCompare(test, "CopticChronology", true);
232 inlineCompare(test, true);
233 }
234
235 public void testSerializedISOChronology() throws Exception {
236 ISOChronology test = ISOChronology.getInstance(PARIS);
237 loadAndCompare(test, "ISOChronology", true);
238 inlineCompare(test, true);
239 }
240
241 public void testSerializedGJChronology() throws Exception {
242 GJChronology test = GJChronology.getInstance(TOKYO);
243 loadAndCompare(test, "GJChronology", true);
244 inlineCompare(test, true);
245 }
246
247 public void testSerializedGJChronologyChangedInternals() throws Exception {
248 GJChronology test = GJChronology.getInstance(PARIS, 123L, 2);
249 loadAndCompare(test, "GJChronologyChangedInternals", true);
250 inlineCompare(test, true);
251 }
252
253 public void testSerializedGregorianChronology() throws Exception {
254 GregorianChronology test = GregorianChronology.getInstance(PARIS);
255 loadAndCompare(test, "GregorianChronology", true);
256 inlineCompare(test, true);
257 }
258
259 public void testSerializedJulianChronology() throws Exception {
260 JulianChronology test = JulianChronology.getInstance(PARIS);
261 loadAndCompare(test, "JulianChronology", true);
262 inlineCompare(test, true);
263 }
264
265 public void testSerializedBuddhistChronology() throws Exception {
266 BuddhistChronology test = BuddhistChronology.getInstance(PARIS);
267 loadAndCompare(test, "BuddhistChronology", true);
268 inlineCompare(test, true);
269 }
270
271 public void testSerializedPeriodType() throws Exception {
272 PeriodType test = PeriodType.dayTime();
273 loadAndCompare(test, "PeriodType", false);
274 inlineCompare(test, false);
275 }
276
277 public void testSerializedDateTimeFieldType() throws Exception {
278 DateTimeFieldType test = DateTimeFieldType.clockhourOfDay();
279 loadAndCompare(test, "DateTimeFieldType", true);
280 inlineCompare(test, true);
281 }
282
283 public void testSerializedUnsupportedDateTimeField() throws Exception {
284 UnsupportedDateTimeField test = UnsupportedDateTimeField.getInstance(
285 DateTimeFieldType.year(),
286 UnsupportedDurationField.getInstance(DurationFieldType.years()));
287 loadAndCompare(test, "UnsupportedDateTimeField", true);
288 inlineCompare(test, true);
289 }
290
291 private void loadAndCompare(Serializable test, String filename, boolean same) throws Exception {
292 FileInputStream fis = new FileInputStream("src/test/resources/" + filename + ".dat");
293 ObjectInputStream ois = new ObjectInputStream(fis);
294 Object obj = ois.readObject();
295 ois.close();
296 if (same) {
297 assertSame(test, obj);
298 } else {
299 assertEquals(test, obj);
300 }
301 // try {
302 // fis = new FileInputStream("src/test/resources/" + filename + "2.dat");
303 // ois = new ObjectInputStream(fis);
304 // obj = ois.readObject();
305 // ois.close();
306 // if (same) {
307 // assertSame(test, obj);
308 // } else {
309 // assertEquals(test, obj);
310 // }
311 // } catch (FileNotFoundException ex) {
312 // // ignore
313 // }
314 }
315
316 public void inlineCompare(Serializable test, boolean same) throws Exception {
317 ByteArrayOutputStream baos = new ByteArrayOutputStream();
318 ObjectOutputStream oos = new ObjectOutputStream(baos);
319 oos.writeObject(test);
320 oos.close();
321
322 ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
323 ObjectInputStream ois = new ObjectInputStream(bais);
324 Object obj = ois.readObject();
325 ois.close();
326
327 if (same) {
328 assertSame(test, obj);
329 } else {
330 assertEquals(test, obj);
331 }
332 }
333
334 // //-----------------------------------------------------------------------
335 // public void testStoreSerializedInstant() throws Exception {
336 // Instant test = new Instant();
337 // store(test, "Instant.dat");
338 // }
339 //
340 // public void testStoreSerializedDateTime() throws Exception {
341 // DateTime test = new DateTime();
342 // store(test, "DateTime.dat");
343 // }
344 //
345 // public void testStoreSerializedMutableDateTime() throws Exception {
346 // MutableDateTime test = new MutableDateTime();
347 // store(test, "MutableDateTime.dat");
348 // }
349 //
350 // public void testStoreSerializedDateMidnight() throws Exception {
351 // DateMidnight test = new DateMidnight();
352 // store(test, "DateMidnight.dat");
353 // }
354 //
355 // public void testStoreSerializedLocalDate() throws Exception {
356 // LocalDate test = new LocalDate();
357 // store(test, "LocalDate.dat");
358 // }
359 //
360 // public void testStoreSerializedLocalDateBuddhist() throws Exception {
361 // LocalDate test = new LocalDate(BuddhistChronology.getInstanceUTC());
362 // store(test, "LocalDateBuddhist.dat");
363 // }
364 //
365 // public void testStoreSerializedLocalTime() throws Exception {
366 // LocalTime test = new LocalTime();
367 // store(test, "LocalTime.dat");
368 // }
369 //
370 // public void testStoreSerializedLocalDateTime() throws Exception {
371 // LocalDateTime test = new LocalDateTime();
372 // store(test, "LocalDateTime.dat");
373 // }
374 //
375 // public void testStoreSerializedYearMonthDay() throws Exception {
376 // YearMonthDay test = new YearMonthDay();
377 // store(test, "YearMonthDay.dat");
378 // }
379 //
380 // public void testStoreSerializedYearMonthDayProperty() throws Exception {
381 // YearMonthDay.Property test = new YearMonthDay().monthOfYear();
382 // store(test, "YearMonthDayProperty.dat");
383 // }
384 //
385 // public void testStoreSerializedTimeOfDay() throws Exception {
386 // TimeOfDay test = new TimeOfDay();
387 // store(test, "TimeOfDay.dat");
388 // }
389 //
390 // public void testStoreSerializedTimeOfDayProperty() throws Exception {
391 // TimeOfDay.Property test = new TimeOfDay().hourOfDay();
392 // store(test, "TimeOfDayProperty.dat");
393 // }
394 //
395 // public void testStoreSerializedDateTimeZoneUTC() throws Exception {
396 // DateTimeZone test = DateTimeZone.UTC;
397 // store(test, "DateTimeZoneUTC.dat");
398 // }
399 //
400 // public void testStoreSerializedDateTimeZone() throws Exception {
401 // DateTimeZone test = PARIS;
402 // store(test, "DateTimeZone.dat");
403 // }
404 //
405 // public void testStoreSerializedCopticChronology() throws Exception {
406 // CopticChronology test = CopticChronology.getInstance(LONDON);
407 // store(test, "CopticChronology.dat");
408 // }
409 //
410 // public void testStoreSerializedISOChronology() throws Exception {
411 // ISOChronology test = ISOChronology.getInstance(PARIS);
412 // store(test, "ISOChronology.dat");
413 // }
414 //
415 // public void testStoreSerializedGJChronology() throws Exception {
416 // GJChronology test = GJChronology.getInstance(TOKYO);
417 // store(test, "GJChronology.dat");
418 // }
419 //
420 // // Format changed in v1.2 - min days in first week not deserialized in v1.0/1.1
421 // public void testStoreSerializedGJChronologyChangedInternals() throws Exception {
422 // GJChronology test = GJChronology.getInstance(PARIS, 123L, 2);
423 // store(test, "GJChronologyChangedInternals.dat");
424 // }
425 //
426 // public void testStoreSerializedGregorianChronology() throws Exception {
427 // GregorianChronology test = GregorianChronology.getInstance(PARIS);
428 // store(test, "GregorianChronology.dat");
429 // }
430 //
431 // public void testStoreSerializedJulianChronology() throws Exception {
432 // JulianChronology test = JulianChronology.getInstance(PARIS);
433 // store(test, "JulianChronology.dat");
434 // }
435 //
436 // public void testStoreSerializedBuddhistChronology() throws Exception {
437 // BuddhistChronology test = BuddhistChronology.getInstance(PARIS);
438 // store(test, "BuddhistChronology.dat");
439 // }
440 //
441 // public void testStoreSerializedPeriodType() throws Exception {
442 // PeriodType test = PeriodType.dayTime();
443 // store(test, "PeriodType.dat");
444 // }
445 //
446 // public void testStoreSerializedDateTimeFieldType() throws Exception {
447 // DateTimeFieldType test = DateTimeFieldType.clockhourOfDay();
448 // store(test, "DateTimeFieldType.dat");
449 // }
450 //
451 // public void testStoreSerializedUnsupportedDateTimeField() throws Exception {
452 // UnsupportedDateTimeField test = UnsupportedDateTimeField.getInstance(
453 // DateTimeFieldType.year(),
454 // UnsupportedDurationField.getInstance(DurationFieldType.years()));
455 // store(test, "UnsupportedDateTimeField.dat");
456 // }
457 //
458 // public void testStoreSerializedDurationFieldType() throws Exception {
459 // DurationFieldType test = DurationFieldType.MINUTES_TYPE;
460 // store(test, "DurationFieldType.dat");
461 // }
462 //
463 // public void testStoreSerializedMillisDurationField() throws Exception {
464 // MillisDurationField test = (MillisDurationField) MillisDurationField.INSTANCE;
465 // store(test, "MillisDurationField.dat");
466 // }
467 //
468 // public void testStoreSerializedDelegatedDurationField() throws Exception {
469 // DelegatedDurationField test = new MockDelegatedDurationField();
470 // store(test, "DelegatedDurationField.dat");
471 // }
472 //
473 // public void testStoreSerializedUnsupportedDurationField() throws Exception {
474 // UnsupportedDurationField test = UnsupportedDurationField.getInstance(DurationFieldType.eras());
475 // store(test, "UnsupportedDurationField.dat");
476 // }
477 //
478 // format changed (properly defined) in v1.1
479 // public void testStoreSerializedDateTimeProperty() throws Exception {
480 // DateTime.Property test = new DateTime().hourOfDay();
481 // store(test, "DateTimeProperty.dat");
482 // }
483 //
484 // public void testStoreSerializedMutableDateTimeProperty() throws Exception {
485 // MutableDateTime.Property test = new MutableDateTime().hourOfDay();
486 // store(test, "MutableDateTimeProperty.dat");
487 // }
488 //
489 // public void testStoreSerializedDateMidnightProperty() throws Exception {
490 // DateMidnight.Property test = new DateMidnight().monthOfYear();
491 // store(test, "DateMidnightProperty.dat");
492 // }
493 //
494 // public void testStoreSerializedDateMidnightProperty() throws Exception {
495 // Duration test = Duration.millis(12345);
496 // store(test, "Duration.dat");
497 // }
498
499 private void store(Serializable test, String filename) throws Exception {
500 FileOutputStream fos = new FileOutputStream("src/test/resources/" + filename);
501 ObjectOutputStream oos = new ObjectOutputStream(fos);
502 try {
503 oos.writeObject(test);
504 } finally {
505 oos.close();
506 }
507 oos.close();
508 }
509
510 }