home *** CD-ROM | disk | FTP | other *** search
Java Source | 1999-09-19 | 9.0 KB | 264 lines |
- /*
- *
- * @(#)EvolvedClass.java 1.7 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.awt.*;
-
- /**
- *
- * This example shows how to use the Serializable Fields API with
- * Serialization, demonstrating that the class can define fields
- * other than those already in the class to be serializable. This
- * differs from just rewriting the writeObject method to customize
- * the data format (see the Custom Data Format example) because,
- * in this example, versioning support still holds.
- *
- * Using the Serializable Fields API, this example specifically
- * changes the internal representation of a rectangle from
- * x1,y1,x2,y2 implementation (see Original Class) to Point(x1,y1),
- * Point(x2,y2) (see Evolved Class) while the external representation
- * still remains x1, y1, x2, y2. This ensures bidirectional compatibility
- * between the original and evolved representations.
- *
- * The original rectangle class (in OriginalClass.java) consists of four
- * integers (x1, y1, x2, y2). Instead of four integers, the evolved rectangle
- * class (in this file) has two Points as fields. In order for this
- * evolved class to fulfill its contract with the original class, the
- * evolved class saves its fields as four integers (x1, y1, x2, y2)
- * instead of two points. By doing this the evolved class ensures
- * bidirectional compatibility with the original class.
- *
- * To see how to run this: see OriginalClass.java
- *
- * Compiled and Tested with JDK1.2
- */
-
- public class EvolvedClass {
-
- /**
- * 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[]) {
-
- ARectangle orgClass = new ARectangle(100, 100, 102, 102);
- ARectangle newClass = null;
-
- boolean serialize = false;
- boolean deserialize = false;
-
- /*
- * 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 the original class if that's the option chosen
- */
- if (serialize) {
- try {
- FileOutputStream fo = new FileOutputStream("evolve.tmp");
- ObjectOutputStream so = new ObjectOutputStream(fo);
- so.writeObject(orgClass);
- so.flush();
- } catch (Exception e) {
- System.out.println(e);
- System.exit(1);
- }
- }
-
- /*
- * Deserialize, if that's the option chosen and print the name
- * of the object, which will allow us to see who serialized the
- * object, the original class or the evolved class file
- */
- if (deserialize) {
- try {
- FileInputStream fi = new FileInputStream("evolve.tmp");
- ObjectInputStream si = new ObjectInputStream(fi);
- newClass = (ARectangle) si.readObject();
- } catch (Exception e) {
- System.out.println(e);
- System.exit(1);
- }
- System.out.println("Now printing deserialized object: ");
- System.out.println();
- System.out.println(newClass);
- }
- }
-
- /**
- * 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 Rectangle Class. Interally consists of two fields of type
- * Point but externally is still 4 integers (so that it is compatible
- * with the original rectangle class)
- *
- * In order to make this possible, we need to use the Serializable
- * Field API so that we can define serializable fields that are
- * not part of the implementation class.
- */
- class ARectangle implements java.io.Serializable {
-
- // new rectangle representation
-
- /**
- * First of two points forming diagonal of rectangle.
- *
- * Note that this field is not a default serializable field
- * due to the use of serialPersistentFields member within this class.
- */
- Point point1;
-
-
- /**
- * Second of two points forming diagonal of rectangle.
- *
- * Note that this field is not a default serializable field
- * due to the use of serialPersistentFields member within this class.
- */
- Point point2;
-
- /*
- * mandatory SUID field for an evolved Serializable class.
- * serialVersionUID is gotten by doing the serialver command
- * on the original class:
- * serialver ARectangle (the original rectangle)
- */
- static final long serialVersionUID = 9030593813711490592L;
-
-
- /**
- * The special member, serialPeristentFields, explicitly declares
- * Serializable fields for this class. This allows for fields other
- * than the fields in the class to be persistent. Since we want to
- * save the state of the two Points point1 and point2, we declare
- * the 4 ints as the serial persistent fields
- *
- * @serialField x1 Integer
- * X-coordinate of point 1 of diagonal points of rectangle.
- * @serialField y1 Integer
- * Y-coordinate of point 1 of diagonal points of rectangle.
- * @serialField x2 Integer
- * X-coordinate of point 2 of diagonal points of rectangle.
- * @serialField y2 Integer
- * Y-coordinate of point 2 of diagonal points of rectangle.
- */
- private static final ObjectStreamField[] serialPersistentFields = {
- new ObjectStreamField("x1", Integer.TYPE),
- new ObjectStreamField("y1", Integer.TYPE),
- new ObjectStreamField("x2", Integer.TYPE),
- new ObjectStreamField("y2", Integer.TYPE)
- };
-
- ARectangle(int x1, int y1, int x2, int y2) {
- point1 = new Point(x1, y1);
- point2 = new Point(x2, y2);
- }
-
- /**
- * writeObject - Writes out the serializable fields
- * (the 4 integers, x1, y1, x2, y2) using the
- * Serializable Field API. (the methods putFields and
- * writeFields of the ObjectOutputStream Class and the method put
- * of the ObjectOutputStream.PutField inner class)
- *
- * @serialData Only the serializable fields of the class are written.
- * No optional data written.
- */
- private void writeObject(ObjectOutputStream s)
- throws IOException {
-
- // set the values of the Serializable fields
- ObjectOutputStream.PutField fields = s.putFields();
- fields.put("x1", point1.x);
- fields.put("y1", point1.y);
- fields.put("x2", point2.x);
- fields.put("y2", point2.y);
-
- // save them
- s.writeFields();
- }
-
- /**
- * readsObject - Reads in the serializable fields
- * (the 4 integers, x1, y1, x2, y2) using the
- * Serializable Field API. (the methods getFields and
- * readFields of the ObjectInputStream Class and the method get
- * of the ObjectOutputStream.GetField inner class)
- *
- * @serialData No optional data is read.
- */
- private void readObject(ObjectInputStream s)
- throws IOException {
-
- // prepare to read the alternate persistent fields
- ObjectInputStream.GetField fields = null;
- try {
- fields = s.readFields();
- } catch (Exception ClassNotFoundException) {
- throw new IOException();
- }
-
- // read the alternate persistent fields
- int x1 = (int)fields.get("x1", 0);
- int y1 = (int)fields.get("y1", 0);
- int x2 = (int)fields.get("x2", 0);
- int y2 = (int)fields.get("y2", 0);
-
- // save them back as Points.
- point1 = new Point(x1, y1);
- point2 = new Point(x2, y2);
- }
-
- public String toString() {
- return("point1.x: " + point1.x + "\npoint1.y: " + point1.y + "\npoint2.x: " + point2.x + "\npoint2.y: " + point2.y);
- }
- }
-
-