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/18 16:18:26 UTC

svn commit: r816642 - 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/ test/java/org/apache/cayenne/serialization/...

Author: aadamchik
Date: Fri Sep 18 14:18:26 2009
New Revision: 816642

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

adding chain assembly API

Added:
    cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/SubgraphBuilder.java
    cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/SubgraphCallback.java
      - copied, changed from r816206, cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/DeserializationCallback.java
Modified:
    cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/DeserializationCallback.java
    cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/SerializationCallback.java
    cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/Subgraph.java
    cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/DeserializerStack.java
    cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/SubgraphTest.java
    cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/xstream/XStreamDeserializerTest.java
    cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/xstream/XStreamSerializerTest.java

Modified: cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/DeserializationCallback.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/DeserializationCallback.java?rev=816642&r1=816641&r2=816642&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/DeserializationCallback.java (original)
+++ cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/DeserializationCallback.java Fri Sep 18 14:18:26 2009
@@ -18,7 +18,11 @@
  ****************************************************************/
 package org.apache.cayenne.serialization;
 
-public interface DeserializationCallback {
+public interface DeserializationCallback extends SubgraphCallback {
 
+	/**
+	 * Called when an object is deserialized and all its properties (inlcuding
+	 * relationships) are set.
+	 */
 	void postDeserialize(SubgraphNode node, Object object);
 }

Modified: cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/SerializationCallback.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/SerializationCallback.java?rev=816642&r1=816641&r2=816642&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/SerializationCallback.java (original)
+++ cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/SerializationCallback.java Fri Sep 18 14:18:26 2009
@@ -20,7 +20,7 @@
 
 import org.apache.cayenne.query.Query;
 
-public interface SerializationCallback {
+public interface SerializationCallback extends SubgraphCallback {
 
 	Query relationshipQuery(SubgraphNode node, Object sourceObject);
 }

Modified: cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/Subgraph.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/Subgraph.java?rev=816642&r1=816641&r2=816642&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/Subgraph.java (original)
+++ cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/Subgraph.java Fri Sep 18 14:18:26 2009
@@ -28,7 +28,7 @@
  * Represents a subgraph of the Cayenne-mapped persistent object graph. Used as
  * a model for serialization.
  */
-public class Subgraph<T> {
+public class Subgraph<T> implements SubgraphBuilder {
 
 	private SubgraphNode rootNode;
 
@@ -51,6 +51,10 @@
 		this.rootNode = new SubgraphNode(descriptor);
 	}
 
+	Subgraph(SubgraphNode rootNode) {
+		this.rootNode = rootNode;
+	}
+
 	public SubgraphNode getRootNode() {
 		return rootNode;
 	}
@@ -60,7 +64,7 @@
 	 * useful for excluding mapped ids or attributes auto-generated with
 	 * listeners. The path must end in the ObjAttribute.
 	 */
-	public void excludeAttribute(String path) {
+	public SubgraphBuilder excludeAttribute(String path) {
 		StringTokenizer tokens = new StringTokenizer(path, ".");
 
 		SubgraphNode node = rootNode;
@@ -75,19 +79,26 @@
 				node.excludeAttribute(token);
 			}
 		}
+		
+		return new Subgraph<Object>(node);
 	}
 
 	/**
 	 * Adds a subgraph path based on a relationship. On deserialization a new
 	 * object will be created in the database.
 	 */
-	public void addSerializeByValuePath(String path) {
+	public SubgraphBuilder addClonePath(String path,
+			SubgraphCallback... callbacks) {
 		StringTokenizer tokens = new StringTokenizer(path, ".");
 
 		SubgraphNode node = rootNode;
 		while (tokens.hasMoreTokens()) {
 			node = node.getChild(tokens.nextToken(), true);
 		}
+
+		addCallbacks(node, callbacks);
+
+		return new Subgraph<Object>(node);
 	}
 
 	/**
@@ -95,7 +106,8 @@
 	 * reference to its ObjectId. Such objects will be matched against the
 	 * existing DB rows, and no new objects will be created for them.
 	 */
-	public void addSerializeByReferencePath(String path) {
+	public SubgraphBuilder addRefPath(String path,
+			SubgraphCallback... callbacks) {
 		StringTokenizer tokens = new StringTokenizer(path, ".");
 
 		SubgraphNode node = rootNode;
@@ -104,33 +116,30 @@
 			node = node.getChild(token, true);
 			node.setSerializedByReference(!tokens.hasMoreTokens());
 		}
-	}
-
-	public void addDeserializationCallback(String path,
-			DeserializationCallback callback) {
-
-		StringTokenizer tokens = new StringTokenizer(path, ".");
-
-		SubgraphNode node = rootNode;
-		while (tokens.hasMoreTokens()) {
-			String token = tokens.nextToken();
-			node = node.getChild(token, false);
-		}
 
-		node.addDeserializationCallback(callback);
+		addCallbacks(node, callbacks);
+		return new Subgraph<Object>(node);
 	}
-
-	public void addSerializationCallback(String path,
-			SerializationCallback callback) {
-
-		StringTokenizer tokens = new StringTokenizer(path, ".");
-
-		SubgraphNode node = rootNode;
-		while (tokens.hasMoreTokens()) {
-			String token = tokens.nextToken();
-			node = node.getChild(token, false);
+	
+	public SubgraphBuilder addCallbacks(SubgraphCallback... callbacks) {
+		addCallbacks(rootNode, callbacks);
+		return this;
+	}
+
+	private void addCallbacks(SubgraphNode node, SubgraphCallback... callbacks) {
+		if (callbacks != null && callbacks.length > 0) {
+			for (SubgraphCallback callback : callbacks) {
+				if (callback instanceof DeserializationCallback) {
+					node
+							.addDeserializationCallback((DeserializationCallback) callback);
+				} else if (callback instanceof SerializationCallback) {
+					node
+							.addSerializationCallback((SerializationCallback) callback);
+				} else {
+					throw new IllegalArgumentException(
+							"Unsupported callback type: " + callback);
+				}
+			}
 		}
-
-		node.addSerializationCallback(callback);
 	}
 }

Added: cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/SubgraphBuilder.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/SubgraphBuilder.java?rev=816642&view=auto
==============================================================================
--- cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/SubgraphBuilder.java (added)
+++ cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/SubgraphBuilder.java Fri Sep 18 14:18:26 2009
@@ -0,0 +1,46 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.serialization;
+
+/**
+ * An interface providing a chain assembly API to build Subgraphs. Subgraph
+ * class itself implements this interface.
+ */
+public interface SubgraphBuilder {
+
+	SubgraphBuilder addCallbacks(SubgraphCallback... callbacks);
+
+	/**
+	 * Adds a subgraph path based on a relationship and sets an optional list of
+	 * callbacks for this path. On deserialization a new object will be created
+	 * in the database. Returns a SubgraphBuilder with the root node being the
+	 * node pointed by the path.
+	 */
+	SubgraphBuilder addClonePath(String path, SubgraphCallback... callbacks);
+
+	/**
+	 * Adds a subgraph path to a related entity that should be serialized as a
+	 * reference to its ObjectId and sets an optional list of callbacks for this
+	 * path. Such objects will be matched against existing DB rows, and no new
+	 * objects will be created for them.
+	 */
+	SubgraphBuilder addRefPath(String path, SubgraphCallback... callbacks);
+
+	SubgraphBuilder excludeAttribute(String path);
+}

Copied: cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/SubgraphCallback.java (from r816206, cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/DeserializationCallback.java)
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/SubgraphCallback.java?p2=cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/SubgraphCallback.java&p1=cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/DeserializationCallback.java&r1=816206&r2=816642&rev=816642&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/DeserializationCallback.java (original)
+++ cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/SubgraphCallback.java Fri Sep 18 14:18:26 2009
@@ -18,7 +18,9 @@
  ****************************************************************/
 package org.apache.cayenne.serialization;
 
-public interface DeserializationCallback {
+/**
+ * A tag interface for serialization or deserialization callback object.
+ */
+public interface SubgraphCallback {
 
-	void postDeserialize(SubgraphNode node, Object object);
 }

Modified: cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/DeserializerStack.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/DeserializerStack.java?rev=816642&r1=816641&r2=816642&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/DeserializerStack.java (original)
+++ cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/DeserializerStack.java Fri Sep 18 14:18:26 2009
@@ -56,22 +56,30 @@
 			}
 		}
 
-		// apply callbacks
-		for (DeserializationCallback callback : node
-				.getDeserializationCallbacks()) {
-			callback.postDeserialize(node, object);
-		}
-
 		objectStack.push(object);
 	}
 
 	int popObject() {
 		Persistent object = (Persistent) objectStack.pop();
-		if (object != null
-				&& object.getPersistenceState() == PersistenceState.NEW) {
+		if (object != null) {
 			counter++;
 		}
-		
+
+		if (object != null) {
+
+			SubgraphNode node = (SubgraphNode) subgraphStack.peek();
+
+			// apply callbacks
+			for (DeserializationCallback callback : node
+					.getDeserializationCallbacks()) {
+				callback.postDeserialize(node, object);
+			}
+
+			if (object.getPersistenceState() == PersistenceState.NEW) {
+				counter++;
+			}
+		}
+
 		return counter;
 	}
 

Modified: cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/SubgraphTest.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/SubgraphTest.java?rev=816642&r1=816641&r2=816642&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/SubgraphTest.java (original)
+++ cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/SubgraphTest.java Fri Sep 18 14:18:26 2009
@@ -33,24 +33,19 @@
 		assertEquals(0, subgraph.getRootNode().getChildren().size());
 	}
 
-	public void testAddDerserializationCallback() {
+	public void testAddCallbackDerserialization() {
 		Subgraph<Table2> subgraph = new Subgraph<Table2>(Table2.class,
 				newContext().getEntityResolver());
-		subgraph.addSerializeByReferencePath(Table2.TABLE1_PROPERTY);
-
-		SubgraphNode node = subgraph.getRootNode().getChild(
-				Table2.TABLE1_PROPERTY, false);
-
-		assertEquals(0, node.getSerializationCallbacks().size());
-		assertEquals(0, node.getDeserializationCallbacks().size());
-
-		subgraph.addDeserializationCallback(Table2.TABLE1_PROPERTY,
+		subgraph.addRefPath(Table2.TABLE1_PROPERTY,
 				new DeserializationCallback() {
 					public void postDeserialize(SubgraphNode node, Object object) {
 						// noop
 					}
 				});
 
+		SubgraphNode node = subgraph.getRootNode().getChild(
+				Table2.TABLE1_PROPERTY, false);
+
 		assertEquals(0, node.getSerializationCallbacks().size());
 		assertEquals(1, node.getDeserializationCallbacks().size());
 	}
@@ -58,15 +53,7 @@
 	public void testAddSerializationCallback() {
 		Subgraph<Table2> subgraph = new Subgraph<Table2>(Table2.class,
 				newContext().getEntityResolver());
-		subgraph.addSerializeByReferencePath(Table2.TABLE1_PROPERTY);
-
-		SubgraphNode node = subgraph.getRootNode().getChild(
-				Table2.TABLE1_PROPERTY, false);
-
-		assertEquals(0, node.getSerializationCallbacks().size());
-		assertEquals(0, node.getDeserializationCallbacks().size());
-
-		subgraph.addSerializationCallback(Table2.TABLE1_PROPERTY,
+		subgraph.addRefPath(Table2.TABLE1_PROPERTY,
 				new SerializationCallback() {
 
 					public Query relationshipQuery(SubgraphNode node,
@@ -76,6 +63,9 @@
 					}
 				});
 
+		SubgraphNode node = subgraph.getRootNode().getChild(
+				Table2.TABLE1_PROPERTY, false);
+
 		assertEquals(1, node.getSerializationCallbacks().size());
 		assertEquals(0, node.getDeserializationCallbacks().size());
 	}
@@ -83,7 +73,7 @@
 	public void testAddSerializeByReferencePathToOne() {
 		Subgraph<Table2> subgraph = new Subgraph<Table2>(Table2.class,
 				newContext().getEntityResolver());
-		subgraph.addSerializeByReferencePath(Table2.TABLE1_PROPERTY);
+		subgraph.addRefPath(Table2.TABLE1_PROPERTY);
 
 		SubgraphNode node = subgraph.getRootNode();
 		assertEquals(1, node.getChildren().size());
@@ -95,7 +85,7 @@
 	public void testAddSerializeByReferencePathToMany() {
 		Subgraph<Table1> subgraph = new Subgraph<Table1>(Table1.class,
 				newContext().getEntityResolver());
-		subgraph.addSerializeByReferencePath(Table1.TABLE2S_PROPERTY);
+		subgraph.addRefPath(Table1.TABLE2S_PROPERTY);
 
 		SubgraphNode node = subgraph.getRootNode();
 		assertEquals(1, node.getChildren().size());

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=816642&r1=816641&r2=816642&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 Fri Sep 18 14:18:26 2009
@@ -78,7 +78,7 @@
 
 		Subgraph<Table2> subgraph = new Subgraph<Table2>(Table2.class, context
 				.getEntityResolver());
-		subgraph.addSerializeByValuePath(Table2.TABLE1_PROPERTY);
+		subgraph.addClonePath(Table2.TABLE1_PROPERTY);
 
 		XStreamDeserializer deserializer = new XStreamDeserializer();
 
@@ -119,7 +119,7 @@
 
 		Subgraph<Table2> subgraph = new Subgraph<Table2>(Table2.class, context
 				.getEntityResolver());
-		subgraph.addSerializeByReferencePath(Table2.TABLE1_PROPERTY);
+		subgraph.addRefPath(Table2.TABLE1_PROPERTY);
 
 		XStreamDeserializer deserializer = new XStreamDeserializer();
 
@@ -153,7 +153,7 @@
 
 		Subgraph<Table1> subgraph = new Subgraph<Table1>(Table1.class, context
 				.getEntityResolver());
-		subgraph.addSerializeByValuePath(Table1.TABLE2S_PROPERTY);
+		subgraph.addClonePath(Table1.TABLE2S_PROPERTY);
 
 		XStreamDeserializer deserializer = new XStreamDeserializer();
 
@@ -200,8 +200,7 @@
 
 		Subgraph<Table2> subgraph = new Subgraph<Table2>(Table2.class, context
 				.getEntityResolver());
-		subgraph.addSerializeByReferencePath(Table2.TABLE1_PROPERTY);
-		subgraph.addDeserializationCallback(Table2.TABLE1_PROPERTY,
+		subgraph.addRefPath(Table2.TABLE1_PROPERTY,
 				new DeserializationCallback() {
 					public void postDeserialize(SubgraphNode node, Object object) {
 						assertNotNull(node);
@@ -238,8 +237,7 @@
 
 		Subgraph<Table1> subgraph = new Subgraph<Table1>(Table1.class, context
 				.getEntityResolver());
-		subgraph.addSerializeByValuePath(Table1.TABLE2S_PROPERTY);
-		subgraph.addDeserializationCallback(Table1.TABLE2S_PROPERTY,
+		subgraph.addClonePath(Table1.TABLE2S_PROPERTY,
 				new DeserializationCallback() {
 					public void postDeserialize(SubgraphNode node, Object object) {
 						assertNotNull(node);
@@ -248,7 +246,11 @@
 						assertNotNull(object);
 						assertTrue(object instanceof Table2);
 
+						Table2 t2 = (Table2) object;
+						assertTrue(t2.getName() != null);
+
 						callbackInvoked[0] = true;
+
 					}
 				});
 

Modified: cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/xstream/XStreamSerializerTest.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/xstream/XStreamSerializerTest.java?rev=816642&r1=816641&r2=816642&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/xstream/XStreamSerializerTest.java (original)
+++ cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/xstream/XStreamSerializerTest.java Fri Sep 18 14:18:26 2009
@@ -58,7 +58,7 @@
 
 		Subgraph<Table2> subgraph = new Subgraph<Table2>(Table2.class, context
 				.getEntityResolver());
-		subgraph.addSerializeByValuePath(Table2.TABLE1_PROPERTY);
+		subgraph.addClonePath(Table2.TABLE1_PROPERTY);
 
 		File file = tempFile(".xml");
 		XStreamSerializer serializer = new XStreamSerializer();
@@ -93,7 +93,7 @@
 
 		Subgraph<Table1> subgraph = new Subgraph<Table1>(Table1.class, context
 				.getEntityResolver());
-		subgraph.addSerializeByValuePath(Table1.TABLE2S_PROPERTY);
+		subgraph.addClonePath(Table1.TABLE2S_PROPERTY);
 
 		File file = tempFile(".xml");
 		XStreamSerializer serializer = new XStreamSerializer();
@@ -128,7 +128,7 @@
 
 		Subgraph<Table2> subgraph = new Subgraph<Table2>(Table2.class, context
 				.getEntityResolver());
-		subgraph.addSerializeByReferencePath(Table2.TABLE1_PROPERTY);
+		subgraph.addRefPath(Table2.TABLE1_PROPERTY);
 
 		File file = tempFile(".xml");
 		XStreamSerializer serializer = new XStreamSerializer();
@@ -215,8 +215,7 @@
 
 		Subgraph<Table1> subgraph = new Subgraph<Table1>(Table1.class, context
 				.getEntityResolver());
-		subgraph.addSerializeByValuePath(Table1.TABLE2S_PROPERTY);
-		subgraph.addSerializationCallback(Table1.TABLE2S_PROPERTY,
+		subgraph.addClonePath(Table1.TABLE2S_PROPERTY,
 				new SerializationCallback() {
 					public Query relationshipQuery(SubgraphNode node,
 							Object sourceObject) {