add PrefetchTreeNodeSchema to support readResolve() method;
update Protostuff version;
cleanup;


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/5ce1af22
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/5ce1af22
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/5ce1af22

Branch: refs/heads/master
Commit: 5ce1af220f4f91e9366920ebefe7c6ef1d58b316
Parents: 0c26497
Author: Savva Kolbachev <s.kolbac...@gmail.com>
Authored: Tue May 17 19:36:21 2016 +0300
Committer: Savva Kolbachev <s.kolbac...@gmail.com>
Committed: Mon May 23 17:23:08 2016 +0300

----------------------------------------------------------------------
 cayenne-protostuff/pom.xml                      |   2 +-
 .../rop/client/ProtostuffModule.java            |   4 +-
 .../cayenne/query/PrefetchTreeNodeSchema.java   | 157 +++++++++++++++++++
 .../ProtostuffROPSerializationService.java      |  41 ++---
 ...otostuffROPSerializationServiceProvider.java |  32 ----
 .../apache/cayenne/rop/protostuff/Wrapper.java  |  38 +++++
 .../ProtostuffPrefetchTreeNodeSchemaIT.java     |  62 ++++++++
 .../ProtostuffROPSerializationServiceIT.java    |   4 +-
 .../apache/cayenne/query/PrefetchTreeNode.java  |  12 +-
 9 files changed, 291 insertions(+), 61 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/5ce1af22/cayenne-protostuff/pom.xml
----------------------------------------------------------------------
diff --git a/cayenne-protostuff/pom.xml b/cayenne-protostuff/pom.xml
index 76af8a4..0934f64 100644
--- a/cayenne-protostuff/pom.xml
+++ b/cayenne-protostuff/pom.xml
@@ -21,7 +21,7 @@
     <name>Cayenne Protostuff Extension</name>
 
     <properties>
-        <protostuff.version>1.4.1</protostuff.version>
+        <protostuff.version>1.4.2</protostuff.version>
     </properties>
 
     <dependencyManagement>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/5ce1af22/cayenne-protostuff/src/main/java/org/apache/cayenne/configuration/rop/client/ProtostuffModule.java
----------------------------------------------------------------------
diff --git 
a/cayenne-protostuff/src/main/java/org/apache/cayenne/configuration/rop/client/ProtostuffModule.java
 
b/cayenne-protostuff/src/main/java/org/apache/cayenne/configuration/rop/client/ProtostuffModule.java
index b4a89e5..45d6d65 100644
--- 
a/cayenne-protostuff/src/main/java/org/apache/cayenne/configuration/rop/client/ProtostuffModule.java
+++ 
b/cayenne-protostuff/src/main/java/org/apache/cayenne/configuration/rop/client/ProtostuffModule.java
@@ -21,7 +21,7 @@ package org.apache.cayenne.configuration.rop.client;
 import org.apache.cayenne.di.Binder;
 import org.apache.cayenne.di.Module;
 import org.apache.cayenne.rop.ROPSerializationService;
-import 
org.apache.cayenne.rop.protostuff.ProtostuffROPSerializationServiceProvider;
+import org.apache.cayenne.rop.protostuff.ProtostuffROPSerializationService;
 
 /**
  * A DI module that uses Protostuff Object Graph Serialization as Cayenne 
{@link ROPSerializationService}.
@@ -39,6 +39,6 @@ public class ProtostuffModule implements Module {
 
     @Override
     public void configure(Binder binder) {
-        
binder.bind(ROPSerializationService.class).toProvider(ProtostuffROPSerializationServiceProvider.class);
+        
binder.bind(ROPSerializationService.class).to(ProtostuffROPSerializationService.class).inSingletonScope();
     }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/5ce1af22/cayenne-protostuff/src/main/java/org/apache/cayenne/query/PrefetchTreeNodeSchema.java
----------------------------------------------------------------------
diff --git 
a/cayenne-protostuff/src/main/java/org/apache/cayenne/query/PrefetchTreeNodeSchema.java
 
b/cayenne-protostuff/src/main/java/org/apache/cayenne/query/PrefetchTreeNodeSchema.java
new file mode 100644
index 0000000..2d4a9a2
--- /dev/null
+++ 
b/cayenne-protostuff/src/main/java/org/apache/cayenne/query/PrefetchTreeNodeSchema.java
@@ -0,0 +1,157 @@
+/*****************************************************************
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.query;
+
+import io.protostuff.Input;
+import io.protostuff.Output;
+import io.protostuff.Schema;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * As {@link PrefetchTreeNode} has {@link PrefetchTreeNode#readResolve 
readResolve} method, which isn't supported
+ * by Protostuff, we have to provide custom schema for this class.
+ *
+ * @see java.io.Serializable
+ */
+public class PrefetchTreeNodeSchema implements Schema<PrefetchTreeNode> {
+
+    private static final HashMap<String, Integer> fieldMap = new HashMap<>();
+
+    static {
+        fieldMap.put("name", 1);
+        fieldMap.put("phantom", 2);
+        fieldMap.put("semantics", 3);
+        fieldMap.put("ejbqlPathEntityId", 4);
+        fieldMap.put("entityName", 5);
+        fieldMap.put("children", 6);
+    }
+
+    @Override
+    public String getFieldName(int number) {
+        switch (number) {
+            case 1:
+                return "name";
+            case 2:
+                return "phantom";
+            case 3:
+                return "semantics";
+            case 4:
+                return "ejbqlPathEntityId";
+            case 5:
+                return "entityName";
+            case 6:
+                return "children";
+            default:
+                return null;
+        }
+    }
+
+    @Override
+    public int getFieldNumber(String name) {
+        return fieldMap.getOrDefault(name, 0);
+    }
+
+    @Override
+    public boolean isInitialized(PrefetchTreeNode message) {
+        return true;
+    }
+
+    @Override
+    public PrefetchTreeNode newMessage() {
+        return new PrefetchTreeNode();
+    }
+
+    @Override
+    public String messageName() {
+        return PrefetchTreeNode.class.getSimpleName();
+    }
+
+    @Override
+    public String messageFullName() {
+        return PrefetchTreeNode.class.getName();
+    }
+
+    @Override
+    public Class<PrefetchTreeNode> typeClass() {
+        return PrefetchTreeNode.class;
+    }
+
+    @Override
+    public void mergeFrom(Input input, PrefetchTreeNode message) throws 
IOException {
+        for (int number = input.readFieldNumber(this);; number = 
input.readFieldNumber(this)) {
+            switch (number) {
+                case 0:
+                    message.readResolve();
+                    return;
+                case 1:
+                    message.name = input.readString();
+                    break;
+                case 2:
+                    message.setPhantom(input.readBool());
+                    break;
+                case 3:
+                    message.setSemantics(input.readInt32());
+                    break;
+                case 4:
+                    message.setEjbqlPathEntityId(input.readString());
+                    break;
+                case 5:
+                    message.setEntityName(input.readString());
+                    break;
+                case 6:
+                    if (message.children == null) {
+                        message.children = new ArrayList<>(4);
+                    }
+                    message.children.add(input.mergeObject(null, this));
+                    break;
+                default:
+                    input.handleUnknownField(number, this);
+            }
+        }
+    }
+
+    @Override
+    public void writeTo(Output output, PrefetchTreeNode message) throws 
IOException {
+        if (message.getName() != null) {
+            output.writeString(1, message.getName(), false);
+        }
+
+        output.writeBool(2, message.isPhantom(), false);
+        output.writeInt32(3, message.getSemantics(), false);
+
+        if (message.getEjbqlPathEntityId() != null) {
+            output.writeString(4, message.getEjbqlPathEntityId(), false);
+        }
+
+        if (message.getEntityName() != null) {
+            output.writeString(5, message.getEntityName(), false);
+        }
+
+        if (message.hasChildren()) {
+            for (PrefetchTreeNode node : message.getChildren()) {
+                output.writeObject(6, node, this, true);
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/5ce1af22/cayenne-protostuff/src/main/java/org/apache/cayenne/rop/protostuff/ProtostuffROPSerializationService.java
----------------------------------------------------------------------
diff --git 
a/cayenne-protostuff/src/main/java/org/apache/cayenne/rop/protostuff/ProtostuffROPSerializationService.java
 
b/cayenne-protostuff/src/main/java/org/apache/cayenne/rop/protostuff/ProtostuffROPSerializationService.java
index 39cdbc9..371c42f 100644
--- 
a/cayenne-protostuff/src/main/java/org/apache/cayenne/rop/protostuff/ProtostuffROPSerializationService.java
+++ 
b/cayenne-protostuff/src/main/java/org/apache/cayenne/rop/protostuff/ProtostuffROPSerializationService.java
@@ -22,7 +22,10 @@ import io.protostuff.GraphIOUtil;
 import io.protostuff.LinkedBuffer;
 import io.protostuff.Schema;
 import io.protostuff.runtime.RuntimeSchema;
+import org.apache.cayenne.query.PrefetchTreeNode;
+import org.apache.cayenne.query.PrefetchTreeNodeSchema;
 import org.apache.cayenne.rop.ROPSerializationService;
+import org.apache.cayenne.util.PersistentObjectList;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -31,43 +34,45 @@ import java.io.OutputStream;
 /**
  * This {@link ROPSerializationService} implementation uses Protostuff {@link 
GraphIOUtil} to (de)serialize
  * Cayenne object graph.
+ *
+ * @since 4.0
  */
 public class ProtostuffROPSerializationService implements 
ROPSerializationService {
 
+    protected Schema<Wrapper> wrapperSchema;
+
+    public ProtostuffROPSerializationService() {
+        this.wrapperSchema = RuntimeSchema.getSchema(Wrapper.class);
+        registerSchemas();
+    }
+
+    protected void registerSchemas() {
+        RuntimeSchema.register(PersistentObjectList.class, 
RuntimeSchema.getSchema(PersistentObjectList.class));
+        RuntimeSchema.register(PrefetchTreeNode.class, new 
PrefetchTreeNodeSchema());
+    }
+
     @Override
     public byte[] serialize(Object object) throws IOException {
-        Schema<Wrapper> schema = RuntimeSchema.getSchema(Wrapper.class);
-        return GraphIOUtil.toByteArray(new Wrapper(object), schema, 
LinkedBuffer.allocate());
+        return GraphIOUtil.toByteArray(new Wrapper(object), wrapperSchema, 
LinkedBuffer.allocate());
     }
 
     @Override
     public void serialize(Object object, OutputStream outputStream) throws 
IOException {
-        Schema<Wrapper> schema = RuntimeSchema.getSchema(Wrapper.class);
-        GraphIOUtil.writeTo(outputStream, new Wrapper(object), schema, 
LinkedBuffer.allocate());
+        GraphIOUtil.writeTo(outputStream, new Wrapper(object), wrapperSchema, 
LinkedBuffer.allocate());
     }
 
     @Override
     public <T> T deserialize(InputStream inputStream, Class<T> objectClass) 
throws IOException {
-        Schema<Wrapper> schema = RuntimeSchema.getSchema(Wrapper.class);
-        Wrapper result = schema.newMessage();
-        GraphIOUtil.mergeFrom(inputStream, result, schema, 
LinkedBuffer.allocate());
+        Wrapper result = wrapperSchema.newMessage();
+        GraphIOUtil.mergeFrom(inputStream, result, wrapperSchema, 
LinkedBuffer.allocate());
         return objectClass.cast(result.data);
-
     }
 
     @Override
     public <T> T deserialize(byte[] serializedObject, Class<T> objectClass) 
throws IOException {
-        Schema<Wrapper> schema = RuntimeSchema.getSchema(Wrapper.class);
-        Wrapper result = schema.newMessage();
-        GraphIOUtil.mergeFrom(serializedObject, result, schema);
+        Wrapper result = wrapperSchema.newMessage();
+        GraphIOUtil.mergeFrom(serializedObject, result, wrapperSchema);
         return objectClass.cast(result.data);
     }
 
-    private class Wrapper {
-        private Object data;
-
-        public Wrapper(Object data) {
-            this.data = data;
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/5ce1af22/cayenne-protostuff/src/main/java/org/apache/cayenne/rop/protostuff/ProtostuffROPSerializationServiceProvider.java
----------------------------------------------------------------------
diff --git 
a/cayenne-protostuff/src/main/java/org/apache/cayenne/rop/protostuff/ProtostuffROPSerializationServiceProvider.java
 
b/cayenne-protostuff/src/main/java/org/apache/cayenne/rop/protostuff/ProtostuffROPSerializationServiceProvider.java
deleted file mode 100644
index 35a164d..0000000
--- 
a/cayenne-protostuff/src/main/java/org/apache/cayenne/rop/protostuff/ProtostuffROPSerializationServiceProvider.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*****************************************************************
- *   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.rop.protostuff;
-
-import org.apache.cayenne.di.DIRuntimeException;
-import org.apache.cayenne.di.Provider;
-import org.apache.cayenne.rop.ROPSerializationService;
-
-public class ProtostuffROPSerializationServiceProvider implements 
Provider<ROPSerializationService> {
-
-    @Override
-    public ROPSerializationService get() throws DIRuntimeException {
-        return new ProtostuffROPSerializationService();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/5ce1af22/cayenne-protostuff/src/main/java/org/apache/cayenne/rop/protostuff/Wrapper.java
----------------------------------------------------------------------
diff --git 
a/cayenne-protostuff/src/main/java/org/apache/cayenne/rop/protostuff/Wrapper.java
 
b/cayenne-protostuff/src/main/java/org/apache/cayenne/rop/protostuff/Wrapper.java
new file mode 100644
index 0000000..c3679b0
--- /dev/null
+++ 
b/cayenne-protostuff/src/main/java/org/apache/cayenne/rop/protostuff/Wrapper.java
@@ -0,0 +1,38 @@
+/*****************************************************************
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.rop.protostuff;
+
+import java.io.Serializable;
+
+/**
+ * As Protostuff has limitation that nested messages should not contain 
references to the root message, so we provide
+ * a simple wrapper for the root message.
+ *
+ * <a href="http://www.protostuff.io/documentation/object-graphs/";>
+ */
+public class Wrapper implements Serializable {
+
+    public Object data;
+
+    public Wrapper(Object data) {
+        this.data = data;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/5ce1af22/cayenne-protostuff/src/test/java/org/apache/cayenne/query/ProtostuffPrefetchTreeNodeSchemaIT.java
----------------------------------------------------------------------
diff --git 
a/cayenne-protostuff/src/test/java/org/apache/cayenne/query/ProtostuffPrefetchTreeNodeSchemaIT.java
 
b/cayenne-protostuff/src/test/java/org/apache/cayenne/query/ProtostuffPrefetchTreeNodeSchemaIT.java
new file mode 100644
index 0000000..3f182b4
--- /dev/null
+++ 
b/cayenne-protostuff/src/test/java/org/apache/cayenne/query/ProtostuffPrefetchTreeNodeSchemaIT.java
@@ -0,0 +1,62 @@
+/*****************************************************************
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.query;
+
+import org.apache.cayenne.rop.ROPSerializationService;
+import org.apache.cayenne.rop.protostuff.ProtostuffROPSerializationService;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class ProtostuffPrefetchTreeNodeSchemaIT {
+
+    private ROPSerializationService clientService;
+    private ROPSerializationService serverService;
+
+    @Before
+    public void setUp() throws Exception {
+        clientService = new ProtostuffROPSerializationService();
+        serverService = new ProtostuffROPSerializationService();
+    }
+
+    @Test
+    public void testPrefetchTreeNodeSchema() throws IOException {
+        PrefetchTreeNode parent = new PrefetchTreeNode(null, "parent");
+        PrefetchTreeNode child = new PrefetchTreeNode(parent, "child");
+        parent.addChild(child);
+
+        byte[] data = clientService.serialize(parent);
+        PrefetchTreeNode parent0 = serverService.deserialize(data, 
PrefetchTreeNode.class);
+
+        assertNotNull(parent0);
+        assertTrue(parent0.hasChildren());
+
+        PrefetchTreeNode child0 = parent0.getChild("child");
+        assertNotNull(child0);
+        assertNotNull(child0.parent);
+        assertEquals(child0.parent, parent0);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/5ce1af22/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/ProtostuffROPSerializationServiceIT.java
----------------------------------------------------------------------
diff --git 
a/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/ProtostuffROPSerializationServiceIT.java
 
b/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/ProtostuffROPSerializationServiceIT.java
index b077056..0b73dd6 100644
--- 
a/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/ProtostuffROPSerializationServiceIT.java
+++ 
b/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/ProtostuffROPSerializationServiceIT.java
@@ -80,8 +80,8 @@ public class ProtostuffROPSerializationServiceIT {
         table2.setTable1(table1);
         table2.setGlobalAttribute(GLOBAL_ATTRIBUTE2);
 
-        clientService = new ProtostuffROPSerializationServiceProvider().get();
-        serverService = new ProtostuffROPSerializationServiceProvider().get();
+        clientService = new ProtostuffROPSerializationService();
+        serverService = new ProtostuffROPSerializationService();
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/cayenne/blob/5ce1af22/cayenne-server/src/main/java/org/apache/cayenne/query/PrefetchTreeNode.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/query/PrefetchTreeNode.java 
b/cayenne-server/src/main/java/org/apache/cayenne/query/PrefetchTreeNode.java
index e44b08d..d71a7f4 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/query/PrefetchTreeNode.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/query/PrefetchTreeNode.java
@@ -19,6 +19,11 @@
 
 package org.apache.cayenne.query;
 
+import org.apache.cayenne.map.Entity;
+import org.apache.cayenne.util.Util;
+import org.apache.cayenne.util.XMLEncoder;
+import org.apache.cayenne.util.XMLSerializable;
+
 import java.io.ObjectStreamException;
 import java.io.Serializable;
 import java.util.ArrayList;
@@ -26,11 +31,6 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.StringTokenizer;
 
-import org.apache.cayenne.map.Entity;
-import org.apache.cayenne.util.Util;
-import org.apache.cayenne.util.XMLEncoder;
-import org.apache.cayenne.util.XMLSerializable;
-
 /**
  * Defines a node in a prefetch tree.
  *
@@ -472,7 +472,7 @@ public class PrefetchTreeNode implements Serializable, 
XMLSerializable {
        // implementing 'readResolve' instead of 'readObject' so that this would
        // work with
        // hessian
-       private Object readResolve() throws ObjectStreamException {
+       protected Object readResolve() throws ObjectStreamException {
 
                if (hasChildren()) {
                        for (PrefetchTreeNode child : children) {

Reply via email to