[jboss-svn-commits] JBL Code SVN: r18727 - labs/jbossrules/branches/ming-serialization/drools-core/src/main/java/org/drools/common.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Thu Mar 6 08:54:52 EST 2008
Author: mingjin
Date: 2008-03-06 08:54:51 -0500 (Thu, 06 Mar 2008)
New Revision: 18727
Added:
labs/jbossrules/branches/ming-serialization/drools-core/src/main/java/org/drools/common/DroolsObjectInput.java
labs/jbossrules/branches/ming-serialization/drools-core/src/main/java/org/drools/common/DroolsObjectOutputStream.java
Log:
Implementation of custom serialization.
Added: labs/jbossrules/branches/ming-serialization/drools-core/src/main/java/org/drools/common/DroolsObjectInput.java
===================================================================
--- labs/jbossrules/branches/ming-serialization/drools-core/src/main/java/org/drools/common/DroolsObjectInput.java (rev 0)
+++ labs/jbossrules/branches/ming-serialization/drools-core/src/main/java/org/drools/common/DroolsObjectInput.java 2008-03-06 13:54:51 UTC (rev 18727)
@@ -0,0 +1,26 @@
+package org.drools.common;
+
+import org.drools.rule.*;
+import org.drools.rule.Package;
+import org.drools.base.ClassFieldExtractorCache;
+
+import java.io.ObjectInput;
+
+/**
+ * Created by IntelliJ IDEA. User: SG0521861 Date: Mar 4, 2008 Time: 7:24:07 AM To change this template use File |
+ * Settings | File Templates.
+ */
+public interface DroolsObjectInput {
+ ClassLoader getClassLoader();
+ void setClassLoader(ClassLoader classLoader);
+ InternalRuleBase getRuleBase();
+ void setRuleBase(InternalRuleBase ruleBase);
+ void setWorkingMemory(InternalWorkingMemory workingMemory);
+ InternalWorkingMemory getWorkingMemory();
+ Package getPackage();
+ void setPackage(Package pkg);
+ DialectDatas getDialectDatas();
+ void setDialectDatas(DialectDatas dialectDatas);
+ ClassFieldExtractorCache getExtractorFactory();
+ void setExtractorFactory(ClassFieldExtractorCache extractorFactory);
+}
Added: labs/jbossrules/branches/ming-serialization/drools-core/src/main/java/org/drools/common/DroolsObjectOutputStream.java
===================================================================
--- labs/jbossrules/branches/ming-serialization/drools-core/src/main/java/org/drools/common/DroolsObjectOutputStream.java (rev 0)
+++ labs/jbossrules/branches/ming-serialization/drools-core/src/main/java/org/drools/common/DroolsObjectOutputStream.java 2008-03-06 13:54:51 UTC (rev 18727)
@@ -0,0 +1,624 @@
+package org.drools.common;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.NotSerializableException;
+import java.io.ObjectOutput;
+import java.io.OutputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.IdentityHashMap;
+import java.util.Map;
+
+/**
+ *
+ */
+public class DroolsObjectOutputStream implements ObjectOutput, DroolsObjectStreamConstants {
+ private static final Class EMPTY_SET_CLASS = Collections.EMPTY_SET.getClass();
+ private static final Class EMPTY_MAP_CLASS = Collections.EMPTY_MAP.getClass();
+ private static final Class EMPTY_LIST_CLASS = Collections.EMPTY_LIST.getClass();
+
+ private final Map<Object, Integer> handlesByObject = new IdentityHashMap<Object, Integer>();
+ private final ObjectOutput dataOutput;
+
+ public DroolsObjectOutputStream(OutputStream outputStream) throws IOException {
+ this((ObjectOutput)new ObjectOutputStream(outputStream));
+ }
+ public DroolsObjectOutputStream(ObjectOutput dataOutput) throws IOException {
+ this.dataOutput = dataOutput;
+// writeStreamHeader();
+ }
+
+ private void writeNull() throws IOException {
+ writeRecordType(RT_NULL);
+ }
+
+ private void writeObjectOrReference(Object object, Class clazz) throws IOException {
+ int handle = registerObject(object);
+ if (handle < 0) {
+ writeObject(object, clazz, -handle);
+ } else {
+ writeReference(handle);
+ }
+ }
+
+ private void writeObject(Object object, Class clazz, int handle) throws IOException {
+ if (Externalizable.class.isAssignableFrom(clazz)) {
+ writeExternalizable((Externalizable) object, clazz, handle);
+ } else if (String.class.isAssignableFrom(clazz)) {
+ writeString((String) object, handle);
+ } else if (Map.class.isAssignableFrom(clazz)) {
+ writeMap((Map) object, clazz, handle);
+ } else if (Collection.class.isAssignableFrom(clazz)) {
+ writeCollection((Collection) object, clazz, handle);
+ } else if (clazz == Class.class) {
+ writeClass((Class) object, handle);
+ } else if (clazz.isArray()) {
+ writeArray(object, clazz, handle);
+ } else if (Serializable.class.isAssignableFrom(clazz)) {
+ writeSerializable((Serializable) object, clazz, handle);
+ } else {
+ throw new NotSerializableException("Unsupported class: " + clazz);
+ }
+ }
+
+ private void writeArray(Object array, Class clazz, int handle) throws IOException {
+ writeRecordType(RT_ARRAY);
+ writeHandle(handle);
+ writeObject(clazz);
+ Class componentType = clazz.getComponentType();
+ if (componentType.isPrimitive()) {
+ writePrimitiveArray(array, componentType);
+ } else {
+ writeObjectArray((Object[]) array);
+ }
+ }
+
+ private void writePrimitiveArray(Object array, Class clazz) throws IOException {
+ if (clazz == Integer.TYPE) {
+ writeIntArray(array);
+ } else if (clazz == Byte.TYPE) {
+ writeByteArray(array);
+ } else if (clazz == Long.TYPE) {
+ writeLongArray(array);
+ } else if (clazz == Float.TYPE) {
+ writeFloatArray(array);
+ } else if (clazz == Double.TYPE) {
+ writeDoubleArray(array);
+ } else if (clazz == Short.TYPE) {
+ writeShortArray(array);
+ } else if (clazz == Character.TYPE) {
+ writeCharArray(array);
+ } else if (clazz == Boolean.TYPE) {
+ writeBooleanArray(array);
+ } else {
+ throw new NotSerializableException("Unsupported array type: " + clazz);
+ }
+ }
+
+ private void writeIntArray(Object array) throws IOException {
+ int[] ints = (int[]) array;
+ int length = ints.length;
+ writeInt(length);
+ for (int i = 0; i < length; ++i) {
+ writeInt(ints[i]);
+ }
+ }
+
+ private void writeByteArray(Object array) throws IOException {
+ byte[] bytes = (byte[]) array;
+ int length = bytes.length;
+ writeInt(length);
+ write(bytes, 0, length);
+ }
+
+ private void writeLongArray(Object array) throws IOException {
+ long[] longs = (long[]) array;
+ int length = longs.length;
+ writeInt(length);
+ for (int i = 0; i < length; ++i) {
+ writeLong(longs[i]);
+ }
+ }
+
+ private void writeFloatArray(Object array) throws IOException {
+ float[] floats = (float[]) array;
+ int length = floats.length;
+ writeFloat(length);
+ for (int i = 0; i < length; ++i) {
+ writeFloat(floats[i]);
+ }
+ }
+
+ private void writeDoubleArray(Object array) throws IOException {
+ double[] doubles = (double[]) array;
+ int length = doubles.length;
+ writeInt(length);
+ for (int i = 0; i < length; ++i) {
+ writeDouble(doubles[i]);
+ }
+ }
+
+ private void writeShortArray(Object array) throws IOException {
+ short[] shorts = (short[]) array;
+ int length = shorts.length;
+ writeInt(length);
+ for (int i = 0; i < length; ++i) {
+ writeShort(shorts[i]);
+ }
+ }
+
+ private void writeCharArray(Object array) throws IOException {
+ char[] chars = (char[]) array;
+ int length = chars.length;
+ writeInt(length);
+ for (int i = 0; i < length; ++i) {
+ writeChar(chars[i]);
+ }
+ }
+
+ private void writeBooleanArray(Object array) throws IOException {
+ boolean[] booleans = (boolean[]) array;
+ int length = booleans.length;
+ writeInt(length);
+ for (int i = 0; i < length; ++i) {
+ writeBoolean(booleans[i]);
+ }
+ }
+
+ private void writeObjectArray(Object[] objects) throws IOException {
+ int length = objects.length;
+ writeInt(length);
+ for (int i = 0; i < length; ++i) {
+ writeObject(objects[i]);
+ }
+ }
+
+ private void writeClass(Class clazz, int handle) throws IOException {
+ writeRecordType(RT_CLASS);
+ writeHandle(handle);
+ writeObjectOrReference(clazz.getName(), String.class);
+ }
+
+ private void writeReference(int handle) throws IOException {
+ writeRecordType(RT_REFERENCE);
+ writeHandle(handle);
+ }
+
+ private void writeString(String string, int handle) throws IOException {
+ writeRecordType(RT_STRING);
+ writeHandle(handle);
+ writeUTF(string);
+ }
+
+ private void writeExternalizable(Externalizable externalizable, Class clazz, int handle) throws IOException {
+ writeRecordType(RT_EXTERNALIZABLE);
+ writeHandle(handle);
+ writeObject(clazz);
+ externalizable.writeExternal(this);
+ }
+
+ private void writeSerializable(Serializable serializable, Class clazz, int handle) throws IOException {
+ writeRecordType(RT_SERIALIZABLE);
+ writeHandle(handle);
+ dataOutput.writeObject(serializable);
+ }
+
+ private void writeMap(Map map, Class clazz, int handle) throws IOException {
+ writeRecordType(RT_MAP);
+ writeHandle(handle);
+ writeObject(clazz);
+ writeInt(map.size());
+ for (Object object : map.entrySet()) {
+ Map.Entry entry = (Map.Entry) object;
+ writeObject(entry.getKey());
+ writeObject(entry.getValue());
+ }
+ }
+
+ private void writeCollection(Collection collection, Class clazz, int handle) throws IOException {
+ writeRecordType(RT_COLLECTION);
+ writeHandle(handle);
+ writeObject(clazz);
+ writeInt(collection.size());
+ for (Object object : collection) {
+ writeObject(object);
+ }
+ }
+
+ private void writeEmptySet() throws IOException {
+ writeRecordType(RT_EMPTY_SET);
+ }
+
+ private void writeEmptyList() throws IOException {
+ writeRecordType(RT_EMPTY_LIST);
+ }
+
+ private void writeEmptyMap() throws IOException {
+ writeRecordType(RT_EMPTY_MAP);
+ }
+
+ private void writeRecordType(byte type) throws IOException {
+ writeByte(type);
+ }
+
+ private void writeHandle(int handle) throws IOException {
+ writeInt(handle);
+ }
+
+ private void writeStreamHeader() throws IOException {
+ writeInt(STREAM_MAGIC);
+ writeShort(STREAM_VERSION);
+ }
+
+ private int registerObject(Object object) {
+ Integer handle = handlesByObject.get(object);
+ if (handle == null) {
+ handle = handlesByObject.size() + 1;
+ handlesByObject.put(object, handle);
+ handle = -handle;
+ }
+ return handle;
+ }
+
+ /*==========================================================================
+ Implementations of ObjectOutput
+ ==========================================================================*/
+ /**
+ * Write an object to the underlying storage or stream. The object was written
+ * in Drools specific format.
+ *
+ * @param object the object to be written
+ * @exception IOException Any of the usual Input/Output related exceptions.
+ */
+ public void writeObject(Object object) throws IOException {
+ if (object == null) {
+ writeNull();
+ } else {
+ Class clazz = object.getClass();
+
+ if (clazz == EMPTY_SET_CLASS) {
+ writeEmptySet();
+ } else if (clazz == EMPTY_LIST_CLASS) {
+ writeEmptyList();
+ } else if (clazz == EMPTY_MAP_CLASS) {
+ writeEmptyMap();
+ } else if (clazz == String.class) {
+ writeObjectOrReference(((String) object).intern(), clazz);
+ } else {
+ writeObjectOrReference(object, clazz);
+ }
+ }
+ flush();
+ }
+
+ /**
+ * Writes a byte. This method will block until the byte is actually
+ * written.
+ * @param b the byte
+ * @exception IOException If an I/O error has occurred.
+ */
+ public void write(int b) throws IOException {
+ dataOutput.write(b);
+ }
+
+ /**
+ * Writes an array of bytes. This method will block until the bytes
+ * are actually written.
+ * @param b the data to be written
+ * @exception IOException If an I/O error has occurred.
+ */
+ public void write(byte b[]) throws IOException {
+ dataOutput.write(b);
+ }
+
+ /**
+ * Writes a sub array of bytes.
+ * @param b the data to be written
+ * @param off the start offset in the data
+ * @param len the number of bytes that are written
+ * @exception IOException If an I/O error has occurred.
+ */
+ public void write(byte b[], int off, int len) throws IOException {
+ dataOutput.write(b, off, len);
+ }
+
+ /**
+ * Flushes the stream. This will write any buffered
+ * output bytes.
+ * @exception IOException If an I/O error has occurred.
+ */
+ public void flush() throws IOException {
+ dataOutput.flush();
+ }
+
+ /**
+ * Closes the stream. This method must be called
+ * to release any resources associated with the
+ * stream.
+ * @exception IOException If an I/O error has occurred.
+ */
+ public void close() throws IOException {
+ dataOutput.close();
+ }
+
+ /**
+ * Writes a <code>boolean</code> value to this output stream.
+ * If the argument <code>v</code>
+ * is <code>true</code>, the value <code>(byte)1</code>
+ * is written; if <code>v</code> is <code>false</code>,
+ * the value <code>(byte)0</code> is written.
+ * The byte written by this method may
+ * be read by the <code>readBoolean</code>
+ * method of interface <code>DataInput</code>,
+ * which will then return a <code>boolean</code>
+ * equal to <code>v</code>.
+ *
+ * @param v the boolean to be written.
+ * @exception IOException if an I/O error occurs.
+ */
+ public void writeBoolean(boolean v) throws IOException {
+ dataOutput.writeBoolean(v);
+ }
+
+ /**
+ * Writes to the output stream the eight low-
+ * order bits of the argument <code>v</code>.
+ * The 24 high-order bits of <code>v</code>
+ * are ignored. (This means that <code>writeByte</code>
+ * does exactly the same thing as <code>write</code>
+ * for an integer argument.) The byte written
+ * by this method may be read by the <code>readByte</code>
+ * method of interface <code>DataInput</code>,
+ * which will then return a <code>byte</code>
+ * equal to <code>(byte)v</code>.
+ *
+ * @param v the byte value to be written.
+ * @exception IOException if an I/O error occurs.
+ */
+ public void writeByte(int v) throws IOException {
+ dataOutput.writeByte(v);
+ }
+
+ /**
+ * Writes two bytes to the output
+ * stream to represent the value of the argument.
+ * The byte values to be written, in the order
+ * shown, are: <p>
+ * <pre><code>
+ * (byte)(0xff & (v >> 8))
+ * (byte)(0xff & v)
+ * </code> </pre> <p>
+ * The bytes written by this method may be
+ * read by the <code>readShort</code> method
+ * of interface <code>DataInput</code> , which
+ * will then return a <code>short</code> equal
+ * to <code>(short)v</code>.
+ *
+ * @param v the <code>short</code> value to be written.
+ * @exception IOException if an I/O error occurs.
+ */
+ public void writeShort(int v) throws IOException {
+ dataOutput.writeShort(v);
+ }
+
+ /**
+ * Writes a <code>char</code> value, which
+ * is comprised of two bytes, to the
+ * output stream.
+ * The byte values to be written, in the order
+ * shown, are:
+ * <p><pre><code>
+ * (byte)(0xff & (v >> 8))
+ * (byte)(0xff & v)
+ * </code></pre><p>
+ * The bytes written by this method may be
+ * read by the <code>readChar</code> method
+ * of interface <code>DataInput</code> , which
+ * will then return a <code>char</code> equal
+ * to <code>(char)v</code>.
+ *
+ * @param v the <code>char</code> value to be written.
+ * @exception IOException if an I/O error occurs.
+ */
+ public void writeChar(int v) throws IOException {
+ dataOutput.writeChar(v);
+ }
+
+ /**
+ * Writes an <code>int</code> value, which is
+ * comprised of four bytes, to the output stream.
+ * The byte values to be written, in the order
+ * shown, are:
+ * <p><pre><code>
+ * (byte)(0xff & (v >> 24))
+ * (byte)(0xff & (v >> 16))
+ * (byte)(0xff & (v >>    8))
+ * (byte)(0xff & v)
+ * </code></pre><p>
+ * The bytes written by this method may be read
+ * by the <code>readInt</code> method of interface
+ * <code>DataInput</code> , which will then
+ * return an <code>int</code> equal to <code>v</code>.
+ *
+ * @param v the <code>int</code> value to be written.
+ * @exception IOException if an I/O error occurs.
+ */
+ public void writeInt(int v) throws IOException {
+ dataOutput.writeInt(v);
+ }
+
+ /**
+ * Writes a <code>long</code> value, which is
+ * comprised of eight bytes, to the output stream.
+ * The byte values to be written, in the order
+ * shown, are:
+ * <p><pre><code>
+ * (byte)(0xff & (v >> 56))
+ * (byte)(0xff & (v >> 48))
+ * (byte)(0xff & (v >> 40))
+ * (byte)(0xff & (v >> 32))
+ * (byte)(0xff & (v >> 24))
+ * (byte)(0xff & (v >> 16))
+ * (byte)(0xff & (v >> 8))
+ * (byte)(0xff & v)
+ * </code></pre><p>
+ * The bytes written by this method may be
+ * read by the <code>readLong</code> method
+ * of interface <code>DataInput</code> , which
+ * will then return a <code>long</code> equal
+ * to <code>v</code>.
+ *
+ * @param v the <code>long</code> value to be written.
+ * @exception IOException if an I/O error occurs.
+ */
+ public void writeLong(long v) throws IOException {
+ dataOutput.writeLong(v);
+ }
+
+ /**
+ * Writes a <code>float</code> value,
+ * which is comprised of four bytes, to the output stream.
+ * It does this as if it first converts this
+ * <code>float</code> value to an <code>int</code>
+ * in exactly the manner of the <code>Float.floatToIntBits</code>
+ * method and then writes the <code>int</code>
+ * value in exactly the manner of the <code>writeInt</code>
+ * method. The bytes written by this method
+ * may be read by the <code>readFloat</code>
+ * method of interface <code>DataInput</code>,
+ * which will then return a <code>float</code>
+ * equal to <code>v</code>.
+ *
+ * @param v the <code>float</code> value to be written.
+ * @exception IOException if an I/O error occurs.
+ */
+ public void writeFloat(float v) throws IOException {
+ dataOutput.writeFloat(v);
+ }
+
+ /**
+ * Writes a <code>double</code> value,
+ * which is comprised of eight bytes, to the output stream.
+ * It does this as if it first converts this
+ * <code>double</code> value to a <code>long</code>
+ * in exactly the manner of the <code>Double.doubleToLongBits</code>
+ * method and then writes the <code>long</code>
+ * value in exactly the manner of the <code>writeLong</code>
+ * method. The bytes written by this method
+ * may be read by the <code>readDouble</code>
+ * method of interface <code>DataInput</code>,
+ * which will then return a <code>double</code>
+ * equal to <code>v</code>.
+ *
+ * @param v the <code>double</code> value to be written.
+ * @exception IOException if an I/O error occurs.
+ */
+ public void writeDouble(double v) throws IOException {
+ dataOutput.writeDouble(v);
+ }
+
+ /**
+ * Writes a string to the output stream.
+ * For every character in the string
+ * <code>s</code>, taken in order, one byte
+ * is written to the output stream. If
+ * <code>s</code> is <code>null</code>, a <code>NullPointerException</code>
+ * is thrown.<p> If <code>s.length</code>
+ * is zero, then no bytes are written. Otherwise,
+ * the character <code>s[0]</code> is written
+ * first, then <code>s[1]</code>, and so on;
+ * the last character written is <code>s[s.length-1]</code>.
+ * For each character, one byte is written,
+ * the low-order byte, in exactly the manner
+ * of the <code>writeByte</code> method . The
+ * high-order eight bits of each character
+ * in the string are ignored.
+ *
+ * @param s the string of bytes to be written.
+ * @exception IOException if an I/O error occurs.
+ */
+ public void writeBytes(String s) throws IOException {
+ dataOutput.writeBytes(s);
+ }
+
+ /**
+ * Writes every character in the string <code>s</code>,
+ * to the output stream, in order,
+ * two bytes per character. If <code>s</code>
+ * is <code>null</code>, a <code>NullPointerException</code>
+ * is thrown. If <code>s.length</code>
+ * is zero, then no characters are written.
+ * Otherwise, the character <code>s[0]</code>
+ * is written first, then <code>s[1]</code>,
+ * and so on; the last character written is
+ * <code>s[s.length-1]</code>. For each character,
+ * two bytes are actually written, high-order
+ * byte first, in exactly the manner of the
+ * <code>writeChar</code> method.
+ *
+ * @param s the string value to be written.
+ * @exception IOException if an I/O error occurs.
+ */
+ public void writeChars(String s) throws IOException {
+ dataOutput.writeChars(s);
+ }
+
+ /**
+ * Writes two bytes of length information
+ * to the output stream, followed
+ * by the
+ * <a href="DataInput.html#modified-utf-8">modified UTF-8</a>
+ * representation
+ * of every character in the string <code>s</code>.
+ * If <code>s</code> is <code>null</code>,
+ * a <code>NullPointerException</code> is thrown.
+ * Each character in the string <code>s</code>
+ * is converted to a group of one, two, or
+ * three bytes, depending on the value of the
+ * character.<p>
+ * If a character <code>c</code>
+ * is in the range <code>\u0001</code> through
+ * <code>\u007f</code>, it is represented
+ * by one byte:<p>
+ * <pre>(byte)c </pre> <p>
+ * If a character <code>c</code> is <code>\u0000</code>
+ * or is in the range <code>\u0080</code>
+ * through <code>\u07ff</code>, then it is
+ * represented by two bytes, to be written
+ * in the order shown:<p> <pre><code>
+ * (byte)(0xc0 | (0x1f & (c >> 6)))
+ * (byte)(0x80 | (0x3f & c))
+ * </code></pre> <p> If a character
+ * <code>c</code> is in the range <code>\u0800</code>
+ * through <code>uffff</code>, then it is
+ * represented by three bytes, to be written
+ * in the order shown:<p> <pre><code>
+ * (byte)(0xe0 | (0x0f & (c >> 12)))
+ * (byte)(0x80 | (0x3f & (c >> 6)))
+ * (byte)(0x80 | (0x3f & c))
+ * </code></pre> <p> First,
+ * the total number of bytes needed to represent
+ * all the characters of <code>s</code> is
+ * calculated. If this number is larger than
+ * <code>65535</code>, then a <code>UTFDataFormatException</code>
+ * is thrown. Otherwise, this length is written
+ * to the output stream in exactly the manner
+ * of the <code>writeShort</code> method;
+ * after this, the one-, two-, or three-byte
+ * representation of each character in the
+ * string <code>s</code> is written.<p> The
+ * bytes written by this method may be read
+ * by the <code>readUTF</code> method of interface
+ * <code>DataInput</code> , which will then
+ * return a <code>String</code> equal to <code>s</code>.
+ *
+ * @param str the string value to be written.
+ * @exception IOException if an I/O error occurs.
+ */
+ public void writeUTF(String str) throws IOException {
+ dataOutput.writeUTF(str);
+ }
+}
More information about the jboss-svn-commits
mailing list