http://git-wip-us.apache.org/repos/asf/cayenne/blob/df1324e4/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..8d5c21f --- /dev/null +++ b/docs/asciidoc/upgrade-guide/src/docs/asciidoc/upgrade-guide.adoc @@ -0,0 +1,42 @@ +// 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 4.1 Features +: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 +// 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._# + + +This guide highlights the new features and changes introduced in Apache Cayenne 4.1. For a full list of changes consult +RELEASE-NOTES.txt included in Cayenne download. For release-specific upgrade instructions check UPGRADE.txt. + +include::_upgrade-guide/new-features.adoc[] \ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cayenne/blob/df1324e4/docs/doc/pom.xml ---------------------------------------------------------------------- diff --git a/docs/doc/pom.xml b/docs/doc/pom.xml index 69d4af3..02574f2 100644 --- a/docs/doc/pom.xml +++ b/docs/doc/pom.xml @@ -157,6 +157,7 @@ <!-- this is relative to target/site/apidocs --> <destDir>doc/api</destDir> <stylesheet>java</stylesheet> + <header><![CDATA[<a href="http://cayenne.apache.org" target="top">Apache Cayenne</a>]]></header> <additionalDependencies> <additionalDependency> <groupId>net.sf.ehcache</groupId> http://git-wip-us.apache.org/repos/asf/cayenne/blob/df1324e4/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 786f1ef..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>4.1.M2-SNAPSHOT</version> - </parent> - - <modelVersion>4.0.0</modelVersion> - <artifactId>cayenne-guide</artifactId> - <name>cayenne-guide: Docbook - Cayenne Guide</name> -</project> http://git-wip-us.apache.org/repos/asf/cayenne/blob/df1324e4/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 f75ba15..0000000 --- a/docs/docbook/cayenne-guide/src/docbkx/appendix-a.xml +++ /dev/null @@ -1,190 +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.server.external_tx</code> - defines whether runtime should use - external transactions.</td> - <td>true, false</td> - <td>false</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/df1324e4/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<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<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<DataChannelFilter></code></td> - <td>Stores DataDomain filters.</td> - </tr> - <tr> - <td><code>cayenne.server.project_locations</code></td> - <td><code>List<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<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<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<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<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/df1324e4/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 -<DEFAULT> SKIP : { -" " -| "\t" -| "\n" -| "\r" -} - -<DEFAULT> TOKEN : { -<NULL: "null" | "NULL"> -| <TRUE: "true" | "TRUE"> -| <FALSE: "false" | "FALSE"> -} - -<DEFAULT> TOKEN : { -<PROPERTY_PATH: <IDENTIFIER> ("." <IDENTIFIER>)*> -} - -<DEFAULT> TOKEN : { -<IDENTIFIER: <LETTER> (<LETTER> | <DIGIT>)* (["+"])?> -| <#LETTER: ["_","a"-"z","A"-"Z"]> -| <#DIGIT: ["0"-"9"]> -} - -/** - * Quoted Strings, whose object value is stored in the token manager's - * "literalValue" field. Both single and double qoutes are allowed - */<DEFAULT> MORE : { -"\'" : WithinSingleQuoteLiteral -| "\"" : WithinDoubleQuoteLiteral -} - -<WithinSingleQuoteLiteral> MORE : { -<ESC: "\\" (["n","r","t","b","f","\\","\'","`","\""] | (["0"-"3"])? ["0"-"7"] (["0"-"7"])?)> : { -| <~["\'","\\"]> : { -} - -<WithinSingleQuoteLiteral> TOKEN : { -<SINGLE_QUOTED_STRING: "\'"> : DEFAULT -} - -<WithinDoubleQuoteLiteral> MORE : { -<STRING_ESC: <ESC>> : { -| <~["\"","\\"]> : { -} - -<WithinDoubleQuoteLiteral> TOKEN : { -<DOUBLE_QUOTED_STRING: "\""> : DEFAULT -} - -/** - * Integer or real Numeric literal, whose object value is stored in the token manager's - * "literalValue" field. - */<DEFAULT> TOKEN : { -<INT_LITERAL: ("0" (["0"-"7"])* | ["1"-"9"] (["0"-"9"])* | "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+) - (["l","L","h","H"])?> : { -| <FLOAT_LITERAL: <DEC_FLT> (<EXPONENT>)? (<FLT_SUFF>)? | <DEC_DIGITS> <EXPONENT> (<FLT_SUFF>)? -| <DEC_DIGITS> <FLT_SUFF>> : { -| <#DEC_FLT: (["0"-"9"])+ "." (["0"-"9"])* | "." (["0"-"9"])+> -| <#DEC_DIGITS: (["0"-"9"])+> -| <#EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+> -| <#FLT_SUFF: ["d","D","f","F","b","B"]> -} - -NON-TERMINALS - expression := orCondition <EOF> - orCondition := andCondition ( "or" andCondition )* - andCondition := notCondition ( "and" notCondition )* - notCondition := ( "not" | "!" ) simpleCondition - | simpleCondition - simpleCondition := <TRUE> - | <FALSE> - | scalarConditionExpression - ( simpleNotCondition - | ( "=" | "==" ) scalarExpression - | ( "!=" | "<>" ) scalarExpression - | "<=" scalarExpression - | "<" 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 - | <SINGLE_QUOTED_STRING> - | <DOUBLE_QUOTED_STRING> - | <NULL> - scalarExpression := scalarConditionExpression - | <TRUE> - | <FALSE> - scalarConstExpression := <SINGLE_QUOTED_STRING> - | <DOUBLE_QUOTED_STRING> - | namedParameter - | <INT_LITERAL> - | <FLOAT_LITERAL> - | <TRUE> - | <FALSE> - scalarNumericExpression := multiplySubtractExp - ( "+" multiplySubtractExp | "-" multiplySubtractExp )* - multiplySubtractExp := numericTerm ( "*" numericTerm | "/" numericTerm )* - numericTerm := ( "+" )? numericPrimary - | "-" numericPrimary - numericPrimary := "(" orCondition ")" - | pathExpression - | namedParameter - | <INT_LITERAL> - | <FLOAT_LITERAL> - namedParameter := "$" <PROPERTY_PATH> - pathExpression := ( <PROPERTY_PATH> - | "obj:" <PROPERTY_PATH> - | "db:" <PROPERTY_PATH> - | "enum:" <PROPERTY_PATH> ) - -</programlisting> - </para> - - -</appendix> http://git-wip-us.apache.org/repos/asf/cayenne/blob/df1324e4/docs/docbook/cayenne-guide/src/docbkx/cayenne-mapping-structure.xml ---------------------------------------------------------------------- diff --git a/docs/docbook/cayenne-guide/src/docbkx/cayenne-mapping-structure.xml b/docs/docbook/cayenne-guide/src/docbkx/cayenne-mapping-structure.xml deleted file mode 100644 index 6d76ef2..0000000 --- a/docs/docbook/cayenne-guide/src/docbkx/cayenne-mapping-structure.xml +++ /dev/null @@ -1,95 +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. ---> -<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" - version="5.0" xml:id="cayenne-mapping-structure"> - <title>Cayenne Mapping Structure</title> - <section xml:id="cayenne-project"> - <title>Cayenne Project</title> - <para>A Cayenne project is an XML representation of a model connecting database schema with - Java classes. A project is normally created and manipulated via CayenneModeler GUI and - then used to initialize Cayenne runtime. A project is made of one or more files. There's - always a root project descriptor file in any valid project. It is normally called - <code>cayenne-xyz.xml</code>, where "xyz" is the name of the project.</para> - <para>Project descriptor can reference DataMap files, one per DataMap. DataMap files are - normally called <code>xyz.map.xml</code>, where "xyz" is the name of the DataMap. For - legacy reasons this naming convention is different from the convention for the root - project descriptor above, and we may align it in the future versions. Here is how a - typical project might look on the file - system:<screen><prompt>$</prompt> <userinput>ls -l</userinput> -total 24 --rw-r--r-- 1 cayenne staff 491 Jan 28 18:25 cayenne-project.xml --rw-r--r-- 1 cayenne staff 313 Jan 28 18:25 datamap.map.xml</screen></para> - <para>DataMap are referenced by name in the root - descriptor:<programlisting language="xml"><map name="datamap"/></programlisting></para> - <para>Map files are resolved by Cayenne by appending "<code>.map.xml</code>" extension to the - map name, and resolving the resulting string relative to the root descriptor URI. The - following sections discuss varios ORM model objects, without regards to their XML - representation. XML format details are really unimportant to the Cayenne users.</para> - </section> - <section xml:id="datamap"> - <title>DataMap</title> - <para>DataMap is a container of persistent entities and other object-relational metadata. - DataMap provides developers with a scope to organize their entities, but it does not - provide a namespace for entities. In fact all DataMaps present in runtime are combined - in a single namespace. Each DataMap must be associated with a DataNode. This is how - Cayenne knows which database to use when running a query.</para> - </section> - <section xml:id="datanode"> - <title>DataNode</title> - <para>DataNode is model of a database. It is actually pretty simple. It has an arbitrary - user-provided name and information needed to create or locate a JDBC DataSource. Most - projects only have one DataNode, though there may be any number of nodes if - needed.</para> - </section> - <section xml:id="dbentity"> - <title>DbEntity</title> - <para>DbEntity is a model of a single DB table or view. DbEntity is made of DbAttributes - that correspond to columns, and DbRelationships that map PK/FK pairs. DbRelationships - are not strictly tied to FK constraints in DB, and should be mapped for all logical - "relationships" between the tables.</para> - </section> - <section xml:id="objentity"> - <title>ObjEntity</title> - <para>ObjEntity is a model of a single persistent Java class. ObjEntity is made of - ObjAttributes and ObjRelationships. Both correspond to entity class properties. However - ObjAttributes represent "simple" properties (normally things like String, numbers, - dates, etc.), while ObjRelationships correspond to properties that have a type of - another entity. </para> - <para>ObjEntity maps to one or more DbEntities. There's always one "root" DbEntity for each - ObjEntity. ObjAttribiute maps to a DbAttribute or an Embeddable. Most often mapped - DbAttribute is from the root DbEntity. Sometimes mapping is done to a DbAttribute from - another DbEntity somehow related to the root DbEntity. Such ObjAttribute is called - "flattened". Similarly ObjRelationship maps either to a single DbRelationship, or to a - chain of DbRelationships ("flattened" ObjRelationship).</para> - <para>ObjEntities may also contain mapping of their lifecycle callback methods.</para> - </section> - <section xml:id="embeddable"> - <title>Embeddable</title> - <para>Embeddable is a model of a Java class that acts as a single attribute of an ObjEntity, - but maps to multiple columns in the database.</para> - </section> - <section xml:id="procedure"> - <title>Procedure</title> - <para>A model of a stored procedure in the database.</para> - </section> - <section xml:id="query"> - <title>Query</title> - <para>A model of a query. Cayenne allows queries to be mapped in Cayenne project, or created - in the code. Depending on the circumstances the users may take one or the other - approach.</para> - </section> -</chapter> http://git-wip-us.apache.org/repos/asf/cayenne/blob/df1324e4/docs/docbook/cayenne-guide/src/docbkx/cayennemodeler-application.xml ---------------------------------------------------------------------- diff --git a/docs/docbook/cayenne-guide/src/docbkx/cayennemodeler-application.xml b/docs/docbook/cayenne-guide/src/docbkx/cayennemodeler-application.xml deleted file mode 100644 index 4c6b9ae..0000000 --- a/docs/docbook/cayenne-guide/src/docbkx/cayennemodeler-application.xml +++ /dev/null @@ -1,116 +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. ---> -<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" - version="5.0" xml:id="cayennemodeler-application"> - <title>CayenneModeler Application</title> - <section xml:id="working-with-mapping-projects"> - <title>Working with Mapping Projects</title> - <para></para> - </section> - <section xml:id="reverse-engineering-database"> - <title>Reverse Engineering Database</title> - <para> - See chapter <link linkend="re-modeler">Reverse Engineering in Cayenne Modeler</link> - </para> - </section> - <section xml:id="generating-database-schema"> - <title>Generating Database Schema</title> - <para> - With Cayenne Modeler you can create simple database schemas without any additional database tools. - This is a good option for initial database setup if you completely created you model with the Modeler. - You can start SQL schema generation by selecting menu - <emphasis role="strong"> - <guimenu>Tools</guimenu> > <guimenuitem>Generate Database Schema</guimenuitem> - </emphasis> - </para> - <para> - You can select what database parts should be generated and what tables you want - </para> - </section> - <section xml:id="migrations"> - <title>Migrations</title> - <para> </para> - </section> - <section xml:id="generating-java-classes"> - <title>Generating Java Classes</title> - <para> - Before using Cayenne in you code you need to generate java source code for persistent objects. - This can be done with Modeler GUI or via <link linkend="mvn-cgen">cgen</link> maven/ant plugin. - </para> - <para> - To generate classes in the modeler use - <emphasis role="strong"> - <guimenu>Tools</guimenu> > <guimenuitem>Generate Classes</guimenuitem> - </emphasis> - </para> - <para> - There is three default types of code generation - <itemizedlist> - <listitem> - <para><emphasis role="strong">Standard Persistent Objects</emphasis></para> - <para> - Default type of generation suitable for almost all cases. - Use this type unless you now what exactly you need to customize. - </para> - </listitem> - <listitem> - <para><emphasis role="strong">Client Persistent Objects</emphasis></para> - <para> - - </para> - </listitem> - <listitem> - <para><emphasis role="strong">Advanced.</emphasis></para> - <para> - In advanced mode you can control almost all aspects of code generation including custom templates for java code. - See default Cayenne templates on - <link xlink:href="https://github.com/apache/cayenne/tree/master/cayenne-tools/src/main/resources/templates/v1_2">GitHub</link> - as an example - </para> - </listitem> - </itemizedlist> - </para> - </section> - <section xml:id="modeling-inheritance"> - <title>Modeling Inheritance</title> - <para> </para> - </section> - <section xml:id="modeling-generic-persistence-classes"> - <title>Modeling Generic Persistent Classes</title> - <para>Normally each ObjEntity is mapped to a specific Java class (such as Artist or - Painting) that explicitly declare all entity properties as pairs of getters and setters. - However Cayenne allows to map a completly generic class to any number of entities. The - only expectation is that a generic class implements - <emphasis>org.apache.cayenne.DataObject</emphasis>. So an ideal candidate for a - generic class is CayenneDataObject, or some custom subclass of CayenneDataObject.</para> - <para>If you don't enter anything for Java Class of an ObjEntity, Cayenne assumes generic - mapping and uses the following implicit rules to determine a class of a generic object. - If DataMap "Custom Superclass" is set, runtime uses this class to instantiate new - objects. If not, org.apache.cayenne.CayenneDataObject is used.</para> - <para>Class generation procedures (either done in the Modeler or with Ant or Maven) would - skip entities that are mapped to CayenneDataObject explicitly or have no class - mapping.</para> - </section> - <section xml:id="mapping-objattributes-to-custom-classes"> - <title>Mapping ObjAttributes to Custom Classes</title> - <para> </para> - </section> - <section xml:id="modeling-pk-generation-strategy"> - <title>Modeling Primary Key Generation Strategy</title> - <para> </para> - </section> -</chapter> http://git-wip-us.apache.org/repos/asf/cayenne/blob/df1324e4/docs/docbook/cayenne-guide/src/docbkx/current-limitations.xml ---------------------------------------------------------------------- diff --git a/docs/docbook/cayenne-guide/src/docbkx/current-limitations.xml b/docs/docbook/cayenne-guide/src/docbkx/current-limitations.xml deleted file mode 100644 index 4b69324..0000000 --- a/docs/docbook/cayenne-guide/src/docbkx/current-limitations.xml +++ /dev/null @@ -1,20 +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. ---> -<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" - version="5.0" xml:id="current-limitations"> - <title>Current Limitations</title> -</chapter> http://git-wip-us.apache.org/repos/asf/cayenne/blob/df1324e4/docs/docbook/cayenne-guide/src/docbkx/customizing-cayenne-runtime.xml ---------------------------------------------------------------------- diff --git a/docs/docbook/cayenne-guide/src/docbkx/customizing-cayenne-runtime.xml b/docs/docbook/cayenne-guide/src/docbkx/customizing-cayenne-runtime.xml deleted file mode 100644 index 89b6e38..0000000 --- a/docs/docbook/cayenne-guide/src/docbkx/customizing-cayenne-runtime.xml +++ /dev/null @@ -1,470 +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. ---> -<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="customizing-cayenne-runtime"> - <title>Customizing Cayenne Runtime</title> - <section xml:id="depdendency-injection-container"> - <title>Dependency Injection Container</title> - <para>Cayenne runtime is built around a small powerful dependency injection (DI) container. Just - like other popular DI technologies, such as Spring or Guice, Cayenne DI container - manages sets of interdependent objects and allows users to configure them. These - objects are regular Java objects. We are calling them "services" in this document to - distinguish from all other objects that are not configured in the container and are not - managed. DI container is responsible for service instantiation, injecting correct - dependencies, maintaining service instances scope, and dispatching scope events to - services. </para> - <para>The services are configured in special Java classes called "modules". Each module - defines binding of service interfaces to implementation instances, implementation types - or providers of implementation instances. There are no XML configuration files, and all - the bindings are type-safe. The container supports injection into instance variables and - constructor parameters based on the <code>@Inject</code> annotation. This mechanism is - very close to Google Guice.</para> - <para>The discussion later in this chapter demonstrates a standalone DI container. But keep in - mind that Cayenne already has a built-in Injector, and a set of default modules. A - Cayenne user would normally only use the API below to write custom extension modules - that will be loaded in that existing container when creating ServerRuntime. See - "Starting and Stopping ServerRuntime" chapter for an example of passing an extension - module to Cayenne.</para> - <para>Cayenne DI probably has ~80% of the features expected in a DI container and has no - dependency on the rest of Cayenne, so in theory can be used as an application-wide DI - engine. But it's primary purpose is still to serve Cayenne. Hence there are no plans to - expand it beyond Cayenne needs. It is an ideal "embedded" DI that does not interfere - with Spring, Guice or any other such framework present elsewhere in the - application.</para> - <section xml:id="di-bindings-api"> - <title>DI Bindings API</title> - <para>To have a working DI container, we need three things: service interfaces and - classes, a module that describes service bindings, a container that loads the - module, and resolves the depedencies. Let's start with service interfaces and - classes:<programlisting language="java">public interface Service1 { - public String getString(); -}</programlisting><programlisting language="java">public interface Service2 { - public int getInt(); -}</programlisting></para> - <para>A service implementation using instance variable - injection:<programlisting language="java">public class Service1Impl implements Service1 { - @Inject - private Service2 service2; - - public String getString() { - return service2.getInt() + "_Service1Impl"; - } -}</programlisting>Same - thing, but using constructor - injection:<programlisting language="java">public class Service1Impl implements Service1 { - - private Service2 service2; - - public Service1Impl(@Inject Service2 service2) { - this.service2 = service2; - } - - public String getString() { - return service2.getInt() + "_Service1Impl"; - } -} -</programlisting><programlisting language="java">public class Service2Impl implements Service2 { - private int i; - - public int getInt() { - return i++; - } -}</programlisting></para> - <para>Now let's create a module implementing - <code>org.apache.cayenne.tutorial.di.Module</code> interface that will contain - DI configuration. A module binds service objects to keys that are reference. Binder - provided by container implements fluent API to connect the key to implementation, - and to configure various binding options (the options, such as scope, are - demonstrated later in this chapter). The simplest form of a key is a Java Class - object representing service interface. Here is a module that binds Service1 and - Service2 to corresponding default implementations:</para> - <para> - <programlisting language="java">public class Module1 implements Module { - - public void configure(Binder binder) { - binder.bind(Service1.class).to(Service1Impl.class); - binder.bind(Service2.class).to(Service2Impl.class); - } -}</programlisting> - </para> - <para>Once we have at least one module, we can create a DI container. - <code>org.apache.cayenne.di.Injector</code> is the container class in - Cayenne:<programlisting language="java">Injector injector = DIBootstrap.createInjector(new Module1());</programlisting></para> - <para>Now that we have created the container, we can obtain services from it and call - their - methods:<programlisting language="java">Service1 s1 = injector.getInstance(Service1.class); -for (int i = 0; i < 5; i++) { - System.out.println("S1 String: " + s1.getString()); -}</programlisting></para> - <para>This outputs the following lines, demonstrating that s1 was Service1Impl and - Service2 injected into it was - Service2Impl:<programlisting language="java">0_Service1Impl -1_Service1Impl -2_Service1Impl -3_Service1Impl -4_Service1Impl</programlisting></para> - <para>There are more flavors of bindings: - <programlisting language="java">// binding to instance - allowing user to create and configure instance -// inside the module class -binder.bind(Service2.class).toInstance(new Service2Impl()); - -// binding to provider - delegating instance creation to a special -// provider class -binder.bind(Service1.class).toProvider(Service1Provider.class); - -// binding to provider instance -binder.bind(Service1.class).toProviderInstance(new Service1Provider()); - -// multiple bindings of the same type using Key -// injection can reference the key name in annotation: -// @Inject("i1") -// private Service2 service2; -binder.bind(Key.get(Service2.class, "i1")).to(Service2Impl.class); -binder.bind(Key.get(Service2.class, "i2")).to(Service2Impl.class);</programlisting></para> - <para>Another types of confiuguration that can be bound in the container are lists and - maps. They will be discussed in the following chapters. </para> - </section> - <section xml:id="managing-services-lifecycle"> - <title>Service Lifecycle</title> - <para>An important feature of the Cayenne DI container is instance <emphasis role="italic" - >scope</emphasis>. 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 - <code>Injector.getInstance(..)</code>, as well as injected into classes that - declare it as a dependency. </para> - <para>Singleton scope dispatches a "BeforeScopeEnd" event to interested services. This - event occurs before the scope is shutdown, i.e. when - <code>Injector.shutdown()</code> is called. Note that the built-in Cayenne - injector is shutdown behind the scenes when <code>ServerRuntime.shutdown()</code> - is invoked. Services may register as listeners for this event by annotating a - no-argument method with <code>@BeforeScopeEnd</code> annotation. Such method should - be implemented if a service needs to clean up some resources, stop threads, - etc.</para> - <para>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:<programlisting language="java">binder.bind(Service2.class).to(Service2Impl.class).withoutScope();</programlisting>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 - <code>org.apache.cayenne.di.spi.DefaultScope</code> with startup and shutdown - managed by the application (e.g. singleton scope is a DefaultScope managed by the - Injector) . </para> - </section> - <section xml:id="overriding-services"> - <title>Overriding Services</title> - <para>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.</para> - </section> - </section> - <section xml:id="ways-to-customize-runtime"> - <title> Customization Strategies</title> - <para>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:</para><programlisting language="java">public class MyExtensionsModule implements Module { - public void configure(Binder binder) { - // customizations go here... - } -}</programlisting><programlisting language="java">Module extensions = new MyExtensionsModule(); -ServerRuntime runtime = ServerRuntime.builder() - .addConfig("com/example/cayenne-mydomain.xml") - .addModule(extensions) - .build();</programlisting> - <section xml:id="changing-properties-of-existing-services"> - <title>Changing Properties of Existing Services</title> - <para>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".</para> - <para>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.<screen><prompt>$</prompt> java -Dcayenne.server.contexts_sync_strategy=false ...</screen></para> - <para>A second one is to contribute a property to - <code>org.apache.cayenne.configuration.DefaultRuntimeProperties.properties - </code>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. </para> - <para>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.</para> - <para>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.</para> - </section> - <section xml:id="contributing-to-service-lists-maps"> - <title>Contributing to Service Collections</title> - <para>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 - <code>org.apache.cayenne.configuration.server.DefaultDbAdapterFactory.detectors</code> - list:</para> - <programlisting language="java">public class MyDbAdapterDetector implements DbAdapterDetector { - public DbAdapter createAdapter(DatabaseMetaData md) throws SQLException { - // check if we support this database and retun custom adapter - ... - } -}</programlisting> - <programlisting language="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);</programlisting> - <para>Maps are customized using a similar "<code>bindMap</code>" method.</para> - <para>The names of built-in collections are listed in "Appendix B".</para> - </section> - <section xml:id="alternative-service-implementations"> - <title>Alternative Service Implementations</title> - <para>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 - <code>org.apache.cayenne.configuration.server.ServerModule</code> - the main - built-in module in Cayenne. </para> - <para>Now an example of overriding <code>QueryCache</code> service. The default - implementation of this service is provided by <code>MapQueryCacheProvider</code>. - But if we want to use <code>EhCacheQueryCache</code> (a Cayenne wrapper for the - EhCache framework), we can define it like - this:<programlisting language="java">binder.bind(QueryCache.class).to(EhCacheQueryCache.class);</programlisting></para> - </section> - </section> - <section> - <title>Using custom data types</title> - <section> - <title>Value object type</title> - <para> - <code>ValueObjectType</code> is a new and lightweight alternative to the Extended Types API described in the following section. - In most cases is should be preferred as is it easier to understand and use. Currently only one case is known when <code>ExtendedType</code> should be used: - when your value object can be mapped on different JDBC types. - </para> - <para> - In order to use your custom data type you should implement <code>ValueObjectType</code> describing it in terms of some type already known to Cayenne - (e.g. backed by system or user ExtendedType). - Let's assume we want to support some data type called <code>Money</code>: - <programlisting language="java"><![CDATA[public class Money { - private BigDecimal value; - - public Money(BigDecimal value) { - this.value = value; - } - - public BigDecimal getValue() { - return value; - } - - // .. some other business logic .. -}]]></programlisting> - Here is how <code>ValueObjectType</code> that will allow to store our <code>Money</code> class as <code>BigDecimal</code> - can be implemented: - <programlisting language="java"><![CDATA[public class MoneyValueObjectType implements ValueObjectType<Money, BigDecimal> { - - @Override - public Class<BigDecimal> getTargetType() { - return BigDecimal.class; - } - - @Override - public Class<Money> getValueType() { - return Money.class; - } - - @Override - public Money toJavaObject(BigDecimal value) { - return new Money(value); - } - - @Override - public BigDecimal fromJavaObject(Money object) { - return object.getValue(); - } - - @Override - public String toCacheKey(Money object) { - return object.getValue().toString(); - } -}]]></programlisting> - </para> - <para> - Last step is to register this new type in <code>ServerRuntime</code>: - <programlisting language="java"><![CDATA[ServerRuntime runtime = ServerRuntime.builder() - .addConfig("cayenne-project.xml") - .addModule(binder -> ServerModule.contributeValueObjectTypes(binder).add(MoneyValueObjectType.class)) - .build();]]></programlisting> - </para> - <para>More examples of implementation you can find in - <link xlink:href="https://github.com/apache/cayenne/tree/master/cayenne-joda">cayenne-joda module</link>.</para> - </section> - <section xml:id="extendedtypes"> - <title>Extended Types</title> - <para>JDBC specification defines a set of "standard" database column types (defined in java.sql.Types class) - and a very specific mapping of these types to Java Object Types, such as java.lang.String, - java.math.BigDecimal, etc. Sometimes there is a need to use a custom Java type not known to JDBC driver and - Cayenne allows to configure it. For this Cayenne needs to know how to instantiate this type from - a database "primitive" value, and conversely, how to transform an object of the custom type to - a JDBC-compatible object.</para> - <section xml:id="supporting-non-standard-types"> - <title>Supporting Non-Standard Types</title> - <para>For supporting non-standard type you should define it via an interface <code>org.apache.cayenne.access.types.ExtendedType</code>. - An implementation must provide <code>ExtendedType.getClassName()</code> method that returns - a fully qualified Java class name for the supported custom type, and a number of methods - that convert data between JDBC and custom type. - The following example demonstrates how to add a custom DoubleArrayType - to store <code>java.lang.Double[]</code> as a custom string in a database:</para> - <programlisting language="java"> -/** -* Defines methods to read Java objects from JDBC ResultSets and write as parameters of -* PreparedStatements. -*/ -public class DoubleArrayType implements ExtendedType { - - private final String SEPARATOR = ","; - - /** - * Returns a full name of Java class that this ExtendedType supports. - */ - @Override - public String getClassName() { - return Double[].class.getCanonicalName(); - } - - /** - * Initializes a single parameter of a PreparedStatement with object value. - */ - @Override - public void setJdbcObject(PreparedStatement statement, Object value, - int pos, int type, int scale) throws Exception { - - String str = StringUtils.join((Double[]) value, SEPARATOR); - statement.setString(pos, str); - } - - - /** - * Reads an object from JDBC ResultSet column, converting it to class returned by - * 'getClassName' method. - * - * @throws Exception if read error occurred, or an object can't be converted to a - * target Java class. - */ - @Override - public Object materializeObject(ResultSet rs, int index, int type) throws Exception { - String[] str = rs.getString(index).split(SEPARATOR); - Double[] res = new Double[str.length]; - - for (int i = 0; i < str.length; i++) { - res[i] = Double.valueOf(str[i]); - } - - return res; - } - - /** - * Reads an object from a stored procedure OUT parameter, converting it to class - * returned by 'getClassName' method. - * - * @throws Exception if read error ocurred, or an object can't be converted to a - * target Java class. - */ - @Override - public Object materializeObject(CallableStatement rs, int index, int type) throws Exception { - String[] str = rs.getString(index).split(SEPARATOR); - Double[] res = new Double[str.length]; - - for (int i = 0; i < str.length; i++) { - res[i] = Double.valueOf(str[i]); - } - - return res; - } -} - </programlisting> - <para>For Java7</para> - <programlisting language="java"> -// add DoubleArrayType to list of user types -ServerRuntime runtime = ServerRuntime.builder() - .addConfig("cayenne-project.xml") - .addModule(new Module() { - @Override - public void configure(Binder binder) { - ServerModule.contributeUserTypes(binder).add(new DoubleArrayType()); - } - }) - .build(); - </programlisting> - <para>For Java8</para> - <programlisting language="java"> -// add DoubleArrayType to list of user types -ServerRuntime runtime = ServerRuntime.builder() - .addConfig("cayenne-project.xml") - .addModule(binder -> ServerModule.contributeUserTypes(binder).add(new DoubleArrayType())) - .build(); - </programlisting> - </section> - <section xml:id="dbadapters-and-extended-types"> - <title>DbAdapters and Extended Types</title> - <para>As shown in the example above, ExtendedTypes are stored by DbAdapter. In fact DbAdapters often install - their own extended types to address incompatibilities, incompleteness and differences between - JDBC drivers in handling "standard" JDBC types. For instance some drivers support reading large - character columns (CLOB) as java.sql.Clob, but some other - as "character stream", etc. - Adapters provided with Cayenne override <code>configureExtendedTypes()</code> method to install their own types, - possibly substituting Cayenne defaults. Custom DbAdapters can use the same technique.</para> - </section> - </section> - </section> - <section xml:id="noteworthy-runtime-components"> - <title>Noteworthy Built-in Services</title> - <section xml:id="jdbceventlogger"> - <title>JdbcEventLogger</title> - <para><code>org.apache.cayenne.log.JdbcEventLogger</code> is the service that defines - logging API for Cayenne internals. It provides facilities for logging queries, - commits, transactions, etc. The default implementation is - <code>org.apache.cayenne.log.Slf4jJdbcEventLogger</code> that performs logging - via slf4j-api library. Cayenne library includes another potentially useful - logger - <code>org.apache.cayenne.log.FormattedSlf4jJdbcEventLogger</code> that - produces formatted multiline SQL output that can be easier to read.</para> - </section> - <section xml:id="datasourcefactory"> - <title>DataSourceFactory</title> - <para>Factory that returns <code>javax.sql.DataSource</code> object based on the configuration provided in the - "nodeDescriptor". - </para> - </section> - <section xml:id="datachannelfilter"> - <title>DataChannelFilter</title> - <para> An interface of a filter that allows to intercept DataChannel operations. Filters allow - to implement chains of custom processors around a DataChannel, that can be used for - security, monitoring, business logic, providing context to lifecycle event listeners, - etc. - </para> - </section> - <section xml:id="querycache"> - <title>QueryCache</title> - <para>Defines API of a cache that stores query results.</para> - </section> - </section> -</chapter>
