Repository: cayenne
Updated Branches:
  refs/heads/STABLE-4.0 27923edf8 -> e4eb10f03


Update documentation
 - match latest API
 - remove empty ROP sections
 - remove mentions of deprecated code
 - add cross-links and styling

(cherry picked from commit 4517505)


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

Branch: refs/heads/STABLE-4.0
Commit: e4eb10f03589a5dc3c718ef487a57843efb9c9af
Parents: 27923ed
Author: Nikita Timofeev <stari...@gmail.com>
Authored: Tue Jan 30 15:51:01 2018 +0300
Committer: Nikita Timofeev <stari...@gmail.com>
Committed: Tue Jan 30 16:03:26 2018 +0300

----------------------------------------------------------------------
 .../_cayenne-guide/part2/customize.adoc         |  77 ++++++++----
 .../_cayenne-guide/part2/lifecycle.adoc         |  30 +++--
 .../_cayenne-guide/part2/objectContext.adoc     | 123 ++++++++++++++-----
 .../asciidoc/_cayenne-guide/part2/tuning.adoc   |  64 ++--------
 .../src/docs/asciidoc/_cayenne-guide/part3.adoc |  13 +-
 .../_cayenne-guide/part3/ropDeployment.adoc     |  18 ++-
 .../_cayenne-guide/part5/cacheInvalidation.adoc |   2 +-
 7 files changed, 188 insertions(+), 139 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/e4eb10f0/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part2/customize.adoc
----------------------------------------------------------------------
diff --git 
a/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part2/customize.adoc
 
b/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part2/customize.adoc
index aa78d0d..fffa96c 100644
--- 
a/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part2/customize.adoc
+++ 
b/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part2/customize.adoc
@@ -153,9 +153,14 @@ Another types of confiuguration that can be bound in the 
container are lists and
 
 ===== Service Lifecycle
 
-An important feature of the Cayenne DI container is instance scope. The 
default scope (implicitly used in all examples above) is "singleton", meaning 
that a binding would result in creation of only one service instance, that will 
be repeatedly returned from `Injector.getInstance(..)`, as well as injected 
into classes that declare it as a dependency.
+An important feature of the Cayenne DI container is instance scope. The 
default scope (implicitly used in all examples above)
+is "singleton", meaning that a binding would result in creation of only one 
service instance, that will be repeatedly returned from 
`Injector.getInstance(..)`,
+as well as injected into classes that declare it as a dependency.
 
-Singleton scope dispatches a "BeforeScopeEnd" event to interested services. 
This event occurs before the scope is shutdown, i.e. when `Injector.shutdown()` 
is called. Note that the built-in Cayenne injector is shutdown behind the 
scenes when `ServerRuntime.shutdown()` is invoked. Services may register as 
listeners for this event by annotating a no-argument method with 
`@BeforeScopeEnd` annotation. Such method should be implemented if a service 
needs to clean up some resources, stop threads, etc.
+Singleton scope dispatches a "BeforeScopeEnd" event to interested services. 
This event occurs before the scope is shutdown,
+i.e. when `Injector.shutdown()` is called. Note that the built-in Cayenne 
injector is shutdown behind the scenes when `ServerRuntime.shutdown()` is 
invoked.
+Services may register as listeners for this event by annotating a no-argument 
method with `@BeforeScopeEnd` annotation.
+Such method should be implemented if a service needs to clean up some 
resources, stop threads, etc.
 
 Another useful scope is "no scope", meaning that every time a container is 
asked to provide a service instance for a given key, a new instance will be 
created and returned:
 
@@ -164,15 +169,26 @@ Another useful scope is "no scope", meaning that every 
time a container is asked
 binder.bind(Service2.class).to(Service2Impl.class).withoutScope();
 ----
 
-Users can also create their own scopes, e.g. a web application request scope 
or a session scope. Most often than not custom scopes can be created as 
instances of `org.apache.cayenne.di.spi.DefaultScope` with startup and shutdown 
managed by the application (e.g. singleton scope is a DefaultScope managed by 
the Injector) .
+Users can also create their own scopes, e.g. a web application request scope 
or a session scope. Most often than not custom scopes
+can be created as instances of `org.apache.cayenne.di.spi.DefaultScope` with 
startup and shutdown managed by the application
+(e.g. singleton scope is a DefaultScope managed by the Injector) .
 
 ===== Overriding Services
 
-Cayenne DI allows to override services already definied in the current module, 
or more commonly - some other module in the the same container. Actually 
there's no special API to override a service, you'd just bind the service key 
again with a new implementation or provider. The last binding for a key takes 
precedence. This means that the order of modules is important when configuring 
a container. The built-in Cayenne injector ensures that Cayenne standard 
modules are loaded first, followed by optional user extension modules. This way 
the application can override the standard services in Cayenne.
+Cayenne DI allows to override services already definied in the current module, 
or more commonly - some other module
+in the the same container. Actually there's no special API to override a 
service, you'd just bind the service key again
+with a new implementation or provider. The last binding for a key takes 
precedence. This means that the order of modules is important when configuring 
a container.
+The built-in Cayenne injector ensures that Cayenne standard modules are loaded 
first, followed by optional user extension modules.
+This way the application can override the standard services in Cayenne.
 
 ==== Customization Strategies
 
-The previous section discussed how Cayenne DI works in general terms. Since 
Cayenne users will mostly be dealing with an existing Injector provided by 
ServerRuntime, it is important to understand how to build custom extensions to 
a preconfigured container. As shown in "Starting and Stopping ServerRuntime" 
chapter, custom extensions are done by writing an aplication DI module (or 
multiple modules) that configures service overrides. This section shows all the 
configuration possibilities in detail, including changing properties of the 
existing services, contributing services to standard service lists and maps, 
and overriding service implementations. All the code examples later in this 
section are assumed to be placed in an application module "configure" method:
+The previous section discussed how Cayenne DI works in general terms. Since 
Cayenne users will mostly be dealing with
+an existing Injector provided by ServerRuntime, it is important to understand 
how to build custom extensions to a preconfigured container.
+As shown in "Starting and Stopping ServerRuntime" chapter, custom extensions 
are done by writing an application
+DI module (or multiple modules) that configures service overrides. This 
section shows all the configuration possibilities in detail,
+including changing properties of the existing services, contributing services 
to standard service lists and maps, and overriding service implementations.
+All the code examples later in this section are assumed to be placed in an 
application module "configure" method:
 
 [source, Java]
 ----
@@ -194,7 +210,9 @@ ServerRuntime runtime = ServerRuntime.builder()
 
 ===== Changing Properties of Existing Services
 
-Many built-in Cayenne services change their behavior based on a value of some 
environment property. A user may change Cayenne behavior without even knowing 
which services are responsible for it, but setting a specific value of a known 
property. Supported property names are listed in "Appendix A".
+Many built-in Cayenne services change their behavior based on a value of some 
environment property.
+A user may change Cayenne behavior without even knowing which services are 
responsible for it, but setting a specific value of a known property.
+Supported property names are listed in "Appendix A".
 
 There are two ways to set service properties. The most obvious one is to pass 
it to the JVM with -D flag on startup. E.g.
 
@@ -202,15 +220,21 @@ There are two ways to set service properties. The most 
obvious one is to pass it
 $ java -Dcayenne.server.contexts_sync_strategy=false ...
 ----
 
-A second one is to contribute a property to 
`org.apache.cayenne.configuration.DefaultRuntimeProperties.properties` map (see 
the next section on how to do that). This map contains the default property 
values and can accept application-specific values, overrding the defaults.
+A second one is to contribute a property to 
`o.a.c.configuration.DefaultRuntimeProperties.properties` map (see the next 
section on how to do that).
+This map contains the default property values and can accept 
application-specific values, overrding the defaults.
 
-Note that if a property value is a name of a Java class, when this Java class 
is instantiated by Cayenne, the container performs injection of instance 
variables. So even the dynamically specified Java classes can use @Inject 
annotation to get a hold of other Cayenne services.
+Note that if a property value is a name of a Java class, when this Java class 
is instantiated by Cayenne,
+the container performs injection of instance variables. So even the 
dynamically specified Java classes can use @Inject annotation to get a hold of 
other Cayenne services.
 
-If the same property is specified both in the command line and in the 
properties map, the command-line value takes precedence. The map value will be 
ignored. This way Cayenne runtime can be reconfigured during deployment.
+If the same property is specified both in the command line and in the 
properties map, the command-line value takes precedence.
+The map value will be ignored. This way Cayenne runtime can be reconfigured 
during deployment.
 
 ===== Contributing to Service Collections
 
-Cayenne can be extended by adding custom objects to named maps or lists bound 
in DI. We are calling these lists/maps "service collections". A service 
collection allows things like appending a custom strategy to a list of built-in 
strategies. E.g. an application that needs to install a custom DbAdapter for 
some database type may contribute an instance of custom DbAdapterDetector to a 
`org.apache.cayenne.configuration.server.DefaultDbAdapterFactory.detectors` 
list:
+Cayenne can be extended by adding custom objects to named maps or lists bound 
in DI. We are calling these lists/maps "service collections".
+A service collection allows things like appending a custom strategy to a list 
of built-in strategies.
+E.g. an application that needs to install a custom DbAdapter for some database 
type may contribute an instance of custom
+DbAdapterDetector to a 
`o.a.c.configuration.server.DefaultDbAdapterFactory.detectors` list:
 
 [source, Java]
 ----
@@ -224,25 +248,29 @@ public class MyDbAdapterDetector implements 
DbAdapterDetector {
 
 [source, Java]
 ----
-// since build-in list for this key is a singleton, repeated
-// calls to 'bindList' will return the same instance
-binder.bindList(DefaultDbAdapterFactory.DETECTORS_LIST)
-       .add(MyDbAdapterDetector.class);
+ServerModule.contributeAdapterDetectors(binder)
+    .add(MyDbAdapterDetector.class);
 ----
 
-Maps are customized using a similar `"bindMap"` method.
-
 The names of built-in collections are listed in "Appendix B".
 
 ===== Alternative Service Implementations
 
-As mentioned above, custom modules are loaded by ServerRuntime after the 
built-in modules. So it is easy to redefine a built-in service in Cayenne by 
rebinding desired implementations or providers. To do that, first we need to 
know what those services to redefine are. While we describe some of them in the 
following sections, the best way to get a full list is to check the source code 
of the Cayenne version you are using and namely look in 
`org.apache.cayenne.configuration.server.ServerModule` - the main built-in 
module in Cayenne.
+As mentioned above, custom modules are loaded by ServerRuntime after the 
built-in modules.
+So it is easy to redefine a built-in service in Cayenne by rebinding desired 
implementations or providers.
+To do that, first we need to know what those services to redefine are.
+While we describe some of them in the following sections, the best way to get 
a full list
+is to check the source code of the Cayenne version you are using and
+namely look in `org.apache.cayenne.configuration.server.ServerModule` - the 
main built-in module in Cayenne.
 
-Now an example of overriding `QueryCache` service. The default implementation 
of this service is provided by `MapQueryCacheProvider`. But if we want to use 
`EhCacheQueryCache` (a Cayenne wrapper for the EhCache framework), we can 
define it like this:
+Now an example of overriding `JdbcEventLogger` service. The default 
implementation of this service
+is provided by `Slf4jJdbcEventLogger`. But if we want to use 
`FormattedSlf4jJdbcEventLogger`
+(a logger with basic SQL formatting), we can define it like this:
 
 [source, Java]
 ----
-binder.bind(QueryCache.class).to(EhCacheQueryCache.class);
+binder.bind(JdbcEventLogger.class)
+    .to(FormattedSlf4jJdbcEventLogger.class);
 ----
 
 ==== Using custom data types
@@ -309,11 +337,14 @@ Last step is to register this new type in `ServerRuntime`:
 ----
 ServerRuntime runtime = ServerRuntime.builder()
     .addConfig("cayenne-project.xml")
-    .addModule(binder -> 
ServerModule.contributeValueObjectTypes(binder).add(MoneyValueObjectType.class))
+    .addModule(binder ->
+        ServerModule.contributeValueObjectTypes(binder)
+            .add(MoneyValueObjectType.class))
     .build();
 ----
 
-More examples of implementation you can find in 
https://github.com/apache/cayenne/tree/master/cayenne-joda[cayenne-joda module].
+More examples of implementation you can find in
+https://github.com/apache/cayenne/blob/master/cayenne-server/src/main/java/org/apache/cayenne/access/types/LocalDateValueType.java[cayenne-server].
 
 ===== Extended Types
 
@@ -416,7 +447,9 @@ For Java8
 // add DoubleArrayType to list of user types
 ServerRuntime runtime = ServerRuntime.builder()
                 .addConfig("cayenne-project.xml")
-                .addModule(binder -> 
ServerModule.contributeUserTypes(binder).add(new DoubleArrayType()))
+                .addModule(binder ->
+                    ServerModule.contributeUserTypes(binder)
+                        .add(new DoubleArrayType()))
                 .build();
 ----
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e4eb10f0/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part2/lifecycle.adoc
----------------------------------------------------------------------
diff --git 
a/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part2/lifecycle.adoc
 
b/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part2/lifecycle.adoc
index 9305723..4457ef3 100644
--- 
a/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part2/lifecycle.adoc
+++ 
b/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part2/lifecycle.adoc
@@ -130,10 +130,15 @@ Ignore the annotations for a minute. The important point 
here is that the listen
 
 [source, Java]
 ----
-ServerRuntime runtime = ...
-
-runtime.getDataDomain().addListener(new Listener1());
-runtime.getDataDomain().addListener(new Listener2());
+ServerRuntime runtime = ServerRuntime.builder()
+       // ..
+       .addModule(binder ->
+            ServerModule.contributeDomainListeners()
+                .add(new Listener1())
+                .add(new Listener2())
+       )
+       // ..
+       .build();
 ----
 
 
@@ -253,14 +258,15 @@ Now since this is both a filter and a listener, it needs 
to be registered as suc
 
 [source, Java]
 ----
-CommittedObjectCounter counter = new CommittedObjectCounter();
-
-ServerRuntime runtime = ...
-DataDomain domain = runtime.getDataDomain();
-
-// register filter
-// this will also add it as a listener (since 3.2)
-domain.addFilter(counter);
+// this will also add filter as a listener
+ServerRuntime runtime = ServerRuntime.builder()
+        // ..
+        .addModule(b ->
+                ServerModule.contributeDomainFilters(b)
+                        .add(CommittedObjectCounter.class)
+        )
+        // ..
+        .build();
 ----
 
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e4eb10f0/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part2/objectContext.adoc
----------------------------------------------------------------------
diff --git 
a/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part2/objectContext.adoc
 
b/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part2/objectContext.adoc
index 888be47..117c263 100644
--- 
a/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part2/objectContext.adoc
+++ 
b/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part2/objectContext.adoc
@@ -66,17 +66,21 @@ Each persistent object belongs to a single ObjectContext, 
and can be in one of t
 
 ==== ObjectContext Persistence API
 
-One of the first things users usually want to do with an ObjectContext is to 
select some objects from a database. This is done by calling "performQuery" 
method:
+One of the first things users usually want to do with an `ObjectContext` is to 
select some objects from a database:
 
 [source, java]
 ----
-SelectQuery query = new SelectQuery(Artist.class);
-List<Artist> artists = context.performQuery(query);
+List<Artist> artists = ObjectSelect.query(Artist.class)
+    .select(context);
 ----
 
-We'll discuss queries in some detail in the following chapters. The example 
above is self-explanatory - we create a SelectQuery that matches all Artist 
objects present in the database, and then call "performQuery", getting a list 
of Artist objects.
+We'll discuss queries in some detail in the <<queries,Queries>> chapter. The 
example above is self-explanatory -
+we create a `ObjectSelect` that matches all `Artist` objects present in the 
database, and then use `select`
+to get the result.
 
-Some queries can be quite complex, returning multiple result sets or even 
updating the database. For such queries ObjectContext provides 
"performGenericQuery"method. While not nearly as commonly-used as 
"performQuery", it is nevertheless important in some situations. E.g.:
+Some queries can be quite complex, returning multiple result sets or even 
updating the database.
+For such queries ObjectContext provides `performGenericQuery()` method.
+While not commonly-used, it is nevertheless important in some situations. E.g.:
 
 [source, java]
 ----
@@ -95,23 +99,27 @@ Artist selectedArtist = artists.get(0);
 selectedArtist.setName("Dali");
 ----
 
-The first time the object property is changed, the object's state is 
automatically set to "MODIFIED" by Cayenne. Cayenne tracks all in-memory 
changes until a user calls "commitChanges":
+The first time the object property is changed, the object's state is 
automatically set to *MODIFIED* by Cayenne.
+Cayenne tracks all in-memory changes until a user calls `commitChanges`:
 
 [source, java]
 ----
 context.commitChanges();
 ----
 
-At this point all in-memory changes are analyzed and a minimal set of SQL 
statements is issued in a single transaction to synchronize the database with 
the in-memory state. In our example "commitChanges" commits just one object, 
but generally it can be any number of objects.
+At this point all in-memory changes are analyzed and a minimal set of SQL 
statements is issued in a single transaction
+to synchronize the database with the in-memory state. In our example 
`commitChanges` commits just one object,
+but generally it can be any number of objects.
 
-If instead of commit, we wanted to reset all changed objects to the previously 
committed state, we'd call `rollbackChanges` instead:
+If instead of commit, we wanted to reset all changed objects to the previously 
committed state,
+we'd call `rollbackChanges` instead:
 
 [source, java]
 ----
 context.rollbackChanges();
 ----
 
-"newObject" method call creates a persistent object and sets its state to 
"NEW":
+`newObject` method call creates a persistent object and sets its state to 
*NEW*:
 
 [source, java]
 ----
@@ -119,9 +127,11 @@ Artist newArtist = context.newObject(Artist.class);
 newArtist.setName("Picasso");
 ----
 
-It will only exist in memory until "commitChanges" is issued. On commit 
Cayenne might generate a new primary key (unless a user set it explicitly, or a 
PK was inferred from a relationship) and issue an INSERT SQL statement to 
permanently store the object.
+It will only exist in memory until `commitChanges` is issued. On commit 
Cayenne might generate a new primary key
+(unless a user set it explicitly, or a PK was inferred from a relationship) 
and issue an
+`INSERT` SQL statement to permanently store the object.
 
-`deleteObjects` method takes one or more Persistent objects and marks them as 
"DELETED":
+`deleteObjects` method takes one or more Persistent objects and marks them as 
*DELETED*:
 
 [source, java]
 ----
@@ -129,11 +139,16 @@ context.deleteObjects(artist1);
 context.deleteObjects(artist2, artist3, artist4);
 ----
 
-Additionally "deleteObjects" processes all delete rules modeled for the 
affected objects. This may result in implicitly deleting or modifying extra 
related objects. Same as insert and update, delete operations are sent to the 
database only when "commitChanges" is called. Similarly "rollbackChanges" will 
undo the effect of "newObject" and "deleteObjects".
+Additionally `deleteObjects` processes all delete rules modeled for the 
affected objects.
+This may result in implicitly deleting or modifying extra related objects.
+Same as insert and update, delete operations are sent to the database only 
when `commitChanges` is called.
+Similarly `rollbackChanges` will undo the effect of `newObject` and 
`deleteObjects`.
 
-`localObject` returns a copy of a given persistent object that is "local" to a 
given ObjectContext:
+`localObject` returns a copy of a given persistent object that is _local_ to a 
given ObjectContext:
 
-Since an application often works with more than one context, "localObject" is 
a rather common operation. E.g. to improve performance a user might utilize a 
single shared context to select and cache data, and then occasionally transfer 
some selected objects to another context to modify and commit them:
+Since an application often works with more than one context, `localObject` is 
a rather common operation.
+E.g. to improve performance a user might utilize a single shared context to 
select and cache data,
+and then occasionally transfer some selected objects to another context to 
modify and commit them:
 
 
 [source, java]
@@ -142,18 +157,23 @@ ObjectContext editingContext = runtime.newContext();
 Artist localArtist = editingContext.localObject(artist);
 ----
 
-Often an appliction needs to inspect mapping metadata. This information is 
stored in the EntityResolver object, accessible via the ObjectContext:
+Often an application needs to inspect mapping metadata. This information is 
stored in the `EntityResolver` object,
+accessible via the `ObjectContext`:
 
 [source, java]
 ----
 EntityResolver resolver = objectContext.getEntityResolver();
 ----
 
-Here we discussed the most commonly used subset of the ObjectContext API. 
There are other useful methods, e.g. those allowing to inspect registered 
objects state in bulk, etc. Check the latest JavaDocs for details.
+Here we discussed the most commonly used subset of the ObjectContext API.
+There are other useful methods, e.g. those allowing to inspect registered 
objects state in bulk, etc.
+Check the latest JavaDocs for details.
 
 ==== Cayenne Helper Class
 
-There is a useful helper class called "Cayenne" (fully-qualified name 
`"org.apache.cayenne.Cayenne"`) that builds on ObjectContext API to provide a 
number of very common operations. E.g. get a primary key (most entities do not 
model PK as an object property) :
+There is a useful helper class called `Cayenne` (fully-qualified name 
`org.apache.cayenne.Cayenne`)
+that builds on ObjectContext API to provide a number of very common operations.
+E.g. get a primary key (most entities do not model PK as an object property) :
 
 [source, java]
 ----
@@ -177,23 +197,36 @@ Artist artist = (Artist) Cayenne.objectForQuery(context, 
new SelectQuery(Artist.
 Feel free to explore Cayenne class API for other useful methods.
 
 ==== ObjectContext Nesting
-In all the examples shown so far an ObjectContext would directly connect to a 
database to select data or synchronize its state (either via commit or 
rollback). However another context can be used in all these scenarios instead 
of a database. This concept is called ObjectContext "nesting". Nesting is a 
parent/child relationship between two contexts, where child is a nested context 
and selects or commits its objects via a parent.
+In all the examples shown so far an ObjectContext would directly connect to a 
database to select data
+or synchronize its state (either via commit or rollback). However another 
context can be used in all these scenarios
+instead of a database. This concept is called ObjectContext "nesting".
+Nesting is a parent/child relationship between two contexts, where child is a 
nested context and selects
+or commits its objects via a parent.
 
-Nesting is useful to create isolated object editing areas (child contexts) 
that need to all be committed to an intermediate in-memory store (parent 
context), or rolled back without affecting changes already recorded in the 
parent. Think cascading GUI dialogs, or parallel AJAX requests coming to the 
same session.
+Nesting is useful to create isolated object editing areas (child contexts) 
that need to
+all be committed to an intermediate in-memory store (parent context),
+or rolled back without affecting changes already recorded in the parent.
+Think cascading GUI dialogs, or parallel AJAX requests coming to the same 
session.
 
-In theory Cayenne supports any number of nesting levels, however applications 
should generally stay with one or two, as deep hierarchies will most certainly 
degrade the performance of the deeply nested child contexts. This is due to the 
fact that each context in a nesting chain has to update its own objects during 
most operations.
+In theory Cayenne supports any number of nesting levels, however applications 
should generally stay with one or two,
+as deep hierarchies will most certainly degrade the performance of the deeply 
nested child contexts.
+This is due to the fact that each context in a nesting chain has to update its 
own objects during most operations.
 
-Cayenne ROP is an extreme case of nesting when a child context is located in a 
separate JVM and communicates with its parent via a web service. ROP is 
discussed in details in the following chapters. Here we concentrate on the 
same-VM nesting.
+Cayenne ROP is an extreme case of nesting when a child context is located in a 
separate JVM and communicates
+with its parent via a web service. ROP is discussed in details in the 
following chapters.
+Here we concentrate on the same-VM nesting.
 
 To create a nested context, use an instance of ServerRuntime, passing it the 
desired parent:
 
 [source, java]
 ----
 ObjectContext parent = runtime.newContext();
-ObjectContext nested = runtime.newContext((DataChannel) parent);
+ObjectContext nested = runtime.newContext(parent);
 ----
 
-From here a nested context operates just like a regular context (you can 
perform queries, create and delete objects, etc.). The only difference is that 
commit and rollback operations can either be limited to synchronization with 
the parent, or cascade all the way to the database:
+From here a nested context operates just like a regular context (you can 
perform queries,
+create and delete objects, etc.). The only difference is that commit and 
rollback operations
+can either be limited to synchronization with the parent, or cascade all the 
way to the database:
 
 [source, java]
 ----
@@ -217,11 +250,16 @@ nested.rollbackChanges();
 
 ==== Generic Persistent Objects
 
-As described in the CayenneModeler chapter, Cayenne supports mapping of 
completely generic classes to specific entities. Although for conveniece most 
applications should stick with entity-specific class mappings, the generic 
feature offers some interesting possibilities, such as creating mappings 
completely on the fly in a running application, etc.
+As described in the CayenneModeler chapter, Cayenne supports mapping of 
completely generic classes
+to specific entities. Although for conveniece most applications should stick 
with entity-specific class mappings,
+the generic feature offers some interesting possibilities, such as creating 
mappings completely
+on the fly in a running application, etc.
 
-Generic objects are first class citizens in Cayenne, and all common persistent 
operations apply to them as well. There are some pecularities however, 
described below.
+Generic objects are first class citizens in Cayenne, and all common persistent 
operations apply to them as well.
+There are some pecularities however, described below.
 
-When creating a new generic object, either cast your ObjectContext to 
DataContext (that provides "newObject(String)" API), or provide your object 
with an explicit ObjectId:
+When creating a new generic object, either cast your ObjectContext to 
DataContext
+(that provides `newObject(String)` API), or provide your object with an 
explicit ObjectId:
 
 [source, java]
 ----
@@ -260,13 +298,29 @@ String entityName = generic.getObjectId().getEntityName();
 
 ==== Transactions
 
-Considering how much attention is given to managing transactions in most other 
ORMs, transactions have been conspicuously absent from the ObjectContext 
discussion till now. The reason is that transactions are seamless in Cayenne in 
all but a few special cases. ObjectContext is an in-memory container of objects 
that is disconnected from the database, except when it needs to run an 
operation. So it does not care about any surrounding transaction scope. Sure 
enough all database operations are transactional, so when an application does a 
commit, all SQL execution is wrapped in a database transaction. But this is 
done behind the scenes and is rarely a concern to the application code.
-
-Two cases where transactions need to be taken into consideration are 
container-managed and application-managed transactions.
-
-If you are using an EJB container (or some other JTA environment), you'll 
likely need to switch Cayenne runtime into "external transactions mode". This 
is done by setting DI configuration property defined in 
`Constants.SERVER_EXTERNAL_TX_PROPERTY` (see Appendix A). If this property is 
set to "true", Cayenne assumes that JDBC Connections obtained by runtime 
whenever that might happen are all coming from a transactional DataSource 
managed by the container. In this case Cayenne does not attempt to commit or 
rollback the connections, leaving it up to the container to do that when 
appropriate.
-
-In the second scenario, an application might need to define its own 
transaction scope that spans more than one Cayenne operation. E.g. two 
sequential commits that need to be rolled back together in case of failure. 
This can be done via `ServerRuntime.performInTransaction` method:
+Considering how much attention is given to managing transactions in most other 
ORMs,
+transactions have been conspicuously absent from the ObjectContext discussion 
till now.
+The reason is that transactions are seamless in Cayenne in all but a few 
special cases.
+ObjectContext is an in-memory container of objects that is disconnected from 
the database,
+except when it needs to run an operation. So it does not care about any 
surrounding transaction scope.
+Sure enough all database operations are transactional, so when an application 
does a commit,
+all SQL execution is wrapped in a database transaction. But this is done 
behind the scenes
+and is rarely a concern to the application code.
+
+Two cases where transactions need to be taken into consideration are 
container-managed and
+application-managed transactions.
+
+If you are using an EJB container (or some other JTA environment),
+you'll likely need to switch Cayenne runtime into "external transactions mode".
+This is done by setting DI configuration property defined in 
`Constants.SERVER_EXTERNAL_TX_PROPERTY` (see Appendix A).
+If this property is set to "true", Cayenne assumes that JDBC Connections 
obtained by runtime
+whenever that might happen are all coming from a transactional DataSource 
managed by the container.
+In this case Cayenne does not attempt to commit or rollback the connections, 
leaving it up to the container
+to do that when appropriate.
+
+In the second scenario, an application might need to define its own 
transaction scope that spans more
+than one Cayenne operation. E.g. two sequential commits that need to be rolled 
back together in case of failure.
+This can be done via `ServerRuntime.performInTransaction` method:
 
 [source, java]
 ----
@@ -284,7 +338,8 @@ Integer result = runtime.performInTransaction(() -> {
 });
 ----
 
-When inside the transaction, current thread Transaction object can be accessed 
via a static method. E.g. here is an example that initializes transaction JDBC 
connection with a custom connection object :
+When inside the transaction, current thread Transaction object can be accessed 
via a static method.
+E.g. here is an example that initializes transaction JDBC connection with a 
custom connection object :
 
 [source, java]
 ----

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e4eb10f0/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part2/tuning.adoc
----------------------------------------------------------------------
diff --git 
a/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part2/tuning.adoc
 
b/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part2/tuning.adoc
index fb5bb3f..ea0fea2 100644
--- 
a/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part2/tuning.adoc
+++ 
b/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part2/tuning.adoc
@@ -290,39 +290,9 @@ Those are arbitrary names that allow to categorize queries 
for the purpose of se
 
 The above API is enough for the caching to work, but by default your cache is 
an unmanaged LRU map. You can't control its size,
 expiration policies, etc. For the managed cache, you will need to explicitly 
use one of the more advanced cache providers.
-One such provider available in Cayenne is a provider for 
http://www.ehcache.org[EhCache].
-It can be enabled on ServerRuntime startup in a custom Module:
+Use can use <<ext-cayenne-jcache,JCache integration module>> to enable any of 
JCache API compatible caching providers.
 
-[source, Java]
-----
-ServerRuntimeBuilder
-  .builder()
-  .addModule((binder) ->
-     binder.bind(QueryCache.class).to(EhCacheQueryCache.class)
-  )
-  .build();
-----
-
-By default EhCache reads a file called "ehcache.xml" located on classpath. You 
can put your cache configuration in that file. E.g.:
-
-[source, XML]
-----
-<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
-       xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="false"
-       monitoring="off" dynamicConfig="false">
-
-       <defaultCache maxEntriesLocalHeap="1000" eternal="false"
-               overflowToDisk="false" timeToIdleSeconds="3600" 
timeToLiveSeconds="3600">
-       </defaultCache>
-
-       <cache name="artists" timeToLiveSeconds="20" maxEntriesLocalHeap="100" 
/>
-</ehcache>
-----
-
-The example shows how to configure default cache settings ("defaultCache") as 
well as settings for a named cache group ("artists").
-For many other things you can put in "ehcache.xml" refer to EhCache docs.
-
-Often "passive" cache expiration policies similar to shown above are not 
sufficient, and the users want real-time cache invalidation when the data 
changes.
+Often "passive" cache expiration policies used by caching providers are not 
sufficient, and the users want real-time cache invalidation when the data 
changes.
 So in addition to those policies, the app can invalidate individual cache 
groups explicitly with `RefreshQuery`:
 
 [source, Java]
@@ -331,30 +301,9 @@ RefreshQuery refresh = new RefreshQuery("artist");
 context.performGenericQuery(refresh);
 ----
 
-The above can be used e.g. to build UI for manual cache invalidation. It is 
also possible to automate cache refresh when certain entities are committed.
-This requires including `cayenne-lifecycle.jar` deoendency. From that library 
you will need two things: `@CacheGroups` annotation
-to mark entities that generate cache invalidation events and  
`CacheInvalidationFilter` that catches the updates to the annotated objects and 
generates appropriate invalidation events:
-
-[source, Java]
-----
-// configure filter on startup
-ServerRuntimeBuilder
-  .builder()
-  .addModule((binder) ->
-     
binder.bindList(Constants.SERVER_DOMAIN_FILTERS_LIST).add(CacheInvalidationFilter.class)
-  )
-  .build();
-----
-
-
-Now you can associate entities with cache groups, so that commits to those 
entities would atomatically invalidate the groups:
-
-[source, Java]
-----
-@CacheGroups("artists")
-public class Artist extends _Artist {
-}
-----
+The above can be used e.g. to build UI for manual cache invalidation.
+It is also possible to automate cache refresh when certain entities are 
committed.
+This can be done with the help of <<ext-cache-invalidation,Cache invalidation 
extension>>.
 
 Finally you may cluster cache group events. They are very small and can be 
efficiently sent over the wire to other JVMs running Cayenne.
 An example of Cayenne setup with event clustering is 
https://github.com/andrus/wowodc13/tree/master/services/src/main/java/demo/services/cayenne[available
 on GitHub].
@@ -395,7 +344,8 @@ public class MyModule implements Module {
 
     @Override
     public void configure(Binder binder) {
-        
binder.bindMap(Constants.PROPERTIES_MAP).put(Constants.SERVER_CONTEXTS_SYNC_PROPERTY,
 "false");
+        ServerModule.contributeProperties(binder)
+            .put(Constants.SERVER_CONTEXTS_SYNC_PROPERTY, "false");
     }
 }
 ----

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e4eb10f0/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part3.adoc
----------------------------------------------------------------------
diff --git 
a/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part3.adoc 
b/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part3.adoc
index 5e211d1..0bf6e6e 100644
--- a/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part3.adoc
+++ b/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part3.adoc
@@ -15,14 +15,11 @@
 == Cayenne Framework - Remote Object Persistence
 
 include::part3/rop.adoc[]
-
-include::part3/ropSetup.adoc[]
-
-include::part3/serverImpl.adoc[]
-
-include::part3/clientImpl.adoc[]
-
 include::part3/ropDeployment.adoc[]
 
-include::part3/limitations.adoc[]
+// TODO: add content to these files:
+//include::part3/ropSetup.adoc[]
+//include::part3/serverImpl.adoc[]
+//include::part3/clientImpl.adoc[]
+//include::part3/limitations.adoc[]
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e4eb10f0/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part3/ropDeployment.adoc
----------------------------------------------------------------------
diff --git 
a/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part3/ropDeployment.adoc
 
b/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part3/ropDeployment.adoc
index 6aa4388..230aef8 100644
--- 
a/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part3/ropDeployment.adoc
+++ 
b/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part3/ropDeployment.adoc
@@ -14,9 +14,17 @@
 
 === ROP Deployment
 
-==== Deploying ROP Server
+==== Server Security Note
 
-NOTE: Recent versions of Tomcat and Jetty containers (e.g. Tomcat 6 and 7, 
Jetty 8) contain code addressing a security concern related to "session 
fixation problem" by resetting the existing session ID of any request that 
requires BASIC authentcaition. If ROP service is protected with declarative 
security (see the ROP tutorial and the following chapters on security), this 
feature prevents the ROP client from attaching to its session, resulting in 
MissingSessionExceptions. To solve that you will need to either switch to an 
alternative security mechanism, or disable "session fixation problem" 
protections of the container. E.g. the later can be achieved in Tomcat 7 by 
adding the following context.xml file to the webapp's META-INF/ directory:
+Recent versions of Tomcat and Jetty containers (e.g. Tomcat 6 and 7, Jetty 8) 
contain code
+addressing a security concern related to "session fixation problem" by 
resetting the existing session ID of any request
+that requires BASIC authentication. If ROP service is protected with 
declarative security
+(see the ROP tutorial and the following chapters on security), this feature 
prevents the ROP client
+from attaching to its session, resulting in `MissingSessionExceptions`.
+
+To solve that you will need to either switch to an alternative security 
mechanism,
+or disable "session fixation problem" protections of the container.
+E.g. the later can be achieved in Tomcat 7 by adding the following 
`context.xml` file to the webapp's `META-INF/` directory:
 
 [source, XML]
 ----
@@ -26,9 +34,9 @@ NOTE: Recent versions of Tomcat and Jetty containers (e.g. 
Tomcat 6 and 7, Jetty
 </Context>
 ----
 
-(The <Valve> tag can also be placed within the <Context> in any other 
locations used by Tomcat to load context configurations)
+(The `<Valve>` tag can also be placed within the `<Context>` in any other 
locations used by Tomcat to load context configurations)
 
-==== Deploying ROP Client
+//==== Deploying ROP Client
 
-==== Security
+//==== Security
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/e4eb10f0/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part5/cacheInvalidation.adoc
----------------------------------------------------------------------
diff --git 
a/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part5/cacheInvalidation.adoc
 
b/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part5/cacheInvalidation.adoc
index 246162f..43a69c5 100644
--- 
a/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part5/cacheInvalidation.adoc
+++ 
b/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part5/cacheInvalidation.adoc
@@ -79,7 +79,7 @@ Now we'll set up it's usage by `ServerRuntime`:
 ----
 ServerRuntime.builder()
         .addModule(CacheInvalidationModule.extend()
-                // this will disable default handler based on @CacheGroups, 
and this is optional
+                // optionally you can disable @CacheGroups annotation 
processing
                 .noCacheGroupsHandler()
                 .addHandler(CustomInvalidationHandler.class)
                 .module())

Reply via email to