Minor refactoring of SerializedObject.

This commit is contained in:
Marcel Kronfeld
2010-06-02 14:18:04 +00:00
parent 0b1a7e30e8
commit 0d2fe54df1
5 changed files with 337 additions and 398 deletions

View File

@@ -31,6 +31,7 @@ import javax.swing.plaf.basic.BasicComboBoxRenderer;
import eva2.server.go.tools.FileTools; import eva2.server.go.tools.FileTools;
import eva2.tools.EVAHELP; import eva2.tools.EVAHELP;
import eva2.tools.SerializedObject;
import eva2.tools.jproxy.RMIProxyLocal; import eva2.tools.jproxy.RMIProxyLocal;
/** /**
* *

View File

@@ -48,6 +48,7 @@ import javax.swing.event.ListSelectionListener;
import eva2.tools.EVAHELP; import eva2.tools.EVAHELP;
import eva2.tools.SelectedTag; import eva2.tools.SelectedTag;
import eva2.tools.SerializedObject;
/*==========================================================================* /*==========================================================================*
* CLASS DECLARATION * CLASS DECLARATION
*==========================================================================*/ *==========================================================================*/

View File

@@ -1,152 +0,0 @@
package eva2.gui;
/*
* Title: EvA2
* Description:
* Copyright: Copyright (c) 2003
* Company: University of Tuebingen, Computer Architecture
* @author Holger Ulmer, Felix Streichert, Hannes Planatscher
* @version: $Revision: 10 $
* $Date: 2006-01-18 11:02:22 +0100 (Wed, 18 Jan 2006) $
* $Author: streiche $
*/
/*==========================================================================*
* IMPORTS
*==========================================================================*/
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import eva2.server.modules.GOParameters;
import eva2.tools.Serializer;
/**
* This class stores an object serialized in memory. It allows compression,
* to be used to conserve memory (for example, when storing large strings
* in memory), or can be used as a mechanism for deep copying objects.
*
*/
public class SerializedObject implements Serializable {
/** Stores the serialized object */
private byte [] m_Serialized;
/** True if the object has been compressed during storage */
private boolean m_Compressed;
/**
* Serializes the supplied object into a byte array without compression.
*
* @param obj the Object to serialize.
* @throws IOException
* @exception Exception if the object is not Serializable.
*/
public SerializedObject(Object obj) throws IOException {
this(obj, false);
}
/**
* Serializes the supplied object into a byte array.
*
* @param obj the Object to serialize.
* @param compress true if the object should be stored compressed.
* @throws IOException
* @exception Exception if the object is not Serializable.
*/
public SerializedObject(Object obj, boolean compress) throws IOException {
//System.err.print("."); System.err.flush();
m_Compressed = compress;
m_Serialized = toByteArray(obj, m_Compressed);
}
/**
* Serializes the supplied object to a byte array.
*
* @param obj the Object to serialize
* @param compress true if the object should be compressed.
* @return the byte array containing the serialized object.
* @throws IOException
* @exception Exception if the object is not Serializable.
*/
protected static byte [] toByteArray(Object obj, boolean compress) throws IOException {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
OutputStream os = bo;
if (compress)
os = new GZIPOutputStream(os);
os = new BufferedOutputStream(os);
ObjectOutputStream oo = new ObjectOutputStream(os);
oo.writeObject(obj);
oo.close();
return bo.toByteArray();
}
/**
* Gets the object stored in this SerializedObject. The object returned
* will be a deep copy of the original stored object.
*
* @return the deserialized Object.
*/
public Object getObject() {
try {
InputStream is = new ByteArrayInputStream(m_Serialized);
if (m_Compressed) {
is = new GZIPInputStream(is);
}
is = new BufferedInputStream(is);
ObjectInputStream oi = new ObjectInputStream(is);
Object result = oi.readObject();
oi.close();
return result;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
/**
* Compares this object with another for equality.
*
* @param other the other Object.
* @return true if the objects are equal.
*/
public final boolean equals(Object other) {
// Check class type
if ((other == null) || !(other.getClass().equals(this.getClass()))) {
return false;
}
// Check serialized length
byte [] os = ((SerializedObject)other).m_Serialized;
if (os.length != m_Serialized.length) {
return false;
}
// Check serialized contents
for (int i = 0; i < m_Serialized.length; i++) {
if (m_Serialized[i] != os[i]) {
return false;
}
}
return true;
}
/**
* Returns a hashcode for this object.
*
* @return the hashcode for this object.
*/
public final int hashCode() {
return m_Serialized.length;
}
/**
* Returns a text representation of the state of this object.
*
* @return a String representing this object.
*/
public String toString() {
return (m_Compressed ? "Compressed object: " : "Uncompressed object: ")
+ m_Serialized.length + " bytes";
}
}

View File

@@ -0,0 +1,137 @@
package eva2.tools;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
/**
* This class stores an object serialized in memory. It allows compression,
* to be used to conserve memory (for example, when storing large strings
* in memory), or can be used as a mechanism for deep copying objects.
*
* @author Holger Ulmer, Felix Streichert, Hannes Planatscher
*/
public class SerializedObject implements Serializable {
/** Stores the serialized object */
private byte [] m_Serialized;
/** True if the object has been compressed during storage */
private boolean m_Compressed;
/**
* Serializes the supplied object into a byte array without compression.
*
* @param obj the Object to serialize.
* @throws IOException
* @exception Exception if the object is not Serializable.
*/
public SerializedObject(Object obj) throws IOException {
this(obj, false);
}
/**
* Serializes the supplied object into a byte array.
*
* @param obj the Object to serialize.
* @param compress true if the object should be stored compressed.
* @throws IOException
* @exception Exception if the object is not Serializable.
*/
public SerializedObject(Object obj, boolean compress) throws IOException {
m_Compressed = compress;
m_Serialized = toByteArray(obj, m_Compressed);
}
/**
* Serializes the supplied object to a byte array.
*
* @param obj the Object to serialize
* @param compress true if the object should be compressed.
* @return the byte array containing the serialized object.
* @throws IOException
* @exception Exception if the object is not Serializable.
*/
protected static byte [] toByteArray(Object obj, boolean compress) throws IOException {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
OutputStream os = bo;
if (compress)
os = new GZIPOutputStream(os);
os = new BufferedOutputStream(os);
ObjectOutputStream oo = new ObjectOutputStream(os);
oo.writeObject(obj);
oo.close();
return bo.toByteArray();
}
/**
* Gets the object stored in this SerializedObject. The object returned
* will be a deep copy of the original stored object.
*
* @return the deserialized Object.
*/
public Object getObject() {
try {
InputStream is = new ByteArrayInputStream(m_Serialized);
if (m_Compressed) {
is = new GZIPInputStream(is);
}
is = new BufferedInputStream(is);
ObjectInputStream oi = new ObjectInputStream(is);
Object result = oi.readObject();
oi.close();
return result;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
/**
* Compares this object with another for equality.
*
* @param other the other Object.
* @return true if the objects are equal.
*/
public final boolean equals(Object other) {
// Check class type
if ((other == null) || !(other.getClass().equals(this.getClass()))) {
return false;
}
// Check serialized length
byte [] os = ((SerializedObject)other).m_Serialized;
if (os.length != m_Serialized.length) {
return false;
}
// Check serialized contents
for (int i = 0; i < m_Serialized.length; i++) {
if (m_Serialized[i] != os[i]) {
return false;
}
}
return true;
}
/**
* Returns a hashcode for this object.
*
* @return the hashcode for this object.
*/
public final int hashCode() {
return m_Serialized.length;
}
/**
* Returns a text representation of the state of this object.
*
* @return a String representing this object.
*/
public String toString() {
return (m_Compressed ? "Compressed object: " : "Uncompressed object: ")
+ m_Serialized.length + " bytes";
}
}

View File

@@ -1,17 +1,5 @@
package eva2.tools; package eva2.tools;
/**
* Title: EvA2
* Description:
* Copyright: Copyright (c) 2003
* Company: University of Tuebingen, Computer Architecture
* @author Holger Ulmer, Felix Streichert, Hannes Planatscher
* @version: $Revision: 319 $
* $Date: 2007-12-05 11:29:32 +0100 (Wed, 05 Dec 2007) $
* $Author: mkron $
*/
/*==========================================================================*
* IMPORTS
*==========================================================================*/
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
@@ -23,248 +11,212 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.io.Serializable; import java.io.Serializable;
import eva2.gui.SerializedObject;
import eva2.server.go.problems.PSymbolicRegression;
import eva2.server.modules.GOParameters;
/*==========================================================================*
* CLASS DECLARATION
*==========================================================================*/
/** /**
* This class defines utility routines that use Java serialization. * This class defines utility routines that use Java serialization. Any
* serializable object can be stored to a file, loaded, and cloned (returning
* a deep copy).
*
* @author Holger Ulmer, Felix Streichert, Hannes Planatscher, Marcel Kronfeld
**/ **/
public class Serializer { public class Serializer {
/** /**
* Serialize the object o (and any Serializable objects it refers to) and * Serialize the object o (and any Serializable objects it refers to) and
* store its serialized state in File f. If serializeInMem is true, the object * store its serialized state in File f. If serializeInMem is true, the object
* is wrapped in a SerializedObject first, which seems to be more efficient than * is wrapped in a SerializedObject first, which seems to be more efficient than
* writing a nested object directly to a file. * writing a nested object directly to a file.
* *
* @param o the object to write * @param o the object to write
* @param f the file to write to * @param f the file to write to
* @param serializeInMem flag whether to wrap the object in a SerializedObject * @param serializeInMem flag whether to wrap the object in a SerializedObject
* @throws IOException * @throws IOException
**/ **/
static public void store(Serializable o, File f, boolean serializeInMem) throws IOException { static public void store(Serializable o, File f, boolean serializeInMem) throws IOException {
FileOutputStream file = new FileOutputStream(f); FileOutputStream file = new FileOutputStream(f);
ObjectOutputStream out = new ObjectOutputStream(file); ObjectOutputStream out = new ObjectOutputStream(file);
try { try {
Object objToStore = o; Object objToStore = o;
if (serializeInMem) objToStore = new SerializedObject((Object)o); if (serializeInMem) objToStore = new SerializedObject((Object)o);
// System.out.println("Writing " + o.getClass()); // System.out.println("Writing " + o.getClass());
out.writeObject(objToStore); out.writeObject(objToStore);
} catch (java.io.NotSerializableException e) { } catch (java.io.NotSerializableException e) {
System.err.println("Error: Object " + o.getClass() + " is not serializable - run settings cannot be stored."); System.err.println("Error: Object " + o.getClass() + " is not serializable - run settings cannot be stored.");
e.printStackTrace(); e.printStackTrace();
} }
out.flush(); out.flush();
out.close(); out.close();
file.close(); file.close();
} }
// try { // try {
// FileOutputStream OutStream = new FileOutputStream("ESPara.ser"); // FileOutputStream OutStream = new FileOutputStream("ESPara.ser");
// ObjectOutputStream OutObjectStream = new ObjectOutputStream (OutStream); // ObjectOutputStream OutObjectStream = new ObjectOutputStream (OutStream);
// OutObjectStream.writeObject(this); // OutObjectStream.writeObject(this);
// OutObjectStream.flush(); // OutObjectStream.flush();
// OutStream.close(); // OutStream.close();
// } catch (Exception e) { // } catch (Exception e) {
// System.out.println ("ERROR ESPara.ser"+e.getMessage()); // System.out.println ("ERROR ESPara.ser"+e.getMessage());
// } // }
/** /**
* Deserialize the contents of File f and return the resulting object. * Deserialize the contents of File f and return the resulting object.
* A SerializedObject is unwrapped once. * A SerializedObject is unwrapped once.
**/ **/
static public Object load(File f) throws IOException, ClassNotFoundException { static public Object load(File f) throws IOException, ClassNotFoundException {
FileInputStream file = new FileInputStream(f); FileInputStream file = new FileInputStream(f);
ObjectInputStream in = new ObjectInputStream(file); ObjectInputStream in = new ObjectInputStream(file);
Object ret = in.readObject(); Object ret = in.readObject();
if (ret instanceof SerializedObject) ret = ((SerializedObject)ret).getObject(); if (ret instanceof SerializedObject) ret = ((SerializedObject)ret).getObject();
in.close(); in.close();
file.close(); file.close();
return ret; return ret;
} }
/** /**
* Returns a copy of the object, or null if the object cannot * Use object serialization to make a "deep clone" of the object o.
* be serialized. * This method serializes o and all of its member objects, and then
*/ * deserializes that graph of objects, which means that everything is
public static Object deepClone(Object orig) { * copied. This differs from the clone() method of an object which is
Object obj = null; * usually implemented to produce a "shallow" clone that copies references
try { * to other objects, instead of copying all referenced objects.
// Write the object out to a byte array **/
ByteArrayOutputStream bos = new ByteArrayOutputStream(); public static Object deepClone(Object o) {
ObjectOutputStream out = new ObjectOutputStream(bos); Object obj = null;
out.writeObject(orig); try {
out.flush(); // Write the object out to a byte array
out.close(); ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bos);
out.writeObject(o);
out.flush();
out.close();
// Make an input stream from the byte array and read // Make an input stream from the byte array and read
// a copy of the object back in. // a copy of the object back in.
ObjectInputStream in = new ObjectInputStream( ObjectInputStream in = new ObjectInputStream(
new ByteArrayInputStream(bos.toByteArray())); new ByteArrayInputStream(bos.toByteArray()));
obj = in.readObject(); obj = in.readObject();
} }
catch(IOException e) { catch(IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
catch(ClassNotFoundException cnfe) { catch(ClassNotFoundException cnfe) {
cnfe.printStackTrace(); cnfe.printStackTrace();
} }
return obj; return obj;
} }
/**
* This is a simple serializable data structure that we use below for
* testing the methods above
**/
static class ExampleDataStruct implements Serializable {
String message;
int[] data;
ExampleDataStruct other;
public String toString() {
String s = message;
for(int i = 0; i < data.length; i++)
s += " " + data[i];
if (other != null) s += "\n\t" + other.toString();
return s;
}
}
/** public static void main(String[] args) throws IOException, ClassNotFoundException {
* Use object serialization to make a "deep clone" of the object o. // Create a simple object graph
* This method serializes o and all objects it refers to, and then ExampleDataStruct ds = new ExampleDataStruct();
* deserializes that graph of objects, which means that everything is ds.message = "hello world";
* copied. This differs from the clone() method of an object which is ds.data = new int[] { 1, 2, 3, 4 };
* usually implemented to produce a "shallow" clone that copies references ds.other = new ExampleDataStruct();
* to other objects, instead of copying all referenced objects. ds.other.message = "nested structure";
**/ ds.other.data = new int[] { 9, 8, 7 };
// static public Object deepclone(final Serializable o) throws IOException, ClassNotFoundException { // Display the original object graph
// // Create a connected pair of "piped" streams. System.out.println("Original data structure: " + ds);
// // We'll write bytes to one, and them from the other one. // Output it to a file
// final PipedOutputStream pipeout = new PipedOutputStream(); File f = new File("datastructure.ser");
// PipedInputStream pipein = new PipedInputStream(pipeout); System.out.println("Storing to a file...");
// // Now define an independent thread to serialize the object and write Serializer.store(ds, f, true);
// // its bytes to the PipedOutputStream // Read it back from the file, and display it again
// Thread writer = new Thread() { ds = (ExampleDataStruct) Serializer.load(f);
// public void run() { System.out.println("Read from the file: " + ds);
// ObjectOutputStream out = null; // Create a deep clone and display that. After making the copy
// try { // modify the original to prove that the clone is "deep".
// out = new ObjectOutputStream(pipeout); ExampleDataStruct ds2 = (ExampleDataStruct) Serializer.deepClone(ds);
// out.writeObject(o); } ds.other.message = null; ds.other.data = null; // Change original
// catch(IOException e) { System.out.println("Deep clone: " + ds2);
// System.out.println("ERROR in Serialization1"+ e.getMessage()); }
// }
// finally {
// try { out.close(); } catch (Exception e) {
// System.out.println("ERROR in Serialization2"+ e.getMessage());
// }
// }
// }
// };
// writer.start();
// // Meanwhile, in this thread, read and deserialize from the piped
// // input stream. The resulting object is a deep clone of the original.
// ObjectInputStream in = new ObjectInputStream(pipein);
// return in.readObject();
// }
/**
* This is a simple serializable data structure that we use below for
* testing the methods above
**/
public static class DataStructure implements Serializable {
String message;
int[] data;
DataStructure other;
public String toString() {
String s = message;
for(int i = 0; i < data.length; i++)
s += " " + data[i];
if (other != null) s += "\n\t" + other.toString();
return s;
}
}
public static void main(String[] args) throws IOException, ClassNotFoundException { /**
// Create a simple object graph * Serialize the string s and
DataStructure ds = new DataStructure(); * store its serialized state in File with name Filename.
ds.message = "hello world"; **/
ds.data = new int[] { 1, 2, 3, 4 }; public static void storeString (String Filename,String s) {
ds.other = new DataStructure(); try {
ds.other.message = "nested structure"; store(s, new File(Filename), false);
ds.other.data = new int[] { 9, 8, 7 }; } catch (Exception e) {
// Display the original object graph System.out.println("ERROR writing string File "+Filename+ " String "+s);
System.out.println("Original data structure: " + ds); }
// Output it to a file }
File f = new File("datastructure.ser"); /**
System.out.println("Storing to a file..."); * Deserialize the contents of File f containing
Serializer.store(ds, f, true); * a string and return the resulting string.
// Read it back from the file, and display it again **/
ds = (DataStructure) Serializer.load(f); public static String loadString (String Filename) {
System.out.println("Read from the file: " + ds); String s = null;
// Create a deep clone and display that. After making the copy try {
// modify the original to prove that the clone is "deep". s=(String)load(new File(Filename));
DataStructure ds2 = (DataStructure) Serializer.deepClone(ds); } catch (Exception e) {
ds.other.message = null; ds.other.data = null; // Change original // System.out.println("WARNING: Loading string File "+Filename+ " not possible !!");
System.out.println("Deep clone: " + ds2); }
} return s;
}
/**
* Serialize the string s and
* store its serialized state in File with name Filename.
**/
public static File storeObject (String Filename,Serializable s) {
File ret = new File(Filename);
try {
store(s, ret, true);
} catch (Exception e) {
System.err.println("ERROR writing Object File "+Filename+ " String "+s);
System.err.println(e.getMessage());
e.printStackTrace();
}
return ret;
}
/** /**
* Serialize the string s and * Deserialize the contents of File with given name containing
* store its serialized state in File with name Filename. * a string and return the resulting string. If the indicated file
**/ * doesnt exist or an error occurs, null is returned.
public static void storeString (String Filename,String s) { **/
try { public static Object loadObject (String Filename) {
store(s, new File(Filename), false); return loadObject(Filename, true);
} catch (Exception e) { }
System.out.println("ERROR writing string File "+Filename+ " String "+s);
}
}
/**
* Deserialize the contents of File f containing
* a string and return the resulting string.
**/
public static String loadString (String Filename) {
String s = null;
try {
s=(String)load(new File(Filename));
} catch (Exception e) {
// System.out.println("WARNING: Loading string File "+Filename+ " not possible !!");
}
return s;
}
/**
* Serialize the string s and
* store its serialized state in File with name Filename.
**/
public static File storeObject (String Filename,Serializable s) {
File ret = new File(Filename);
try {
store(s, ret, true);
} catch (Exception e) {
System.err.println("ERROR writing Object File "+Filename+ " String "+s);
System.err.println(e.getMessage());
e.printStackTrace();
}
return ret;
}
/**
* Deserialize the contents of File with given name containing
* a string and return the resulting string. If the indicated file
* doesnt exist or an error occurs, null is returned.
**/
public static Object loadObject (String Filename) {
return loadObject(Filename, true);
}
/**
* Deserialize the contents of File with given name containing
* a string and return the resulting string. If the indicated file
* doesnt exist or an error occurs, null is returned.
* If casually is false, an error message is printed and an exception
* is raised if the file was not found or an error occured on loading.
**/
public static Object loadObject (String Filename, boolean casually) {
Object s = null;
File f = new File(Filename); /**
if (f.exists()) { * Deserialize the contents of File with given name containing
try { * a string and return the resulting string. If the indicated file
s=(Object)load(new File(Filename)); * doesnt exist or an error occurs, null is returned.
} catch (InvalidClassException e) { * If casually is false, an error message is printed and an exception
System.err.println("WARNING: loading object File "+Filename+ " not possible, this may happen on source code changes."); * is raised if the file was not found or an error occured on loading.
System.err.println(e.getMessage()); **/
} catch (Exception e) { public static Object loadObject (String Filename, boolean casually) {
throw new RuntimeException("WARNING: loading object File "+Filename+ " not possible! ("+e.getMessage()+")"); Object s = null;
}
return s; File f = new File(Filename);
} else { if (f.exists()) {
if (!casually) System.err.println("Error in Serializer: file " + Filename + " not found!"); try {
return null; s=(Object)load(new File(Filename));
} } catch (InvalidClassException e) {
} System.err.println("WARNING: loading object File "+Filename+ " not possible, this may happen on source code changes.");
System.err.println(e.getMessage());
} catch (Exception e) {
throw new RuntimeException("WARNING: loading object File "+Filename+ " not possible! ("+e.getMessage()+")");
}
return s;
} else {
if (!casually) System.err.println("Error in Serializer: file " + Filename + " not found!");
return null;
}
}
} }