Author: julien_viet
Date: 2010-01-13 18:44:52 -0500 (Wed, 13 Jan 2010)
New Revision: 1269
Added:
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/serial/DataContainer.java
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/serial/ObjectReader.java
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/serial/ObjectWriter.java
portal/trunk/webui/core/src/test/java/org/exoplatform/webui/replication/E.java
portal/trunk/webui/core/src/test/java/org/exoplatform/webui/replication/TestSerialization.java
Log:
other impl of stream serialization
Added:
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/serial/DataContainer.java
===================================================================
---
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/serial/DataContainer.java
(rev 0)
+++
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/serial/DataContainer.java 2010-01-13
23:44:52 UTC (rev 1269)
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+
+package org.exoplatform.webui.application.replication.serial;
+
+import java.io.*;
+import java.util.LinkedList;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien
Viet</a>
+ * @version $Revision$
+ */
+public class DataContainer implements Serializable
+{
+
+ /** . */
+ private final LinkedList<Object> structure;
+
+ public DataContainer()
+ {
+ this.structure = new LinkedList<Object>();
+ }
+
+ public void writeInt(int i)
+ {
+ structure.add(i);
+ }
+
+ public void writeObject(Object o)
+ {
+ structure.add(o);
+ }
+
+ public int readInt()
+ {
+ return (Integer)structure.removeFirst();
+ }
+
+ public Object readObject()
+ {
+ return structure.removeFirst();
+ }
+
+ @Override
+ public String toString()
+ {
+ return "DataContainer[" + structure + "]";
+ }
+}
Added:
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/serial/ObjectReader.java
===================================================================
---
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/serial/ObjectReader.java
(rev 0)
+++
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/serial/ObjectReader.java 2010-01-13
23:44:52 UTC (rev 1269)
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+
+package org.exoplatform.webui.application.replication.serial;
+
+import org.exoplatform.webui.application.replication.model.ClassTypeModel;
+import org.exoplatform.webui.application.replication.model.FieldModel;
+import org.exoplatform.webui.application.replication.model.TypeDomain;
+import org.exoplatform.webui.application.replication.model.TypeModel;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.util.*;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien
Viet</a>
+ * @version $Revision$
+ */
+public class ObjectReader extends ObjectInputStream
+{
+
+ /** . */
+ private final TypeDomain domain;
+
+ /** . */
+ private final Map<Integer, Object> idToObject;
+
+ /** . */
+ private final Map<Integer, List<Resolution>> idToResolutions;
+
+ public ObjectReader(TypeDomain domain, InputStream in) throws IOException
+ {
+ super(in);
+
+ //
+ enableResolveObject(true);
+
+ //
+ this.domain = domain;
+ this.idToObject = new HashMap<Integer, Object>();
+ this.idToResolutions = new HashMap<Integer, List<Resolution>>();
+ }
+
+ @Override
+ protected Object resolveObject(Object obj) throws IOException
+ {
+ if (obj instanceof DataContainer)
+ {
+ DataContainer container = (DataContainer) obj;
+
+ int id;
+ switch (container.readInt())
+ {
+ case DataKind.OBJECT_REF:
+ id = container.readInt();
+ Object o1 = idToObject.get(id);
+ if (o1 == null)
+ {
+ throw new AssertionError();
+ }
+ return o1;
+ case DataKind.OBJECT:
+ id = container.readInt();
+ Class clazz = (Class) container.readObject();
+ Object instance;
+ try
+ {
+ instance = clazz.newInstance();
+ }
+ catch (Exception e)
+ {
+ throw new AssertionError(e);
+ }
+ ClassTypeModel typeModel = (ClassTypeModel) domain.getTypeModel(clazz);
+ idToObject.put(id, instance);
+
+ //
+ ClassTypeModel currentTypeModel = typeModel;
+ while (true)
+ {
+ for (FieldModel fieldModel : (currentTypeModel).getFields())
+ {
+ switch (container.readInt())
+ {
+ case DataKind.NULL_VALUE:
+ fieldModel.setValue(instance, null);
+ break;
+ case DataKind.OBJECT_REF:
+ int refId = container.readInt();
+ Object refO = idToObject.get(refId);
+ if (refO != null)
+ {
+ fieldModel.setValue(instance, refO);
+ }
+ else
+ {
+ List<Resolution> resolutions =
idToResolutions.get(refId);
+ if (resolutions == null)
+ {
+ resolutions = new ArrayList<Resolution>();
+ idToResolutions.put(refId, resolutions);
+ }
+ resolutions.add(new Resolution(instance, fieldModel));
+ }
+ break;
+ case DataKind.OBJECT:
+ Object o = container.readObject();
+ fieldModel.setValue(instance, o);
+ break;
+
+ }
+ }
+ TypeModel currentSuperTypeModel = currentTypeModel.getSuperType();
+ if (currentSuperTypeModel == null)
+ {
+ break;
+ }
+ if (currentSuperTypeModel instanceof ClassTypeModel)
+ {
+ currentTypeModel = (ClassTypeModel)currentSuperTypeModel;
+ }
+ else
+ {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ //
+ List<Resolution> resolutions = idToResolutions.remove(id);
+ if (resolutions != null)
+ {
+ for (Resolution resolution : resolutions)
+ {
+ resolution.fieldModel.setValue(resolution.target, instance);
+ }
+ }
+
+ //
+ return instance;
+ default:
+ throw new AssertionError();
+ }
+ }
+ else
+ {
+ return obj;
+ }
+ }
+
+ private static class Resolution
+ {
+ /** . */
+ private final Object target;
+
+ /** . */
+ private final FieldModel fieldModel;
+
+ private Resolution(Object target, FieldModel fieldModel)
+ {
+ this.target = target;
+ this.fieldModel = fieldModel;
+ }
+ }
+
+}
Added:
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/serial/ObjectWriter.java
===================================================================
---
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/serial/ObjectWriter.java
(rev 0)
+++
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/serial/ObjectWriter.java 2010-01-13
23:44:52 UTC (rev 1269)
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+
+package org.exoplatform.webui.application.replication.serial;
+
+import org.exoplatform.webui.application.replication.model.ClassTypeModel;
+import org.exoplatform.webui.application.replication.model.FieldModel;
+import org.exoplatform.webui.application.replication.model.TypeDomain;
+import org.exoplatform.webui.application.replication.model.TypeModel;
+
+import java.io.*;
+import java.util.HashMap;
+import java.util.IdentityHashMap;
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien
Viet</a>
+ * @version $Revision$
+ */
+public class ObjectWriter extends ObjectOutputStream
+{
+
+ /** . */
+ private final TypeDomain domain;
+
+ /** . */
+ private final IdentityHashMap<Object, Integer> objectToId;
+
+ public ObjectWriter(TypeDomain domain, OutputStream out) throws IOException
+ {
+ super(out);
+
+ //
+ enableReplaceObject(true);
+
+ //
+ this.domain = domain;
+ this.objectToId = new IdentityHashMap<Object, Integer>();
+ }
+
+ private int register(Object o)
+ {
+ int nextId = objectToId.size();
+ objectToId.put(o, nextId);
+ return nextId;
+ }
+
+ @Override
+ protected Object replaceObject(Object obj) throws IOException
+ {
+ if (obj instanceof Serializable)
+ {
+ return obj;
+ }
+
+ //
+ DataContainer output = new DataContainer();
+
+ //
+ Integer id = objectToId.get(obj);
+ if (id != null)
+ {
+ output.writeInt(DataKind.OBJECT_REF);
+ output.writeObject(id);
+ }
+ else
+ {
+ ClassTypeModel typeModel = (ClassTypeModel)
domain.getTypeModel(obj.getClass());
+
+ //
+ if (typeModel == null)
+ {
+ throw new NotSerializableException("Object " + obj + " is not
serializable");
+ }
+
+ //
+ output.writeInt(DataKind.OBJECT);
+ output.writeInt(register(obj));
+ output.writeObject(obj.getClass());
+
+ //
+ ClassTypeModel currentTypeModel = typeModel;
+ while (true)
+ {
+ for (FieldModel fieldModel : (currentTypeModel).getFields())
+ {
+ Object fieldValue = fieldModel.getValue(obj);
+ if (fieldValue == null)
+ {
+ output.writeObject(DataKind.NULL_VALUE);
+ }
+ else
+ {
+ Integer fieldValueId = objectToId.get(fieldValue);
+ if (fieldValueId != null)
+ {
+ output.writeObject(DataKind.OBJECT_REF);
+ output.writeInt(fieldValueId);
+ }
+ else
+ {
+ output.writeObject(DataKind.OBJECT);
+ output.writeObject(fieldValue);
+ }
+ }
+ }
+
+ //
+ TypeModel currentSuperTypeModel = currentTypeModel.getSuperType();
+ if (currentSuperTypeModel == null)
+ {
+ break;
+ }
+
+ //
+ if (currentSuperTypeModel instanceof ClassTypeModel)
+ {
+ currentTypeModel = (ClassTypeModel)currentSuperTypeModel;
+ }
+ else
+ {
+ throw new UnsupportedOperationException();
+ }
+ }
+ }
+
+ //
+ return output;
+ }
+}
\ No newline at end of file
Added: portal/trunk/webui/core/src/test/java/org/exoplatform/webui/replication/E.java
===================================================================
--- portal/trunk/webui/core/src/test/java/org/exoplatform/webui/replication/E.java
(rev 0)
+++
portal/trunk/webui/core/src/test/java/org/exoplatform/webui/replication/E.java 2010-01-13
23:44:52 UTC (rev 1269)
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+
+package org.exoplatform.webui.replication;
+
+import org.exoplatform.webui.application.replication.annotations.ReplicatedType;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien
Viet</a>
+ * @version $Revision$
+ */
+@ReplicatedType
+public class E
+{
+
+ E left;
+ E right;
+
+}
Added:
portal/trunk/webui/core/src/test/java/org/exoplatform/webui/replication/TestSerialization.java
===================================================================
---
portal/trunk/webui/core/src/test/java/org/exoplatform/webui/replication/TestSerialization.java
(rev 0)
+++
portal/trunk/webui/core/src/test/java/org/exoplatform/webui/replication/TestSerialization.java 2010-01-13
23:44:52 UTC (rev 1269)
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+
+package org.exoplatform.webui.replication;
+
+import junit.framework.TestCase;
+import org.exoplatform.webui.application.replication.model.TypeDomain;
+import org.exoplatform.webui.application.replication.serial.ObjectReader;
+import org.exoplatform.webui.application.replication.serial.ObjectWriter;
+
+import java.io.*;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien
Viet</a>
+ * @version $Revision$
+ */
+public class TestSerialization extends TestCase
+{
+
+ public void testBar() throws Exception
+ {
+ TypeDomain domain = new TypeDomain();
+ domain.add(A.class);
+ A a = new A();
+ a.a = "foo";
+ a.b = 2;
+ a.c = true;
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectWriter writer = new ObjectWriter(domain, baos);
+ writer.writeObject(a);
+ writer.close();
+ ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+ ObjectReader in = new ObjectReader(domain, bais);
+ a = (A)in.readObject();
+ assertEquals("foo", a.a);
+ assertEquals(2, a.b);
+ assertEquals(true, a.c);
+ }
+
+ public void testFoo() throws Exception
+ {
+ TypeDomain domain = new TypeDomain();
+ domain.add(B.class);
+ B b = new B();
+ b.ref = new B(b);
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectWriter writer = new ObjectWriter(domain, baos);
+ writer.writeObject(b);
+ ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+ ObjectReader in = new ObjectReader(domain, bais);
+ b = (B)in.readObject();
+ assertNotNull(b.ref);
+ assertSame(b, b.ref.ref);
+ }
+
+ public void testAAA() throws Exception
+ {
+ TypeDomain domain = new TypeDomain();
+ domain.add(E.class);
+ E e = new E();
+ e.left = new E();
+ e.left.left = new E();
+ e.left.right = new E();
+ e.right = new E();
+ e.right.left = e.left.left;
+ e.right.right = e.left.right;
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectWriter writer = new ObjectWriter(domain, baos);
+ writer.writeObject(e);
+ ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+ ObjectReader in = new ObjectReader(domain, bais);
+ e = (E)in.readObject();
+ assertSame(e.left.left, e.right.left);
+ assertSame(e.left.right, e.right.right);
+ }
+}