ICU-3474 serialization fix for icu4j calendar

X-SVN-Rev: 22500
This commit is contained in:
Steven R. Loomis 2007-08-24 00:17:00 +00:00
parent a5af7ed95a
commit 0d1388172a
2 changed files with 111 additions and 16 deletions

View file

@ -7,6 +7,11 @@
package com.ibm.icu.dev.test.calendar;
import com.ibm.icu.util.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Date;
import java.util.Locale;
import java.util.MissingResourceException;
@ -1949,6 +1954,108 @@ public class CalendarRegression extends com.ibm.icu.dev.test.TestFmwk {
*/
}
/**
* test serialize-and-modify.
* @throws ClassNotFoundException
*/
public void TestSerialization3474() {
try {
ByteArrayOutputStream icuStream = new ByteArrayOutputStream();
logln("icu Calendar");
com.ibm.icu.util.GregorianCalendar icuCalendar =
new com.ibm.icu.util.GregorianCalendar();
icuCalendar.setTimeInMillis(1187912555931L);
long expectMillis = 1187912520931L; // with seconds (not ms) cleared.
logln("instantiated: "+icuCalendar);
logln("getMillis: "+icuCalendar.getTimeInMillis());
icuCalendar.set(com.ibm.icu.util.GregorianCalendar.SECOND, 0);
logln("setSecond=0: "+icuCalendar);
{
long gotMillis = icuCalendar.getTimeInMillis();
if(gotMillis != expectMillis) {
errln("expect millis "+expectMillis+" but got "+gotMillis);
} else {
logln("getMillis: "+gotMillis);
}
}
ObjectOutputStream icuOut =
new ObjectOutputStream(icuStream);
icuOut.writeObject(icuCalendar);
icuOut.flush();
icuOut.close();
ObjectInputStream icuIn =
new ObjectInputStream(new ByteArrayInputStream(icuStream.toByteArray()));
icuCalendar = null;
icuCalendar = (com.ibm.icu.util.GregorianCalendar)icuIn.readObject();
logln("serialized back in: "+icuCalendar);
{
long gotMillis = icuCalendar.getTimeInMillis();
if(gotMillis != expectMillis) {
errln("expect millis "+expectMillis+" but got "+gotMillis);
} else {
logln("getMillis: "+gotMillis);
}
}
icuCalendar.set(com.ibm.icu.util.GregorianCalendar.SECOND, 0);
logln("setSecond=0: "+icuCalendar);
{
long gotMillis = icuCalendar.getTimeInMillis();
if(gotMillis != expectMillis) {
errln("expect millis "+expectMillis+" after stream and setSecond but got "+gotMillis);
} else {
logln("getMillis after stream and setSecond: "+gotMillis);
}
}
} catch(IOException e) {
errln(e.toString());
e.printStackTrace();
} catch(ClassNotFoundException cnf) {
errln(cnf.toString());
cnf.printStackTrace();
}
// JDK works correctly, etc etc.
// ByteArrayOutputStream jdkStream = new ByteArrayOutputStream();
// logln("\nSUN Calendar");
//
// java.util.GregorianCalendar sunCalendar =
// new java.util.GregorianCalendar();
//
// logln("instanzieren: "+sunCalendar);
// logln("getMillis: "+sunCalendar.getTimeInMillis());
// sunCalendar.set(java.util.GregorianCalendar.SECOND, 0);
// logln("setSecond=0: "+sunCalendar);
// logln("getMillis: "+sunCalendar.getTimeInMillis());
//
// ObjectOutputStream sunOut =
// new ObjectOutputStream(jdkStream);
// sunOut.writeObject(sunCalendar);
// sunOut.flush();
// sunOut.close();
//
// ObjectInputStream sunIn =
// new ObjectInputStream(new ByteArrayInputStream(jdkStream.toByteArray()));
// sunCalendar = null;
// sunCalendar = (java.util.GregorianCalendar)sunIn.readObject();
//
// logln("serialized: "+sunCalendar);
// logln("getMillis: "+sunCalendar.getTimeInMillis());
//
// sunCalendar.set(java.util.GregorianCalendar.SECOND, 0);
// logln("setSecond=0: "+sunCalendar);
// logln("getMillis: "+sunCalendar.getTimeInMillis());
}
}
//eof

View file

@ -1310,9 +1310,9 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable {
/**
* True if all fields have been virtually set, but have not yet been
* computed. This occurs only in setTimeInMillis(). A calendar set
* to this state will compute all fields from the time if it becomes
* necessary, but otherwise will delay such computation.
* computed. This occurs only in setTimeInMillis(), or after readObject().
* A calendar set to this state will compute all fields from the time if it
* becomes necessary, but otherwise will delay such computation.
*/
private transient boolean areFieldsVirtuallySet;
@ -1416,9 +1416,6 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable {
/**
* The next available value for <code>stamp[]</code>, an internal array.
* This actually should not be written out to the stream, and will probably
* be removed from the stream in the near future. In the meantime,
* a value of <code>MINIMUM_USER_STAMP</code> should be used.
* @serial
*/
private transient int nextStamp = MINIMUM_USER_STAMP;
@ -3968,16 +3965,6 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable {
/**
* Save the state of this object to a stream (i.e., serialize it).
*
* Ideally, <code>Calendar</code> would only write out its state data and
* the current time, and not write any field data out, such as
* <code>fields[]</code>, <code>isTimeSet</code>, <code>areFieldsSet</code>,
* and <code>isSet[]</code>. <code>nextStamp</code> also should not be part
* of the persistent state. Unfortunately, this didn't happen before JDK 1.1
* shipped. To be compatible with JDK 1.1, we will always have to write out
* the field values and state flags. However, <code>nextStamp</code> can be
* removed from the serialization stream; this will probably happen in the
* near future.
*/
private void writeObject(ObjectOutputStream stream)
throws IOException
@ -4007,6 +3994,7 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable {
isTimeSet = true;
areFieldsSet = areAllFieldsSet = false;
areFieldsVirtuallySet = true; // cause fields to be recalculated if requested.
nextStamp = MINIMUM_USER_STAMP;
}