/*
* @(#)ExternExampleEvolvedClass.java 1.3 98/10/01
*
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
*
* This software is the confidential and proprietary information of Sun
* Microsystems, Inc. ("Confidential Information"). You shall not
* disclose such Confidential Information and shall use it only in
* accordance with the terms of the license agreement you entered into
* with Sun.
*
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
* THIS SOFTWARE OR ITS DERIVATIVES.
*
*
*/
import java.io.*;
import java.util.*;
/**
* This is a continuation of the Externalizable Persistence Example.
* This file contains the evolved version of the ExternVersioningClass.
* Of course, normally, the evolved class would actually take place of the
* original class but we just keep both of them to demonstrate the evolution
*
* For information on how to run, see file ExternExampleOriginalClass.java
*/
public class ExternExampleEvolvedClass {
/**
* There are two options: either a user can serialize an object or
* deserialize it. (using the -s or -d flag). These options allow
* for the demonstration of bidirection readability and writeability
* between the original and the evolved class. In other words,
* one can serialize an object here and deserialize it with the evolved
* class or vice versa.
*/
public static void main(String args[]) {
boolean serialize = false;
boolean deserialize = false;
ExternVersioningClass wobj = new ExternVersioningClass
(1, "evolvedclass", true, 1.23);
ExternVersioningClass robj = null;
/*
* see if we are serializing or deserializing.
* The ability to deserialize or serialize allows
* us to see the bidirectional readability and writeability
*/
if (args.length == 1) {
if (args[0].equals("-d")) {
deserialize = true;
} else if (args[0].equals("-s")) {
serialize = true;
} else {
usage();
System.exit(0);
}
} else {
usage();
System.exit(0);
}
/*
* serialize, if that's the chosen option
*/
if (serialize) {
try {
FileOutputStream fo = new FileOutputStream("evolve.tmp");
ObjectOutputStream so = new ObjectOutputStream(fo);
so.writeObject(wobj);
so.flush();
} catch (Exception e) {
System.out.println(e);
System.exit(1);
}
}
/*
* deserialize, if that's the chosen option
*/
if (deserialize) {
try {
FileInputStream fi = new FileInputStream("evolve.tmp");
ObjectInputStream si = new ObjectInputStream(fi);
robj = (ExternVersioningClass) si.readObject();
} catch (Exception e) {
System.out.println(e);
System.exit(1);
}
}
}
/**
* Prints out the usage
*/
static void usage() {
System.out.println("Usage:");
System.out.println(" -s (in order to serialize)");
System.out.println(" -d (in order to deserialize)");
}
}
/**
* The evolved class!
*/
class ExternVersioningClass implements Externalizable {
/*
* Each versioned class must identify the original class version from which
* it evolved. This SUID is obtained using the command serialver on the
* original class
*/
static final long serialVersionUID = -6527577423406625824L;
public static final int version = 2;
// the data that was part of the original class
int dimension;
int array[];
String name;
// new data
boolean b;
double d;
// ***need to have a public-no-arg constructor***
public ExternVersioningClass() {}
ExternVersioningClass(int dim, String n, boolean boo, double dou){
// initialize
dimension = dim;
array = new int[dimension];
name = n;
b = boo;
d = dou;
}
/**
* the mandatory writeExternal method. First writes out the version number
* (ie. 2 because this is the evolved class.) Then writes out the fields
* that were a part of the original class and then the fields that are
* in this class. (since the original class assumes that the new data
* fields are appended)
*
* @serialData Writes out the int "class version number" 2. Next, the
* dimension field is written as an int. Followed by
* the array field written as an object. The
* name field is written as an object. The new b field is
* written as a boolean. Lastly, the new d field is written
* as a double.
*/
public void writeExternal(ObjectOutput out) throws IOException {
// we first write out the class version number (ie. # 2)
out.writeInt(version);
// We have to first write out the data of the original class because it
// it assumes that we appended the new data.
out.writeInt(dimension);
out.writeObject(array);
out.writeObject(name);
// the original class will ignore this data.
out.writeBoolean(b);
out.writeDouble(d);
}
/**
* mandatory readExternal method.
*
* @serialData First reads in the version number and
* then if the version number suggests that the object
* was written as an original class, gives the new fields
* default values but if the object was written by this
* evolved class, then reads in all the fields accordingly.
*/
public void readExternal(ObjectInput in)
throws IOException, java.lang.ClassNotFoundException
{
int version = in.readInt();
System.out.println
("Reading an Object written by Version #: " + version);
dimension = in.readInt();
// need to allocate memory for the array we will read in
array = (int[]) in.readObject();
name = (String) in.readObject();
/*
* only if the object was written out by the evolved class, do we
* read in the rest of the data.
*/
if (version == 2) {
b = in.readBoolean();
d = in.readDouble();
}
// otherwise, we give it default values
else if(version == 1) {
b = true;
d = 1.00;
}
}
}
|