cayenne-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From skolbac...@apache.org
Subject [4/4] cayenne git commit: add Protostuff as serialization service for ROP
Date Mon, 23 May 2016 14:42:39 GMT
add Protostuff as serialization service for ROP


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

Branch: refs/heads/master
Commit: 7783be1ffbdaa6ccd1332d3b49fab8a4cf7b565e
Parents: c117eb1
Author: Savva Kolbachev <s.kolbachev@gmail.com>
Authored: Sun May 1 23:34:54 2016 +0300
Committer: Savva Kolbachev <s.kolbachev@gmail.com>
Committed: Mon May 23 17:23:08 2016 +0300

----------------------------------------------------------------------
 cayenne-protostuff/pom.xml                      | 151 +++++++++++++++
 .../rop/client/ProtostuffClientModule.java      |  32 ++++
 .../ProtostuffROPSerializationService.java      |  70 +++++++
 ...otostuffROPSerializationServiceProvider.java |  32 ++++
 .../ProtostuffROPSerializationServiceIT.java    | 137 +++++++++++++
 .../protostuff/persistent/ClientMtTable1.java   |  12 ++
 .../protostuff/persistent/ClientMtTable2.java   |  12 ++
 .../rop/protostuff/persistent/MtTable1.java     |   9 +
 .../rop/protostuff/persistent/MtTable2.java     |   9 +
 .../persistent/auto/_ClientMtTable1.java        | 191 +++++++++++++++++++
 .../persistent/auto/_ClientMtTable2.java        |  69 +++++++
 .../protostuff/persistent/auto/_MtTable1.java   |  87 +++++++++
 .../protostuff/persistent/auto/_MtTable2.java   |  38 ++++
 .../src/test/resources/cayenne-protostuff.xml   |   4 +
 .../src/test/resources/protostuff.map.xml       |  42 ++++
 pom.xml                                         |   5 +-
 16 files changed, 898 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783be1f/cayenne-protostuff/pom.xml
----------------------------------------------------------------------
diff --git a/cayenne-protostuff/pom.xml b/cayenne-protostuff/pom.xml
new file mode 100644
index 0000000..a26baab
--- /dev/null
+++ b/cayenne-protostuff/pom.xml
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 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. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.cayenne</groupId>
+        <artifactId>cayenne-parent</artifactId>
+        <version>4.0.M4-SNAPSHOT</version>
+    </parent>
+    <artifactId>cayenne-protostuff</artifactId>
+    <packaging>jar</packaging>
+    <name>Cayenne Protostuff Extension</name>
+
+    <properties>
+        <protostuff.version>1.4.1</protostuff.version>
+    </properties>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>io.protostuff</groupId>
+                <artifactId>protostuff-core</artifactId>
+                <version>${protostuff.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>io.protostuff</groupId>
+                <artifactId>protostuff-runtime</artifactId>
+                <version>${protostuff.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>io.protostuff</groupId>
+                <artifactId>protostuff-api</artifactId>
+                <version>${protostuff.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>io.protostuff</groupId>
+                <artifactId>protostuff-collectionschema</artifactId>
+                <version>${protostuff.version}</version>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cayenne</groupId>
+            <artifactId>cayenne-client</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>io.protostuff</groupId>
+            <artifactId>protostuff-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.protostuff</groupId>
+            <artifactId>protostuff-runtime</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.protostuff</groupId>
+            <artifactId>protostuff-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.protostuff</groupId>
+            <artifactId>protostuff-collectionschema</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.cayenne.plugins</groupId>
+                <artifactId>maven-cayenne-plugin</artifactId>
+                <version>${project.version}</version>
+                <configuration>
+                    <map>${project.basedir}/src/test/resources/protostuff.map.xml</map>
+                    <destDir>${project.basedir}/src/test/java</destDir>
+                    <client>true</client>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>default-cli</id>
+                        <goals>
+                            <goal>cgen</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <artifactId>maven-remote-resources-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>process</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-failsafe-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+
+    <profiles>
+        <profile>
+            <id>code-quality</id>
+
+            <activation>
+                <property>
+                    <name>!fast-and-dirty</name>
+                </property>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <artifactId>maven-checkstyle-plugin</artifactId>
+                        <!--<configuration>
+                            <suppressionsLocation>${project.basedir}/cayenne-checkstyle-suppression.xml</suppressionsLocation>
+                        </configuration>-->
+                    </plugin>
+                    <plugin>
+                        <artifactId>maven-pmd-plugin</artifactId>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783be1f/cayenne-protostuff/src/main/java/org/apache/cayenne/configuration/rop/client/ProtostuffClientModule.java
----------------------------------------------------------------------
diff --git a/cayenne-protostuff/src/main/java/org/apache/cayenne/configuration/rop/client/ProtostuffClientModule.java
b/cayenne-protostuff/src/main/java/org/apache/cayenne/configuration/rop/client/ProtostuffClientModule.java
new file mode 100644
index 0000000..80b81f5
--- /dev/null
+++ b/cayenne-protostuff/src/main/java/org/apache/cayenne/configuration/rop/client/ProtostuffClientModule.java
@@ -0,0 +1,32 @@
+/*****************************************************************
+ * 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.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;
+
+public class ProtostuffClientModule implements Module {
+
+    @Override
+    public void configure(Binder binder) {
+        binder.bind(ROPSerializationService.class).toProvider(ProtostuffROPSerializationServiceProvider.class);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783be1f/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
new file mode 100644
index 0000000..599b9c0
--- /dev/null
+++ b/cayenne-protostuff/src/main/java/org/apache/cayenne/rop/protostuff/ProtostuffROPSerializationService.java
@@ -0,0 +1,70 @@
+/*****************************************************************
+ * 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 io.protostuff.GraphIOUtil;
+import io.protostuff.LinkedBuffer;
+import io.protostuff.Schema;
+import io.protostuff.runtime.RuntimeSchema;
+import org.apache.cayenne.rop.ROPSerializationService;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+public class ProtostuffROPSerializationService implements ROPSerializationService {
+
+    @Override
+    public byte[] serialize(Object object) throws IOException {
+        Schema<Wrapper> schema = RuntimeSchema.getSchema(Wrapper.class);
+        return GraphIOUtil.toByteArray(new Wrapper(object), schema, 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());
+    }
+
+    @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());
+        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);
+        return objectClass.cast(result.data);
+
+    }
+
+    private class Wrapper {
+        public Object data;
+
+        public Wrapper(Object data) {
+            this.data = data;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783be1f/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
new file mode 100644
index 0000000..35a164d
--- /dev/null
+++ b/cayenne-protostuff/src/main/java/org/apache/cayenne/rop/protostuff/ProtostuffROPSerializationServiceProvider.java
@@ -0,0 +1,32 @@
+/*****************************************************************
+ *   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/7783be1f/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
new file mode 100644
index 0000000..d2c73bb
--- /dev/null
+++ b/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/ProtostuffROPSerializationServiceIT.java
@@ -0,0 +1,137 @@
+/*****************************************************************
+ *   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.ObjectContext;
+import org.apache.cayenne.configuration.rop.client.ClientLocalRuntime;
+import org.apache.cayenne.configuration.rop.client.ClientRuntime;
+import org.apache.cayenne.configuration.rop.client.ProtostuffClientModule;
+import org.apache.cayenne.configuration.server.ServerRuntime;
+import org.apache.cayenne.rop.ROPSerializationService;
+import org.apache.cayenne.rop.protostuff.persistent.ClientMtTable1;
+import org.apache.cayenne.rop.protostuff.persistent.ClientMtTable2;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.util.Collections;
+import java.util.Date;
+
+import static org.junit.Assert.assertEquals;
+
+public class ProtostuffROPSerializationServiceIT {
+
+    private static final String GLOBAL_ATTRIBUTE1 = "Test table1";
+    private static final String GLOBAL_ATTRIBUTE2 = "Test table2";
+
+    private ClientMtTable1 table1;
+    private ClientMtTable2 table2;
+
+    private Date oldDate;
+    private LocalDate localDate;
+    private LocalTime localTime;
+    private LocalDateTime localDateTime;
+
+    private ROPSerializationService clientService;
+    private ROPSerializationService serverService;
+
+    @Before
+    public void setUp() throws Exception {
+        ClientRuntime clientRuntime = new ClientLocalRuntime(
+                new ServerRuntime("cayenne-protostuff.xml").getInjector(),
+                Collections.emptyMap(),
+                new ProtostuffClientModule());
+
+        ObjectContext context = clientRuntime.newContext();
+
+        oldDate = new Date();
+        localDate = LocalDate.now();
+        localTime = LocalTime.now();
+        localDateTime = LocalDateTime.now();
+
+        table1 = context.newObject(ClientMtTable1.class);
+        table1.setGlobalAttribute(GLOBAL_ATTRIBUTE1);
+        table1.setOldDateAttribute(oldDate);
+        table1.setDateAttribute(localDate);
+        table1.setTimeAttribute(localTime);
+        table1.setTimestampAttribute(localDateTime);
+
+        table2 = context.newObject(ClientMtTable2.class);
+        table2.setTable1(table1);
+        table2.setGlobalAttribute(GLOBAL_ATTRIBUTE2);
+
+        clientService = new ProtostuffROPSerializationServiceProvider().get();
+        serverService = new ProtostuffROPSerializationServiceProvider().get();
+    }
+
+    @Test
+    public void testByteArraySerialization() throws Exception {
+        // test client to server serialization
+        byte[] data = clientService.serialize(table2);
+        ClientMtTable2 serverTable2 = serverService.deserialize(data, ClientMtTable2.class);
+
+        assertCorrectness(serverTable2);
+
+        // test server to client serialization
+        data = serverService.serialize(table2);
+        ClientMtTable2 clientTable2 = clientService.deserialize(data, ClientMtTable2.class);
+
+        assertCorrectness(clientTable2);
+    }
+
+    @Test
+    public void testStreamSerialization() throws Exception {
+
+        // test client to server serialization
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        clientService.serialize(table2, out);
+        out.flush();
+
+        ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
+        ClientMtTable2 serverTable2 = serverService.deserialize(in, ClientMtTable2.class);
+
+        assertCorrectness(serverTable2);
+
+        // test server to client serialization
+        out = new ByteArrayOutputStream();
+        serverService.serialize(table2, out);
+        out.flush();
+
+        in = new ByteArrayInputStream(out.toByteArray());
+        ClientMtTable2 clientTable2 = clientService.deserialize(in, ClientMtTable2.class);
+
+        assertCorrectness(clientTable2);
+    }
+
+    private void assertCorrectness(ClientMtTable2 table2) {
+        ClientMtTable1 table1 = table2.getTable1();
+
+        assertEquals(GLOBAL_ATTRIBUTE2, table2.getGlobalAttribute());
+        assertEquals(GLOBAL_ATTRIBUTE1, table1.getGlobalAttribute());
+        assertEquals(oldDate, table1.getOldDateAttribute());
+        assertEquals(localDate, table1.getDateAttribute());
+        assertEquals(localTime, table1.getTimeAttribute());
+        assertEquals(localDateTime, table1.getTimestampAttribute());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783be1f/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/persistent/ClientMtTable1.java
----------------------------------------------------------------------
diff --git a/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/persistent/ClientMtTable1.java
b/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/persistent/ClientMtTable1.java
new file mode 100644
index 0000000..6b7853b
--- /dev/null
+++ b/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/persistent/ClientMtTable1.java
@@ -0,0 +1,12 @@
+package org.apache.cayenne.rop.protostuff.persistent;
+
+import org.apache.cayenne.rop.protostuff.persistent.auto._ClientMtTable1;
+
+/**
+ * A persistent class mapped as "MtTable1" Cayenne entity.
+ */
+public class ClientMtTable1 extends _ClientMtTable1 {
+
+     private static final long serialVersionUID = 1L; 
+     
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783be1f/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/persistent/ClientMtTable2.java
----------------------------------------------------------------------
diff --git a/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/persistent/ClientMtTable2.java
b/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/persistent/ClientMtTable2.java
new file mode 100644
index 0000000..15d1119
--- /dev/null
+++ b/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/persistent/ClientMtTable2.java
@@ -0,0 +1,12 @@
+package org.apache.cayenne.rop.protostuff.persistent;
+
+import org.apache.cayenne.rop.protostuff.persistent.auto._ClientMtTable2;
+
+/**
+ * A persistent class mapped as "MtTable2" Cayenne entity.
+ */
+public class ClientMtTable2 extends _ClientMtTable2 {
+
+     private static final long serialVersionUID = 1L; 
+     
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783be1f/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/persistent/MtTable1.java
----------------------------------------------------------------------
diff --git a/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/persistent/MtTable1.java
b/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/persistent/MtTable1.java
new file mode 100644
index 0000000..21b1f3f
--- /dev/null
+++ b/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/persistent/MtTable1.java
@@ -0,0 +1,9 @@
+package org.apache.cayenne.rop.protostuff.persistent;
+
+import org.apache.cayenne.rop.protostuff.persistent.auto._MtTable1;
+
+public class MtTable1 extends _MtTable1 {
+
+    private static final long serialVersionUID = 1L; 
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783be1f/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/persistent/MtTable2.java
----------------------------------------------------------------------
diff --git a/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/persistent/MtTable2.java
b/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/persistent/MtTable2.java
new file mode 100644
index 0000000..7f3888f
--- /dev/null
+++ b/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/persistent/MtTable2.java
@@ -0,0 +1,9 @@
+package org.apache.cayenne.rop.protostuff.persistent;
+
+import org.apache.cayenne.rop.protostuff.persistent.auto._MtTable2;
+
+public class MtTable2 extends _MtTable2 {
+
+    private static final long serialVersionUID = 1L; 
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783be1f/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/persistent/auto/_ClientMtTable1.java
----------------------------------------------------------------------
diff --git a/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/persistent/auto/_ClientMtTable1.java
b/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/persistent/auto/_ClientMtTable1.java
new file mode 100644
index 0000000..74febc7
--- /dev/null
+++ b/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/persistent/auto/_ClientMtTable1.java
@@ -0,0 +1,191 @@
+package org.apache.cayenne.rop.protostuff.persistent.auto;
+
+import org.apache.cayenne.PersistentObject;
+import org.apache.cayenne.exp.Property;
+import org.apache.cayenne.rop.protostuff.persistent.ClientMtTable2;
+import org.apache.cayenne.util.PersistentObjectList;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * A generated persistent class mapped as "MtTable1" Cayenne entity. It is a good idea to
+ * avoid changing this class manually, since it will be overwritten next time code is
+ * regenerated. If you need to make any customizations, put them in a subclass.
+ */
+public abstract class _ClientMtTable1 extends PersistentObject {
+
+    public static final Property<LocalDate> DATE_ATTRIBUTE = new Property<LocalDate>("dateAttribute");
+    public static final Property<String> GLOBAL_ATTRIBUTE = new Property<String>("globalAttribute");
+    public static final Property<Date> OLD_DATE_ATTRIBUTE = new Property<Date>("oldDateAttribute");
+    public static final Property<String> SERVER_ATTRIBUTE = new Property<String>("serverAttribute");
+    public static final Property<LocalTime> TIME_ATTRIBUTE = new Property<LocalTime>("timeAttribute");
+    public static final Property<LocalDateTime> TIMESTAMP_ATTRIBUTE = new Property<LocalDateTime>("timestampAttribute");
+    public static final Property<List<ClientMtTable2>> TABLE2ARRAY = new Property<List<ClientMtTable2>>("table2Array");
+
+    protected LocalDate dateAttribute;
+    protected String globalAttribute;
+    protected Date oldDateAttribute;
+    protected String serverAttribute;
+    protected LocalTime timeAttribute;
+    protected LocalDateTime timestampAttribute;
+    protected List<ClientMtTable2> table2Array;
+
+    public LocalDate getDateAttribute() {
+        if(objectContext != null) {
+            objectContext.prepareForAccess(this, "dateAttribute", false);
+        }
+
+        return dateAttribute;
+    }
+    public void setDateAttribute(LocalDate dateAttribute) {
+        if(objectContext != null) {
+            objectContext.prepareForAccess(this, "dateAttribute", false);
+        }
+
+        Object oldValue = this.dateAttribute;
+        // notify objectContext about simple property change
+        if(objectContext != null) {
+            objectContext.propertyChanged(this, "dateAttribute", oldValue, dateAttribute);
+        }
+        
+        this.dateAttribute = dateAttribute;
+    }
+
+    public String getGlobalAttribute() {
+        if(objectContext != null) {
+            objectContext.prepareForAccess(this, "globalAttribute", false);
+        }
+
+        return globalAttribute;
+    }
+    public void setGlobalAttribute(String globalAttribute) {
+        if(objectContext != null) {
+            objectContext.prepareForAccess(this, "globalAttribute", false);
+        }
+
+        Object oldValue = this.globalAttribute;
+        // notify objectContext about simple property change
+        if(objectContext != null) {
+            objectContext.propertyChanged(this, "globalAttribute", oldValue, globalAttribute);
+        }
+        
+        this.globalAttribute = globalAttribute;
+    }
+
+    public Date getOldDateAttribute() {
+        if(objectContext != null) {
+            objectContext.prepareForAccess(this, "oldDateAttribute", false);
+        }
+
+        return oldDateAttribute;
+    }
+    public void setOldDateAttribute(Date oldDateAttribute) {
+        if(objectContext != null) {
+            objectContext.prepareForAccess(this, "oldDateAttribute", false);
+        }
+
+        Object oldValue = this.oldDateAttribute;
+        // notify objectContext about simple property change
+        if(objectContext != null) {
+            objectContext.propertyChanged(this, "oldDateAttribute", oldValue, oldDateAttribute);
+        }
+        
+        this.oldDateAttribute = oldDateAttribute;
+    }
+
+    public String getServerAttribute() {
+        if(objectContext != null) {
+            objectContext.prepareForAccess(this, "serverAttribute", false);
+        }
+
+        return serverAttribute;
+    }
+    public void setServerAttribute(String serverAttribute) {
+        if(objectContext != null) {
+            objectContext.prepareForAccess(this, "serverAttribute", false);
+        }
+
+        Object oldValue = this.serverAttribute;
+        // notify objectContext about simple property change
+        if(objectContext != null) {
+            objectContext.propertyChanged(this, "serverAttribute", oldValue, serverAttribute);
+        }
+        
+        this.serverAttribute = serverAttribute;
+    }
+
+    public LocalTime getTimeAttribute() {
+        if(objectContext != null) {
+            objectContext.prepareForAccess(this, "timeAttribute", false);
+        }
+
+        return timeAttribute;
+    }
+    public void setTimeAttribute(LocalTime timeAttribute) {
+        if(objectContext != null) {
+            objectContext.prepareForAccess(this, "timeAttribute", false);
+        }
+
+        Object oldValue = this.timeAttribute;
+        // notify objectContext about simple property change
+        if(objectContext != null) {
+            objectContext.propertyChanged(this, "timeAttribute", oldValue, timeAttribute);
+        }
+        
+        this.timeAttribute = timeAttribute;
+    }
+
+    public LocalDateTime getTimestampAttribute() {
+        if(objectContext != null) {
+            objectContext.prepareForAccess(this, "timestampAttribute", false);
+        }
+
+        return timestampAttribute;
+    }
+    public void setTimestampAttribute(LocalDateTime timestampAttribute) {
+        if(objectContext != null) {
+            objectContext.prepareForAccess(this, "timestampAttribute", false);
+        }
+
+        Object oldValue = this.timestampAttribute;
+        // notify objectContext about simple property change
+        if(objectContext != null) {
+            objectContext.propertyChanged(this, "timestampAttribute", oldValue, timestampAttribute);
+        }
+        
+        this.timestampAttribute = timestampAttribute;
+    }
+
+    public List<ClientMtTable2> getTable2Array() {
+        if(objectContext != null) {
+            objectContext.prepareForAccess(this, "table2Array", true);
+        } else if (this.table2Array == null) {
+        	this.table2Array = new PersistentObjectList(this, "table2Array");
+		}
+
+        return table2Array;
+    }
+    public void addToTable2Array(ClientMtTable2 object) {
+        if(objectContext != null) {
+            objectContext.prepareForAccess(this, "table2Array", true);
+        } else if (this.table2Array == null) {
+        	this.table2Array = new PersistentObjectList(this, "table2Array");
+		}
+
+        this.table2Array.add(object);
+    }
+    public void removeFromTable2Array(ClientMtTable2 object) {
+        if(objectContext != null) {
+            objectContext.prepareForAccess(this, "table2Array", true);
+        } else if (this.table2Array == null) {
+        	this.table2Array = new PersistentObjectList(this, "table2Array");
+		}
+
+        this.table2Array.remove(object);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783be1f/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/persistent/auto/_ClientMtTable2.java
----------------------------------------------------------------------
diff --git a/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/persistent/auto/_ClientMtTable2.java
b/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/persistent/auto/_ClientMtTable2.java
new file mode 100644
index 0000000..2faf6ef
--- /dev/null
+++ b/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/persistent/auto/_ClientMtTable2.java
@@ -0,0 +1,69 @@
+package org.apache.cayenne.rop.protostuff.persistent.auto;
+
+import org.apache.cayenne.PersistentObject;
+import org.apache.cayenne.ValueHolder;
+import org.apache.cayenne.exp.Property;
+import org.apache.cayenne.rop.protostuff.persistent.ClientMtTable1;
+import org.apache.cayenne.util.PersistentObjectHolder;
+
+/**
+ * A generated persistent class mapped as "MtTable2" Cayenne entity. It is a good idea to
+ * avoid changing this class manually, since it will be overwritten next time code is
+ * regenerated. If you need to make any customizations, put them in a subclass.
+ */
+public abstract class _ClientMtTable2 extends PersistentObject {
+
+    public static final Property<String> GLOBAL_ATTRIBUTE = new Property<String>("globalAttribute");
+    public static final Property<ClientMtTable1> TABLE1 = new Property<ClientMtTable1>("table1");
+
+    protected String globalAttribute;
+    protected ValueHolder table1;
+
+    public String getGlobalAttribute() {
+        if(objectContext != null) {
+            objectContext.prepareForAccess(this, "globalAttribute", false);
+        }
+
+        return globalAttribute;
+    }
+    public void setGlobalAttribute(String globalAttribute) {
+        if(objectContext != null) {
+            objectContext.prepareForAccess(this, "globalAttribute", false);
+        }
+
+        Object oldValue = this.globalAttribute;
+        // notify objectContext about simple property change
+        if(objectContext != null) {
+            objectContext.propertyChanged(this, "globalAttribute", oldValue, globalAttribute);
+        }
+        
+        this.globalAttribute = globalAttribute;
+    }
+
+    public ClientMtTable1 getTable1() {
+        if(objectContext != null) {
+            objectContext.prepareForAccess(this, "table1", true);
+        } else if (this.table1 == null) {
+        	this.table1 = new PersistentObjectHolder(this, "table1");
+		}
+
+        return (ClientMtTable1) table1.getValue();
+    }
+    public void setTable1(ClientMtTable1 table1) {
+        if(objectContext != null) {
+            objectContext.prepareForAccess(this, "table1", true);
+        } else if (this.table1 == null) {
+        	this.table1 = new PersistentObjectHolder(this, "table1");
+		}
+
+        // note how we notify ObjectContext of change BEFORE the object is actually
+        // changed... this is needed to take a valid current snapshot
+        Object oldValue = this.table1.getValueDirectly();
+        if (objectContext != null) {
+        	objectContext.propertyChanged(this, "table1", oldValue, table1);
+        }
+        
+        this.table1.setValue(table1);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783be1f/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/persistent/auto/_MtTable1.java
----------------------------------------------------------------------
diff --git a/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/persistent/auto/_MtTable1.java
b/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/persistent/auto/_MtTable1.java
new file mode 100644
index 0000000..0eb33bd
--- /dev/null
+++ b/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/persistent/auto/_MtTable1.java
@@ -0,0 +1,87 @@
+package org.apache.cayenne.rop.protostuff.persistent.auto;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.cayenne.CayenneDataObject;
+import org.apache.cayenne.exp.Property;
+import org.apache.cayenne.rop.protostuff.persistent.MtTable2;
+
+/**
+ * Class _MtTable1 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 _MtTable1 extends CayenneDataObject {
+
+    private static final long serialVersionUID = 1L; 
+
+    public static final String TABLE1_ID_PK_COLUMN = "TABLE1_ID";
+
+    public static final Property<LocalDate> DATE_ATTRIBUTE = new Property<LocalDate>("dateAttribute");
+    public static final Property<String> GLOBAL_ATTRIBUTE = new Property<String>("globalAttribute");
+    public static final Property<Date> OLD_DATE_ATTRIBUTE = new Property<Date>("oldDateAttribute");
+    public static final Property<String> SERVER_ATTRIBUTE = new Property<String>("serverAttribute");
+    public static final Property<LocalTime> TIME_ATTRIBUTE = new Property<LocalTime>("timeAttribute");
+    public static final Property<LocalDateTime> TIMESTAMP_ATTRIBUTE = new Property<LocalDateTime>("timestampAttribute");
+    public static final Property<List<MtTable2>> TABLE2ARRAY = new Property<List<MtTable2>>("table2Array");
+
+    public void setDateAttribute(LocalDate dateAttribute) {
+        writeProperty("dateAttribute", dateAttribute);
+    }
+    public LocalDate getDateAttribute() {
+        return (LocalDate)readProperty("dateAttribute");
+    }
+
+    public void setGlobalAttribute(String globalAttribute) {
+        writeProperty("globalAttribute", globalAttribute);
+    }
+    public String getGlobalAttribute() {
+        return (String)readProperty("globalAttribute");
+    }
+
+    public void setOldDateAttribute(Date oldDateAttribute) {
+        writeProperty("oldDateAttribute", oldDateAttribute);
+    }
+    public Date getOldDateAttribute() {
+        return (Date)readProperty("oldDateAttribute");
+    }
+
+    public void setServerAttribute(String serverAttribute) {
+        writeProperty("serverAttribute", serverAttribute);
+    }
+    public String getServerAttribute() {
+        return (String)readProperty("serverAttribute");
+    }
+
+    public void setTimeAttribute(LocalTime timeAttribute) {
+        writeProperty("timeAttribute", timeAttribute);
+    }
+    public LocalTime getTimeAttribute() {
+        return (LocalTime)readProperty("timeAttribute");
+    }
+
+    public void setTimestampAttribute(LocalDateTime timestampAttribute) {
+        writeProperty("timestampAttribute", timestampAttribute);
+    }
+    public LocalDateTime getTimestampAttribute() {
+        return (LocalDateTime)readProperty("timestampAttribute");
+    }
+
+    public void addToTable2Array(MtTable2 obj) {
+        addToManyTarget("table2Array", obj, true);
+    }
+    public void removeFromTable2Array(MtTable2 obj) {
+        removeToManyTarget("table2Array", obj, true);
+    }
+    @SuppressWarnings("unchecked")
+    public List<MtTable2> getTable2Array() {
+        return (List<MtTable2>)readProperty("table2Array");
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783be1f/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/persistent/auto/_MtTable2.java
----------------------------------------------------------------------
diff --git a/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/persistent/auto/_MtTable2.java
b/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/persistent/auto/_MtTable2.java
new file mode 100644
index 0000000..682e272
--- /dev/null
+++ b/cayenne-protostuff/src/test/java/org/apache/cayenne/rop/protostuff/persistent/auto/_MtTable2.java
@@ -0,0 +1,38 @@
+package org.apache.cayenne.rop.protostuff.persistent.auto;
+
+import org.apache.cayenne.CayenneDataObject;
+import org.apache.cayenne.exp.Property;
+import org.apache.cayenne.rop.protostuff.persistent.MtTable1;
+
+/**
+ * Class _MtTable2 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 _MtTable2 extends CayenneDataObject {
+
+    private static final long serialVersionUID = 1L; 
+
+    public static final String TABLE2_ID_PK_COLUMN = "TABLE2_ID";
+
+    public static final Property<String> GLOBAL_ATTRIBUTE = new Property<String>("globalAttribute");
+    public static final Property<MtTable1> TABLE1 = new Property<MtTable1>("table1");
+
+    public void setGlobalAttribute(String globalAttribute) {
+        writeProperty("globalAttribute", globalAttribute);
+    }
+    public String getGlobalAttribute() {
+        return (String)readProperty("globalAttribute");
+    }
+
+    public void setTable1(MtTable1 table1) {
+        setToOneTarget("table1", table1, true);
+    }
+
+    public MtTable1 getTable1() {
+        return (MtTable1)readProperty("table1");
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783be1f/cayenne-protostuff/src/test/resources/cayenne-protostuff.xml
----------------------------------------------------------------------
diff --git a/cayenne-protostuff/src/test/resources/cayenne-protostuff.xml b/cayenne-protostuff/src/test/resources/cayenne-protostuff.xml
new file mode 100644
index 0000000..3d2049e
--- /dev/null
+++ b/cayenne-protostuff/src/test/resources/cayenne-protostuff.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<domain project-version="8">
+	<map name="protostuff"/>
+</domain>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783be1f/cayenne-protostuff/src/test/resources/protostuff.map.xml
----------------------------------------------------------------------
diff --git a/cayenne-protostuff/src/test/resources/protostuff.map.xml b/cayenne-protostuff/src/test/resources/protostuff.map.xml
new file mode 100644
index 0000000..373b84e
--- /dev/null
+++ b/cayenne-protostuff/src/test/resources/protostuff.map.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<data-map xmlns="http://cayenne.apache.org/schema/8/modelMap"
+	 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	 xsi:schemaLocation="http://cayenne.apache.org/schema/8/modelMap http://cayenne.apache.org/schema/8/modelMap.xsd"
+	 project-version="8">
+	<property name="defaultPackage" value="org.apache.cayenne.rop.protostuff.persistent"/>
+	<property name="clientSupported" value="true"/>
+	<property name="defaultClientPackage" value="org.apache.cayenne.rop.protostuff.persistent"/>
+	<db-entity name="MT_TABLE1">
+		<db-attribute name="DATE_ATTRIBUTE" type="DATE"/>
+		<db-attribute name="GLOBAL_ATTRIBUTE" type="VARCHAR" length="100"/>
+		<db-attribute name="OLD_DATE_ATTRIBUTE" type="TIMESTAMP"/>
+		<db-attribute name="SERVER_ATTRIBUTE" type="VARCHAR" length="100"/>
+		<db-attribute name="TABLE1_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+		<db-attribute name="TIMESTAMP_ATTRIBUTE" type="TIMESTAMP"/>
+		<db-attribute name="TIME_ATTRIBUTE" type="TIME"/>
+	</db-entity>
+	<db-entity name="MT_TABLE2">
+		<db-attribute name="GLOBAL_ATTRIBUTE" type="VARCHAR" length="100"/>
+		<db-attribute name="TABLE1_ID" type="INTEGER"/>
+		<db-attribute name="TABLE2_ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+	</db-entity>
+	<obj-entity name="MtTable1" className="org.apache.cayenne.rop.protostuff.persistent.MtTable1"
clientClassName="org.apache.cayenne.rop.protostuff.persistent.ClientMtTable1" dbEntityName="MT_TABLE1">
+		<obj-attribute name="dateAttribute" type="java.time.LocalDate" db-attribute-path="DATE_ATTRIBUTE"/>
+		<obj-attribute name="globalAttribute" type="java.lang.String" db-attribute-path="GLOBAL_ATTRIBUTE"/>
+		<obj-attribute name="oldDateAttribute" type="java.util.Date" db-attribute-path="OLD_DATE_ATTRIBUTE"/>
+		<obj-attribute name="serverAttribute" type="java.lang.String" db-attribute-path="SERVER_ATTRIBUTE"/>
+		<obj-attribute name="timeAttribute" type="java.time.LocalTime" db-attribute-path="TIME_ATTRIBUTE"/>
+		<obj-attribute name="timestampAttribute" type="java.time.LocalDateTime" db-attribute-path="TIMESTAMP_ATTRIBUTE"/>
+	</obj-entity>
+	<obj-entity name="MtTable2" className="org.apache.cayenne.rop.protostuff.persistent.MtTable2"
clientClassName="org.apache.cayenne.rop.protostuff.persistent.ClientMtTable2" dbEntityName="MT_TABLE2">
+		<obj-attribute name="globalAttribute" type="java.lang.String" db-attribute-path="GLOBAL_ATTRIBUTE"/>
+	</obj-entity>
+	<db-relationship name="table2Array" source="MT_TABLE1" target="MT_TABLE2" toMany="true">
+		<db-attribute-pair source="TABLE1_ID" target="TABLE1_ID"/>
+	</db-relationship>
+	<db-relationship name="table1" source="MT_TABLE2" target="MT_TABLE1" toMany="false">
+		<db-attribute-pair source="TABLE1_ID" target="TABLE1_ID"/>
+	</db-relationship>
+	<obj-relationship name="table2Array" source="MtTable1" target="MtTable2" deleteRule="Deny"
db-relationship-path="table2Array"/>
+	<obj-relationship name="table1" source="MtTable2" target="MtTable1" deleteRule="Nullify"
db-relationship-path="table1"/>
+</data-map>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783be1f/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index a547108..a68e6b5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -64,7 +64,7 @@
 		<module>plugins</module>
 		<module>tutorials</module>
 		<module>docs</module>
-    </modules>
+	</modules>
 	<issueManagement>
 		<system>jira</system>
 		<url>https://issues.apache.org/jira/browse/CAY</url>
@@ -1457,7 +1457,8 @@
 			</activation>
 			<modules>
 				<module>cayenne-java8</module>
-                <module>assembly</module>
+				<module>cayenne-protostuff</module>
+				<module>assembly</module>
 			</modules>
 		</profile>
 	</profiles>


Mime
View raw message