CAY-2371 Switch documentation from Docbook to Asciidoctor format
Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/7783cd34 Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/7783cd34 Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/7783cd34 Branch: refs/heads/STABLE-3.1 Commit: 7783cd34a0501595b5af26378e0dd7ae16efa003 Parents: 4cc7a6e Author: Nikita Timofeev <stari...@gmail.com> Authored: Fri Jan 5 17:21:10 2018 +0300 Committer: Nikita Timofeev <stari...@gmail.com> Committed: Fri Jan 5 17:21:11 2018 +0300 ---------------------------------------------------------------------- .../resources/assemblies/assembly-generic.xml | 8 +- .../main/resources/assemblies/assembly-mac.xml | 8 +- .../resources/assemblies/assembly-windows.xml | 8 +- .../asciidoc/cayenne-asciidoc-extension/pom.xml | 43 ++ .../cayenne/asciidoc/CayennePostProcessor.java | 209 ++++++ docs/asciidoc/cayenne-guide/pom.xml | 151 ++++ .../_cayenne-guide/configurationProperties.adoc | 118 ++++ .../asciidoc/_cayenne-guide/expressionsBNF.adoc | 140 ++++ .../docs/asciidoc/_cayenne-guide/header.html | 23 + .../asciidoc/_cayenne-guide/listOfTables.adoc | 25 + .../src/docs/asciidoc/_cayenne-guide/part1.adoc | 21 + .../asciidoc/_cayenne-guide/part1/mapping.adoc | 70 ++ .../asciidoc/_cayenne-guide/part1/modeler.adoc | 42 ++ .../asciidoc/_cayenne-guide/part1/setup.adoc | 58 ++ .../src/docs/asciidoc/_cayenne-guide/part2.adoc | 33 + .../_cayenne-guide/part2/customize.adoc | 288 ++++++++ .../_cayenne-guide/part2/expressions.adoc | 244 +++++++ .../_cayenne-guide/part2/including.adoc | 394 +++++++++++ .../_cayenne-guide/part2/lifecycle.adoc | 280 ++++++++ .../_cayenne-guide/part2/objectContext.adoc | 309 +++++++++ .../_cayenne-guide/part2/orderings.adoc | 36 + .../asciidoc/_cayenne-guide/part2/queries.adoc | 691 +++++++++++++++++++ .../asciidoc/_cayenne-guide/part2/starting.adoc | 120 ++++ .../asciidoc/_cayenne-guide/part2/tuning.adoc | 269 ++++++++ .../src/docs/asciidoc/_cayenne-guide/part3.adoc | 28 + .../_cayenne-guide/part3/clientImpl.adoc | 16 + .../_cayenne-guide/part3/limitations.adoc | 18 + .../docs/asciidoc/_cayenne-guide/part3/rop.adoc | 54 ++ .../_cayenne-guide/part3/ropDeployment.adoc | 34 + .../asciidoc/_cayenne-guide/part3/ropSetup.adoc | 20 + .../_cayenne-guide/part3/serverImpl.adoc | 16 + .../_cayenne-guide/serviceCollections.adoc | 62 ++ .../src/docs/asciidoc/_cayenne-guide/var.adoc | 1 + .../src/docs/asciidoc/cayenne-guide.adoc | 47 ++ .../asciidoc/images/ext-crypto-obj-entity.png | Bin 0 -> 18145 bytes .../images/re-modeler-datasource-select.png | Bin 0 -> 32658 bytes .../re-modeler-reverseengineering-dialog.png | Bin 0 -> 37668 bytes .../images/remote-object-persistence.jpg | Bin 0 -> 54407 bytes docs/asciidoc/getting-started-guide/pom.xml | 170 +++++ .../asciidoc/_getting-started-guide/delete.adoc | 72 ++ .../asciidoc/_getting-started-guide/header.html | 24 + .../_getting-started-guide/java-classes.adoc | 70 ++ .../_getting-started-guide/object-context.adoc | 86 +++ .../object-relational-mapping.adoc | 111 +++ .../asciidoc/_getting-started-guide/part2.adoc | 20 + .../asciidoc/_getting-started-guide/part3.adoc | 22 + .../persistent-objects.adoc | 119 ++++ .../_getting-started-guide/select-query.adoc | 63 ++ .../asciidoc/_getting-started-guide/setup.adoc | 31 + .../starting-project.adoc | 93 +++ .../asciidoc/_getting-started-guide/var.adoc | 1 + .../asciidoc/_getting-started-guide/webapp.adoc | 284 ++++++++ .../docs/asciidoc/getting-started-guide.adoc | 48 ++ .../src/docs/asciidoc/images/base-datamap.png | Bin 0 -> 91074 bytes .../src/docs/asciidoc/images/base-datanode.png | Bin 0 -> 81748 bytes .../asciidoc/images/cayenne-tutorial-model.png | Bin 0 -> 18875 bytes .../docs/asciidoc/images/database-schema.jpg | Bin 0 -> 28434 bytes .../asciidoc/images/datamap-enableclient.png | Bin 0 -> 104778 bytes .../images/eclipse-generatedclasses.png | Bin 0 -> 141000 bytes .../src/docs/asciidoc/images/eclipse-mvnrun.png | Bin 0 -> 147012 bytes .../docs/asciidoc/images/eclipse-xmlfiles.png | Bin 0 -> 27801 bytes .../src/docs/asciidoc/images/firefox-webapp.png | Bin 0 -> 25898 bytes .../src/docs/asciidoc/images/icon-attribute.png | Bin 0 -> 293 bytes .../src/docs/asciidoc/images/icon-datamap.png | Bin 0 -> 411 bytes .../src/docs/asciidoc/images/icon-dbentity.png | Bin 0 -> 142 bytes .../src/docs/asciidoc/images/icon-edit.png | Bin 0 -> 340 bytes .../docs/asciidoc/images/icon-new_objentity.png | Bin 0 -> 563 bytes .../src/docs/asciidoc/images/icon-node.png | Bin 0 -> 350 bytes .../docs/asciidoc/images/icon-relationship.png | Bin 0 -> 347 bytes .../src/docs/asciidoc/images/icon-sync.png | Bin 0 -> 280 bytes .../docs/asciidoc/images/idea-file-run-menu.png | Bin 0 -> 32911 bytes .../asciidoc/images/idea-run-configuration.png | Bin 0 -> 93059 bytes .../asciidoc/images/maven-plugin-install.png | Bin 0 -> 97455 bytes .../docs/asciidoc/images/modeler-artistid.png | Bin 0 -> 59372 bytes .../asciidoc/images/modeler-dbrelationship.png | Bin 0 -> 42245 bytes .../docs/asciidoc/images/modeler-deleterule.png | Bin 0 -> 69992 bytes .../docs/asciidoc/images/modeler-started.png | Bin 0 -> 133410 bytes .../asciidoc/images/tutorial-idea-project.png | Bin 0 -> 70937 bytes docs/asciidoc/getting-started-rop/pom.xml | 151 ++++ .../asciidoc/_getting-started-rop/header.html | 24 + .../asciidoc/_getting-started-rop/part1.adoc | 17 + .../part1/prerequisites.adoc | 25 + .../asciidoc/_getting-started-rop/part2.adoc | 23 + .../_getting-started-rop/part2/adding.adoc | 129 ++++ .../_getting-started-rop/part2/connect.adoc | 176 +++++ .../part2/hessianWebServ.adoc | 113 +++ .../_getting-started-rop/part2/starting.adoc | 93 +++ .../docs/asciidoc/_getting-started-rop/var.adoc | 1 + .../src/docs/asciidoc/getting-started-rop.adoc | 45 ++ .../asciidoc/images/datamap-enableclient.png | Bin 0 -> 104778 bytes docs/asciidoc/pom.xml | 113 +++ docs/asciidoc/upgrade-guide/pom.xml | 151 ++++ .../_upgrade-guide/cayenne-configuration.adoc | 47 ++ .../_upgrade-guide/content-structure.adoc | 26 + .../docs/asciidoc/_upgrade-guide/features.adoc | 25 + .../docs/asciidoc/_upgrade-guide/framework.adoc | 75 ++ .../docs/asciidoc/_upgrade-guide/header.html | 24 + .../docs/asciidoc/_upgrade-guide/lifecycle.adoc | 18 + .../docs/asciidoc/_upgrade-guide/modeler.adoc | 20 + .../src/docs/asciidoc/upgrade-guide.adoc | 44 ++ docs/docbook/cayenne-guide/pom.xml | 31 - .../cayenne-guide/src/docbkx/appendix-a.xml | 184 ----- .../cayenne-guide/src/docbkx/appendix-b.xml | 100 --- .../cayenne-guide/src/docbkx/appendix-c.xml | 147 ---- .../src/docbkx/cayenne-mapping-structure.xml | 95 --- .../src/docbkx/cayennemodeler-application.xml | 60 -- .../src/docbkx/current-limitations.xml | 20 - .../src/docbkx/customizing-cayenne-runtime.xml | 279 -------- .../cayenne-guide/src/docbkx/expressions.xml | 265 ------- .../src/docbkx/implementing-rop-client.xml | 20 - .../src/docbkx/implementing-rop-server.xml | 20 - .../src/docbkx/including-cayenne-in-project.xml | 546 --------------- docs/docbook/cayenne-guide/src/docbkx/index.xml | 46 -- .../src/docbkx/lifecycle-events.xml | 333 --------- .../cayenne-guide/src/docbkx/orderings.xml | 31 - docs/docbook/cayenne-guide/src/docbkx/part1.xml | 23 - docs/docbook/cayenne-guide/src/docbkx/part2.xml | 29 - docs/docbook/cayenne-guide/src/docbkx/part3.xml | 26 - .../src/docbkx/performance-tuning.xml | 289 -------- .../docbkx/persistent-objects-objectcontext.xml | 300 -------- .../cayenne-guide/src/docbkx/queries.xml | 628 ----------------- .../cayenne-guide/src/docbkx/rop-deployment.xml | 47 -- .../src/docbkx/rop-introduction.xml | 98 --- .../cayenne-guide/src/docbkx/rop-setup.xml | 26 - docs/docbook/cayenne-guide/src/docbkx/setup.xml | 82 --- .../src/docbkx/starting-cayenne.xml | 158 ----- .../docbook/cayenne-guide/src/images/.gitignore | 0 .../src/images/remote-object-persistence.jpg | Bin 54407 -> 0 bytes docs/docbook/docbook-stylesheets/pom.xml | 47 -- .../src/main/resources/css/cayenne-doc.css | 140 ---- .../src/main/resources/css/highlight.css | 35 - .../stylesheets/common-customizations.xsl | 32 - .../main/resources/stylesheets/highlight.xsl | 104 --- .../src/main/resources/stylesheets/html.xsl | 244 ------- .../src/main/resources/stylesheets/pdf.xsl | 505 -------------- docs/docbook/getting-started-rop/pom.xml | 40 -- .../src/docbkx/authentification.xml | 131 ---- .../src/docbkx/client-code.xml | 161 ----- .../src/docbkx/client-project.xml | 131 ---- .../getting-started-rop/src/docbkx/index.xml | 43 -- .../getting-started-rop/src/docbkx/part1.xml | 22 - .../getting-started-rop/src/docbkx/part2.xml | 24 - .../getting-started-rop/src/docbkx/setup.xml | 53 -- .../src/docbkx/web-service.xml | 131 ---- .../src/images/datamap-enableclient.png | Bin 104778 -> 0 bytes docs/docbook/getting-started/pom.xml | 40 -- .../getting-started/src/docbkx/delete.xml | 80 --- .../getting-started/src/docbkx/index.xml | 44 -- .../getting-started/src/docbkx/java-classes.xml | 99 --- .../src/docbkx/object-context.xml | 92 --- .../src/docbkx/object-relational-mapping.xml | 163 ----- .../getting-started/src/docbkx/part1.xml | 21 - .../getting-started/src/docbkx/part2.xml | 25 - .../getting-started/src/docbkx/part3.xml | 26 - .../getting-started/src/docbkx/part4.xml | 22 - .../src/docbkx/persistent-objects.xml | 146 ---- .../getting-started/src/docbkx/select-query.xml | 69 -- .../getting-started/src/docbkx/setup.xml | 50 -- .../src/docbkx/starting-project.xml | 151 ---- .../getting-started/src/docbkx/webapp.xml | 301 -------- .../getting-started/src/images/base-datamap.png | Bin 91074 -> 0 bytes .../src/images/base-datanode.png | Bin 81748 -> 0 bytes .../src/images/database-schema.jpg | Bin 28434 -> 0 bytes .../src/images/eclipse-generatedclasses.png | Bin 141000 -> 0 bytes .../src/images/eclipse-mvnrun.png | Bin 147012 -> 0 bytes .../src/images/eclipse-xmlfiles.png | Bin 27801 -> 0 bytes .../src/images/firefox-webapp.png | Bin 25898 -> 0 bytes .../src/images/maven-plugin-install.png | Bin 97455 -> 0 bytes .../src/images/modeler-artistid.png | Bin 59372 -> 0 bytes .../src/images/modeler-dbrelationship.png | Bin 42245 -> 0 bytes .../src/images/modeler-deleterule.png | Bin 69992 -> 0 bytes .../src/images/modeler-started.png | Bin 133410 -> 0 bytes .../src/images/tutorial-eclipse-project.png | Bin 70937 -> 0 bytes docs/docbook/pom.xml | 173 ----- docs/docbook/upgrade-guide/pom.xml | 39 -- docs/docbook/upgrade-guide/src/docbkx/index.xml | 27 - .../upgrade-guide/src/docbkx/new-features.xml | 162 ----- .../docbook/upgrade-guide/src/images/.gitignore | 2 - docs/pom.xml | 2 +- .../java/org/apache/cayenne/tutorial/Main.java | 8 + .../cayenne/tutorial/persistent/Artist.java | 2 + tutorials/tutorial/src/main/webapp/detail.jsp | 4 +- tutorials/tutorial/src/main/webapp/index.jsp | 4 +- 183 files changed, 6443 insertions(+), 7473 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/assembly/src/main/resources/assemblies/assembly-generic.xml ---------------------------------------------------------------------- diff --git a/assembly/src/main/resources/assemblies/assembly-generic.xml b/assembly/src/main/resources/assemblies/assembly-generic.xml index 6d33d20..ecf1c72 100644 --- a/assembly/src/main/resources/assemblies/assembly-generic.xml +++ b/assembly/src/main/resources/assemblies/assembly-generic.xml @@ -48,22 +48,22 @@ <files> <file> - <source>../docs/docbook/getting-started/target/site/getting-started.pdf</source> + <source>../docs/asciidoc/getting-started-guide/target/generated-docs/getting-started-guide.pdf</source> <outputDirectory>doc</outputDirectory> <destName>getting-started.pdf</destName> </file> <file> - <source>../docs/docbook/getting-started-rop/target/site/getting-started-rop.pdf</source> + <source>../docs/asciidoc/getting-started-rop/target/generated-docs/getting-started-rop.pdf</source> <outputDirectory>doc</outputDirectory> <destName>getting-started-rop.pdf</destName> </file> <file> - <source>../docs/docbook/cayenne-guide/target/site/cayenne-guide.pdf</source> + <source>../docs/asciidoc/cayenne-guide/target/generated-docs/cayenne-guide.pdf</source> <outputDirectory>doc</outputDirectory> <destName>cayenne-guide.pdf</destName> </file> <file> - <source>../docs/docbook/upgrade-guide/target/site/upgrade-guide.pdf</source> + <source>../docs/asciidoc/upgrade-guide/target/generated-docs/upgrade-guide.pdf</source> <outputDirectory>doc</outputDirectory> <destName>upgrade-guide.pdf</destName> </file> http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/assembly/src/main/resources/assemblies/assembly-mac.xml ---------------------------------------------------------------------- diff --git a/assembly/src/main/resources/assemblies/assembly-mac.xml b/assembly/src/main/resources/assemblies/assembly-mac.xml index 91c4b52..c74b7e7 100644 --- a/assembly/src/main/resources/assemblies/assembly-mac.xml +++ b/assembly/src/main/resources/assemblies/assembly-mac.xml @@ -48,22 +48,22 @@ <files> <file> - <source>../docs/docbook/getting-started/target/site/getting-started.pdf</source> + <source>../docs/asciidoc/getting-started-guide/target/generated-docs/getting-started-guide.pdf</source> <outputDirectory>doc</outputDirectory> <destName>getting-started.pdf</destName> </file> <file> - <source>../docs/docbook/getting-started-rop/target/site/getting-started-rop.pdf</source> + <source>../docs/asciidoc/getting-started-rop/target/generated-docs/getting-started-rop.pdf</source> <outputDirectory>doc</outputDirectory> <destName>getting-started-rop.pdf</destName> </file> <file> - <source>../docs/docbook/cayenne-guide/target/site/cayenne-guide.pdf</source> + <source>../docs/asciidoc/cayenne-guide/target/generated-docs/cayenne-guide.pdf</source> <outputDirectory>doc</outputDirectory> <destName>cayenne-guide.pdf</destName> </file> <file> - <source>../docs/docbook/upgrade-guide/target/site/upgrade-guide.pdf</source> + <source>../docs/asciidoc/upgrade-guide/target/generated-docs/upgrade-guide.pdf</source> <outputDirectory>doc</outputDirectory> <destName>upgrade-guide.pdf</destName> </file> http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/assembly/src/main/resources/assemblies/assembly-windows.xml ---------------------------------------------------------------------- diff --git a/assembly/src/main/resources/assemblies/assembly-windows.xml b/assembly/src/main/resources/assemblies/assembly-windows.xml index 586ce7a..5878b90 100644 --- a/assembly/src/main/resources/assemblies/assembly-windows.xml +++ b/assembly/src/main/resources/assemblies/assembly-windows.xml @@ -48,22 +48,22 @@ <files> <file> - <source>../docs/docbook/getting-started/target/site/getting-started.pdf</source> + <source>../docs/asciidoc/getting-started-guide/target/generated-docs/getting-started-guide.pdf</source> <outputDirectory>doc</outputDirectory> <destName>getting-started.pdf</destName> </file> <file> - <source>../docs/docbook/getting-started-rop/target/site/getting-started-rop.pdf</source> + <source>../docs/asciidoc/getting-started-rop/target/generated-docs/getting-started-rop.pdf</source> <outputDirectory>doc</outputDirectory> <destName>getting-started-rop.pdf</destName> </file> <file> - <source>../docs/docbook/cayenne-guide/target/site/cayenne-guide.pdf</source> + <source>../docs/asciidoc/cayenne-guide/target/generated-docs/cayenne-guide.pdf</source> <outputDirectory>doc</outputDirectory> <destName>cayenne-guide.pdf</destName> </file> <file> - <source>../docs/docbook/upgrade-guide/target/site/upgrade-guide.pdf</source> + <source>../docs/asciidoc/upgrade-guide/target/generated-docs/upgrade-guide.pdf</source> <outputDirectory>doc</outputDirectory> <destName>upgrade-guide.pdf</destName> </file> http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/docs/asciidoc/cayenne-asciidoc-extension/pom.xml ---------------------------------------------------------------------- diff --git a/docs/asciidoc/cayenne-asciidoc-extension/pom.xml b/docs/asciidoc/cayenne-asciidoc-extension/pom.xml new file mode 100644 index 0000000..5e66e6d --- /dev/null +++ b/docs/asciidoc/cayenne-asciidoc-extension/pom.xml @@ -0,0 +1,43 @@ +<?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-asciidoc-parent</artifactId> + <version>3.1.3-SNAPSHOT</version> + </parent> + + <artifactId>cayenne-asciidoc-extension</artifactId> + <description>AsciidoctorJ extension for website version of Cayenne documentation</description> + <packaging>jar</packaging> + <modelVersion>4.0.0</modelVersion> + + <dependencies> + <dependency> + <!-- jsoup HTML parser library @ https://jsoup.org/ --> + <groupId>org.jsoup</groupId> + <artifactId>jsoup</artifactId> + <version>1.11.2</version> + </dependency> + </dependencies> +</project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/docs/asciidoc/cayenne-asciidoc-extension/src/main/java/org/apache/cayenne/asciidoc/CayennePostProcessor.java ---------------------------------------------------------------------- diff --git a/docs/asciidoc/cayenne-asciidoc-extension/src/main/java/org/apache/cayenne/asciidoc/CayennePostProcessor.java b/docs/asciidoc/cayenne-asciidoc-extension/src/main/java/org/apache/cayenne/asciidoc/CayennePostProcessor.java new file mode 100644 index 0000000..4689dbd --- /dev/null +++ b/docs/asciidoc/cayenne-asciidoc-extension/src/main/java/org/apache/cayenne/asciidoc/CayennePostProcessor.java @@ -0,0 +1,209 @@ +/***************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + ****************************************************************/ + +package org.apache.cayenne.asciidoc; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.nio.charset.Charset; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.StandardCharsets; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.OpenOption; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.util.Collections; +import java.util.Map; + +import org.asciidoctor.Options; +import org.asciidoctor.ast.Document; +import org.asciidoctor.ast.DocumentRuby; +import org.asciidoctor.extension.Postprocessor; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Element; + +/** + * <p> + * AsciidoctorJ post processor, that extracts ToC into separate file and optionally can inject content into rendered document. + * Can be used only for HTML backend, will <b>fail</b> if used with PDF. + * <p> + * It is targeted to inject "front-matter" section suitable for cayenne website tools. + * <p> + * Extension controlled by attributes in *.adoc file: + * <ul> + * <li>cayenne-header: header file name or constant "front-matter" that will inject empty front matter markup + * <li>cayenne-header-position [optional]: "top" to inject just above all content or "body" to inject right after >body< tag + * <li>cayenne-footer: footer file name or constant "front-matter" that will inject empty front matter markup + * <li>cayenne-footer-position [optional]: "bottom" to inject just after all content or "body" to inject right before >/body< tag + * </ul> + * + */ +public class CayennePostProcessor extends Postprocessor { + + private static final String FRONT_MATTER = "front-matter"; + private static final String EMPTY_FRONT_MATTER = "---\n---\n\n"; + private static final String POSITION_TOP = "top"; + private static final String POSITION_BODY = "body"; + private static final String POSITION_BOTTOM = "bottom"; + + public CayennePostProcessor(DocumentRuby documentRuby) { + super(); + } + + public String process(Document document, String output) { + output = extractTableOfContents(document, output); + output = fixupDom(document, output); + output = processHeader(document, output); + output = processFooter(document, output); + return output; + } + + private String fixupDom(Document document, String output) { + org.jsoup.nodes.Document jsoupDoc = Jsoup.parseBodyFragment(output); + + jsoupDoc.select(".icon-note") + .removeClass("icon-note") + .addClass("fa-info-circle") + .addClass("fa-2x"); + + jsoupDoc.select(".icon-tip") + .removeClass("icon-tip") + .addClass("fa-lightbulb-o") + .addClass("fa-2x"); + + for(Element el : jsoupDoc.select("code")) { + String codeClass = el.attr("data-lang"); + if(!codeClass.isEmpty()) { + el.addClass(codeClass); + } + } + + jsoupDoc.select("div#preamble").remove(); + + return jsoupDoc.body().html(); + } + + protected String extractTableOfContents(Document document, String output) { + int start = output.indexOf("<div id=\"toc\" class=\"toc\">"); + if(start == -1) { + // no toc found, exit + return output; + } + + String tocEndString = "</ul>\n</div>"; + int end = output.indexOf(tocEndString, start); + if(end == -1) { + // bad, no end.. + return output; + } + + end += tocEndString.length() + 1; + + org.jsoup.nodes.Document tocDoc = Jsoup.parseBodyFragment(output.substring(start, end)); + tocDoc.select("ul").addClass("nav"); + tocDoc.select("a").addClass("nav-link"); + tocDoc.select("div#toc").addClass("toc-side"); + String toc = tocDoc.body().html(); + + Object destDir = document.getOptions().get(Options.DESTINATION_DIR); + Object docname = ((Map)document.getOptions().get(Options.ATTRIBUTES)).get("docname"); + + Path path = FileSystems.getDefault().getPath((String) destDir, docname + ".toc.html"); + try(BufferedWriter br = newBufferedWriter(path, StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE)) { + br.write(toc, 0, toc.length()); + br.flush(); + } catch (IOException ex) { + ex.printStackTrace(System.err); + } + + if(start == 0) { + return output.substring(end); + } + + return output.substring(0, start) + output.substring(end); + } + + public static BufferedWriter newBufferedWriter(Path path, OpenOption... options) throws IOException { + CharsetEncoder encoder = StandardCharsets.UTF_8.newEncoder(); + Writer writer = new OutputStreamWriter(path.getFileSystem().provider().newOutputStream(path, options), encoder); + return new BufferedWriter(writer); + } + + protected String processHeader(Document document, String output) { + String headerFile = (String) document.getAttr("cayenne-header", ""); + String headerPosition = (String)document.getAttr("cayenne-header-position", POSITION_TOP); + + if(headerFile.isEmpty()) { + return output; + } + + String header = ""; + // inject empty front matter + if(FRONT_MATTER.equals(headerFile.trim())) { + header = EMPTY_FRONT_MATTER ; + } else { + // treat as a file + header = document.readAsset(headerFile, Collections.emptyMap()); + } + + switch (headerPosition.trim()) { + case POSITION_BODY: { + int bodyStart = output.indexOf("<div id=\"header\">"); + if(bodyStart == -1) { + // no header + return header + output; + } + return output.substring(0, bodyStart) + header + output.substring(bodyStart); + } + + case POSITION_TOP: + default: + return header + output; + } + } + + protected String processFooter(Document document, String output) { + String footerFile = (String) document.getAttr("cayenne-footer", ""); + String footerPosition = (String)document.getAttr("cayenne-footer-position", POSITION_BOTTOM); + + if(footerFile.isEmpty()) { + return output; + } + + String footer = document.readAsset(footerFile, Collections.emptyMap()); + + switch (footerPosition.trim()) { + case POSITION_BODY: { + int bodyStart = output.indexOf("</body>"); + if(bodyStart == -1) { + // no footer + return output + footer; + } + return output.substring(0, bodyStart) + footer + output.substring(bodyStart); + } + + case POSITION_BOTTOM: + default: + return output + footer; + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/docs/asciidoc/cayenne-guide/pom.xml ---------------------------------------------------------------------- diff --git a/docs/asciidoc/cayenne-guide/pom.xml b/docs/asciidoc/cayenne-guide/pom.xml new file mode 100644 index 0000000..99f75c1 --- /dev/null +++ b/docs/asciidoc/cayenne-guide/pom.xml @@ -0,0 +1,151 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <groupId>org.apache.cayenne.parents</groupId> + <artifactId>cayenne-asciidoc-parent</artifactId> + <version>3.1.3-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>cayenne-guide</artifactId> + + <packaging>jar</packaging> + <name>cayenne-guide: AsciiDoc - Cayenne Framework Guide</name> + + <build> + <plugins> + <plugin> + <groupId>org.asciidoctor</groupId> + <artifactId>asciidoctor-maven-plugin</artifactId> + <dependencies> + <dependency> + <groupId>org.apache.cayenne.docs</groupId> + <artifactId>cayenne-asciidoc-extension</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <executions> + <!-- generate "embeddable" html content with front matter and without header/footer/styles --> + <execution> + <id>asciidoctor-html-web</id> + <phase>generate-resources</phase> + <goals> + <goal>process-asciidoc</goal> + </goals> + <configuration> + <backend>html5</backend> + <headerFooter>false</headerFooter> <!-- do not generate header and footer --> + <outputDirectory>${project.build.directory}/tmp/</outputDirectory> + <extensions> + <extension> + <className>org.apache.cayenne.asciidoc.CayennePostProcessor</className> + </extension> + </extensions> + <attributes> + <toc>auto</toc> + </attributes> + </configuration> + </execution> + </executions> + </plugin> + + <!-- Move images to proper path for site --> + <plugin> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>copy docs for site</id> + <phase>install</phase> + <goals> + <goal>copy-resources</goal> + </goals> + + <configuration> + <outputDirectory>${project.build.directory}/site/</outputDirectory> + <resources> + <resource> + <directory>${project.build.directory}/tmp/</directory> + <includes> + <include>${project.artifactId}.html</include> + <include>${project.artifactId}.toc.html</include> + </includes> + </resource> + </resources> + </configuration> + </execution> + + <execution> + <id>copy images for site</id> + <phase>install</phase> + <goals> + <goal>copy-resources</goal> + </goals> + + <configuration> + <outputDirectory>${project.build.directory}/site/${project.artifactId}/images/</outputDirectory> + <resources> + <resource> + <directory>${project.build.directory}/tmp/images/</directory> + <filtering>true</filtering> + </resource> + </resources> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + + <profiles> + <profile> + <id>assembly</id> + <build> + <plugins> + <plugin> + <groupId>org.asciidoctor</groupId> + <artifactId>asciidoctor-maven-plugin</artifactId> + <executions> + <!-- generate standalone html help --> + <execution> + <id>asciidoctor-html-standalone</id> + <phase>generate-resources</phase> + <goals> + <goal>process-asciidoc</goal> + </goals> + <configuration> + <backend>html5</backend> + <sourceHighlighter>coderay</sourceHighlighter> + <embedAssets>true</embedAssets> + <attributes> + <toc>left</toc> + </attributes> + </configuration> + </execution> + + <!-- generate PDF --> + <execution> + <id>generate-pdf-doc</id> + <phase>generate-resources</phase> + <goals> + <goal>process-asciidoc</goal> + </goals> + <configuration> + <backend>pdf</backend> + <sourceHighlighter>coderay</sourceHighlighter> + <attributes> + <pagenums/> + <toc/> + </attributes> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + </profile> + </profiles> + +</project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/configurationProperties.adoc ---------------------------------------------------------------------- diff --git a/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/configurationProperties.adoc b/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/configurationProperties.adoc new file mode 100644 index 0000000..d73c8c8 --- /dev/null +++ b/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/configurationProperties.adoc @@ -0,0 +1,118 @@ +// 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 A. Configuration Properties + +Note that the property names below are defined as constants in `org.apache.cayenne.configuration.Constants` interface. + +[#configProperties] +* `cayenne.jdbc.driver[.domain_name.node_name]` + 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. + ** Default value: none, project DataNode configuration is used + +* `cayenne.jdbc.url[.domain_name.node_name]` + 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. + ** Default value: none, project DataNode configuration is used + +* `cayenne.jdbc.username[.domain_name.node_name]` + 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. + ** Possible values: any + ** Default value: none, project DataNode configuration is used + +* `cayenne.jdbc.password[.domain_name.node_name]` + 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 + ** Default value: none, project DataNode configuration is used + +* `cayenne.jdbc.min_connections[.domain_name.node_name]` + 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 + ** Default value: none, project DataNode configuration is used + +* `cayenne.jdbc.max_connections[.domain_name.node_name]` + 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 + ** Default value: none, project DataNode configuration is used + +* `cayenne.querycache.size` + 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. + ** Possible values: any positive int value + ** Default value: 2000 + +* `cayenne.server.contexts_sync_strategy` + 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. + ** Possible values: true, false + ** Default value: true + +* `cayenne.server.object_retain_strategy` + defines fetched objects retain strategy for ObjectContexts. When weak or soft strategy is used, objects retained by ObjectContext + that have no local changes can potentially get garbage collected when JVM feels like doing it. + ** Possible values: weak, soft, hard + ** Default value: weak + +* `cayenne.server.max_id_qualifier_size` + 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. + ** Possible values: any positive int + ** Default value: 10000 + +* `cayenne.rop.service_url` + defines the URL of the ROP server + ** Default value: none + +* `cayenne.rop.service_username` + defines the user name for an ROP client to login to an ROP server. + ** Default value: none + +* `cayenne.rop.service_password` + defines the password for an ROP client to login to an ROP server. + ** Default value: none + +* `cayenne.rop.service.timeout` + a value in milliseconds for the ROP client-server connection read operation timeout + ** Possible values: any positive long value + ** Default value: none + +* `cayenne.rop.shared_session_name` + 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. + ** Default value: none + +* `cayenne.rop.channel_events` + 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. + ** Possible values: true, false + ** Default value: false + +* `cayenne.rop.context_change_events` + 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. + ** Possible values: true, false + ** Default value: false + +* `cayenne.rop.context_lifecycle_events` + 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. + ** Possible values: true,false + ** Default value: false + +* `cayenne.server.rop_event_bridge_factory` + 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`. + ** Default value: false \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/expressionsBNF.adoc ---------------------------------------------------------------------- diff --git a/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/expressionsBNF.adoc b/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/expressionsBNF.adoc new file mode 100644 index 0000000..ee3726a --- /dev/null +++ b/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/expressionsBNF.adoc @@ -0,0 +1,140 @@ +// 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 C. Expressions BNF + +[source] +---- +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> ) +---- + http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/header.html ---------------------------------------------------------------------- diff --git a/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/header.html b/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/header.html new file mode 100644 index 0000000..3bea7ad --- /dev/null +++ b/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/header.html @@ -0,0 +1,23 @@ +--- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +title: "Cayenne Guide" +description: "Cayenne Guide" +cayenneVersion: "3.1" +weight: 20 +--- http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/listOfTables.adoc ---------------------------------------------------------------------- diff --git a/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/listOfTables.adoc b/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/listOfTables.adoc new file mode 100644 index 0000000..66d27be --- /dev/null +++ b/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/listOfTables.adoc @@ -0,0 +1,25 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to you under the Apache License, Version +// 2.0 (the "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 Unless required by +// applicable law or agreed to in writing, software distributed under the +// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for +// the specific language governing permissions and limitations under the +// License. + +== List of tables + +* xref:tablecgen[cgen required parameters] +* xref:cgenOptional[cgen optional parameters] +* xref:cdbgenTable[cdbgen required parameters] +* xref:cdbgenOptionl[cdbgen optional parameters] +* xref:cdbimportTable[cdbimport parameters] +* xref:persistenceStates[Persistence States] +* xref:lifecycleEvent[Lifecycle Event Types] +* xref:congigProperties[Configuration Properties Recognized by ServerRuntime and/or ClientRuntime] +* xref:serviceCollections[Service Collection Keys Present in ServerRuntime and/or ClientRuntime] \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part1.adoc ---------------------------------------------------------------------- diff --git a/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part1.adoc b/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part1.adoc new file mode 100644 index 0000000..a99d627 --- /dev/null +++ b/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part1.adoc @@ -0,0 +1,21 @@ +// 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. + +== Object Relational Mapping with Cayenne + +include::part1/setup.adoc[] + +include::part1/mapping.adoc[] + +include::part1/modeler.adoc[] \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part1/mapping.adoc ---------------------------------------------------------------------- diff --git a/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part1/mapping.adoc b/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part1/mapping.adoc new file mode 100644 index 0000000..2180fed --- /dev/null +++ b/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part1/mapping.adoc @@ -0,0 +1,70 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to you under the Apache License, Version +// 2.0 (the "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 Unless required by +// applicable law or agreed to in writing, software distributed under the +// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for +// the specific language governing permissions and limitations under the +// License. + +=== Cayenne Mapping Structure + +==== Cayenne Project + +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 `cayenne-xyz.xml`, where "xyz" is the name of the project. + +Project descriptor can reference DataMap files, one per DataMap. DataMap files are normally called `xyz.map.xml`, 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: + +---- +~: ls -l +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 +---- + +DataMap are referenced by name in the root descriptor: + +[source,xml] +---- +<map name="datamap"/> +---- + +Map files are resolved by Cayenne by appending ".map.xml" 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. + +==== DataMap + +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. + +==== DataNode + +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. + +==== DbEntity + +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. + +==== ObjEntity + +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. + +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). + +ObjEntities may also contain mapping of their lifecycle callback methods. + +==== Embeddable + +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. + +==== Procedure + +A model of a stored procedure in the database. + +==== Query + +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. + http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part1/modeler.adoc ---------------------------------------------------------------------- diff --git a/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part1/modeler.adoc b/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part1/modeler.adoc new file mode 100644 index 0000000..8afc6ae --- /dev/null +++ b/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part1/modeler.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. + +=== CayenneModeler Application + +==== Working with Mapping Projects + +==== Reverse Engineering Database + + + +==== Generating Database Schema + + +==== Migrations + +==== Generating Java Classes + +==== Modeling Inheritance + +==== Modeling Generic Persistent Classes + +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 org.apache.cayenne.DataObject. So an ideal candidate for a generic class is CayenneDataObject, or some custom subclass of CayenneDataObject. + +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. + +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. + +==== Mapping ObjAttributes to Custom Classes + +==== Modeling Primary Key Generation Strategy \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part1/setup.adoc ---------------------------------------------------------------------- diff --git a/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part1/setup.adoc b/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part1/setup.adoc new file mode 100644 index 0000000..0e93de2 --- /dev/null +++ b/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part1/setup.adoc @@ -0,0 +1,58 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to you under the Apache License, Version +// 2.0 (the "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 Unless required by +// applicable law or agreed to in writing, software distributed under the +// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for +// the specific language governing permissions and limitations under the +// License. + +include::../var.adoc[] + +=== Setup + +==== System Requirements + +- Java: Cayenne runtime framework and CayenneModeler GUI tool are written in 100% Java, and run on any Java-compatible platform. Required JDK version is 1.5 or higher. The last version of Cayenne compatible with JDK 1.4 is 1.2.x/2.0.x and JDK 1.3 is 1.1.x + +- JDBC Driver: An appropriate DB-specific JDBC driver is needed to access the database. It can be included in the application or used in web container DataSource configuration. + +- Third-party Libraries: Cayenne runtime framework has a minimal set of required and a few more optional dependencies on third-party open source packages. See "Including Cayenne in a Project" chapter for details. + +[[runModeler]] +==== Running CayenneModeler + +CayenneModeler GUI tool is intended to work with object relational mapping projects. While you can edit your XML by hand, it is rarely needed, as the Modeler is a pretty advanced tool included in Cayenne distribution. To obtain CayenneModeler, download Cayenne distribution archive from http://cayenne.apache.org/download.html matching the OS you are using. Of course Java needs to be installed on the machine where you are going to run the Modeler. + +- OS X distribution contains CayenneModeler.app at the root of the distribution disk image. +- Windows distribution contains CayenneModeler.exe file in the bin directory. +- Cross-platform distribution (targeting Linux, but as the name implies, compatible with any OS) contains a runnable CayenneModeler.jar in the bin directory. It can be executed either by double-clicking, or if the environment is not configured to execute jars, by running from command-line: + +---- +$ java -jar CayenneModeler.jar +---- + +The Modeler can also be started from Maven. While it may look like an exotic way to start a GUI application, it has its benefits - no need to download Cayenne distribution, the version of the Modeler always matches the version of the framework, the plugin can find mapping files in the project automatically. So it is an attractive option to some developers. Maven option requires a declaration in the POM: +[source,xml,subs="verbatim,attributes"] +---- +<build> + <plugins> + <plugin> + <groupId>org.apache.cayenne.plugins</groupId> + <artifactId>maven-cayenne-modeler-plugin</artifactId> + <version>{version}</version> + </plugin> + </plugins> +</build> +---- + +And then can be run as + +---- +$ mvn cayenne-modeler:run +---- http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part2.adoc ---------------------------------------------------------------------- diff --git a/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part2.adoc b/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part2.adoc new file mode 100644 index 0000000..505a029 --- /dev/null +++ b/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part2.adoc @@ -0,0 +1,33 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to you under the Apache License, Version +// 2.0 (the "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 Unless required by +// applicable law or agreed to in writing, software distributed under the +// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for +// the specific language governing permissions and limitations under the +// License. + +== Cayenne Framework + +include::part2/including.adoc[] + +include::part2/starting.adoc[] + +include::part2/objectContext.adoc[] + +include::part2/expressions.adoc[] + +include::part2/orderings.adoc[] + +include::part2/queries.adoc[] + +include::part2/lifecycle.adoc[] + +include::part2/tuning.adoc[] + +include::part2/customize.adoc[] \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cayenne/blob/7783cd34/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 new file mode 100644 index 0000000..919a697 --- /dev/null +++ b/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part2/customize.adoc @@ -0,0 +1,288 @@ +// 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. + +[[customize]] +=== Customizing Cayenne Runtime + +==== Dependency Injection Container + +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. + +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 `@Inject` annotation. This mechanism is very close to Google Guice. + +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. + +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. + +===== DI Bindings API + +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: + +[source, Java] +---- +public interface Service1 { + public String getString(); +} +---- + +[source, Java] +---- +public interface Service2 { + public int getInt(); +} +---- + +A service implementation using instance variable injection: + +[source, Java] +---- +public class Service1Impl implements Service1 { + @Inject + private Service2 service2; + + public String getString() { + return service2.getInt() + "_Service1Impl"; + } +} +---- + +Same thing, but using constructor injection: + +[source, Java] +---- +public class Service1Impl implements Service1 { + + private Service2 service2; + + public Service1Impl(@Inject Service2 service2) { + this.service2 = service2; + } + + public String getString() { + return service2.getInt() + "_Service1Impl"; + } +} +---- + +[source, Java] +---- +public class Service2Impl implements Service2 { + private int i; + + public int getInt() { + return i++; + } +} +---- + +Now let's create a module implementing `org.apache.cayenne.tutorial.di.Module` 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: + +[source, 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); + } +} +---- + +Once we have at least one module, we can create a DI container. `org.apache.cayenne.di.Injector` is the container class in Cayenne: + +[source, Java] +---- +Injector injector = DIBootstrap.createInjector(new Module1()); +---- + +Now that we have created the container, we can obtain services from it and call their methods: + +[source, Java] +---- +Service1 s1 = injector.getInstance(Service1.class); +for (int i = 0; i < 5; i++) { + System.out.println("S1 String: " + s1.getString()); +} +---- + +This outputs the following lines, demonstrating that s1 was Service1Impl and Service2 injected into it was Service2Impl: + +[source] +---- +0_Service1Impl +1_Service1Impl +2_Service1Impl +3_Service1Impl +4_Service1Impl +---- + +There are more flavors of bindings: + +[source, 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); +---- + + +Another types of confiuguration that can be bound in the container are lists and maps. They will be discussed in the following chapters. + +===== 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. + +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: + +[source, Java] +---- +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) . + +===== 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. + +==== 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: + +[source, Java] +---- +public class MyExtensionsModule implements Module { + public void configure(Binder binder) { + // customizations go here... + } +} +---- + +[source, Java] +---- +Module extensions = new MyExtensionsModule(); +ServerRuntime runtime = + new ServerRuntime("com/example/cayenne-mydomain.xml", extensions); +---- + +===== 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". + +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. + +---- +$ 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. + +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. + +===== 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: + +[source, Java] +---- +public class MyDbAdapterDetector implements DbAdapterDetector { + public DbAdapter createAdapter(DatabaseMetaData md) throws SQLException { + // check if we support this database and retun custom adapter + ... + } +} +---- + +[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); +---- + +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. + +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: + +[source, Java] +---- +binder.bind(QueryCache.class).to(EhCacheQueryCache.class); +---- + +==== Noteworthy Built-in Services + +===== JdbcEventLogger + +`org.apache.cayenne.log.JdbcEventLogger` is the service that defines logging API for Cayenne internals. It provides facilities for logging queries, commits, transactions, etc. The default implementation is `org.apache.cayenne.log.Slf4jJdbcEventLogger` that performs logging via slf4j-api library. Cayenne library includes another potentially useful logger - `org.apache.cayenne.log.FormattedSlf4jJdbcEventLogger` that produces formatted multiline SQL output that can be easier to read. + +===== DataSourceFactory + +===== DataChannelFilter + +===== QueryCache + +===== ExtebdedTypes + + + + + + + + + + + + + + + + + + + + + + + + + + + +