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 00:05:40 UTC
svn commit: r815515 - in /cayenne/sandbox/cayenne-serialization: ./
src/main/java/org/apache/cayenne/serialization/xstream/ src/test/
src/test/java/ src/test/java/org/ src/test/java/org/apache/
src/test/java/org/apache/cayenne/ src/test/java/org/apache...
Author: aadamchik
Date: Tue Sep 15 22:05:39 2009
New Revision: 815515
URL: http://svn.apache.org/viewvc?rev=815515&view=rev
Log:
prototyping (de)serializer based on XStream:
unit tests
deserialization by ref
Added:
cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/Attributes.java
cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/CompactXPPDriver.java
- copied, changed from r814869, cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/ObjectIdMarshalConverter.java
cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/ObjectIdConverter.java
cayenne/sandbox/cayenne-serialization/src/test/
cayenne/sandbox/cayenne-serialization/src/test/java/
cayenne/sandbox/cayenne-serialization/src/test/java/org/
cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/
cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/
cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/
cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/BaseDeserializerTest.java
- copied, changed from r814869, cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/XStreamSerializer.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/persistent/
cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/persistent/Serialization.java
- copied, changed from r814869, cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/XStreamSerializer.java
cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/persistent/Table1.java
cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/persistent/Table2.java
cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/persistent/auto/
cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/persistent/auto/_Serialization.java
cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/persistent/auto/_Table1.java
cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/persistent/auto/_Table2.java
cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/unit/
cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/unit/SerializationCase.java
cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/xstream/
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
cayenne/sandbox/cayenne-serialization/src/test/resources/
cayenne/sandbox/cayenne-serialization/src/test/resources/cayenne.xml
cayenne/sandbox/cayenne-serialization/src/test/resources/serialization.driver.xml
cayenne/sandbox/cayenne-serialization/src/test/resources/serialization.map.xml
Removed:
cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/ObjectIdMarshalConverter.java
cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/XStreamUtil.java
Modified:
cayenne/sandbox/cayenne-serialization/pom.xml
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/PersistentMarshalConverter.java
cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/XStreamDeserializer.java
cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/XStreamSerializer.java
Modified: cayenne/sandbox/cayenne-serialization/pom.xml
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-serialization/pom.xml?rev=815515&r1=815514&r2=815515&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-serialization/pom.xml (original)
+++ cayenne/sandbox/cayenne-serialization/pom.xml Tue Sep 15 22:05:39 2009
@@ -41,6 +41,11 @@
<artifactId>xstream</artifactId>
<version>1.3.1</version>
</dependency>
+ <dependency>
+ <groupId>hsqldb</groupId>
+ <artifactId>hsqldb</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
<plugins>
Added: cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/Attributes.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/Attributes.java?rev=815515&view=auto
==============================================================================
--- cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/Attributes.java (added)
+++ cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/Attributes.java Tue Sep 15 22:05:39 2009
@@ -0,0 +1,23 @@
+/*****************************************************************
+ * 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.xstream;
+
+enum Attributes {
+ ref
+}
Copied: cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/CompactXPPDriver.java (from r814869, cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/ObjectIdMarshalConverter.java)
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/CompactXPPDriver.java?p2=cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/CompactXPPDriver.java&p1=cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/ObjectIdMarshalConverter.java&r1=814869&r2=815515&rev=815515&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/ObjectIdMarshalConverter.java (original)
+++ cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/CompactXPPDriver.java Tue Sep 15 22:05:39 2009
@@ -18,37 +18,26 @@
****************************************************************/
package org.apache.cayenne.serialization.xstream;
-import java.util.Map;
+import java.io.Writer;
-import org.apache.cayenne.ObjectId;
-
-import com.thoughtworks.xstream.converters.Converter;
-import com.thoughtworks.xstream.converters.MarshallingContext;
-import com.thoughtworks.xstream.converters.UnmarshallingContext;
-import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
+import com.thoughtworks.xstream.io.xml.CompactWriter;
+import com.thoughtworks.xstream.io.xml.XmlFriendlyReplacer;
+import com.thoughtworks.xstream.io.xml.XppDriver;
-class ObjectIdMarshalConverter implements Converter {
-
- public void marshal(Object source, HierarchicalStreamWriter writer,
- MarshallingContext context) {
-
- ObjectId id = (ObjectId) source;
- for (Map.Entry<String, Object> entry : id.getIdSnapshot().entrySet()) {
+class CompactXPPDriver extends XppDriver {
- writer.startNode(entry.getKey());
- context.convertAnother(entry.getValue());
- writer.endNode();
- }
+ public CompactXPPDriver() {
+ super();
}
- public Object unmarshal(HierarchicalStreamReader reader,
- UnmarshallingContext context) {
- throw new UnsupportedOperationException();
+ public CompactXPPDriver(XmlFriendlyReplacer replacer) {
+ super(replacer);
}
- public boolean canConvert(Class type) {
- return ObjectId.class.isAssignableFrom(type);
+ @Override
+ public HierarchicalStreamWriter createWriter(Writer out) {
+ return new CompactWriter(out, xmlFriendlyReplacer());
}
}
Added: cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/ObjectIdConverter.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/ObjectIdConverter.java?rev=815515&view=auto
==============================================================================
--- cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/ObjectIdConverter.java (added)
+++ cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/ObjectIdConverter.java Tue Sep 15 22:05:39 2009
@@ -0,0 +1,139 @@
+/*****************************************************************
+ * 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.xstream;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.cayenne.ObjectId;
+import org.apache.cayenne.dba.TypesMapping;
+import org.apache.cayenne.map.DbAttribute;
+import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.map.EntityResolver;
+import org.apache.cayenne.map.ObjAttribute;
+import org.apache.cayenne.reflect.AttributeProperty;
+import org.apache.cayenne.reflect.ClassDescriptor;
+import org.apache.cayenne.reflect.Property;
+import org.apache.cayenne.util.Util;
+
+import com.thoughtworks.xstream.converters.Converter;
+import com.thoughtworks.xstream.converters.MarshallingContext;
+import com.thoughtworks.xstream.converters.UnmarshallingContext;
+import com.thoughtworks.xstream.io.HierarchicalStreamReader;
+import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
+
+class ObjectIdConverter implements Converter {
+
+ private EntityResolver entityResolver;
+ private Map<String, Map<String, Class<?>>> idTypesMap;
+
+ ObjectIdConverter(EntityResolver entityResolver) {
+ this.entityResolver = entityResolver;
+ this.idTypesMap = new ConcurrentHashMap<String, Map<String, Class<?>>>();
+ }
+
+ public void marshal(Object source, HierarchicalStreamWriter writer,
+ MarshallingContext context) {
+
+ ObjectId id = (ObjectId) source;
+ writer.startNode(id.getEntityName());
+ writer.addAttribute(Attributes.ref.name(), "true");
+
+ for (Map.Entry<String, Object> entry : id.getIdSnapshot().entrySet()) {
+
+ writer.startNode(entry.getKey());
+ context.convertAnother(entry.getValue());
+ writer.endNode();
+ }
+ writer.endNode();
+ }
+
+ public Object unmarshal(HierarchicalStreamReader reader,
+ UnmarshallingContext context) {
+
+ String entityName = reader.getNodeName();
+
+ Map<String, Class<?>> idTypeMap = getIdTypesMap(entityName);
+
+ Map<String, Object> id = new HashMap<String, Object>();
+ while (reader.hasMoreChildren()) {
+ reader.moveDown();
+
+ String key = reader.getNodeName();
+
+ Object value = context.convertAnother(id, idTypeMap.get(key));
+ id.put(key, value);
+
+ reader.moveUp();
+ }
+
+ return new ObjectId(entityName, id);
+ }
+
+ public boolean canConvert(Class type) {
+ return ObjectId.class.isAssignableFrom(type);
+ }
+
+ private Map<String, Class<?>> getIdTypesMap(String entityName) {
+
+ Map<String, Class<?>> typesMap = idTypesMap.get(entityName);
+
+ if (typesMap == null) {
+ typesMap = new HashMap<String, Class<?>>();
+ ClassDescriptor descriptor = entityResolver
+ .getClassDescriptor(entityName);
+
+ Iterator<Property> mappedIdProperties = descriptor
+ .getIdProperties();
+ while (mappedIdProperties.hasNext()) {
+ AttributeProperty property = (AttributeProperty) mappedIdProperties
+ .next();
+
+ ObjAttribute attribute = property.getAttribute();
+ typesMap.put(attribute.getDbAttributeName(), attribute
+ .getJavaClass());
+ }
+
+ DbEntity dbEntity = descriptor.getEntity().getDbEntity();
+ if (dbEntity != null) {
+ for (DbAttribute attribute : dbEntity.getPrimaryKeys()) {
+ if (!typesMap.containsKey(attribute.getName())) {
+ String type = TypesMapping.getJavaBySqlType(attribute
+ .getType(), attribute.getMaxLength(), attribute
+ .getScale());
+ try {
+ typesMap.put(attribute.getName(), Util
+ .getJavaClass(type));
+ } catch (ClassNotFoundException e) {
+ throw new IllegalStateException("Invalid type: "
+ + type, e);
+ }
+ }
+ }
+ }
+
+ idTypesMap.put(entityName, typesMap);
+ }
+
+ return typesMap;
+ }
+
+}
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=815515&r1=815514&r2=815515&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 Tue Sep 15 22:05:39 2009
@@ -18,13 +18,14 @@
****************************************************************/
package org.apache.cayenne.serialization.xstream;
+import org.apache.cayenne.DataObjectUtils;
import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.ObjectId;
import org.apache.cayenne.Persistent;
+import org.apache.cayenne.reflect.ArcProperty;
import org.apache.cayenne.reflect.AttributeProperty;
import org.apache.cayenne.reflect.ClassDescriptor;
-import org.apache.cayenne.reflect.PropertyVisitor;
-import org.apache.cayenne.reflect.ToManyProperty;
-import org.apache.cayenne.reflect.ToOneProperty;
+import org.apache.cayenne.reflect.Property;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
@@ -36,10 +37,6 @@
* "Clone" in {@link PersistentCloneUnmarshalConverter} means that ids of the
* Persistent objects will be ignored, and new objects will be created.
*/
-// TODO: use Subgraph to follow the stack instead of going directly to Cayenne
-// metadata. This will ensure performance as well as alignment with the subgraph
-// mapping... (or maybe we don't care to even have a subgraph, and just
-// deserialize what's coming in??)
class PersistentCloneUnmarshalConverter implements Converter {
private static final String TRAVERSAL_CONTEXT_KEY = PersistentCloneUnmarshalConverter.class
@@ -60,39 +57,62 @@
return Persistent.class.isAssignableFrom(objectClass);
}
- public Object unmarshal(final HierarchicalStreamReader reader,
- final UnmarshallingContext context) {
+ public void marshal(Object source, HierarchicalStreamWriter writer,
+ MarshallingContext context) {
+ throw new UnsupportedOperationException();
+ }
- String entityName = reader.getNodeName();
+ public Object unmarshal(HierarchicalStreamReader reader,
+ UnmarshallingContext context) {
+
+ String ref = reader.getAttribute(Attributes.ref.name());
+ if ("true".equals(ref)) {
+ return deserializeExisting(reader, context);
+ } else {
+ return deserializeNew(reader, context);
+ }
+ }
+ private Object deserializeExisting(HierarchicalStreamReader reader,
+ UnmarshallingContext context) {
+
+ ObjectId id = (ObjectId) context.convertAnother(null, ObjectId.class);
+
+ return DataObjectUtils.objectForPK(objectContext, id);
+ // TODO: handle deleted objects that no longer exist...
+ }
+
+ private Object deserializeNew(HierarchicalStreamReader reader,
+ UnmarshallingContext context) {
+
+ String entityName = reader.getNodeName();
ClassDescriptor descriptor = objectContext.getEntityResolver()
.getClassDescriptor(entityName);
- final Object object = descriptor.createObject();
-
+ Object object = descriptor.createObject();
objectContext.registerNewObject(object);
DeserializerCounter deserializerCounter = getDeserialierCounter(context);
- descriptor.visitProperties(new PropertyVisitor() {
- public boolean visitAttribute(AttributeProperty property) {
- reader.moveDown();
- Object value = context.convertAnother(object, property
- .getAttribute().getJavaClass());
- reader.moveUp();
+ while (reader.hasMoreChildren()) {
+ reader.moveDown();
- property.writeProperty(object, null, value);
- return true;
+ Property property = descriptor.getProperty(reader.getNodeName());
+ if (property instanceof AttributeProperty) {
+ deserializeAttribute(reader, context, object,
+ (AttributeProperty) property);
+ } else {
+ ArcProperty arc = (ArcProperty) property;
+
+ if (arc.getRelationship().isToMany()) {
+ deserializeToManyRelationship(reader, context, object, arc);
+ } else {
+ deserializeToOneRelationship(reader, context, object, arc);
+ }
}
- public boolean visitToMany(ToManyProperty property) {
- return true;
- }
-
- public boolean visitToOne(ToOneProperty property) {
- return true;
- }
- });
+ reader.moveUp();
+ }
if (commitCountThreshold > 0
&& deserializerCounter.incrementCounter()
@@ -103,9 +123,34 @@
return object;
}
- public void marshal(Object source, HierarchicalStreamWriter writer,
- MarshallingContext context) {
- throw new UnsupportedOperationException();
+ private void deserializeAttribute(HierarchicalStreamReader reader,
+ UnmarshallingContext context, Object parentObject,
+ AttributeProperty property) {
+
+ Class<?> javaType = property.getAttribute().getJavaClass();
+ Object value = context.convertAnother(parentObject, javaType);
+ property.writeProperty(parentObject, null, value);
+ }
+
+ private void deserializeToOneRelationship(HierarchicalStreamReader reader,
+ UnmarshallingContext context, Object parentObject,
+ ArcProperty property) {
+
+ Class<?> javaType = property.getTargetDescriptor().getObjectClass();
+
+ reader.moveDown();
+
+ Object value = context.convertAnother(parentObject, javaType);
+ property.writeProperty(parentObject, null, value);
+
+ reader.moveUp();
+ }
+
+ private void deserializeToManyRelationship(HierarchicalStreamReader reader,
+ UnmarshallingContext context, Object parentObject,
+ ArcProperty property) {
+
+ throw new UnsupportedOperationException("TODO");
}
private DeserializerCounter getDeserialierCounter(
Modified: cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/PersistentMarshalConverter.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/PersistentMarshalConverter.java?rev=815515&r1=815514&r2=815515&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/PersistentMarshalConverter.java (original)
+++ cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/PersistentMarshalConverter.java Tue Sep 15 22:05:39 2009
@@ -60,6 +60,13 @@
SubgraphNode node = serializerContext.peekNode();
+ // don't generate tags for the root node, as they are generated via the
+ // 'alias' mechanism
+ if (node.getIncomingProperty() != null) {
+ Persistent persistent = (Persistent) object;
+ writer.startNode(persistent.getObjectId().getEntityName());
+ }
+
for (AttributeProperty property : node.getAttributeProperties()) {
marshalAttribute(object, property, writer, context);
}
@@ -70,22 +77,20 @@
serializerContext.pushNode(child);
ArcProperty incoming = child.getIncomingProperty();
- if (child.isSerializedByReference()) {
- if (incoming.getRelationship().isToMany()) {
- marshalToManyReference(object, incoming, writer, context);
- } else {
- marshalToOneReference(object, incoming, writer, context);
- }
+ boolean byReference = child.isSerializedByReference();
+
+ if (incoming.getRelationship().isToMany()) {
+ marshalToMany(object, incoming, writer, context, byReference);
} else {
- if (incoming.getRelationship().isToMany()) {
- marshalToMany(object, incoming, writer, context);
- } else {
- marshalToOne(object, incoming, writer, context);
- }
+ marshalToOne(object, incoming, writer, context, byReference);
}
serializerContext.popNode();
}
+
+ if (node.getIncomingProperty() != null) {
+ writer.endNode();
+ }
}
private void marshalAttribute(Object object, Property property,
@@ -100,45 +105,23 @@
}
}
- private void marshalToOneReference(Object object, ArcProperty arc,
- HierarchicalStreamWriter writer, MarshallingContext context) {
-
- Persistent value = (Persistent) arc.readProperty(object);
-
- if (value != null) {
-
- SerializerStack serializerStack = getSerializerStack(context);
- writer.startNode(arc.getName());
- writer.startNode(serializerStack.getCayenneNamespace() + ":ref");
- context.convertAnother(value.getObjectId());
- writer.endNode();
- writer.endNode();
- }
- }
-
private void marshalToOne(Object object, ArcProperty arc,
- HierarchicalStreamWriter writer, MarshallingContext context) {
+ HierarchicalStreamWriter writer, MarshallingContext context,
+ boolean byReference) {
writer.startNode(arc.getName());
Persistent value = (Persistent) arc.readProperty(object);
-
if (value != null) {
- writer.startNode(value.getObjectId().getEntityName());
- context.convertAnother(value);
- writer.endNode();
+ context.convertAnother(byReference ? value.getObjectId() : value);
}
writer.endNode();
}
- private void marshalToManyReference(Object object, ArcProperty arc,
- HierarchicalStreamWriter writer, MarshallingContext context) {
- throw new UnsupportedOperationException("TODO: implement");
- }
-
private void marshalToMany(Object object, ArcProperty arc,
- HierarchicalStreamWriter writer, MarshallingContext context) {
+ HierarchicalStreamWriter writer, MarshallingContext context,
+ boolean byReference) {
writer.startNode(arc.getName());
@@ -162,12 +145,11 @@
while (it.hasNextRow()) {
DataRow next = (DataRow) it.nextRow();
- writer.startNode(next.getEntityName());
DataObject target = dataContext.objectFromDataRow(next
.getEntityName(), next, true);
- context.convertAnother(target);
- writer.endNode();
+ context.convertAnother(byReference ? target.getObjectId()
+ : target);
}
} finally {
it.close();
Modified: cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/XStreamDeserializer.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/XStreamDeserializer.java?rev=815515&r1=815514&r2=815515&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/XStreamDeserializer.java (original)
+++ cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/XStreamDeserializer.java Tue Sep 15 22:05:39 2009
@@ -21,10 +21,12 @@
import java.io.InputStream;
import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.reflect.ClassDescriptor;
import org.apache.cayenne.serialization.BaseDeserializer;
import org.apache.cayenne.serialization.Subgraph;
import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.io.xml.XppDriver;
public class XStreamDeserializer extends BaseDeserializer {
@@ -34,7 +36,7 @@
// TODO: make sure all the converters are stateless... then we can cache
// xstream instances by subgraph and reuse them
- XStream xstream = XStreamUtil.defaultXStream(subgraph.getRootNode()
+ XStream xstream = createXStream(subgraph.getRootNode()
.getClassDescriptor());
int commitCountThreshold = isCommitting() ? getCommitCountThreshold()
@@ -42,6 +44,8 @@
xstream.registerConverter(new PersistentCloneUnmarshalConverter(
context, commitCountThreshold));
+ xstream.registerConverter(new ObjectIdConverter(context
+ .getEntityResolver()));
T object = (T) xstream.fromXML(in);
@@ -52,4 +56,19 @@
return object;
}
+ protected XStream createXStream(ClassDescriptor rootDescriptor) {
+ XStream xstream = new XStream(new XppDriver());
+
+ // this is required to get a real streaming API an release all
+ // serialized objects...
+ xstream.setMode(XStream.NO_REFERENCES);
+
+ // TODO: we need to implement our own algorithm for object cycle
+ // detection... XStream also supports Immutable classes. we may classify
+ // objects according to their participation in a cycle.
+
+ xstream.alias(rootDescriptor.getEntity().getName(), rootDescriptor
+ .getObjectClass());
+ return xstream;
+ }
}
Modified: cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/XStreamSerializer.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/XStreamSerializer.java?rev=815515&r1=815514&r2=815515&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/XStreamSerializer.java (original)
+++ cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/XStreamSerializer.java Tue Sep 15 22:05:39 2009
@@ -20,26 +20,61 @@
import java.io.OutputStream;
+import org.apache.cayenne.reflect.ClassDescriptor;
import org.apache.cayenne.serialization.BaseSerializer;
import org.apache.cayenne.serialization.Subgraph;
import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.io.HierarchicalStreamDriver;
+import com.thoughtworks.xstream.io.xml.XppDriver;
public class XStreamSerializer extends BaseSerializer {
+ protected boolean creatingCompactXML;
+
@Override
public <T> void serialize(T object, Subgraph<T> subgraph, OutputStream out) {
// TODO: make sure all the converters are stateless... then we can cache
// xstream instances by subgraph and reuse them
- XStream xstream = XStreamUtil.defaultXStream(subgraph.getRootNode()
+ XStream xstream = createXStream(subgraph.getRootNode()
.getClassDescriptor());
xstream.registerConverter(new PersistentMarshalConverter<T>(subgraph,
statementFetchSize));
- xstream.registerConverter(new ObjectIdMarshalConverter());
+ xstream.registerConverter(new ObjectIdConverter(null));
xstream.toXML(object, out);
}
+ protected XStream createXStream(ClassDescriptor rootDescriptor) {
+ HierarchicalStreamDriver driver = isCreatingCompactXML() ? new CompactXPPDriver()
+ : new XppDriver();
+
+ XStream xstream = new XStream(driver);
+
+ // this is required to get a real streaming API an release all
+ // serialized objects...
+ xstream.setMode(XStream.NO_REFERENCES);
+
+ // TODO: we need to implement our own algorithm for object cycle
+ // detection... XStream also supports Immutable classes. we may classify
+ // objects according to their participation in a cycle.
+
+ xstream.alias(rootDescriptor.getEntity().getName(), rootDescriptor
+ .getObjectClass());
+ return xstream;
+ }
+
+ public boolean isCreatingCompactXML() {
+ return creatingCompactXML;
+ }
+
+ /**
+ * Sets whether serializer should skip spaces and line breaks used for
+ * pretty formatting, and output unformatted XML.
+ */
+ public void setCreatingCompactXML(boolean createCompactXML) {
+ this.creatingCompactXML = createCompactXML;
+ }
}
Copied: cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/BaseDeserializerTest.java (from r814869, cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/XStreamSerializer.java)
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/BaseDeserializerTest.java?p2=cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/BaseDeserializerTest.java&p1=cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/XStreamSerializer.java&r1=814869&r2=815515&rev=815515&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/XStreamSerializer.java (original)
+++ cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/BaseDeserializerTest.java Tue Sep 15 22:05:39 2009
@@ -16,30 +16,27 @@
* specific language governing permissions and limitations
* under the License.
****************************************************************/
-package org.apache.cayenne.serialization.xstream;
+package org.apache.cayenne.serialization;
-import java.io.OutputStream;
+import java.io.InputStream;
-import org.apache.cayenne.serialization.BaseSerializer;
-import org.apache.cayenne.serialization.Subgraph;
+import org.apache.cayenne.ObjectContext;
-import com.thoughtworks.xstream.XStream;
+import junit.framework.TestCase;
-public class XStreamSerializer extends BaseSerializer {
+public class BaseDeserializerTest extends TestCase {
- @Override
- public <T> void serialize(T object, Subgraph<T> subgraph, OutputStream out) {
+ public void testCommitCountThreshould() {
+ BaseDeserializer deserializer = new BaseDeserializer() {
+ @Override
+ public <T> T deserialize(ObjectContext context,
+ Subgraph<T> subgraph, InputStream in) {
+ return null;
+ }
+ };
- // TODO: make sure all the converters are stateless... then we can cache
- // xstream instances by subgraph and reuse them
- XStream xstream = XStreamUtil.defaultXStream(subgraph.getRootNode()
- .getClassDescriptor());
-
- xstream.registerConverter(new PersistentMarshalConverter<T>(subgraph,
- statementFetchSize));
- xstream.registerConverter(new ObjectIdMarshalConverter());
-
- xstream.toXML(object, out);
+ assertEquals(1000, deserializer.getCommitCountThreshold());
+ deserializer.setCommitCountThreshold(3);
+ assertEquals(3, deserializer.getCommitCountThreshold());
}
-
}
Added: 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=815515&view=auto
==============================================================================
--- cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/SubgraphTest.java (added)
+++ cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/SubgraphTest.java Tue Sep 15 22:05:39 2009
@@ -0,0 +1,58 @@
+/*****************************************************************
+ * 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;
+
+import org.apache.cayenne.serialization.persistent.Table1;
+import org.apache.cayenne.serialization.persistent.Table2;
+import org.apache.cayenne.serialization.unit.SerializationCase;
+
+public class SubgraphTest extends SerializationCase {
+
+ public void testGetRootNode() {
+
+ Subgraph<Table1> subgraph = new Subgraph<Table1>(Table1.class,
+ newContext().getEntityResolver());
+ assertNotNull(subgraph.getRootNode());
+ assertEquals(0, subgraph.getRootNode().getChildren().size());
+ }
+
+ public void testAddSerializeByReferencePathToOne() {
+ Subgraph<Table2> subgraph = new Subgraph<Table2>(Table2.class,
+ newContext().getEntityResolver());
+ subgraph.addSerializeByReferencePath(Table2.TABLE1_PROPERTY);
+
+ SubgraphNode node = subgraph.getRootNode();
+ assertEquals(1, node.getChildren().size());
+
+ SubgraphNode child = node.getChildren().iterator().next();
+ assertTrue(child.isSerializedByReference());
+ }
+
+ public void testAddSerializeByReferencePathToMany() {
+ Subgraph<Table1> subgraph = new Subgraph<Table1>(Table1.class,
+ newContext().getEntityResolver());
+ subgraph.addSerializeByReferencePath(Table1.TABLE2S_PROPERTY);
+
+ SubgraphNode node = subgraph.getRootNode();
+ assertEquals(1, node.getChildren().size());
+
+ SubgraphNode child = node.getChildren().iterator().next();
+ assertTrue(child.isSerializedByReference());
+ }
+}
Copied: cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/persistent/Serialization.java (from r814869, cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/XStreamSerializer.java)
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/persistent/Serialization.java?p2=cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/persistent/Serialization.java&p1=cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/XStreamSerializer.java&r1=814869&r2=815515&rev=815515&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-serialization/src/main/java/org/apache/cayenne/serialization/xstream/XStreamSerializer.java (original)
+++ cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/persistent/Serialization.java Tue Sep 15 22:05:39 2009
@@ -16,30 +16,21 @@
* specific language governing permissions and limitations
* under the License.
****************************************************************/
-package org.apache.cayenne.serialization.xstream;
+package org.apache.cayenne.serialization.persistent;
-import java.io.OutputStream;
+import org.apache.cayenne.serialization.persistent.auto._Serialization;
-import org.apache.cayenne.serialization.BaseSerializer;
-import org.apache.cayenne.serialization.Subgraph;
+public class Serialization extends _Serialization {
-import com.thoughtworks.xstream.XStream;
+ private static Serialization instance;
-public class XStreamSerializer extends BaseSerializer {
+ private Serialization() {}
- @Override
- public <T> void serialize(T object, Subgraph<T> subgraph, OutputStream out) {
-
- // TODO: make sure all the converters are stateless... then we can cache
- // xstream instances by subgraph and reuse them
- XStream xstream = XStreamUtil.defaultXStream(subgraph.getRootNode()
- .getClassDescriptor());
-
- xstream.registerConverter(new PersistentMarshalConverter<T>(subgraph,
- statementFetchSize));
- xstream.registerConverter(new ObjectIdMarshalConverter());
-
- xstream.toXML(object, out);
- }
+ public static Serialization getInstance() {
+ if(instance == null) {
+ instance = new Serialization();
+ }
+ return instance;
+ }
}
Added: cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/persistent/Table1.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/persistent/Table1.java?rev=815515&view=auto
==============================================================================
--- cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/persistent/Table1.java (added)
+++ cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/persistent/Table1.java Tue Sep 15 22:05:39 2009
@@ -0,0 +1,25 @@
+/*****************************************************************
+ * 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.persistent;
+
+import org.apache.cayenne.serialization.persistent.auto._Table1;
+
+public class Table1 extends _Table1 {
+
+}
Added: cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/persistent/Table2.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/persistent/Table2.java?rev=815515&view=auto
==============================================================================
--- cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/persistent/Table2.java (added)
+++ cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/persistent/Table2.java Tue Sep 15 22:05:39 2009
@@ -0,0 +1,25 @@
+/*****************************************************************
+ * 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.persistent;
+
+import org.apache.cayenne.serialization.persistent.auto._Table2;
+
+public class Table2 extends _Table2 {
+
+}
Added: cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/persistent/auto/_Serialization.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/persistent/auto/_Serialization.java?rev=815515&view=auto
==============================================================================
--- cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/persistent/auto/_Serialization.java (added)
+++ cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/persistent/auto/_Serialization.java Tue Sep 15 22:05:39 2009
@@ -0,0 +1,12 @@
+package org.apache.cayenne.serialization.persistent.auto;
+
+
+
+/**
+ * This class was generated by Cayenne.
+ * It is probably a good idea to avoid changing this class manually,
+ * since it may be overwritten next time code is regenerated.
+ * If you need to make any customizations, please use subclass.
+ */
+public class _Serialization {
+}
\ No newline at end of file
Added: cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/persistent/auto/_Table1.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/persistent/auto/_Table1.java?rev=815515&view=auto
==============================================================================
--- cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/persistent/auto/_Table1.java (added)
+++ cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/persistent/auto/_Table1.java Tue Sep 15 22:05:39 2009
@@ -0,0 +1,40 @@
+package org.apache.cayenne.serialization.persistent.auto;
+
+import java.util.List;
+
+import org.apache.cayenne.CayenneDataObject;
+import org.apache.cayenne.serialization.persistent.Table2;
+
+/**
+ * Class _Table1 was generated by Cayenne.
+ * It is probably a good idea to avoid changing this class manually,
+ * since it may be overwritten next time code is regenerated.
+ * If you need to make any customizations, please use subclass.
+ */
+public abstract class _Table1 extends CayenneDataObject {
+
+ public static final String NAME_PROPERTY = "name";
+ public static final String TABLE2S_PROPERTY = "table2s";
+
+ public static final String PK_PK_COLUMN = "PK";
+
+ public void setName(String name) {
+ writeProperty("name", name);
+ }
+ public String getName() {
+ return (String)readProperty("name");
+ }
+
+ public void addToTable2s(Table2 obj) {
+ addToManyTarget("table2s", obj, true);
+ }
+ public void removeFromTable2s(Table2 obj) {
+ removeToManyTarget("table2s", obj, true);
+ }
+ @SuppressWarnings("unchecked")
+ public List<Table2> getTable2s() {
+ return (List<Table2>)readProperty("table2s");
+ }
+
+
+}
Added: cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/persistent/auto/_Table2.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/persistent/auto/_Table2.java?rev=815515&view=auto
==============================================================================
--- cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/persistent/auto/_Table2.java (added)
+++ cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/persistent/auto/_Table2.java Tue Sep 15 22:05:39 2009
@@ -0,0 +1,53 @@
+package org.apache.cayenne.serialization.persistent.auto;
+
+import java.util.Date;
+
+import org.apache.cayenne.CayenneDataObject;
+import org.apache.cayenne.serialization.persistent.Table1;
+
+/**
+ * Class _Table2 was generated by Cayenne.
+ * It is probably a good idea to avoid changing this class manually,
+ * since it may be overwritten next time code is regenerated.
+ * If you need to make any customizations, please use subclass.
+ */
+public abstract class _Table2 extends CayenneDataObject {
+
+ public static final String DATE_COLUMN_PROPERTY = "dateColumn";
+ public static final String DOUBLE_COLUMN_PROPERTY = "doubleColumn";
+ public static final String NAME_PROPERTY = "name";
+ public static final String TABLE1_PROPERTY = "table1";
+
+ public static final String PK_PK_COLUMN = "PK";
+
+ public void setDateColumn(Date dateColumn) {
+ writeProperty("dateColumn", dateColumn);
+ }
+ public Date getDateColumn() {
+ return (Date)readProperty("dateColumn");
+ }
+
+ public void setDoubleColumn(Double doubleColumn) {
+ writeProperty("doubleColumn", doubleColumn);
+ }
+ public Double getDoubleColumn() {
+ return (Double)readProperty("doubleColumn");
+ }
+
+ public void setName(String name) {
+ writeProperty("name", name);
+ }
+ public String getName() {
+ return (String)readProperty("name");
+ }
+
+ public void setTable1(Table1 table1) {
+ setToOneTarget("table1", table1, true);
+ }
+
+ public Table1 getTable1() {
+ return (Table1)readProperty("table1");
+ }
+
+
+}
Added: cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/unit/SerializationCase.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/unit/SerializationCase.java?rev=815515&view=auto
==============================================================================
--- cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/unit/SerializationCase.java (added)
+++ cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/unit/SerializationCase.java Tue Sep 15 22:05:39 2009
@@ -0,0 +1,93 @@
+/*****************************************************************
+ * 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.unit;
+
+import java.io.File;
+
+import junit.framework.TestCase;
+
+import org.apache.cayenne.CayenneRuntimeException;
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.access.DataContext;
+import org.apache.cayenne.access.DataDomain;
+import org.apache.cayenne.access.DataNode;
+import org.apache.cayenne.access.DbGenerator;
+import org.apache.cayenne.conf.Configuration;
+import org.apache.cayenne.map.DataMap;
+
+public abstract class SerializationCase extends TestCase {
+
+ static final String TEST_DIR = "target/testrun";
+
+ private static boolean pkFixed;
+
+ public SerializationCase() {
+ // this is needed until CAY-1276 is fixed
+
+ if (!pkFixed) {
+
+ DataDomain domain = Configuration.getSharedConfiguration()
+ .getDomain();
+ DataNode node = domain.getDataNodes().iterator().next();
+ DataMap dataMap = domain.getDataMaps().iterator().next();
+
+ DbGenerator dbGenerator = new DbGenerator(node.getAdapter(),
+ dataMap);
+ dbGenerator.setShouldDropPKSupport(true);
+ dbGenerator.setShouldCreatePKSupport(true);
+
+ dbGenerator.setShouldCreateTables(false);
+ dbGenerator.setShouldDropTables(false);
+ dbGenerator.setShouldCreateFKConstraints(false);
+
+ try {
+ dbGenerator.runGenerator(node.getDataSource());
+ } catch (Exception e) {
+ throw new CayenneRuntimeException("Error generating PK", e);
+ }
+
+ pkFixed = true;
+ }
+ }
+
+ protected ObjectContext newContext() {
+ return DataContext.createDataContext();
+ }
+
+ protected File tempFile(String extension) {
+ File baseDir = new File(TEST_DIR);
+ baseDir.mkdirs();
+
+ if (extension == null) {
+ extension = "";
+ }
+
+ String baseName = String.valueOf(System.currentTimeMillis());
+ for (int i = 0; i < 1000; i++) {
+ File file = new File(baseDir, baseName + extension);
+ if (!file.exists()) {
+ return file;
+ }
+ }
+
+ // should never happen
+ throw new IllegalStateException(
+ "Too many files with the same base name of " + baseName + "...");
+ }
+}
Added: 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=815515&view=auto
==============================================================================
--- cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/xstream/XStreamDeserializerTest.java (added)
+++ cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/xstream/XStreamDeserializerTest.java Tue Sep 15 22:05:39 2009
@@ -0,0 +1,145 @@
+/*****************************************************************
+ * 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.xstream;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.cayenne.DataObjectUtils;
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.PersistenceState;
+import org.apache.cayenne.serialization.Subgraph;
+import org.apache.cayenne.serialization.persistent.Table1;
+import org.apache.cayenne.serialization.persistent.Table2;
+import org.apache.cayenne.serialization.unit.SerializationCase;
+
+public class XStreamDeserializerTest extends SerializationCase {
+
+ public void testDeserializeRoot() throws IOException {
+
+ ObjectContext context = newContext();
+ Table1 t11 = context.newObject(Table1.class);
+ t11.setName("t11");
+
+ context.commitChanges();
+
+ Subgraph<Table1> subgraph = new Subgraph<Table1>(Table1.class, context
+ .getEntityResolver());
+
+ XStreamDeserializer deserializer = new XStreamDeserializer();
+
+ String xml = "<Table1><name>t11</name></Table1>";
+
+ Table1 result;
+ InputStream in = new ByteArrayInputStream(xml.getBytes());
+ try {
+ result = deserializer.deserialize(context, subgraph, in);
+ } finally {
+ in.close();
+ }
+
+ assertNotNull(result);
+ assertEquals(PersistenceState.COMMITTED, result.getPersistenceState());
+ assertEquals("t11", result.getName());
+ }
+
+ public void testDeserializeByValueToOne() throws IOException {
+
+ ObjectContext context = newContext();
+ Table1 t11 = context.newObject(Table1.class);
+ t11.setName("t11");
+
+ Table2 t21 = context.newObject(Table2.class);
+ t21.setName("t21");
+ t21.setTable1(t11);
+
+ context.commitChanges();
+
+ Subgraph<Table2> subgraph = new Subgraph<Table2>(Table2.class, context
+ .getEntityResolver());
+ subgraph.addSerializeByValuePath(Table2.TABLE1_PROPERTY);
+
+ XStreamDeserializer deserializer = new XStreamDeserializer();
+
+ String xml = "<Table2><name>t21</name><table1><Table1><name>t11</name></Table1></table1></Table2>";
+
+ Table2 result;
+ InputStream in = new ByteArrayInputStream(xml.getBytes());
+ try {
+ result = deserializer.deserialize(context, subgraph, in);
+ } finally {
+ in.close();
+ }
+
+ assertNotNull(result);
+ assertNotNull(result.getTable1());
+ assertEquals(PersistenceState.COMMITTED, result.getPersistenceState());
+ assertEquals(PersistenceState.COMMITTED, result.getTable1()
+ .getPersistenceState());
+
+ assertEquals("t21", result.getName());
+ assertNotSame(t21, result);
+ assertNotSame(t11, result.getTable1());
+ assertEquals("t11", result.getTable1().getName());
+
+ }
+
+ public void testDeserializeByReferenceToOne() throws IOException {
+
+ ObjectContext context = newContext();
+ Table1 t11 = context.newObject(Table1.class);
+ t11.setName("t11");
+
+ Table2 t21 = context.newObject(Table2.class);
+ t21.setName("t21");
+ t21.setTable1(t11);
+
+ context.commitChanges();
+
+ Subgraph<Table2> subgraph = new Subgraph<Table2>(Table2.class, context
+ .getEntityResolver());
+ subgraph.addSerializeByReferencePath(Table2.TABLE1_PROPERTY);
+
+ XStreamDeserializer deserializer = new XStreamDeserializer();
+
+ int id = DataObjectUtils.intPKForObject(t11);
+ String xml = "<Table2><name>t21</name><table1><Table1 ref=\"true\"><PK>"
+ + id + "</PK></Table1></table1></Table2>";
+
+ Table2 result;
+ InputStream in = new ByteArrayInputStream(xml.getBytes());
+ try {
+ result = deserializer.deserialize(context, subgraph, in);
+ } finally {
+ in.close();
+ }
+
+ assertNotNull(result);
+ assertNotNull(result.getTable1());
+ assertEquals(PersistenceState.COMMITTED, result.getPersistenceState());
+ assertEquals(PersistenceState.COMMITTED, result.getTable1()
+ .getPersistenceState());
+
+ assertEquals("t21", result.getName());
+ assertNotSame(t21, result);
+ assertSame(t11, result.getTable1());
+
+ }
+}
Added: 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=815515&view=auto
==============================================================================
--- cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/xstream/XStreamSerializerTest.java (added)
+++ cayenne/sandbox/cayenne-serialization/src/test/java/org/apache/cayenne/serialization/xstream/XStreamSerializerTest.java Tue Sep 15 22:05:39 2009
@@ -0,0 +1,149 @@
+/*****************************************************************
+ * 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.xstream;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import org.apache.cayenne.DataObjectUtils;
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.serialization.Subgraph;
+import org.apache.cayenne.serialization.persistent.Table1;
+import org.apache.cayenne.serialization.persistent.Table2;
+import org.apache.cayenne.serialization.unit.SerializationCase;
+import org.apache.cayenne.util.Util;
+
+public class XStreamSerializerTest extends SerializationCase {
+
+ public void testCreatingCompactXML() {
+ XStreamSerializer serializer = new XStreamSerializer();
+ assertFalse(serializer.isCreatingCompactXML());
+ serializer.setCreatingCompactXML(true);
+ assertTrue(serializer.isCreatingCompactXML());
+ }
+
+ public void testSerializeByValueToOne() throws IOException {
+
+ ObjectContext context = newContext();
+ Table1 t11 = context.newObject(Table1.class);
+ t11.setName("t11");
+
+ Table2 t21 = context.newObject(Table2.class);
+ t21.setName("t21");
+ t21.setTable1(t11);
+
+ context.commitChanges();
+
+ Subgraph<Table2> subgraph = new Subgraph<Table2>(Table2.class, context
+ .getEntityResolver());
+ subgraph.addSerializeByValuePath(Table2.TABLE1_PROPERTY);
+
+ File file = tempFile(".xml");
+ XStreamSerializer serializer = new XStreamSerializer();
+ serializer.setCreatingCompactXML(true);
+
+ FileOutputStream out = new FileOutputStream(file);
+ try {
+ serializer.serialize(t21, subgraph, out);
+ } finally {
+ out.close();
+ }
+
+ assertTrue(file.isFile());
+ assertTrue(file.length() > 0);
+
+ assertEquals("<Table2><name>t21</name><table1>"
+ + "<Table1><name>t11</name></Table1></table1></Table2>", Util
+ .stringFromFile(file).trim());
+ }
+
+ public void testSerializeByValueToMany() throws IOException {
+
+ ObjectContext context = newContext();
+ Table1 t11 = context.newObject(Table1.class);
+ t11.setName("t11");
+
+ Table2 t21 = context.newObject(Table2.class);
+ t21.setName("t21");
+ t21.setTable1(t11);
+
+ context.commitChanges();
+
+ Subgraph<Table1> subgraph = new Subgraph<Table1>(Table1.class, context
+ .getEntityResolver());
+ subgraph.addSerializeByValuePath(Table1.TABLE2S_PROPERTY);
+
+ File file = tempFile(".xml");
+ XStreamSerializer serializer = new XStreamSerializer();
+ serializer.setCreatingCompactXML(true);
+
+ FileOutputStream out = new FileOutputStream(file);
+ try {
+ serializer.serialize(t11, subgraph, out);
+ } finally {
+ out.close();
+ }
+
+ assertTrue(file.isFile());
+ assertTrue(file.length() > 0);
+
+ assertEquals("<Table1><name>t11</name><table2s>"
+ + "<Table2><name>t21</name></Table2>" + "</table2s></Table1>",
+ Util.stringFromFile(file).trim());
+ }
+
+ public void testSerializeByReferenceToOne() throws IOException {
+
+ ObjectContext context = newContext();
+ Table1 t11 = context.newObject(Table1.class);
+ t11.setName("t11");
+
+ Table2 t21 = context.newObject(Table2.class);
+ t21.setName("t21");
+ t21.setTable1(t11);
+
+ context.commitChanges();
+
+ Subgraph<Table2> subgraph = new Subgraph<Table2>(Table2.class, context
+ .getEntityResolver());
+ subgraph.addSerializeByReferencePath(Table2.TABLE1_PROPERTY);
+
+ File file = tempFile(".xml");
+ XStreamSerializer serializer = new XStreamSerializer();
+ serializer.setCreatingCompactXML(true);
+
+ FileOutputStream out = new FileOutputStream(file);
+ try {
+ serializer.serialize(t21, subgraph, out);
+ } finally {
+ out.close();
+ }
+
+ assertTrue(file.isFile());
+ assertTrue(file.length() > 0);
+
+ int id = DataObjectUtils.intPKForObject(t11);
+
+ assertEquals(
+ "<Table2><name>t21</name><table1><Table1 ref=\"true\"><PK>"
+ + id + "</PK></Table1></table1></Table2>", Util
+ .stringFromFile(file).trim());
+ }
+}
Added: cayenne/sandbox/cayenne-serialization/src/test/resources/cayenne.xml
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-serialization/src/test/resources/cayenne.xml?rev=815515&view=auto
==============================================================================
--- cayenne/sandbox/cayenne-serialization/src/test/resources/cayenne.xml (added)
+++ cayenne/sandbox/cayenne-serialization/src/test/resources/cayenne.xml Tue Sep 15 22:05:39 2009
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<domains project-version="3.0">
+<domain name="serialization">
+ <map name="serialization" location="serialization.map.xml"/>
+
+ <node name="serialization"
+ datasource="serialization.driver.xml"
+ factory="org.apache.cayenne.conf.DriverDataSourceFactory"
+ schema-update-strategy="org.apache.cayenne.access.dbsync.CreateIfNoSchemaStrategy">
+ <map-ref name="serialization"/>
+ </node>
+</domain>
+</domains>
Added: cayenne/sandbox/cayenne-serialization/src/test/resources/serialization.driver.xml
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-serialization/src/test/resources/serialization.driver.xml?rev=815515&view=auto
==============================================================================
--- cayenne/sandbox/cayenne-serialization/src/test/resources/serialization.driver.xml (added)
+++ cayenne/sandbox/cayenne-serialization/src/test/resources/serialization.driver.xml Tue Sep 15 22:05:39 2009
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<driver project-version="3.0" class="org.hsqldb.jdbcDriver">
+ <url value="jdbc:hsqldb:mem:serializationdb"/>
+ <connectionPool min="1" max="1"/>
+ <login userName="sa"/>
+</driver>
Added: cayenne/sandbox/cayenne-serialization/src/test/resources/serialization.map.xml
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-serialization/src/test/resources/serialization.map.xml?rev=815515&view=auto
==============================================================================
--- cayenne/sandbox/cayenne-serialization/src/test/resources/serialization.map.xml (added)
+++ cayenne/sandbox/cayenne-serialization/src/test/resources/serialization.map.xml Tue Sep 15 22:05:39 2009
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<data-map xmlns="http://cayenne.apache.org/schema/3.0/modelMap"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://cayenne.apache.org/schema/3.0/modelMap http://cayenne.apache.org/schema/3.0/modelMap"
+ project-version="3.0">
+ <property name="defaultPackage" value="org.apache.cayenne.serialization.persistent"/>
+ <db-entity name="table1">
+ <db-attribute name="NAME" type="VARCHAR" length="200"/>
+ <db-attribute name="PK" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ </db-entity>
+ <db-entity name="table2">
+ <db-attribute name="DATE_COLUMN" type="DATE"/>
+ <db-attribute name="DOUBLE_COLUMN" type="DOUBLE"/>
+ <db-attribute name="NAME" type="VARCHAR" length="200"/>
+ <db-attribute name="PK" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ <db-attribute name="TABLE1_FK" type="INTEGER"/>
+ </db-entity>
+ <obj-entity name="Table1" className="org.apache.cayenne.serialization.persistent.Table1" dbEntityName="table1">
+ <obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+ </obj-entity>
+ <obj-entity name="Table2" className="org.apache.cayenne.serialization.persistent.Table2" dbEntityName="table2">
+ <obj-attribute name="dateColumn" type="java.util.Date" db-attribute-path="DATE_COLUMN"/>
+ <obj-attribute name="doubleColumn" type="java.lang.Double" db-attribute-path="DOUBLE_COLUMN"/>
+ <obj-attribute name="name" type="java.lang.String" db-attribute-path="NAME"/>
+ </obj-entity>
+ <db-relationship name="table2s" source="table1" target="table2" toMany="true">
+ <db-attribute-pair source="PK" target="TABLE1_FK"/>
+ </db-relationship>
+ <db-relationship name="table1" source="table2" target="table1" toMany="false">
+ <db-attribute-pair source="TABLE1_FK" target="PK"/>
+ </db-relationship>
+ <obj-relationship name="table2s" source="Table1" target="Table2" deleteRule="Deny" db-relationship-path="table2s"/>
+ <obj-relationship name="table1" source="Table2" target="Table1" deleteRule="Nullify" db-relationship-path="table1"/>
+</data-map>