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.tools.EVAHELP;
import eva2.tools.SerializedObject;
import eva2.tools.jproxy.RMIProxyLocal;
/**
*

View File

@ -48,6 +48,7 @@ import javax.swing.event.ListSelectionListener;
import eva2.tools.EVAHELP;
import eva2.tools.SelectedTag;
import eva2.tools.SerializedObject;
/*==========================================================================*
* 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;
/**
* 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.ByteArrayOutputStream;
import java.io.File;
@ -23,248 +11,212 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
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 {
/**
* 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
* is wrapped in a SerializedObject first, which seems to be more efficient than
* writing a nested object directly to a file.
*
* @param o the object to write
* @param f the file to write to
* @param serializeInMem flag whether to wrap the object in a SerializedObject
* @throws IOException
**/
static public void store(Serializable o, File f, boolean serializeInMem) throws IOException {
FileOutputStream file = new FileOutputStream(f);
ObjectOutputStream out = new ObjectOutputStream(file);
try {
Object objToStore = o;
if (serializeInMem) objToStore = new SerializedObject((Object)o);
// System.out.println("Writing " + o.getClass());
out.writeObject(objToStore);
} catch (java.io.NotSerializableException e) {
System.err.println("Error: Object " + o.getClass() + " is not serializable - run settings cannot be stored.");
e.printStackTrace();
}
out.flush();
out.close();
file.close();
}
// try {
// FileOutputStream OutStream = new FileOutputStream("ESPara.ser");
// ObjectOutputStream OutObjectStream = new ObjectOutputStream (OutStream);
// OutObjectStream.writeObject(this);
// OutObjectStream.flush();
// OutStream.close();
// } catch (Exception e) {
// System.out.println ("ERROR ESPara.ser"+e.getMessage());
// }
/**
* 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
* is wrapped in a SerializedObject first, which seems to be more efficient than
* writing a nested object directly to a file.
*
* @param o the object to write
* @param f the file to write to
* @param serializeInMem flag whether to wrap the object in a SerializedObject
* @throws IOException
**/
static public void store(Serializable o, File f, boolean serializeInMem) throws IOException {
FileOutputStream file = new FileOutputStream(f);
ObjectOutputStream out = new ObjectOutputStream(file);
try {
Object objToStore = o;
if (serializeInMem) objToStore = new SerializedObject((Object)o);
// System.out.println("Writing " + o.getClass());
out.writeObject(objToStore);
} catch (java.io.NotSerializableException e) {
System.err.println("Error: Object " + o.getClass() + " is not serializable - run settings cannot be stored.");
e.printStackTrace();
}
out.flush();
out.close();
file.close();
}
// try {
// FileOutputStream OutStream = new FileOutputStream("ESPara.ser");
// ObjectOutputStream OutObjectStream = new ObjectOutputStream (OutStream);
// OutObjectStream.writeObject(this);
// OutObjectStream.flush();
// OutStream.close();
// } catch (Exception e) {
// System.out.println ("ERROR ESPara.ser"+e.getMessage());
// }
/**
* Deserialize the contents of File f and return the resulting object.
* A SerializedObject is unwrapped once.
**/
static public Object load(File f) throws IOException, ClassNotFoundException {
FileInputStream file = new FileInputStream(f);
ObjectInputStream in = new ObjectInputStream(file);
Object ret = in.readObject();
if (ret instanceof SerializedObject) ret = ((SerializedObject)ret).getObject();
in.close();
file.close();
return ret;
}
/**
* Deserialize the contents of File f and return the resulting object.
* A SerializedObject is unwrapped once.
**/
static public Object load(File f) throws IOException, ClassNotFoundException {
FileInputStream file = new FileInputStream(f);
ObjectInputStream in = new ObjectInputStream(file);
Object ret = in.readObject();
if (ret instanceof SerializedObject) ret = ((SerializedObject)ret).getObject();
in.close();
file.close();
return ret;
}
/**
* Returns a copy of the object, or null if the object cannot
* be serialized.
*/
public static Object deepClone(Object orig) {
Object obj = null;
try {
// Write the object out to a byte array
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bos);
out.writeObject(orig);
out.flush();
out.close();
/**
* Use object serialization to make a "deep clone" of the object o.
* This method serializes o and all of its member objects, and then
* deserializes that graph of objects, which means that everything is
* copied. This differs from the clone() method of an object which is
* usually implemented to produce a "shallow" clone that copies references
* to other objects, instead of copying all referenced objects.
**/
public static Object deepClone(Object o) {
Object obj = null;
try {
// Write the object out to a byte array
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
// a copy of the object back in.
ObjectInputStream in = new ObjectInputStream(
new ByteArrayInputStream(bos.toByteArray()));
obj = in.readObject();
}
catch(IOException e) {
e.printStackTrace();
}
catch(ClassNotFoundException cnfe) {
cnfe.printStackTrace();
}
return obj;
}
// Make an input stream from the byte array and read
// a copy of the object back in.
ObjectInputStream in = new ObjectInputStream(
new ByteArrayInputStream(bos.toByteArray()));
obj = in.readObject();
}
catch(IOException e) {
e.printStackTrace();
}
catch(ClassNotFoundException cnfe) {
cnfe.printStackTrace();
}
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;
}
}
/**
* Use object serialization to make a "deep clone" of the object o.
* This method serializes o and all objects it refers to, and then
* deserializes that graph of objects, which means that everything is
* copied. This differs from the clone() method of an object which is
* usually implemented to produce a "shallow" clone that copies references
* to other objects, instead of copying all referenced objects.
**/
// static public Object deepclone(final Serializable o) throws IOException, ClassNotFoundException {
// // Create a connected pair of "piped" streams.
// // We'll write bytes to one, and them from the other one.
// final PipedOutputStream pipeout = new PipedOutputStream();
// PipedInputStream pipein = new PipedInputStream(pipeout);
// // Now define an independent thread to serialize the object and write
// // its bytes to the PipedOutputStream
// Thread writer = new Thread() {
// public void run() {
// ObjectOutputStream out = null;
// try {
// out = new ObjectOutputStream(pipeout);
// out.writeObject(o); }
// catch(IOException e) {
// 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
ExampleDataStruct ds = new ExampleDataStruct();
ds.message = "hello world";
ds.data = new int[] { 1, 2, 3, 4 };
ds.other = new ExampleDataStruct();
ds.other.message = "nested structure";
ds.other.data = new int[] { 9, 8, 7 };
// Display the original object graph
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...");
Serializer.store(ds, f, true);
// Read it back from the file, and display it again
ds = (ExampleDataStruct) Serializer.load(f);
System.out.println("Read from the file: " + ds);
// Create a deep clone and display that. After making the copy
// modify the original to prove that the clone is "deep".
ExampleDataStruct ds2 = (ExampleDataStruct) Serializer.deepClone(ds);
ds.other.message = null; ds.other.data = null; // Change original
System.out.println("Deep clone: " + ds2);
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
// Create a simple object graph
DataStructure ds = new DataStructure();
ds.message = "hello world";
ds.data = new int[] { 1, 2, 3, 4 };
ds.other = new DataStructure();
ds.other.message = "nested structure";
ds.other.data = new int[] { 9, 8, 7 };
// Display the original object graph
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...");
Serializer.store(ds, f, true);
// Read it back from the file, and display it again
ds = (DataStructure) Serializer.load(f);
System.out.println("Read from the file: " + ds);
// Create a deep clone and display that. After making the copy
// modify the original to prove that the clone is "deep".
DataStructure ds2 = (DataStructure) Serializer.deepClone(ds);
ds.other.message = null; ds.other.data = null; // Change original
System.out.println("Deep clone: " + ds2);
}
/**
* Serialize the string s and
* store its serialized state in File with name Filename.
**/
public static void storeString (String Filename,String s) {
try {
store(s, new File(Filename), false);
} 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;
}
/**
* Serialize the string s and
* store its serialized state in File with name Filename.
**/
public static void storeString (String Filename,String s) {
try {
store(s, new File(Filename), false);
} 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;
/**
* 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);
}
File f = new File(Filename);
if (f.exists()) {
try {
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;
}
}
/**
* 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()) {
try {
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;
}
}
}