FileDocCategorySizeDatePackage
CustomDataExample.javaAPI DocExample6474Wed Apr 19 11:21:14 BST 2000None

CustomDataExample.java

/*
 * @(#)CustomDataExample.java	1.4 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.*;
 
/**
 * This example shows how to use writeObject and readObject to encode
 * custom data format. When the persistent data is unwieldy, it is suitable
 * to store it in a more convenient, condensed format. 
 * 
 * Specifically, this example considers the case of a triangular array. A
 * triangular array is simply a 2-dimensional array that is symmetric. So when
 * serializing it, it is desirable to save only 1/2 of the 2-dimensional array
 * rather than the whole.
 *
 * This is different from the Serialization and Serializable Fields API 
 * Example in that this example does not support versioning.  This example
 * differs from using an Externalizable interface in that this example does
 * not have to worry about superclasses.
 *
 * Complied and tested on JDK 1.1 & the Java 2 SDK, v1.2.
 *
 * How to run this example:
 *                         Compile this file: javac CustomDataExample.java
 *                         Then run:          java CustomDataExample
 *
 *  This will print out two arrays: one from before serialization and the
 *  other from after deserialization.
 */
public class CustomDataExample implements Serializable {

    transient int dimension;
    transient int thearray[][];

    /**
     * Create the triangular array of dimension dim and initialize it
     */
    CustomDataExample (int dim) {
  	dimension = dim;
        thearray = new int[dim][dim];
	arrayInit();
    }

    /**
     * Create an CustomDataExample object, serialize it, deserialize it and 
     * see that they are the same. So, basically test that this custom
     * data example's serialization works.
     */
    public static void main(String args[]) {
	CustomDataExample corg = new CustomDataExample(4);
	CustomDataExample cnew = null;
	
	// Serialize the original class object
	try {
	    FileOutputStream fo = new FileOutputStream("cde.tmp");
	    ObjectOutputStream so = new ObjectOutputStream(fo);
	    so.writeObject(corg);
	    so.flush();
	    so.close();
	} catch (Exception e) {
	    e.printStackTrace();
	    System.exit(1);
	}
	
	// Deserialize in to new class object
	try {
	    FileInputStream fi = new FileInputStream("cde.tmp");
	    ObjectInputStream si = new ObjectInputStream(fi);  
	    cnew = (CustomDataExample) si.readObject();
            si.close();
	} catch (Exception e) {
	    e.printStackTrace();
	    System.exit(1);
	}
    
	// Print out to check the correctness
	System.out.println();
	System.out.println("Printing the original array...");
	System.out.println(corg);
	System.out.println();
	System.out.println("Printing the new array...");
	System.out.println(cnew);
	System.out.println();
	System.out.println("The original and new arrays should be the same!");
	System.out.println();
   }
    
    /** 
     * Write out the dimension and 1/2 of the 2-dimensional array to the
     * ObjectOutputStream s. readObject depends on this data format.
     *
     * @serialData Write serializable fields, if any exist.
     *             Write out the integer Dimension of the symetrical,
     *             two-dimensional array. Write out the integers composing
     *             1/2 of the 2-dimensional array. 
     *             
     */
    private void writeObject(ObjectOutputStream s)
	throws IOException {
	    // Call even if there is no default serializable fields.
	    s.defaultWriteObject();

	    // save the dimension
	    s.writeInt(dimension);

	    // write out only 1/2 of the 2-dimensional array
	    for (int i = 0; i < dimension; i++) {
		for (int j = 0; j <= i; j++) {
		    s.writeInt(thearray[i][j]);
		}
	    }	    
    }
  
    /** 
     * Read in the dimension and 1/2 of the 2-dimensional array from the
     * ObjectInputStream s. Was written to by writeObject. Also, copy the
     * 1/2 array to the other half to completely fill the symmetric array.
     *
     * @serialData Read serializable fields, if any exist.
     *             Read optional data consisting of an integer indicating
     *             both dimensions of the 2-dimensional array. Read in
     *             1/2 of the 2-dimensional array. 
     */
    private void readObject(ObjectInputStream s) 
	throws IOException, ClassNotFoundException  {
	    /*  Call even if there is no default serializable fields.
	     *  Enables default serializable fields to be added in future versions
             *  and skipped by this version which has no default serializable fields.
	     */
	    s.defaultReadObject();

	    // restore the dimension
	    dimension = s.readInt();
	    
	    // allocate space for the array
	    thearray = new int[dimension][dimension];
	    
	    // first restore 1/2 the 2-dimensional array
	    for (int i = 0; i < dimension; i++) {
		for (int j = 0; j <= i; j++) {
		    thearray[i][j] = s.readInt();
		}
	    }
	    
	    // copy over to the other side
	    for (int i = 0; i < dimension; i++) {
		for (int j = dimension - 1; j > i; j--) {
		    thearray[i][j] = thearray[j][i];
		}
	    }
    }

    /**
     * Initialize the array to some numbers starting from 0 - make it 
     * symmetrical 
     */ 
    void arrayInit() {
       	int x = 0;
	for (int i = 0; i < dimension; i++) { 
	    for (int j = 0; j <= i; j++) {
		thearray[i][j] = x;
		thearray[j][i] = x;
		x++;
	    }
	}       
    }

    /** 
     * Print the 2-dimensional array. Useful for testing.
     */
    public String toString() {

	StringBuffer sb = new StringBuffer();
	for (int i = 0; i < dimension; i++) { 
	    for (int j = 0; j < dimension; j++) {
		sb.append(Integer.toString(thearray[i][j])+ " ");
	    }
	    sb.append("\n");
	}
	return(sb.toString());
    }
}