You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2009/09/16 20:32:24 UTC

svn commit: r815920 - in /cayenne/sandbox/cayenne-serialization/src: main/java/org/apache/cayenne/serialization/ main/java/org/apache/cayenne/serialization/xstream/ test/java/org/apache/cayenne/serialization/xstream/

Author: aadamchik
Date: Wed Sep 16 18:32:23 2009
New Revision: 815920

URL: http://svn.apache.org/viewvc?rev=815920&view=rev
Log:
prototyping (de)serializer based on XStream:

deserializing to-many
eagerly settin relationships

Added:
    cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/DeserializerStack.java
      - copied, changed from r815515, cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/SerializerStack.java
Removed:
    cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/DeserializerCounter.java
Modified:
    cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/SubgraphNode.java
    cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/PersistentCloneUnmarshalConverter.java
    cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/SerializerStack.java
    cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/xstream/XStreamDeserializerTest.java

Modified: cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/SubgraphNode.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/SubgraphNode.java?rev=815920&r1=815919&r2=815920&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/SubgraphNode.java (original)
+++ cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/SubgraphNode.java Wed Sep 16 18:32:23 2009
@@ -73,6 +73,24 @@
 		this(incomingProperty.getTargetDescriptor());
 		this.incomingProperty = incomingProperty;
 	}
+	
+	public int getMaxDepth() {
+		if(children != null) {
+			int depth = 0;
+			for(SubgraphNode child : children.values()) {
+				int childDepth = child.getMaxDepth();
+				
+				if(depth < childDepth) {
+					depth = childDepth;
+				}
+			}
+			
+			return depth + 1;
+		}
+		else {
+			return 1;
+		}
+	}
 
 	/**
 	 * Returns true if only a reference should be serialized for this node,

Copied: cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/DeserializerStack.java (from r815515, cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/SerializerStack.java)
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/DeserializerStack.java?p2=cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/DeserializerStack.java&p1=cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/SerializerStack.java&r1=815515&r2=815920&rev=815920&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/SerializerStack.java (original)
+++ cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/DeserializerStack.java Wed Sep 16 18:32:23 2009
@@ -18,39 +18,49 @@
  ****************************************************************/
 package org.apache.cayenne.serialization.xstream;
 
-import java.util.ArrayList;
-import java.util.List;
+import org.apache.cayenne.reflect.ArcProperty;
+import org.apache.cayenne.reflect.ToManyProperty;
 
-import org.apache.cayenne.serialization.Subgraph;
-import org.apache.cayenne.serialization.SubgraphNode;
+import com.thoughtworks.xstream.core.util.FastStack;
 
-/**
- * A single-threaded stack for {@link Subgraph} traversal.
- */
-// potentially this can be used with other serializers, we just don't have any
-// at the moment to generalize
-class SerializerStack {
-
-	private List<SubgraphNode> stack;
-
-	public SerializerStack(SubgraphNode graphDescriptorRoot) {
-		stack = new ArrayList<SubgraphNode>();
-		stack.add(graphDescriptorRoot);
+class DeserializerStack {
+
+	private FastStack stack;
+	private int counter;
+
+	DeserializerStack() {
+		stack = new FastStack(10);
 	}
 
-	public String getCayenneNamespace() {
-		return "cay";
+	int incrementCounter() {
+		return ++counter;
 	}
 
-	public void pushNode(SubgraphNode node) {
-		stack.add(node);
+	void push(Object object) {
+
+		// connect to parent
+		Object[] peek = (Object[]) stack.peek();
+		if (peek != null) {
+
+			if (peek[1] instanceof ToManyProperty) {
+				((ToManyProperty) peek[1]).addTarget(peek[0], object, true);
+			} else {
+				((ArcProperty) peek[1]).writeProperty(peek[0], null, object);
+			}
+		}
+
+		Object[] entry = new Object[2];
+		entry[0] = object;
+		stack.push(entry);
 	}
 
-	public void popNode() {
-		stack.remove(stack.size() - 1);
+	void pop() {
+		stack.popSilently();
 	}
 
-	public SubgraphNode peekNode() {
-		return stack.get(stack.size() - 1);
+	void startRelationship(ArcProperty property) {
+		Object[] peek = (Object[]) stack.peek();
+		peek[1] = property;
 	}
+
 }

Modified: cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/PersistentCloneUnmarshalConverter.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/PersistentCloneUnmarshalConverter.java?rev=815920&r1=815919&r2=815920&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/PersistentCloneUnmarshalConverter.java (original)
+++ cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/PersistentCloneUnmarshalConverter.java Wed Sep 16 18:32:23 2009
@@ -26,6 +26,7 @@
 import org.apache.cayenne.reflect.AttributeProperty;
 import org.apache.cayenne.reflect.ClassDescriptor;
 import org.apache.cayenne.reflect.Property;
+import org.apache.cayenne.reflect.ToManyProperty;
 
 import com.thoughtworks.xstream.converters.Converter;
 import com.thoughtworks.xstream.converters.MarshallingContext;
@@ -78,8 +79,16 @@
 
 		ObjectId id = (ObjectId) context.convertAnother(null, ObjectId.class);
 
-		return DataObjectUtils.objectForPK(objectContext, id);
+		Object object = DataObjectUtils.objectForPK(objectContext, id);
 		// TODO: handle deleted objects that no longer exist...
+
+		if (object != null) {
+			DeserializerStack stack = getDeserialierCounter(context);
+			stack.push(object);
+			stack.pop();
+		}
+
+		return object;
 	}
 
 	private Object deserializeNew(HierarchicalStreamReader reader,
@@ -89,10 +98,12 @@
 		ClassDescriptor descriptor = objectContext.getEntityResolver()
 				.getClassDescriptor(entityName);
 
+		DeserializerStack stack = getDeserialierCounter(context);
+
 		Object object = descriptor.createObject();
 		objectContext.registerNewObject(object);
 
-		DeserializerCounter deserializerCounter = getDeserialierCounter(context);
+		stack.push(object);
 
 		while (reader.hasMoreChildren()) {
 			reader.moveDown();
@@ -104,8 +115,11 @@
 			} else {
 				ArcProperty arc = (ArcProperty) property;
 
+				stack.startRelationship(arc);
+
 				if (arc.getRelationship().isToMany()) {
-					deserializeToManyRelationship(reader, context, object, arc);
+					deserializeToManyRelationship(reader, context, object,
+							(ToManyProperty) arc);
 				} else {
 					deserializeToOneRelationship(reader, context, object, arc);
 				}
@@ -115,11 +129,11 @@
 		}
 
 		if (commitCountThreshold > 0
-				&& deserializerCounter.incrementCounter()
-						% commitCountThreshold == 0) {
+				&& stack.incrementCounter() % commitCountThreshold == 0) {
 			objectContext.commitChanges();
 		}
 
+		stack.pop();
 		return object;
 	}
 
@@ -139,27 +153,29 @@
 		Class<?> javaType = property.getTargetDescriptor().getObjectClass();
 
 		reader.moveDown();
-
-		Object value = context.convertAnother(parentObject, javaType);
-		property.writeProperty(parentObject, null, value);
-
+		context.convertAnother(parentObject, javaType);
 		reader.moveUp();
 	}
 
 	private void deserializeToManyRelationship(HierarchicalStreamReader reader,
 			UnmarshallingContext context, Object parentObject,
-			ArcProperty property) {
+			ToManyProperty property) {
 
-		throw new UnsupportedOperationException("TODO");
+		Class<?> javaType = property.getTargetDescriptor().getObjectClass();
+
+		while (reader.hasMoreChildren()) {
+			reader.moveDown();
+			context.convertAnother(parentObject, javaType);
+			reader.moveUp();
+		}
 	}
 
-	private DeserializerCounter getDeserialierCounter(
-			UnmarshallingContext context) {
-		DeserializerCounter deserializerCounter = (DeserializerCounter) context
+	private DeserializerStack getDeserialierCounter(UnmarshallingContext context) {
+		DeserializerStack deserializerCounter = (DeserializerStack) context
 				.get(TRAVERSAL_CONTEXT_KEY);
 
 		if (deserializerCounter == null) {
-			deserializerCounter = new DeserializerCounter();
+			deserializerCounter = new DeserializerStack();
 			context.put(TRAVERSAL_CONTEXT_KEY, deserializerCounter);
 		}
 

Modified: cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/SerializerStack.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/SerializerStack.java?rev=815920&r1=815919&r2=815920&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/SerializerStack.java (original)
+++ cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/SerializerStack.java Wed Sep 16 18:32:23 2009
@@ -18,39 +18,32 @@
  ****************************************************************/
 package org.apache.cayenne.serialization.xstream;
 
-import java.util.ArrayList;
-import java.util.List;
-
 import org.apache.cayenne.serialization.Subgraph;
 import org.apache.cayenne.serialization.SubgraphNode;
 
+import com.thoughtworks.xstream.core.util.FastStack;
+
 /**
  * A single-threaded stack for {@link Subgraph} traversal.
  */
-// potentially this can be used with other serializers, we just don't have any
-// at the moment to generalize
 class SerializerStack {
 
-	private List<SubgraphNode> stack;
+	private FastStack stack;
 
 	public SerializerStack(SubgraphNode graphDescriptorRoot) {
-		stack = new ArrayList<SubgraphNode>();
-		stack.add(graphDescriptorRoot);
-	}
-
-	public String getCayenneNamespace() {
-		return "cay";
+		stack = new FastStack(graphDescriptorRoot.getMaxDepth());
+		stack.push(graphDescriptorRoot);
 	}
 
 	public void pushNode(SubgraphNode node) {
-		stack.add(node);
+		stack.push(node);
 	}
 
 	public void popNode() {
-		stack.remove(stack.size() - 1);
+		stack.popSilently();
 	}
 
 	public SubgraphNode peekNode() {
-		return stack.get(stack.size() - 1);
+		return (SubgraphNode) stack.peek();
 	}
 }

Modified: cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/xstream/XStreamDeserializerTest.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/xstream/XStreamDeserializerTest.java?rev=815920&r1=815919&r2=815920&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/xstream/XStreamDeserializerTest.java (original)
+++ cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/xstream/XStreamDeserializerTest.java Wed Sep 16 18:32:23 2009
@@ -21,6 +21,8 @@
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.HashSet;
+import java.util.Set;
 
 import org.apache.cayenne.DataObjectUtils;
 import org.apache.cayenne.ObjectContext;
@@ -142,4 +144,42 @@
 		assertSame(t11, result.getTable1());
 
 	}
+
+	public void testDeserializeByValueToMany() throws IOException {
+
+		ObjectContext context = newContext();
+
+		Subgraph<Table1> subgraph = new Subgraph<Table1>(Table1.class, context
+				.getEntityResolver());
+		subgraph.addSerializeByValuePath(Table1.TABLE2S_PROPERTY);
+
+		XStreamDeserializer deserializer = new XStreamDeserializer();
+
+		String xml = "<Table1><name>t11</name><table2s>"
+				+ "<Table2><name>t21</name></Table2>"
+				+ "<Table2><name>t22</name></Table2></table2s></Table1>";
+
+		Table1 result;
+		InputStream in = new ByteArrayInputStream(xml.getBytes());
+		try {
+			result = deserializer.deserialize(context, subgraph, in);
+		} finally {
+			in.close();
+		}
+
+		assertNotNull(result);
+		assertEquals(2, result.getTable2s().size());
+		assertEquals(PersistenceState.COMMITTED, result.getPersistenceState());
+		assertEquals(PersistenceState.COMMITTED, result.getTable2s().get(0)
+				.getPersistenceState());
+
+		assertEquals("t11", result.getName());
+
+		Set<String> names = new HashSet<String>();
+		names.add(result.getTable2s().get(0).getName());
+		names.add(result.getTable2s().get(1).getName());
+		assertTrue(names.contains("t21"));
+		assertTrue(names.contains("t22"));
+	}
+
 }