You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by sk...@apache.org on 2016/05/23 14:42:38 UTC
[3/4] cayenne git commit: add PrefetchTreeNodeSchema to support
readResolve() method; update Protostuff version; cleanup;
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....@gmail.com>
Authored: Tue May 17 19:36:21 2016 +0300
Committer: Savva Kolbachev <s....@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) {