cayenne-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ntimof...@apache.org
Subject [07/11] cayenne git commit: CAY-2371 Switch documentation from Docbook to Asciidoctor format
Date Fri, 05 Jan 2018 14:21:35 GMT
http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part2/adding.adoc
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part2/adding.adoc b/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part2/adding.adoc
new file mode 100644
index 0000000..0a9ef94
--- /dev/null
+++ b/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part2/adding.adoc
@@ -0,0 +1,129 @@
+// 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.
+
+=== Adding BASIC Authentication
+
+You probably don't want everybody in the world to connect to your service and access (and update!) arbitrary data in the database. The first step in securing Cayenne service is implementing client authentication. The easiest way to do it is to delegate the authentication task to the web container that is running the service. HessianConnection used in the previous chapter supports BASIC authentication on the client side, so we'll demonstrate how to set it up here.
+
+==== Securing ROP Server Application
+
+Open web.xml file in the server project and setup security constraints with BASIC authentication for the ROP service:
+
+[source, XML]
+----
+<security-constraint>
+    <web-resource-collection>
+        <web-resource-name>CayenneService</web-resource-name>
+        <url-pattern>/cayenne-service</url-pattern>
+    </web-resource-collection>
+    <auth-constraint>
+        <role-name>cayenne-service-user</role-name>
+    </auth-constraint>
+</security-constraint>
+
+<login-config>
+    <auth-method>BASIC</auth-method>
+    <realm-name>Cayenne Realm</realm-name>
+</login-config>
+
+<security-role>
+    <role-name>cayenne-service-user</role-name>
+</security-role>
+----
+
+==== Configuring Jetty for BASIC Authentication
+
+NOTE: These instructions are specific to Jetty 6. Other containers (and versions of Jetty) will have different mechansims to achieve the same thing.
+
+Open pom.xml in the server project and configure a "userRealm" for the Jetty plugin:
+
+[source, XML]
+----
+<plugin>
+    <groupId>org.mortbay.jetty</groupId>
+        <artifactId>maven-jetty-plugin</artifactId>
+        <version>6.1.22</version>
+        <!-- adding configuration below: -->
+        <configuration>
+            <userRealms>
+                <userRealm implementation="org.mortbay.jetty.security.HashUserRealm">
+                    <!-- this name must match the realm-name in web.xml -->
+                    <name>Cayenne Realm</name>
+                    <config>realm.properties</config>
+                </userRealm>
+            </userRealms>
+        </configuration>
+    </plugin>
+</plugins>
+----
+
+Now create a new file called {["realm.properties"}} at the root of the server project and put user login/password in there:
+
+[source]
+----
+cayenne-user: secret,cayenne-service-user
+----
+
+Now let's stop the server and start it again. Everything should start as before, but if you go to http://localhost:8080/tutorial/cayenne-service, your browser should pop up authentication dialog. Enter "cayenne-user/secret" for user name / password, and you should see "Hessian Requires POST" message. So the server is now secured.
+
+==== Running Client with Basic Authentication
+
+If you run the client without any changes, you'll get the following error:
+
+[source]
+----
+org.apache.cayenne.remote.hessian.HessianConnection connect
+INFO: Connecting to [http://localhost:8080/tutorial/cayenne-service] - dedicated session.
+org.apache.cayenne.remote.hessian.HessianConnection connect
+INFO: Error establishing remote session. URL - http://localhost:8080/tutorial/cayenne-service;
+      CAUSE - cannot retry due to server authentication, in streaming mode
+java.net.HttpRetryException: cannot retry due to server authentication, in streaming mode
+    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1257)
+    at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:379)
+    at com.caucho.hessian.client.HessianProxy.invoke(HessianProxy.java:168)
+    at $Proxy0.establishSession(Unknown Source)
+    at org.apache.cayenne.remote.hessian.HessianConnection.connect(HessianConnection.java:210)
+    at org.apache.cayenne.remote.hessian.HessianConnection.getServerEventBridge(HessianConnection.java:114)
+    at org.apache.cayenne.remote.ClientChannel.setupRemoteChannelListener(ClientChannel.java:337)
+    at org.apache.cayenne.remote.ClientChannel.<init>(ClientChannel.java:108)
+    at org.example.cayenne.Main.main(Main.java:25)
+Exception in thread "main" org.apache.cayenne.CayenneRuntimeException: [v.3.1M3 Sep 19 2011 07:12:41]
+Error establishing remote session. URL - http://localhost:8080/tutorial/cayenne-service;
+CAUSE - cannot retry due to server authentication, in streaming mode
+    at org.apache.cayenne.remote.hessian.HessianConnection.connect(HessianConnection.java:229)
+    at org.apache.cayenne.remote.hessian.HessianConnection.getServerEventBridge(HessianConnection.java:114)
+    at org.apache.cayenne.remote.ClientChannel.setupRemoteChannelListener(ClientChannel.java:337)
+    at org.apache.cayenne.remote.ClientChannel.<init>(ClientChannel.java:108)
+    at org.example.cayenne.Main.main(Main.java:25)
+Caused by: java.net.HttpRetryException: cannot retry due to server authentication, in streaming mode
+    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1257)
+    at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:379)
+    at com.caucho.hessian.client.HessianProxy.invoke(HessianProxy.java:168)
+    at $Proxy0.establishSession(Unknown Source)
+    at org.apache.cayenne.remote.hessian.HessianConnection.connect(HessianConnection.java:210)
+    ... 4 more
+----
+
+Which is exactly what you'd expect, as the client is not authenticating itself. So change the line in Main.java where we obtained an ROP connection to this:
+
+[source, java]
+----
+ClientConnection connection = new HessianConnection(
+        "http://localhost:8080/tutorial/cayenne-service",
+        "cayenne-user", "secret", null);
+----
+
+Try running again, and everything should work as before. Obviously in production environment, in addition to authentication you'll need to use HTTPS to access the server to prevent third-party eavesdropping on your password and data.
+
+Congratulations, you are done with the ROP tutorial!

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part2/connect.adoc
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part2/connect.adoc b/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part2/connect.adoc
new file mode 100644
index 0000000..14e4263
--- /dev/null
+++ b/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part2/connect.adoc
@@ -0,0 +1,176 @@
+// 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.
+
+=== Porting Existing Code to Connect to a Web Service Instead of a Database
+
+==== Starting Command Line Client
+
+One of the benefits of ROP is that the client code is no different from the server code - it uses the same ObjectContext interface for access, same query and commit API. So the code below will be similar to the code presented in the first Cayenne Getting Started Guide, although with a few ROP-specific parts required to bootstrap the ObjectContext.
+
+Let's start by creating an empty Main class with the standard main() method in the client project:
+
+[source, java]
+----
+package org.example.cayenne.persistent.client;
+
+public class Main {
+
+    public static void main(String[] args) {
+
+    }
+}
+----
+
+Now the part that is actually different from regular Cayenne - establishing the server connection and obtaining the ObjectContext:
+
+[source, java]
+----
+ClientConnection connection = new HessianConnection("http://localhost:8080/tutorial/cayenne-service");
+DataChannel channel = new ClientChannel(connection, false, new DefaultEventManager(), false);
+ObjectContext context = new CayenneContext(channel);
+----
+
+Note that the "channel" can be used to create as many peer ObjectContexts as needed over the same connection, while ObjectContext is a kind of isolated "persistence session", similar to the server-side context. A few more notes. Since we are using HTTP(S) to communicate with ROP server, there's no need to explicitly close the connection (or channel, or context).
+
+So now let's do the same persistent operaions that we did in the first tutorial "Main" class. Let's start by creating and saving some objects:
+
+[source, java]
+----
+// creating new Artist
+Artist picasso = context.newObject(Artist.class);
+picasso.setName("Pablo Picasso");
+
+// Creating other objects
+Gallery metropolitan = context.newObject(Gallery.class);
+metropolitan.setName("Metropolitan Museum of Art");
+
+Painting girl = context.newObject(Painting.class);
+girl.setName("Girl Reading at a Table");
+
+Painting stein = context.newObject(Painting.class);
+stein.setName("Gertrude Stein");
+
+// connecting objects together via relationships
+picasso.addToPaintings(girl);
+picasso.addToPaintings(stein);
+
+girl.setGallery(metropolitan);
+stein.setGallery(metropolitan);
+
+// saving all the changes above
+context.commitChanges();
+----
+
+Now let's select them back:
+
+[source, java]
+----
+// SelectQuery examples
+SelectQuery select1 = new SelectQuery(Painting.class);
+List<Painting> paintings1 = context.performQuery(select1);
+
+Expression qualifier2 = ExpressionFactory.likeIgnoreCaseExp(
+        Painting.NAME_PROPERTY, "gi%");
+SelectQuery select2 = new SelectQuery(Painting.class, qualifier2);
+List<Painting> paintings2 = context.performQuery(select2);
+----
+
+Now, delete:
+
+[source, java]
+----
+Expression qualifier = ExpressionFactory.matchExp(Artist.NAME_PROPERTY,
+                "Pablo Picasso");
+SelectQuery selectToDelete = new SelectQuery(Artist.class, qualifier);
+Artist picasso = (Artist) DataObjectUtils.objectForQuery(context,
+        selectToDelete);
+
+if (picasso != null) {
+    context.deleteObject(picasso);
+    context.commitChanges();
+}
+----
+
+This code is exactly the same as in the first tutorial. So now let's try running the client and see what happens. In Eclipse open main class and select "Run > Run As > Java Application" from the menu (assuming the ROP server started in the previous step is still running). You will some output in both server and client process consoles. Client:
+
+[source]
+----
+INFO: Connecting to [http://localhost:8080/tutorial/cayenne-service] - dedicated session.
+INFO: === Connected, session: org.apache.cayenne.remote.RemoteSession@26544ec1[sessionId=17uub1h34r9x1] - took 111 ms.
+INFO: --- Message 0: Bootstrap
+INFO: === Message 0: Bootstrap done - took 58 ms.
+INFO: --- Message 1: flush-cascade-sync
+INFO: === Message 1: flush-cascade-sync done - took 1119 ms.
+INFO: --- Message 2: Query
+INFO: === Message 2: Query done - took 48 ms.
+INFO: --- Message 3: Query
+INFO: === Message 3: Query done - took 63 ms.
+INFO: --- Message 4: Query
+INFO: === Message 4: Query done - took 19 ms.
+INFO: --- Message 5: Query
+INFO: === Message 5: Query done - took 7 ms.
+INFO: --- Message 6: Query
+INFO: === Message 6: Query done - took 5 ms.
+INFO: --- Message 7: Query
+INFO: === Message 7: Query done - took 2 ms.
+INFO: --- Message 8: Query
+INFO: === Message 8: Query done - took 4 ms.
+INFO: --- Message 9: flush-cascade-sync
+INFO: === Message 9: flush-cascade-sync done - took 34 ms.
+----
+
+As you see client prints no SQL statmenets, just a bunch of query and flush messages sent to the server. The server side is more verbose, showing the actual client queries executed against the database:
+
+[source]
+----
+...
+INFO: SELECT NEXT_ID FROM AUTO_PK_SUPPORT WHERE TABLE_NAME = ? FOR UPDATE [bind: 1:'ARTIST']
+INFO: SELECT NEXT_ID FROM AUTO_PK_SUPPORT WHERE TABLE_NAME = ? FOR UPDATE [bind: 1:'GALLERY']
+INFO: SELECT NEXT_ID FROM AUTO_PK_SUPPORT WHERE TABLE_NAME = ? FOR UPDATE [bind: 1:'PAINTING']
+INFO: INSERT INTO ARTIST (DATE_OF_BIRTH, ID, NAME) VALUES (?, ?, ?)
+INFO: [batch bind: 1->DATE_OF_BIRTH:NULL, 2->ID:200, 3->NAME:'Pablo Picasso']
+INFO: === updated 1 row.
+INFO: INSERT INTO GALLERY (ID, NAME) VALUES (?, ?)
+INFO: [batch bind: 1->ID:200, 2->NAME:'Metropolitan Museum of Art']
+INFO: === updated 1 row.
+INFO: INSERT INTO PAINTING (ARTIST_ID, GALLERY_ID, ID, NAME) VALUES (?, ?, ?, ?)
+INFO: [batch bind: 1->ARTIST_ID:200, 2->GALLERY_ID:200, 3->ID:200, 4->NAME:'Girl Reading at a Table']
+INFO: [batch bind: 1->ARTIST_ID:200, 2->GALLERY_ID:200, 3->ID:201, 4->NAME:'Gertrude Stein']
+INFO: === updated 2 rows.
+INFO: +++ transaction committed.
+INFO: --- transaction started.
+INFO: SELECT t0.GALLERY_ID, t0.NAME, t0.ARTIST_ID, t0.ID FROM PAINTING t0
+INFO: === returned 2 rows. - took 14 ms.
+INFO: +++ transaction committed.
+INFO: --- transaction started.
+INFO: SELECT t0.GALLERY_ID, t0.NAME, t0.ARTIST_ID, t0.ID FROM PAINTING t0
+      WHERE UPPER(t0.NAME) LIKE UPPER(?) [bind: 1->NAME:'gi%']
+INFO: === returned 1 row. - took 10 ms.
+INFO: +++ transaction committed.
+INFO: --- transaction started.
+INFO: SELECT t0.DATE_OF_BIRTH, t0.NAME, t0.ID FROM ARTIST t0 WHERE t0.NAME = ? [bind: 1->NAME:'Pablo Picasso']
+INFO: === returned 1 row. - took 8 ms.
+INFO: +++ transaction committed.
+INFO: --- transaction started.
+INFO: DELETE FROM PAINTING WHERE ID = ?
+INFO: [batch bind: 1->ID:200]
+INFO: [batch bind: 1->ID:201]
+INFO: === updated 2 rows.
+INFO: DELETE FROM ARTIST WHERE ID = ?
+INFO: [batch bind: 1->ID:200]
+INFO: === updated 1 row.
+INFO: +++ transaction committed.
+----
+
+You are done with the basic ROP client!
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part2/hessianWebServ.adoc
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part2/hessianWebServ.adoc b/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part2/hessianWebServ.adoc
new file mode 100644
index 0000000..cf140ec
--- /dev/null
+++ b/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part2/hessianWebServ.adoc
@@ -0,0 +1,113 @@
+// 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.
+
+===  Setting up Hessian Web Service
+
+==== Setting up Dependencies
+
+Now lets get back to the "tutorial" project that contains a web application and set up dependencies. The only extra one that we don't have yet is resin-hessian.jar, just like the client, so let's add it (and the caucho repo declaration) to the pom.xml.
+
+[source, XML]
+----
+<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">
+    ...
+    <dependencies>
+        ...
+        <dependency>
+            <groupId>com.caucho</groupId>
+            <artifactId>resin-hessian</artifactId>
+            <version>3.1.6</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+    ...
+    </build>
+
+    <repositories>
+        <repository>
+            <id>caucho</id>
+            <name>Caucho Repository</name>
+            <url>http://caucho.com/m2</url>
+            <layout>default</layout>
+            <snapshots>
+                <enabled>false</enabled>
+            </snapshots>
+            <releases>
+                <enabled>true</enabled>
+            </releases>
+        </repository>
+    </repositories>
+    </project>
+----
+
+NOTE: *Maven Optimization Hint* On a real project both server and client modules will likely share a common parent pom.xml where common repository delcaration can be placed, with child pom's "inheriting" it from parent. This would reduce build code duplication.
+
+==== Client Classes on the Server
+
+Since ROP web service requires both server and client persistent classes, we need to generate a second copy of the client classes inside the server project. This is a minor inconvenience that will hopefully go away in the future versions of Cayenne. Don't forget to refresh the project in Eclipse after class generation is done.
+
+==== Configuring web.xml
+
+Cayenne web service is declared in the web.xml. It is implemented as a servlet "org.apache.cayenne.rop.ROPServlet". Open tutorial/src/main/webapp/WEB-INF/web.xml in Eclipse and add a service declaration:
+
+[source, XML]
+----
+<?xml version="1.0" encoding="utf-8"?>
+ <!DOCTYPE web-app
+   PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+   "http://java.sun.com/dtd/web-app_2_3.dtd">
+<web-app>
+    <display-name>Cayenne Tutorial</display-name>
+    <servlet>
+        <servlet-name>cayenne-project</servlet-name>
+        <servlet-class>org.apache.cayenne.configuration.rop.server.ROPHessianServlet</servlet-class>
+        <load-on-startup>0</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>cayenne-project</servlet-name>
+        <url-pattern>/cayenne-service</url-pattern>
+    </servlet-mapping>
+    </web-app>
+----
+
+NOTE: *Extending Server Behavior via Callbacks* While no custom Java code is required on the server, just a service declaration, it is possible to customizing server-side behavior via callbacks and listeners (not shown in the tutorial).
+
+==== Running ROP Server
+
+Use previosly created Eclipse Jetty run configuration available via "Run > Run Configurations..." (or create a new one if none exists yet). You should see output in the Eclipse console similar to the following:
+
+[source]
+----
+[INFO] Scanning for projects...
+[INFO]
+[INFO] ------------------------------------------------------------------------
+[INFO] Building tutorial 0.0.1-SNAPSHOT
+[INFO] ------------------------------------------------------------------------
+...
+[INFO] Starting jetty 6.1.22 ...
+INFO::jetty-6.1.22
+INFO::No Transaction manager found - if your webapp requires one, please configure one.
+INFO::Started SelectChannelConnector@0.0.0.0:8080
+[INFO] Started Jetty Server
+INFO: Loading XML configuration resource from file:cayenne-project.xml
+INFO: loading user name and password.
+INFO: Created connection pool: jdbc:derby:memory:testdb;create=true
+    Driver class: org.apache.derby.jdbc.EmbeddedDriver
+    Min. connections in the pool: 1
+    Max. connections in the pool: 1
+----
+
+Cayenne ROP service URL is http://localhost:8080/tutorial/cayenne-service. If you click on it, you will see "Hessian Requires POST" message, that means that the service is alive, but you need a client other than the web browser to access it.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part2/starting.adoc
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part2/starting.adoc b/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part2/starting.adoc
new file mode 100644
index 0000000..47638dc
--- /dev/null
+++ b/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/part2/starting.adoc
@@ -0,0 +1,93 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to you under the Apache License, Version
+// 2.0 (the "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0 Unless required by
+// applicable law or agreed to in writing, software distributed under the
+// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+// CONDITIONS OF ANY KIND, either express or implied. See the License for
+// the specific language governing permissions and limitations under the
+// License.
+
+include::../var.adoc[]
+
+=== Starting Client Project
+
+==== Create an ROP Client Project in Eclipse
+
+Creation of a new Eclipse project has been discussed in some details in "Getting Started with Cayenne" guide, so we will omit the screenshots for the common parts.
+
+In Eclipse select "File > New > Other..." and then "Maven > Maven Project". Click "Next". On the following screen check "Create a simple project" checkbox and click "Next" again. In the dialog shown on the screenshot below, enter "org.example.cayenne" for the "Group Id" and "tutorial-rop-client" for the "Artifact Id" (both without the quotes) and click "Finish".
+
+Now you should have a new empty project in the Eclipse workspace. Check that the project Java compiler settings are correct. Rightclick on the "tutorial-rop-client" project, select "Properties > Java Compiler" and ensure that "Compiler compliance level" is at least 1.5 (some versions of Maven plugin seem to be setting it to 1.4 by default).
+
+==== Create Client Java Classes
+
+The client doesn't need the XML ORM mapping, as it is loaded from the server. However it needs the client-side Java classes. Let's generate them from the existing mapping:
+
+* Start CayenneModeler and open cayenne.xml from the "tutorial" project (located under "tutorial/src/main/resources", unless it is already open.
+
+* Select the "datamap" DataMap and check "Allow Client Entities" checkbox.
+
+* Enter "org.example.cayenne.persistent.client" for the "Client Java Package" and click "Update.." button next to the field to refresh the client package of all entities.
+
+image::../images/datamap-enableclient.png[align="center"]
+
+* Select "Tools > Generate Classes" menu.
+
+* For "Type" select "Client Persistent Objects".
+
+* For the "Output Directory" select "tutorial-rop-client/src/main/java" folder (as client classes should go in the client project).
+
+* Click on "Classes" tab and check the "Check All Classes" checkbox (unless it is already checked and reads "Uncheck all Classes").
+
+* Click "Generate".
+
+Now go back to Eclipse, right click on "tutorial-rop-client" project and select "Refresh" - you should see pairs of classes generated for each mapped entity, same as on the server. And again, we see a bunch of errors in those classes. Let's fix it now by adding two dependencies, "cayenne-client" and "resin-hessian", in the bottom of the pom.xml file. We also need to add Caucho M2 repository to pull Hessian jar files. The resulting POM should look like this:
+
+[source, XML,subs="verbatim,attributes"]
+----
+<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>
+    <groupId>org.example.cayenne</groupId>
+    <artifactId>tutorial-rop-client</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cayenne</groupId>
+            <artifactId>cayenne-client</artifactId>
+            <!-- Here specify the version of Cayenne you are actually using -->
+            <version>{version}</version>
+        </dependency>
+        <dependency>
+        <groupId>com.caucho</groupId>
+            <artifactId>resin-hessian</artifactId>
+            <version>3.1.6</version>
+        </dependency>
+    </dependencies>
+
+   <repositories>
+           <repository>
+               <id>caucho</id>
+               <name>Caucho Repository</name>
+               <url>http://caucho.com/m2</url>
+               <layout>default</layout>
+               <snapshots>
+                   <enabled>false</enabled>
+               </snapshots>
+               <releases>
+                   <enabled>true</enabled>
+               </releases>
+           </repository>
+       </repositories>
+</project>
+----
+
+Your computer must be connected to the internet. Once you save the pom.xml, Eclipse will download the needed jar files and add them to the project build path. After that all the errors should disappear.
+
+Now let's check the entity class pairs. They look almost identical to their server counterparts, although the superclass and the property access code are different. At this point these differences are somewhat academic, so let's go on with the tutorial.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/var.adoc
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/var.adoc b/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/var.adoc
new file mode 100644
index 0000000..e575eda
--- /dev/null
+++ b/docs/asciidoc/getting-started-rop/src/docs/asciidoc/_getting-started-rop/var.adoc
@@ -0,0 +1 @@
+:version: {project-version}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/docs/asciidoc/getting-started-rop/src/docs/asciidoc/getting-started-rop.adoc
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-rop/src/docs/asciidoc/getting-started-rop.adoc b/docs/asciidoc/getting-started-rop/src/docs/asciidoc/getting-started-rop.adoc
new file mode 100644
index 0000000..9362783
--- /dev/null
+++ b/docs/asciidoc/getting-started-rop/src/docs/asciidoc/getting-started-rop.adoc
@@ -0,0 +1,45 @@
+// 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.
+= Getting Started with Cayenne ROP (Remote Object Persistence)
+:revnumber: {project-major-version} ({project-version})
+// enable section numbering, limiting depth to 2
+:sectnums:
+:sectnumlevels: 2
+// use custom header
+:cayenne-header: _getting_started_rop/header.html
+:cayenne-header-position: body
+// customize final layout
+//:linkcss:
+// base path to java code include
+:cayenne-root: {basedir}/../../..
+
+[small]#Copyright © 2011-2017 Apache Software Foundation and individual authors#
+
+.License
+[small]#_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_#
+
+[small]#_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._#
+
+include::_getting-started-rop/part1.adoc[]
+
+include::_getting-started-rop/part2.adoc[]
+
+
+

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/docs/asciidoc/getting-started-rop/src/docs/asciidoc/images/datamap-enableclient.png
----------------------------------------------------------------------
diff --git a/docs/asciidoc/getting-started-rop/src/docs/asciidoc/images/datamap-enableclient.png b/docs/asciidoc/getting-started-rop/src/docs/asciidoc/images/datamap-enableclient.png
new file mode 100644
index 0000000..62a2af2
Binary files /dev/null and b/docs/asciidoc/getting-started-rop/src/docs/asciidoc/images/datamap-enableclient.png differ

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/docs/asciidoc/pom.xml
----------------------------------------------------------------------
diff --git a/docs/asciidoc/pom.xml b/docs/asciidoc/pom.xml
new file mode 100644
index 0000000..81b0660
--- /dev/null
+++ b/docs/asciidoc/pom.xml
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.apache.cayenne.parents</groupId>
+        <artifactId>cayenne-docs-parent</artifactId>
+        <version>3.1.3-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>cayenne-asciidoc-parent</artifactId>
+    <groupId>org.apache.cayenne.docs</groupId>
+    <name>cayenne-asciidoc: Cayenne AsciiDoc Documentation parent</name>
+    <modelVersion>4.0.0</modelVersion>
+    <packaging>pom</packaging>
+
+    <modules>
+        <module>cayenne-asciidoc-extension</module>
+        <module>getting-started-guide</module>
+        <module>cayenne-guide</module>
+        <module>getting-started-rop</module>
+        <module>upgrade-guide</module>
+    </modules>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <asciidoctorj.version>1.5.6</asciidoctorj.version>
+        <asciidoctor.maven.plugin.version>1.5.6</asciidoctor.maven.plugin.version>
+        <asciidoctorj.pdf.version>1.5.0-alpha.16</asciidoctorj.pdf.version>
+        <jruby.version>1.7.26</jruby.version>
+        <cayenne.major.version>3.1</cayenne.major.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cayenne</groupId>
+            <artifactId>cayenne-server</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.asciidoctor</groupId>
+            <artifactId>asciidoctorj</artifactId>
+            <version>${asciidoctorj.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <groupId>org.asciidoctor</groupId>
+                    <artifactId>asciidoctor-maven-plugin</artifactId>
+                    <version>${asciidoctor.maven.plugin.version}</version>
+                    <dependencies>
+                        <dependency>
+                            <groupId>org.asciidoctor</groupId>
+                            <artifactId>asciidoctorj-pdf</artifactId>
+                            <version>${asciidoctorj.pdf.version}</version>
+                        </dependency>
+                    </dependencies>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+
+        <plugins>
+            <plugin>
+                <groupId>org.asciidoctor</groupId>
+                <artifactId>asciidoctor-maven-plugin</artifactId>
+                <configuration>
+                    <sourceDirectory>src/docs/asciidoc</sourceDirectory>
+                    <doctype>book</doctype>
+                    <!-- Attributes common to all output formats -->
+                    <attributes>
+                        <endpoint-url>http://cayenne.apache.org</endpoint-url>
+
+                        <basedir>${project.basedir}</basedir>
+                        <sourcedir>${project.build.sourceDirectory}</sourcedir>
+                        <project-version>${project.version}</project-version>
+                        <project-major-version>${cayenne.major.version}</project-major-version>
+
+                        <imagesdir>images</imagesdir>
+                        <icons>font</icons>
+
+                        <sectanchors>true</sectanchors>
+                        <idprefix/> <!-- set the idprefix to blank -->
+                        <idseparator>-</idseparator>
+                        <!--
+                        currently it is not possible to specify header location inside final document, so can't use
+                        asciidoc's *-docinfo.html as header, instead we use extension that deal with our header
+                         -->
+                        <!--<docinfo>private</docinfo1>-->
+                    </attributes>
+                </configuration>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.jruby</groupId>
+                        <artifactId>jruby-complete</artifactId>
+                        <version>${jruby.version}</version>
+                    </dependency>
+                </dependencies>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>1.7</source>
+                    <target>1.7</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/docs/asciidoc/upgrade-guide/pom.xml
----------------------------------------------------------------------
diff --git a/docs/asciidoc/upgrade-guide/pom.xml b/docs/asciidoc/upgrade-guide/pom.xml
new file mode 100644
index 0000000..f22ea3d
--- /dev/null
+++ b/docs/asciidoc/upgrade-guide/pom.xml
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.apache.cayenne.parents</groupId>
+        <artifactId>cayenne-asciidoc-parent</artifactId>
+        <version>3.1.3-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>upgrade-guide</artifactId>
+
+    <packaging>jar</packaging>
+    <name>upgrade-guide: Cayenne 3.1 New Features and Upgrade Guide</name>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.asciidoctor</groupId>
+                <artifactId>asciidoctor-maven-plugin</artifactId>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.apache.cayenne.docs</groupId>
+                        <artifactId>cayenne-asciidoc-extension</artifactId>
+                        <version>${project.version}</version>
+                    </dependency>
+                </dependencies>
+
+                <executions>
+                    <!-- generate "embeddable" html content with front matter and without header/footer/styles -->
+                    <execution>
+                        <id>asciidoctor-html-web</id>
+                        <phase>generate-resources</phase>
+                        <goals>
+                            <goal>process-asciidoc</goal>
+                        </goals>
+                        <configuration>
+                            <backend>html5</backend>
+                            <headerFooter>false</headerFooter> <!-- do not generate header and footer -->
+                            <outputDirectory>${project.build.directory}/tmp/</outputDirectory>
+                            <extensions>
+                                <extension>
+                                    <className>org.apache.cayenne.asciidoc.CayennePostProcessor</className>
+                                </extension>
+                            </extensions>
+                            <attributes>
+                                <toc>auto</toc>
+                            </attributes>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <!-- Move images to proper path for site -->
+            <plugin>
+                <artifactId>maven-resources-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>copy docs for site</id>
+                        <phase>install</phase>
+                        <goals>
+                            <goal>copy-resources</goal>
+                        </goals>
+
+                        <configuration>
+                            <outputDirectory>${project.build.directory}/site/</outputDirectory>
+                            <resources>
+                                <resource>
+                                    <directory>${project.build.directory}/tmp/</directory>
+                                    <includes>
+                                        <include>${project.artifactId}.html</include>
+                                        <include>${project.artifactId}.toc.html</include>
+                                    </includes>
+                                </resource>
+                            </resources>
+                        </configuration>
+                    </execution>
+
+                    <execution>
+                        <id>copy images for site</id>
+                        <phase>install</phase>
+                        <goals>
+                            <goal>copy-resources</goal>
+                        </goals>
+
+                        <configuration>
+                            <outputDirectory>${project.build.directory}/site/${project.artifactId}/images/</outputDirectory>
+                            <resources>
+                                <resource>
+                                    <directory>${project.build.directory}/tmp/images/</directory>
+                                    <filtering>true</filtering>
+                                </resource>
+                            </resources>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+    <profiles>
+        <profile>
+            <id>assembly</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.asciidoctor</groupId>
+                        <artifactId>asciidoctor-maven-plugin</artifactId>
+                        <executions>
+                            <!-- generate standalone html help -->
+                            <execution>
+                                <id>asciidoctor-html-standalone</id>
+                                <phase>generate-resources</phase>
+                                <goals>
+                                    <goal>process-asciidoc</goal>
+                                </goals>
+                                <configuration>
+                                    <backend>html5</backend>
+                                    <sourceHighlighter>coderay</sourceHighlighter>
+                                    <embedAssets>true</embedAssets>
+                                    <attributes>
+                                        <toc>left</toc>
+                                    </attributes>
+                                </configuration>
+                            </execution>
+
+                            <!-- generate PDF -->
+                            <execution>
+                                <id>generate-pdf-doc</id>
+                                <phase>generate-resources</phase>
+                                <goals>
+                                    <goal>process-asciidoc</goal>
+                                </goals>
+                                <configuration>
+                                    <backend>pdf</backend>
+                                    <sourceHighlighter>coderay</sourceHighlighter>
+                                    <attributes>
+                                        <pagenums/>
+                                        <toc/>
+                                    </attributes>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/docs/asciidoc/upgrade-guide/src/docs/asciidoc/_upgrade-guide/cayenne-configuration.adoc
----------------------------------------------------------------------
diff --git a/docs/asciidoc/upgrade-guide/src/docs/asciidoc/_upgrade-guide/cayenne-configuration.adoc b/docs/asciidoc/upgrade-guide/src/docs/asciidoc/_upgrade-guide/cayenne-configuration.adoc
new file mode 100644
index 0000000..89e8694
--- /dev/null
+++ b/docs/asciidoc/upgrade-guide/src/docs/asciidoc/_upgrade-guide/cayenne-configuration.adoc
@@ -0,0 +1,47 @@
+// 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.
+
+=== Cayenne Configuration
+
+NOTE: The new DI-based bootstrap and configuration approach is not API-compatible with earlier versions of Cayenne. Make sure you read the `UPGRADE.txt` file for instructions how to upgrade the existing projects.
+
+==== Dependency Injection Container
+
+Cayenne 3.1 runtime stack is built around the ideas of Dependency Injection (DI), making it extremely flexible and easy to extend. It bundles a small, flexible annotations-based DI container to configure its services. The container provides DI services and exposes Cayenne extension points, but does not interfere with other DI containers that may be present in the application. I.e. it is invisible to the users who do not care about advanced Cayenne customization.
+
+==== Bootstrapping Cayenne in Various Environments
+
+Here is a simple example of starting a server-side Cayenne stack:
+
+[source, java]
+----
+ServerRuntime runtime = new ServerRuntime("cayenne-UntitledDomain.xml");
+----
+
+For more detailed examples check the tutorials and other documentation.
+
+==== Configuring Local DataSources, Removal of JNDI Hack
+
+Cayenne 3.1 provides a property-based mechanism to override Modeler DataSource definitions, regardless of whether they are driver configurations, JNDI, DBCP, etc. A quick configuration example is shown below:
+
+[source]
+----
+-Dcayenne.jdbc.driver=com.mysql.jdbc.Driver -Dcayenne.jdbc.url=jdbc:mysql://localhost/mydb \
+-Dcayenne.jdbc.username=user -Dcayenne.jdbc.password=password
+----
+
+For more details and configuration options see javadocs of `org.apache.cayenne.configuration.server.PropertyDataSourceFactory`.
+
+This feature supersedes what was formerly known as "JNDI hack", i.e. JNDI DataSource failover load strategy based on CayenneModeler preferences database. The problem with JNDI hack was unstable and frequently corrupted preferences database, and the need to include hsqldb and cayenne-modeler jars in the runtime.
+

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/docs/asciidoc/upgrade-guide/src/docs/asciidoc/_upgrade-guide/content-structure.adoc
----------------------------------------------------------------------
diff --git a/docs/asciidoc/upgrade-guide/src/docs/asciidoc/_upgrade-guide/content-structure.adoc b/docs/asciidoc/upgrade-guide/src/docs/asciidoc/_upgrade-guide/content-structure.adoc
new file mode 100644
index 0000000..893135a
--- /dev/null
+++ b/docs/asciidoc/upgrade-guide/src/docs/asciidoc/_upgrade-guide/content-structure.adoc
@@ -0,0 +1,26 @@
+// 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.
+
+This guide highlights the new features and changes introduced in 3.1 release. It is a high-level overview. For more details consult *RELEASE-NOTES.txt* file included in each release for the full list of changes, and UPGRADE.txt for the release-specific upgrade instructions.
+
+=== Distribution Contents Structure
+
+Cayenne distribution is made leaner and more modular:
+
+- "cayenne-modeler.jar" is no longer included in the "lib" folder, as it is no longer used for loading local JNDI overrides. Of course "CayenneModeler-the-app" is still included.
+
+- Ashwood library used for commit operation sorting is no longer a third-party dependency. Instead a small subset of the relevant Ashwood classes got included in Cayenne core.
+
+- The following helper modules are split away from Cayenne core: "cayenne-project" and "cayenne-wocompat". They are bundled in CayenneModeler, and are available from the source distribution. They are not included as standalone jars in the binary distribution.
+

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/docs/asciidoc/upgrade-guide/src/docs/asciidoc/_upgrade-guide/features.adoc
----------------------------------------------------------------------
diff --git a/docs/asciidoc/upgrade-guide/src/docs/asciidoc/_upgrade-guide/features.adoc b/docs/asciidoc/upgrade-guide/src/docs/asciidoc/_upgrade-guide/features.adoc
new file mode 100644
index 0000000..f3f4720
--- /dev/null
+++ b/docs/asciidoc/upgrade-guide/src/docs/asciidoc/_upgrade-guide/features.adoc
@@ -0,0 +1,25 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to you under the Apache License, Version
+// 2.0 (the "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0 Unless required by
+// applicable law or agreed to in writing, software distributed under the
+// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+// CONDITIONS OF ANY KIND, either express or implied. See the License for
+// the specific language governing permissions and limitations under the
+// License.
+
+== Guide to 3.1 Features
+
+include::content-structure.adoc[]
+
+include::cayenne-configuration.adoc[]
+
+include::framework.adoc[]
+
+include::modeler.adoc[]
+
+include::lifecycle.adoc[]

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/docs/asciidoc/upgrade-guide/src/docs/asciidoc/_upgrade-guide/framework.adoc
----------------------------------------------------------------------
diff --git a/docs/asciidoc/upgrade-guide/src/docs/asciidoc/_upgrade-guide/framework.adoc b/docs/asciidoc/upgrade-guide/src/docs/asciidoc/_upgrade-guide/framework.adoc
new file mode 100644
index 0000000..0408ee6
--- /dev/null
+++ b/docs/asciidoc/upgrade-guide/src/docs/asciidoc/_upgrade-guide/framework.adoc
@@ -0,0 +1,75 @@
+// 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.
+
+=== Framework API
+
+See UPGRADE.txt for the full list of changes
+
+==== Lifecycle Listener Annotations
+
+Cayenne 3.1 features support for annotations on lifecycle listeners (but not yet on entity callback methods) that simplifies registering listeners via API. Our experience with Cayenne 3.0 shows that mapping listeners in the Modeler doesn't scale well to complex applications, and 3.0 API for mapping the listeners is hard to use. In 3.1 you can annotate listener methods and register multiple callback methods with a single call.
+
+[source, java]
+----
+// declare a listener with annotated methods
+class MyListener {
+    @PostLoad(Entity1.class)
+    @PostPersist(Entity1.class)
+    void postLoad(Object object) {
+        ....
+    }
+}
+
+// register a listener
+ServerRuntime runtime = ..
+MyListener listener = new MyListener();
+runtime.getChannel().getEntityResolver().getCallbackRegistry().addListener(listener);
+----
+
+Moreover, unlike JPA annotations, Cayenne allows to attach a listener to a set of entities not known to the listener upfront, but that are all annotated with some custom annotation:
+
+[source,java]
+----
+class MyListener {
+    @PostLoad(entityAnnotations = CustomAnnotation.class)
+    void postLoad(Object object) {
+        ....
+    }
+}
+----
+
+==== DataChannelFilter for Intercepting DataDomain Operations
+
+Cayenne now features a DataChannelFilter interface that allows to intercept and alter all DataChannel traffic (i.e. selects and commits between a DataContext and DataDomain). It provides a chain of command API very similar to servlet filters. Filters are widely used by "cayenne-lifecyle" extensions and allow to build powerful custom object lifecycle-aware code. To install a filter, the following API is used:
+
+[source, java]
+----
+class MyFilter implement DataChannelFilter { .. }
+
+MyFilter filter = new MyFilter();
+ServerRuntime runtime = ..
+runtime.getDataDomain().addFilter(filter);
+----
+
+Very often filters mark some of their own methods with lifecycle annotations so that certain operations can be triggered by Cayenne inside the scope of filter's onQuery() or onSync() methods. To ensure annotated methods are invoked, filter registration should be combined with listener registration:
+
+[source, java]
+----
+MyFilter filter = new MyFilter();
+ServerRuntime runtime = ..
+runtime.getDataDomain().addFilter(filter);
+runtime.getDataDomain().getEntityResolver().getCallbackRegistry().addListener(filter);
+// noticed that by default runtime.getDataDomain() is equivalent to runtime.getChannel()
+----
+

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/docs/asciidoc/upgrade-guide/src/docs/asciidoc/_upgrade-guide/header.html
----------------------------------------------------------------------
diff --git a/docs/asciidoc/upgrade-guide/src/docs/asciidoc/_upgrade-guide/header.html b/docs/asciidoc/upgrade-guide/src/docs/asciidoc/_upgrade-guide/header.html
new file mode 100644
index 0000000..c5eedd9
--- /dev/null
+++ b/docs/asciidoc/upgrade-guide/src/docs/asciidoc/_upgrade-guide/header.html
@@ -0,0 +1,24 @@
+---
+#  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.
+
+title: "Guide to 3.1 Features"
+description: "This guide highlights the new features and changes introduced in Apache Cayenne 3.1"
+cayenneVersion: "3.1"
+docsMenuTitle: "Upgrade Guide"
+weight: 50
+---

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/docs/asciidoc/upgrade-guide/src/docs/asciidoc/_upgrade-guide/lifecycle.adoc
----------------------------------------------------------------------
diff --git a/docs/asciidoc/upgrade-guide/src/docs/asciidoc/_upgrade-guide/lifecycle.adoc b/docs/asciidoc/upgrade-guide/src/docs/asciidoc/_upgrade-guide/lifecycle.adoc
new file mode 100644
index 0000000..5bc5384
--- /dev/null
+++ b/docs/asciidoc/upgrade-guide/src/docs/asciidoc/_upgrade-guide/lifecycle.adoc
@@ -0,0 +1,18 @@
+// 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.
+
+=== Lifecycle Extensions
+
+Cayenne 3.1 includes an optional cayenne-lifecyle module that implements a few useful extensions based on DataChannelFilters and lifecycle annotations. Those include a concept of a String ID (which is a String URL-friendly representation of ObjectId), support for (de)referencing objects by String ID, String ID-based relationships, annotation-based cache groups invalidation, annotation-based audit of object changes, etc.
+

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/docs/asciidoc/upgrade-guide/src/docs/asciidoc/_upgrade-guide/modeler.adoc
----------------------------------------------------------------------
diff --git a/docs/asciidoc/upgrade-guide/src/docs/asciidoc/_upgrade-guide/modeler.adoc b/docs/asciidoc/upgrade-guide/src/docs/asciidoc/_upgrade-guide/modeler.adoc
new file mode 100644
index 0000000..ea6d48d
--- /dev/null
+++ b/docs/asciidoc/upgrade-guide/src/docs/asciidoc/_upgrade-guide/modeler.adoc
@@ -0,0 +1,20 @@
+// 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.
+
+=== CayenneModeler
+
+==== Java Preferences API
+
+We got rid of HSQLDB-based preferences storage, and are using standard Java Preferences API for the Modeler preferences. This solved a long-standing stability issue with Modeler preferences. So no more lost user preferences.
+

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/docs/asciidoc/upgrade-guide/src/docs/asciidoc/upgrade-guide.adoc
----------------------------------------------------------------------
diff --git a/docs/asciidoc/upgrade-guide/src/docs/asciidoc/upgrade-guide.adoc b/docs/asciidoc/upgrade-guide/src/docs/asciidoc/upgrade-guide.adoc
new file mode 100644
index 0000000..78f0c1c
--- /dev/null
+++ b/docs/asciidoc/upgrade-guide/src/docs/asciidoc/upgrade-guide.adoc
@@ -0,0 +1,44 @@
+// 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.
+= Cayenne New Features and Upgrade Guide
+:revnumber: {project-major-version} ({project-version})
+// enable section numbering, limiting depth to 2
+:sectnums:
+:sectnumlevels: 2
+// use custom header
+:cayenne-header: _upgrade_guide/header.html
+:cayenne-header-position: body
+// customize final layout
+//:linkcss:
+// base path to java code include
+:cayenne-root: {basedir}/../../..
+
+[small]#Copyright © 2011-2017 Apache Software Foundation and individual authors#
+
+.License
+[small]#_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_#
+
+[small]#_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._#
+
+include::_upgrade-guide/features.adoc[]
+
+
+
+

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/docs/docbook/cayenne-guide/pom.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/pom.xml b/docs/docbook/cayenne-guide/pom.xml
deleted file mode 100644
index 0620ff8..0000000
--- a/docs/docbook/cayenne-guide/pom.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?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/xsd/maven-4.0.0.xsd">
-	<parent>
-		<groupId>org.apache.cayenne.docs</groupId>
-		<artifactId>cayenne-docbook</artifactId>
-		<version>3.1.3-SNAPSHOT</version>
-	</parent>
-	<modelVersion>4.0.0</modelVersion>
-	<groupId>org.apache.cayenne.docs</groupId>
-	<artifactId>cayenne-guide</artifactId>
-	<name>Docbook: Cayenne Guide</name>
-</project>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/docs/docbook/cayenne-guide/src/docbkx/appendix-a.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/appendix-a.xml b/docs/docbook/cayenne-guide/src/docbkx/appendix-a.xml
deleted file mode 100644
index e36f681..0000000
--- a/docs/docbook/cayenne-guide/src/docbkx/appendix-a.xml
+++ /dev/null
@@ -1,184 +0,0 @@
-<?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.
--->
-<appendix xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink"
-    version="5.0" xml:id="configuration-properties">
-    <title>Configuration Properties</title>
-    <para>Note that the property names below are defined as constants in
-            <code>org.apache.cayenne.configuration.Constants</code> interface. </para>
-    <para>
-        <table frame="void">
-            <caption>Configuration Properties Recognized by ServerRuntime and/or ClientRuntime</caption>
-            <col width="67%"/>
-            <col width="15%"/>
-            <col width="18%"/>
-            <thead>
-                <tr>
-                    <th>Property</th>
-                    <th>Possible Values</th>
-                    <th>Default Value</th>
-                </tr>
-            </thead>
-            <tbody>
-                <tr>
-                    <td><code>cayenne.jdbc.driver[.domain_name.node_name]</code> - defines a JDBC driver class to
-                        use when creating a DataSource. If domain name and optionally - node name
-                        are specified, the setting overrides DataSource info just for this
-                        domain/node. Otherwise the override is applied to all domains/nodes in the
-                        system.</td>
-                    <td/>
-                    <td>none, project DataNode configuration is used</td>
-                </tr>
-                <tr>
-                    <td><code>cayenne.jdbc.url[.domain_name.node_name] </code>- defines a DB URL to use when
-                        creating a DataSource. If domain name and optionally - node name are
-                        specified, the setting overrides DataSource info just for this domain/node.
-                        Otherwise the override is applied to all domains/nodes in the system.</td>
-                    <td/>
-                    <td>none, project DataNode configuration is used</td>
-                </tr>
-                <tr>
-                    <td><code>cayenne.jdbc.username[.domain_name.node_name] </code>- defines a DB user name to use
-                        when creating a DataSource. If domain name and optionally - node name are
-                        specified, the setting overrides DataSource info just for this domain/node.
-                        Otherwise the override is applied to all domains/nodes in the system.</td>
-                    <td/>
-                    <td>none, project DataNode configuration is used</td>
-                </tr>
-                <tr>
-                    <td><code>cayenne.jdbc.password[.domain_name.node_name]</code> - defines a DB password to use
-                        when creating a DataSource. If domain name and optionally - node name are
-                        specified, the setting overrides DataSource info just for this domain/node.
-                        Otherwise the override is applied to all domains/nodes in the system</td>
-                    <td/>
-                    <td>none, project DataNode configuration is used</td>
-                </tr>
-                <tr>
-                    <td><code>cayenne.jdbc.min_connections[.domain_name.node_name]</code> - defines the DB
-                        connection pool minimal size. If domain name and optionally - node name are
-                        specified, the setting overrides DataSource info just for this domain/node.
-                        Otherwise the override is applied to all domains/nodes in the system</td>
-                    <td/>
-                    <td>none, project DataNode configuration is used</td>
-                </tr>
-                <tr>
-                    <td><code>cayenne.jdbc.max_connections[.domain_name.node_name]</code> - defines the DB
-                        connection pool maximum size. If domain name and optionally - node name are
-                        specified, the setting overrides DataSource info just for this domain/node.
-                        Otherwise the override is applied to all domains/nodes in the system</td>
-                    <td/>
-                    <td>none, project DataNode configuration is used</td>
-                </tr>
-                <tr>
-                    <td><code>cayenne.querycache.size</code> - An integer defining the maximum number of entries in
-                        the query cache. Note that not all QueryCache providers may respect this
-                        property. MapQueryCache uses it, but the rest would use alternative
-                        configuration methods.</td>
-                    <td>any positive int value</td>
-                    <td>2000</td>
-                </tr>
-                <tr>
-                    <td><code>cayenne.server.contexts_sync_strategy</code> - defines whether peer ObjectContexts
-                        should receive snapshot events after commits from other contexts. If true
-                        (default), the contexts would automatically synchronize their state with
-                        peers.</td>
-                    <td>true, false</td>
-                    <td>true</td>
-                </tr>
-                <tr>
-                    <td><code>cayenne.server.object_retain_strategy</code> - defines fetched objects retain
-                        strategy for ObjectContexts. When weak or soft strategy is used, objects
-                        retained by ObjectContext that have no local changes can potetially get
-                        garbage collected when JVM feels like doing it.</td>
-                    <td>weak, soft, hard</td>
-                    <td>weak</td>
-                </tr>
-                <tr>
-                    <td><code>cayenne.server.max_id_qualifier_size</code> - defines a maximum number of ID
-                        qualifiers in the WHERE  clause of queries that are generated for paginated
-                        queries and for DISJOINT_BY_ID prefetch processing. This is needed to avoid
-                        hitting WHERE clause size limitations and memory usage efficiency.</td>
-                    <td>any positive int</td>
-                    <td>10000</td>
-                </tr>
-                <tr>
-                    <td><code>cayenne.rop.service_url</code> - defines the URL of the ROP server</td>
-                    <td/>
-                    <td/>
-                </tr>
-                <tr>
-                    <td><code>cayenne.rop.service_username</code> - defines the user name for an ROP client to
-                        login to an ROP server.</td>
-                    <td/>
-                    <td/>
-                </tr>
-                <tr>
-                    <td><code>cayenne.rop.service_password</code> - defines the password for an ROP client to login
-                        to an ROP server.</td>
-                    <td/>
-                    <td/>
-                </tr>
-                <tr>
-                    <td><code>cayenne.rop.shared_session_name</code>- defines the name of the shared session that
-                        an ROP client wants to join on an ROP server. If omitted, a dedicated
-                        session is created.</td>
-                    <td/>
-                    <td/>
-                </tr>
-                <tr>
-                    <td><code>cayenne.rop.service.timeout</code> - a value in milliseconds for the
-                        ROP client-server connection read operation timeout</td>
-                    <td>any positive long value</td>
-                    <td/>
-                </tr>
-                <tr>
-                    <td><code>cayenne.rop.channel_events</code> - defines whether client-side DataChannel should
-                        dispatch events to child ObjectContexts. If set to true, ObjectContexts will
-                        receive commit events and merge changes committed by peer contexts that
-                        passed through the common client DataChannel.</td>
-                    <td>true, false</td>
-                    <td>false</td>
-                </tr>
-                <tr>
-                    <td><code>cayenne.rop.context_change_events</code>- defines whether object property changes in
-                        the client context result in firing events. Client UI components can listen
-                        to these events and update the UI. Disabled by default.</td>
-                    <td>true, false</td>
-                    <td>false</td>
-                </tr>
-                <tr>
-                    <td><code>cayenne.rop.context_lifecycle_events</code> - defines whether object commit and
-                        rollback operations in the client context result in firing events. Client UI
-                        components can listen to these events and update the UI. Disabled by
-                        default.</td>
-                    <td>true,false</td>
-                    <td>false</td>
-                </tr>
-                <tr>
-                    <td><code>cayenne.server.rop_event_bridge_factory</code> - defines the name of
-                        the org.apache.cayenne.event.EventBridgeFactory that is passed from the ROP
-                        server to the client. I.e. server DI would provide a name of the factory,
-                        passing this name to the client via the wire. The client would instantiate
-                        it to receive events from the server. Note that this property is stored in
-                        "cayenne.server.rop_event_bridge_properties" map, not in the main
-                        "cayenne.properties".</td>
-                    <td/>
-                    <td/>
-                </tr>
-            </tbody>
-        </table>
-    </para>
-</appendix>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/docs/docbook/cayenne-guide/src/docbkx/appendix-b.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/appendix-b.xml b/docs/docbook/cayenne-guide/src/docbkx/appendix-b.xml
deleted file mode 100644
index cf0f035..0000000
--- a/docs/docbook/cayenne-guide/src/docbkx/appendix-b.xml
+++ /dev/null
@@ -1,100 +0,0 @@
-<?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.
--->
-<appendix xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink"
-    version="5.0" xml:id="service-collections">
-    <title>Service Collections</title>
-    <para>Note that the collection keys below are
-                defined as constants in <code>org.apache.cayenne.configuration.Constants</code>
-                interface.</para>
-    <para>
-        <table frame="void">
-            <caption>Service Collection Keys Present in ServerRuntime and/or ClientRuntime</caption>
-            <col width="42%"/>
-            <col width="25%"/>
-            <col width="33%"/>
-            <thead>
-                <tr>
-                    <th>Collection Property</th>
-                    <th>Type</th>
-                    <th>Description</th>
-                </tr>
-            </thead>
-            <tbody>
-                <tr>
-                    <td><code>cayenne.properties</code></td>
-                    <td><code>Map&lt;String,String></code></td> 
-                    <td>Properties used by built-in
-                        Cayenne services. The keys in this map are the property names from the table
-                        in Appendix A. Separate copies of this map exist on the server and ROP
-                        client.</td>
-                </tr>
-                <tr>
-                    <td><code>cayenne.server.adapter_detectors</code></td>
-                    <td><code>List&lt;DbAdapterDetector></code></td>
-                    <td>Contains
-                        objects that can discover the type of current database and install the
-                        correct DbAdapter in runtime.</td>
-                </tr>
-                <tr>
-                    <td><code>cayenne.server.domain_filters</code></td>
-                    <td><code>List&lt;DataChannelFilter></code></td>
-                    <td>Stores DataDomain filters.</td>
-                </tr>
-                <tr>
-                    <td><code>cayenne.server.project_locations</code></td>
-                    <td><code>List&lt;String></code></td>
-                    <td>Stores locations of the one of more project configuration files.</td>
-                </tr>
-                <tr>
-                    <td><code>cayenne.server.default_types</code></td>
-                    <td><code>List&lt;ExtendedType></code></td>
-                    <td>Stores default adapter-agnostic ExtendedTypes. Default ExtendedTypes can be
-                        overridden / extended by DB-specific DbAdapters as well as by user-provided
-                        types configured in another colltecion (see
-                        <code>"cayenne.server.user_types"</code>).</td>
-                </tr>
-                <tr>
-                    <td><code>cayenne.server.user_types</code></td>
-                    <td><code>List&lt;ExtendedType></code></td>
-                    <td>Stores a
-                        user-provided ExtendedTypes. This collection will be merged into a full list
-                        of ExtendedTypes and would override any ExtendedTypes defined in a default
-                        list, or by a DbAdapter.</td>
-                </tr>
-                <tr>
-                    <td><code>cayenne.server.type_factories</code></td>
-                    <td><code>List&lt;ExtendedTypeFactory></code></td>
-                    <td>Stores default and user-provided ExtendedTypeFactories. ExtendedTypeFactory
-                        allows to define ExtendedTypes dynamically for the whole group of Java
-                        classes. E.g. Cayenne supplies a factory to map all Enums regardless of
-                        their type.</td>
-                </tr>
-                <tr>
-                    <td><code>cayenne.server.rop_event_bridge_properties</code></td>
-                    <td><code>Map&lt;String, String></code></td>
-                    <td>Stores event bridge properties passed to the ROP client on
-                        bootstrap. This means that the map is configured by server DI, and passed to
-                        the client via the wire. The properties in this map are specific to
-                        EventBridgeFactory implementation (e.g JMS or XMPP connection prameters).
-                        One common property is <code>"cayenne.server.rop_event_bridge_factory"</code> that
-                        defines the type of the factory.</td>
-                </tr>
-            </tbody>
-        </table>
-    </para>
-
-</appendix>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/docs/docbook/cayenne-guide/src/docbkx/appendix-c.xml
----------------------------------------------------------------------
diff --git a/docs/docbook/cayenne-guide/src/docbkx/appendix-c.xml b/docs/docbook/cayenne-guide/src/docbkx/appendix-c.xml
deleted file mode 100644
index 8b036af..0000000
--- a/docs/docbook/cayenne-guide/src/docbkx/appendix-c.xml
+++ /dev/null
@@ -1,147 +0,0 @@
-<?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.
--->
-<appendix xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink"
-    version="5.0" xml:id="expressions-bnf">
-    <title>Expressions BNF</title>
-    <para>
-        <programlisting>
-TOKENS
-&lt;DEFAULT> SKIP : {
-" "
-| "\t"
-| "\n"
-| "\r"
-}
-
-&lt;DEFAULT> TOKEN : {
-&lt;NULL: "null" | "NULL">
-| &lt;TRUE: "true" | "TRUE">
-| &lt;FALSE: "false" | "FALSE">
-}
-
-&lt;DEFAULT> TOKEN : {
-&lt;PROPERTY_PATH: &lt;IDENTIFIER> ("." &lt;IDENTIFIER>)*>
-}
-
-&lt;DEFAULT> TOKEN : {
-&lt;IDENTIFIER: &lt;LETTER> (&lt;LETTER> | &lt;DIGIT>)* (["+"])?>
-| &lt;#LETTER: ["_","a"-"z","A"-"Z"]>
-| &lt;#DIGIT: ["0"-"9"]>
-}
-
-/** 
- * Quoted Strings, whose object value is stored in the token manager's
- * "literalValue" field. Both single and double qoutes are allowed 
- */&lt;DEFAULT> MORE : {
-"\'" : WithinSingleQuoteLiteral
-| "\"" : WithinDoubleQuoteLiteral
-}
-
-&lt;WithinSingleQuoteLiteral> MORE : {
-&lt;ESC: "\\" (["n","r","t","b","f","\\","\'","`","\""] | (["0"-"3"])? ["0"-"7"] (["0"-"7"])?)> : {
-| &lt;~["\'","\\"]> : {
-}
-
-&lt;WithinSingleQuoteLiteral> TOKEN : {
-&lt;SINGLE_QUOTED_STRING: "\'"> : DEFAULT
-}
-
-&lt;WithinDoubleQuoteLiteral> MORE : {
-&lt;STRING_ESC: &lt;ESC>> : {
-| &lt;~["\"","\\"]> : {
-}
-
-&lt;WithinDoubleQuoteLiteral> TOKEN : {
-&lt;DOUBLE_QUOTED_STRING: "\""> : DEFAULT
-}
-
-/**
- * Integer or real Numeric literal, whose object value is stored in the token manager's
- * "literalValue" field.
- */&lt;DEFAULT> TOKEN : {
-&lt;INT_LITERAL: ("0" (["0"-"7"])* | ["1"-"9"] (["0"-"9"])* | "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+)
-        (["l","L","h","H"])?> : {
-| &lt;FLOAT_LITERAL: &lt;DEC_FLT> (&lt;EXPONENT>)? (&lt;FLT_SUFF>)? | &lt;DEC_DIGITS> &lt;EXPONENT> (&lt;FLT_SUFF>)?
-| &lt;DEC_DIGITS> &lt;FLT_SUFF>> : {
-| &lt;#DEC_FLT: (["0"-"9"])+ "." (["0"-"9"])* | "." (["0"-"9"])+>
-| &lt;#DEC_DIGITS: (["0"-"9"])+>
-| &lt;#EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+>
-| &lt;#FLT_SUFF: ["d","D","f","F","b","B"]>
-}
-
-NON-TERMINALS
-    expression    :=    orCondition &lt;EOF>
-    orCondition    :=    andCondition ( "or" andCondition )*
-    andCondition    :=    notCondition ( "and" notCondition )*
-    notCondition    :=    ( "not" | "!" ) simpleCondition
-        |    simpleCondition
-    simpleCondition    :=    &lt;TRUE>
-        |    &lt;FALSE>
-        |    scalarConditionExpression
-             ( simpleNotCondition 
-               | ( "=" | "==" ) scalarExpression 
-               | ( "!=" | "&lt;>" ) scalarExpression 
-               | "&lt;=" scalarExpression 
-               | "&lt;" scalarExpression | ">" scalarExpression 
-               | ">=" scalarExpression 
-               | "like" scalarExpression 
-               | "likeIgnoreCase" scalarExpression 
-               | "in" ( namedParameter | "(" scalarCommaList ")" ) 
-               | "between" scalarExpression "and" scalarExpression 
-             )?
-    simpleNotCondition    :=    ( "not" | "!" )
-             ( "like" scalarExpression 
-               | "likeIgnoreCase" scalarExpression 
-               | "in" ( namedParameter | "(" scalarCommaList ")" ) 
-               | "between" scalarExpression "and" scalarExpression 
-             )
-    scalarCommaList    :=    ( scalarConstExpression ( "," scalarConstExpression )* )
-    scalarConditionExpression    :=    scalarNumericExpression
-        |    &lt;SINGLE_QUOTED_STRING>
-        |    &lt;DOUBLE_QUOTED_STRING>
-        |    &lt;NULL>
-    scalarExpression    :=    scalarConditionExpression
-        |    &lt;TRUE>
-        |    &lt;FALSE>
-    scalarConstExpression    :=    &lt;SINGLE_QUOTED_STRING>
-        |    &lt;DOUBLE_QUOTED_STRING>
-        |    namedParameter
-        |    &lt;INT_LITERAL>
-        |    &lt;FLOAT_LITERAL>
-        |    &lt;TRUE>
-        |    &lt;FALSE>
-    scalarNumericExpression    :=    multiplySubtractExp
-             ( "+" multiplySubtractExp | "-" multiplySubtractExp )*
-    multiplySubtractExp    :=    numericTerm ( "*" numericTerm | "/" numericTerm )*
-    numericTerm    :=    ( "+" )? numericPrimary
-        |    "-" numericPrimary
-    numericPrimary    :=    "(" orCondition ")"
-        |    pathExpression
-        |    namedParameter
-        |    &lt;INT_LITERAL>
-        |    &lt;FLOAT_LITERAL>
-    namedParameter    :=    "$" &lt;PROPERTY_PATH>
-    pathExpression    :=    ( &lt;PROPERTY_PATH>
-                            | "obj:" &lt;PROPERTY_PATH>  
-                            | "db:" &lt;PROPERTY_PATH>  
-                            | "enum:" &lt;PROPERTY_PATH>  )
-
-</programlisting>
-    </para>
-
-    
-</appendix>


Mime
View raw message