DATAJPA-3 - Initial port of Hades reference documentation.
- created Docbook setup (copied from Document project) - split up Hades documentation into parts and left out what's currently not relevant (extensions, IDE plugin) - removed sample application part for now - clearly separated documentation of the general repository implementation from JPA specifics (use the one from Spring Data Commons) - extracted general namespace configuration into Spring Data Commons - updated project metadata (repositories, source repo, homepage)
59
pom.xml
@@ -168,6 +168,65 @@
|
||||
<target>1.5</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.agilejava.docbkx</groupId>
|
||||
<artifactId>docbkx-maven-plugin</artifactId>
|
||||
<version>2.0.7</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>generate-html</goal>
|
||||
<goal>generate-pdf</goal>
|
||||
</goals>
|
||||
<phase>pre-site</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.docbook</groupId>
|
||||
<artifactId>docbook-xml</artifactId>
|
||||
<version>4.4</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<configuration>
|
||||
<includes>index.xml</includes>
|
||||
<xincludeSupported>true</xincludeSupported>
|
||||
<foCustomization>${project.basedir}/src/docbkx/resources/xsl/fopdf.xsl</foCustomization>
|
||||
<htmlStylesheet>css/html.css</htmlStylesheet>
|
||||
<chunkedOutput>false</chunkedOutput>
|
||||
<htmlCustomization>${project.basedir}/src/docbkx/resources/xsl/html.xsl</htmlCustomization>
|
||||
<useExtensions>1</useExtensions>
|
||||
<highlightSource>1</highlightSource>
|
||||
<highlightDefaultLanguage></highlightDefaultLanguage>
|
||||
<!-- callouts -->
|
||||
<entities>
|
||||
<entity>
|
||||
<name>version</name>
|
||||
<value>${pom.version}</value>
|
||||
</entity>
|
||||
</entities>
|
||||
<postProcess>
|
||||
<copy todir="${project.basedir}/target/site/reference">
|
||||
<fileset dir="${project.basedir}/target/docbkx">
|
||||
<include name="**/*.html" />
|
||||
<include name="**/*.pdf" />
|
||||
</fileset>
|
||||
</copy>
|
||||
<copy todir="${project.basedir}/target/site/reference/html">
|
||||
<fileset dir="${project.basedir}/src/docbkx/resources">
|
||||
<include name="**/*.css" />
|
||||
<include name="**/*.png" />
|
||||
<include name="**/*.gif" />
|
||||
<include name="**/*.jpg" />
|
||||
</fileset>
|
||||
</copy>
|
||||
<move file="${project.basedir}/target/site/reference/pdf/index.pdf"
|
||||
tofile="${project.basedir}/target/site/reference/pdf/${project.artifactId}-reference.pdf"
|
||||
failonerror="false" />
|
||||
</postProcess>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
92
src/docbkx/appendix/faq.xml
Normal file
@@ -0,0 +1,92 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE appendix PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
|
||||
<appendix id="faq">
|
||||
<title>Frequently asked questions</title>
|
||||
|
||||
<qandaset>
|
||||
<qandadiv>
|
||||
<title>Common</title>
|
||||
|
||||
<qandaentry>
|
||||
<question>
|
||||
<para>I'd like to get more detailled logging information on what
|
||||
methods are called inside
|
||||
<interfacename>JpaRepository</interfacename>, e.g. How can I gain
|
||||
them?</para>
|
||||
</question>
|
||||
|
||||
<answer>
|
||||
<para>You can make use of
|
||||
<classname>CustomizableTraceInterceptor</classname> provided by
|
||||
Spring:</para>
|
||||
|
||||
<programlisting language="xml"><bean id="customizableTraceInterceptor" class="
|
||||
org.springframework.aop.interceptor.CustomizableTraceInterceptor">
|
||||
<property name="enterMessage" value="Entering $[methodName]($[arguments])"/>
|
||||
<property name="exitMessage" value="Leaving $[methodName](): $[returnValue]"/>
|
||||
</bean>
|
||||
|
||||
<aop:config>
|
||||
<aop:advisor advice-ref="customizableTraceInterceptor"
|
||||
pointcut="execution(public * org.sfw.data.jpa.repository.JpaRepository+.*(..))"/>
|
||||
</aop:config></programlisting>
|
||||
</answer>
|
||||
</qandaentry>
|
||||
</qandadiv>
|
||||
|
||||
<qandadiv>
|
||||
<title>Infrastructure</title>
|
||||
|
||||
<qandaentry>
|
||||
<question>
|
||||
<para>Currently I have implemented a repository layer based on
|
||||
<classname>HibernateDaoSupport</classname>. I create a
|
||||
<classname>SessionFactory</classname> by using Spring's
|
||||
<classname>AnnotationSessionFactoryBean</classname>. How do I get
|
||||
Hades DAOs working in this environment.</para>
|
||||
</question>
|
||||
|
||||
<answer>
|
||||
<para>You have to replace
|
||||
<classname>AnnotationSessionFactoryBean</classname> with the
|
||||
<classname>LocalContainerEntityManagerFactoryBean</classname>.
|
||||
Supposed you have registered it under
|
||||
<code>entityManagerFactory</code> you can reference it in you
|
||||
repositories based on <classname>HibernateDaoSupport</classname> as
|
||||
follows:</para>
|
||||
|
||||
<example>
|
||||
<title>Looking up a SessionFactory from an
|
||||
HibernateEntityManagerFactory</title>
|
||||
|
||||
<programlisting language="xml"><bean class="com.acme.YourDaoBasedOnHibernateDaoSupport">
|
||||
<property name="sessionFactory">
|
||||
<bean factory-bean="entityManagerFactory"
|
||||
factory-method="getSessionFactory" />
|
||||
</property>
|
||||
</bean></programlisting>
|
||||
</example>
|
||||
</answer>
|
||||
</qandaentry>
|
||||
</qandadiv>
|
||||
|
||||
<qandadiv>
|
||||
<title>Auditing</title>
|
||||
|
||||
<qandaentry>
|
||||
<question>
|
||||
<para>I want to use Spring Data JPA auditing capabilities but have
|
||||
my database already set up to set modification and creation date on
|
||||
entities. How to prevent Hades to set the date
|
||||
programmatically.</para>
|
||||
</question>
|
||||
|
||||
<answer>
|
||||
<para>Just use the <code>set-dates</code> attribute of the
|
||||
<code>auditing</code> namespace element to false.</para>
|
||||
</answer>
|
||||
</qandaentry>
|
||||
</qandadiv>
|
||||
</qandaset>
|
||||
</appendix>
|
||||
114
src/docbkx/appendix/glossary.xml
Normal file
@@ -0,0 +1,114 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
|
||||
<glossary id="glossary">
|
||||
<glossdiv>
|
||||
<title>A</title>
|
||||
|
||||
<glossentry>
|
||||
<glossterm>AOP</glossterm>
|
||||
|
||||
<glossdef>
|
||||
<para>Aspect oriented programming</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
|
||||
<glossdiv>
|
||||
<title>C</title>
|
||||
|
||||
<glossentry>
|
||||
<glossterm>Commons DBCP</glossterm>
|
||||
|
||||
<glossdef>
|
||||
<para>Commons DataBase Connection Pools - Library of the Apache
|
||||
foundation offering pooling implementations of the
|
||||
<interfacename>DataSource</interfacename> interface.</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry>
|
||||
<glossterm>CRUD</glossterm>
|
||||
|
||||
<glossdef>
|
||||
<para>Create, Read, Update, Delete - Basic persistence
|
||||
operations</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
|
||||
<glossdiv>
|
||||
<title>D</title>
|
||||
|
||||
<glossentry>
|
||||
<glossterm>DAO</glossterm>
|
||||
|
||||
<glossdef>
|
||||
<para>Data Access Object - Pattern to separate persisting logic from
|
||||
the object to be persisted</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry>
|
||||
<glossterm>Dependency Injection</glossterm>
|
||||
|
||||
<glossdef>
|
||||
<para>Pattern to hand a component's dependency to the component from
|
||||
outside, freeing the component to lookup the dependant itself. For
|
||||
more information see <ulink
|
||||
url="http://en.wikipedia.org/wiki/Dependency_Injection">http://en.wikipedia.org/wiki/Dependency_Injection</ulink>.</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
|
||||
<glossdiv>
|
||||
<title>E</title>
|
||||
|
||||
<glossentry>
|
||||
<glossterm>EclipseLink</glossterm>
|
||||
|
||||
<glossdef>
|
||||
<para>Object relational mapper implementing JPA - <ulink
|
||||
url="http://www.eclipselink.org">http://www.eclipselink.org</ulink></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
|
||||
<glossdiv>
|
||||
<title>H</title>
|
||||
|
||||
<glossentry>
|
||||
<glossterm>Hibernate</glossterm>
|
||||
|
||||
<glossdef>
|
||||
<para>Object relational mapper implementing JPA - <ulink
|
||||
url="http://www.hibernate.org">http://www.hibernate.org</ulink></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
|
||||
<glossdiv>
|
||||
<title>J</title>
|
||||
|
||||
<glossentry>
|
||||
<glossterm>JPA</glossterm>
|
||||
|
||||
<glossdef>
|
||||
<para>Java Persistence Api</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
|
||||
<glossdiv>
|
||||
<title>S</title>
|
||||
|
||||
<glossentry>
|
||||
<glossterm>Spring</glossterm>
|
||||
|
||||
<glossdef>
|
||||
<para>Java application framework - <ulink
|
||||
url="http://www.springframework.org">http://www.springframework.org</ulink></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
</glossary>
|
||||
77
src/docbkx/index.xml
Normal file
@@ -0,0 +1,77 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
|
||||
<book xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
<bookinfo>
|
||||
<title>Spring Data JPA - Reference Documentation</title>
|
||||
|
||||
<releaseinfo>1.0.0.BUILD-SNAPSHOT</releaseinfo>
|
||||
|
||||
<authorgroup>
|
||||
<author>
|
||||
<firstname>Oliver</firstname>
|
||||
|
||||
<surname>Gierke</surname>
|
||||
|
||||
<affiliation>
|
||||
<jobtitle>Senior Consultant</jobtitle>
|
||||
|
||||
<orgname>SpringSource - a division of VMware</orgname>
|
||||
</affiliation>
|
||||
|
||||
<email>ogierke@vmware.com</email>
|
||||
</author>
|
||||
</authorgroup>
|
||||
|
||||
<legalnotice>
|
||||
<para>Copies of this document may be made for your own use and for
|
||||
distribution to others, provided that you do not charge any fee for such
|
||||
copies and further provided that each copy contains this Copyright
|
||||
Notice, whether distributed in print or electronically.</para>
|
||||
</legalnotice>
|
||||
|
||||
<pubdate />
|
||||
|
||||
<copyright>
|
||||
<year>2008-2011</year>
|
||||
|
||||
<holder>The original authors</holder>
|
||||
</copyright>
|
||||
|
||||
<revhistory>
|
||||
<revision>
|
||||
<date>09.02.2011</date>
|
||||
|
||||
<author>
|
||||
<firstname>Oliver</firstname>
|
||||
|
||||
<surname>Gierke</surname>
|
||||
</author>
|
||||
|
||||
<revremark>Initial port from Hades documentation</revremark>
|
||||
</revision>
|
||||
</revhistory>
|
||||
</bookinfo>
|
||||
|
||||
<toc />
|
||||
|
||||
<xi:include href="preface.xml" />
|
||||
|
||||
<part id="reference">
|
||||
<title>Reference Documentation</title>
|
||||
|
||||
<xi:include href="https://github.com/SpringSource/spring-data-commons/raw/master/src/docbkx/repositories.xml" />
|
||||
|
||||
<xi:include href="reference/jpa.xml" />
|
||||
</part>
|
||||
|
||||
<part id="appendix">
|
||||
<title>Appendix</title>
|
||||
|
||||
<xi:include href="https://github.com/SpringSource/spring-data-commons/raw/master/src/docbkx/repository-namespace-reference.xml" />
|
||||
|
||||
<xi:include href="appendix/faq.xml" />
|
||||
|
||||
<xi:include href="appendix/glossary.xml" />
|
||||
</part>
|
||||
</book>
|
||||
38
src/docbkx/preface.xml
Normal file
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE preface PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
|
||||
<preface id="preface">
|
||||
<title>Preface</title>
|
||||
|
||||
<section id="project">
|
||||
<title>Project metadata</title>
|
||||
|
||||
<itemizedlist spacing="compact">
|
||||
<listitem>
|
||||
<para>Version control - <ulink
|
||||
url="http://git.synyx.org/hades.git">git://github.com/SpringSource/spring-data-jpa.git</ulink></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Bugtracker - <ulink
|
||||
url="http://hades.synyx.org">https://jira.springsource.org/browse/DATAJPA</ulink></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Release repository - <ulink
|
||||
url="http://repo2.maven.org/maven2/org/synyx/hades"><ulink
|
||||
url="http://maven.springframework.org/release">http://maven.springframework.org/release</ulink></ulink></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Milestone repsitory - <ulink
|
||||
url="http://maven.springframework.org/milestone">http://maven.springframework.org/milestone</ulink></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Snapshot repsitory - <ulink
|
||||
url="http://maven.springframework.org/snapshot">http://maven.springframework.org/snapshot</ulink></para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
</preface>
|
||||
673
src/docbkx/reference/core-concepts.xml
Normal file
@@ -0,0 +1,673 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
|
||||
<chapter id="repositories">
|
||||
<title>Repositories</title>
|
||||
|
||||
<section id="introduction">
|
||||
<title>Introduction</title>
|
||||
|
||||
<para>Implementing a data access layer of an application has been
|
||||
cumbersome for quite a while. Too much boilerplate code had to be written.
|
||||
Domain classes were anemic and haven't been designed in a real object
|
||||
oriented or domain driven manner.</para>
|
||||
|
||||
<para>Using both of these technologies makes developers life a lot easier
|
||||
regarding rich domain model's persistence. Nevertheless the amount of
|
||||
boilerplate code to implement repositories especially is still quite high.
|
||||
So the goal of the repository abstraction of Spring Data is to reduce the
|
||||
effort to implement data access layers for various persistence stores
|
||||
significantly</para>
|
||||
|
||||
<para>The following chapters will introduce the core concepts and
|
||||
interfaces of Spring Data repositories.</para>
|
||||
</section>
|
||||
|
||||
<section id="core-concepts">
|
||||
<title>Core concepts</title>
|
||||
|
||||
<para>The central interface in Spring Data repository abstraction is
|
||||
<interfacename>Repository</interfacename> (probably not that much of a
|
||||
surprise). It is typeable to the domain class to manage as well as the id
|
||||
type of the domain class and provides some sophisticated functionality
|
||||
around CRUD for the entity managed.</para>
|
||||
|
||||
<example id="repository">
|
||||
<title>Repository interface</title>
|
||||
|
||||
<programlistingco>
|
||||
<areaspec>
|
||||
<area coords="3" id="repository.save" />
|
||||
|
||||
<area coords="5" id="repository.find-by-id" />
|
||||
|
||||
<area coords="7" id="repository.find-all" />
|
||||
|
||||
<area coords="9" id="repository.find-all-pageable" />
|
||||
|
||||
<area coords="11" id="repository.count" />
|
||||
|
||||
<area coords="13" id="repository.delete" />
|
||||
|
||||
<area coords="15" id="repository.exists" />
|
||||
</areaspec>
|
||||
|
||||
<programlisting language="java">public interface Repository<T, ID extends Serializable> {
|
||||
|
||||
T save(T entity);
|
||||
|
||||
T findById(ID primaryKey);
|
||||
|
||||
List<T> findAll();
|
||||
|
||||
Page<T> findAll(Pageable pageable);
|
||||
|
||||
Long count();
|
||||
|
||||
void delete(T entity);
|
||||
|
||||
boolean exists(ID primaryKey);
|
||||
|
||||
// … more functionality omitted.
|
||||
}</programlisting>
|
||||
|
||||
<calloutlist>
|
||||
<callout arearefs="repository.save">
|
||||
<para>Saves the given entity.</para>
|
||||
</callout>
|
||||
|
||||
<callout arch="" arearefs="repository.find-by-id">
|
||||
<para>Returns the entity identified by the given id.</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="repository.find-all">
|
||||
<para>Returns all entities.</para>
|
||||
</callout>
|
||||
|
||||
<callout arch="" arearefs="repository.find-all-pageable">
|
||||
<para>Returns a page of entities.</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="repository.count">
|
||||
<para>Returns the number of entities.</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="repository.delete">
|
||||
<para>Deletes the given entity.</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="repository.exists">
|
||||
<para>Returns whether an entity with the given id exists.</para>
|
||||
</callout>
|
||||
</calloutlist>
|
||||
</programlistingco>
|
||||
</example>
|
||||
|
||||
<para>Usually we will have persistence technology specific sub-interfaces
|
||||
to include additional technology specific methods. We will now ship
|
||||
implementations for a variety of Spring Data modules that implement that
|
||||
interface.</para>
|
||||
</section>
|
||||
|
||||
<section id="query-methods">
|
||||
<title>Query methods</title>
|
||||
|
||||
<para>Next to standard CRUD functionality repositories are usually query
|
||||
the underlying datastore. With Spring Data declaring those queries becomes
|
||||
a four-step process (we use the JPA based module as example but that works
|
||||
the same way for other stores):</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>Declare an interface extending the technology specific
|
||||
Repository sub-interface and type it to the domain class it shall
|
||||
handle.</para>
|
||||
|
||||
<programlisting language="java">public interface PersonRepository extends JpaRepository<User, Long> { … }</programlisting>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Declare query methods on the interface.</para>
|
||||
|
||||
<programlisting language="java">List<Person> findByLastname(String lastname);</programlisting>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Setup Spring to create proxy instances for those
|
||||
interfaces.</para>
|
||||
|
||||
<programlisting language="xml"><?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://www.springframework.org/schema/data/jpa
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/data/jpa
|
||||
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
|
||||
|
||||
<repositories base-package="com.acme.repositories" />
|
||||
|
||||
</beans></programlisting>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Get the repository instance injected and use it.</para>
|
||||
|
||||
<programlisting language="java">public class SomeClient {
|
||||
|
||||
@Autowired private PersonRepoyitory repository;
|
||||
|
||||
public void doSomething() {
|
||||
List<Person> persons = repository.findByLastname("Matthews");
|
||||
}</programlisting>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
|
||||
<para>At this stage we barely scratched the surface of what's possible
|
||||
with the repositories but the general approach should be clear. Let's go
|
||||
through each of these steps and and figure out details and various options
|
||||
that you have at each stage.</para>
|
||||
|
||||
<section>
|
||||
<title>Defining repository interfaces</title>
|
||||
|
||||
<para>As a very first step you define a domain class specific repository
|
||||
interface to start with. It's got to be typed to the domain class and an
|
||||
ID type so that you get CRUD methods of the
|
||||
<interfacename>Repository</interfacename> interface tailored to
|
||||
it.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Defining query methods</title>
|
||||
|
||||
<section>
|
||||
<title>Query lookup strategies</title>
|
||||
|
||||
<para>The next thing we have to discuss is the definition of query
|
||||
methods. There's roughly two main ways how the repository proxy is
|
||||
generally able to come up with the store specific query from the
|
||||
method name. The first option is to derive the quer from the method
|
||||
name directly, the second is using some kind of additionally created
|
||||
query. What detailed options are available pretty much depends on the
|
||||
actual store. However there's got to be some algorithm the decision
|
||||
which actual query to is made.</para>
|
||||
|
||||
<para>There's three strategies for the repository infrastructure to
|
||||
resolve the query. The strategy to be used can be configured at the
|
||||
namespace through the <code>query-lookup-strategy</code> attribute.
|
||||
However might be the case that some of the strategies are not
|
||||
supported for the specific datastore. Here are your options:</para>
|
||||
|
||||
<simplesect>
|
||||
<title>CREATE</title>
|
||||
|
||||
<para>This strategy will try to construct a store specific query
|
||||
from the query method's name. The general approach is to remove a
|
||||
given set of well-known prefixes from the method name and parse the
|
||||
rest of the method. Read more about query construction in <xref
|
||||
linkend="query-methods.query-creation" />.</para>
|
||||
</simplesect>
|
||||
|
||||
<simplesect>
|
||||
<title>USE_DECLARED_QUERY</title>
|
||||
|
||||
<para>This strategy tries to find a declared query which will be
|
||||
used for execution first. The query could be defined by an
|
||||
annotation somwhere or declared by other means. Please consult the
|
||||
documentation of the specific store to find out what options are
|
||||
available for that store. If the repository infrastructure does not
|
||||
find a declared query for the method at bootstrap time it will
|
||||
fail.</para>
|
||||
</simplesect>
|
||||
|
||||
<simplesect>
|
||||
<title>CREATE_IF_NOT_FOUND (default)</title>
|
||||
|
||||
<para>This strategy is actually a combination of the both mentioned
|
||||
above. It will try to lookup a declared query first but create a
|
||||
custom method name based query if no declared query was found. This
|
||||
is default lookup strategy and thus will be used if you don't
|
||||
configure anything explicitly. It allows quick query definition by
|
||||
method names but also custom tuning of these queries by introducing
|
||||
declared queries for those who need explicit tuning.</para>
|
||||
</simplesect>
|
||||
</section>
|
||||
|
||||
<section id="query-methods.query-creation">
|
||||
<title>Query creation</title>
|
||||
|
||||
<para>The query builder mechanism built into Spring Data repository
|
||||
infrastructue is useful to build constraining queries over entities of
|
||||
the repository. We will strip the prefixes <code>findBy</code>,
|
||||
<code>find</code>, <code>readBy</code>, <code>read</code>,
|
||||
<code>getBy</code> as well as <code>get</code> from the method and
|
||||
start parsing the rest of it. At a very basic level you can define
|
||||
conditions on entity properties and concatenate them with
|
||||
<code>AND</code> and <code>OR</code>.</para>
|
||||
|
||||
<example>
|
||||
<title>Query creation from method names</title>
|
||||
|
||||
<para><programlisting language="java">public interface PersonRepository extends JpaRepository<User, Long> {
|
||||
|
||||
List<Person> findByEmailAddressAndLastname(EmailAddress emailAddress, String lastname);
|
||||
}</programlisting></para>
|
||||
</example>
|
||||
|
||||
<para>The actual result of parsing that method will of course depend
|
||||
on the persistence store we create the query for. However there are
|
||||
some general things to notice. The expression are usually property
|
||||
traversals combined with operators that can be concatenated. As you
|
||||
can see in the example you can combine property expressions with And
|
||||
and Or. Beyond that you will get support for various operators like
|
||||
Between, LessThan, GreaterThan, Like for the property expressions. As
|
||||
the operators supported can vary from datastore to datastore please
|
||||
consult the according part of the reference documentation.</para>
|
||||
|
||||
<section>
|
||||
<title>Property expressions</title>
|
||||
|
||||
<para>Property expressions can just refer to a direct property of
|
||||
the managed entity (as you just saw in the example above. On query
|
||||
creation time we already make sure that the parsed property is at a
|
||||
property of the managed domain class. However you can also traverse
|
||||
nested properties to define constraints on. Assume
|
||||
<classname>Person</classname>s have <classname>Address</classname>es
|
||||
with <classname>ZipCode</classname>s. In that case a method name
|
||||
of</para>
|
||||
|
||||
<programlisting language="java">List<Person> findByAddressZipCode(ZipCode zipCode);</programlisting>
|
||||
|
||||
<para>will create the property traversal
|
||||
<code>x.address.zipCode</code>. The resolution algorithm starts with
|
||||
interpreting the entire part (<literal>AddressZipCode</literal>) as
|
||||
property and checks the domain class for a property with that name
|
||||
(uncapitalized). If it succeeds it just uses that. If not it starts
|
||||
splitting up the source at the camel case parts from the right side
|
||||
into a head and a tail and tries to find the according property,
|
||||
e.g. <literal>AddressZip</literal> and <literal>Code</literal>. If
|
||||
we find a property with that head we take the tail and continue
|
||||
building the tree down from there. As in our case the first split
|
||||
does not match we move the split point to the left
|
||||
(<literal>Address</literal>, <literal>ZipCode</literal>).</para>
|
||||
|
||||
<para>Now although this should work for most cases, there might be
|
||||
cases where the algorithm could select the wrong property. Suppose
|
||||
our <classname>Person</classname> class has a
|
||||
<code>addressZip</code> property as well. Then our algorithm would
|
||||
match in the first split round already and essentially choose the
|
||||
wrong property and finally fail (as the type of
|
||||
<classname>addressZip</classname> probably has no code property). To
|
||||
resolve this ambiguity you can use <literal>_</literal> inside your
|
||||
method name to manually define traversal points. So our method name
|
||||
would end up like so:</para>
|
||||
|
||||
<programlisting language="java">List<Person> findByAddress_ZipCode(ZipCode zipCode);
|
||||
</programlisting>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id="special-parameters">
|
||||
<title>Special parameter handling</title>
|
||||
|
||||
<para>To hand parameters to your query you simply define method
|
||||
parameters as already seen in in examples above. Besides that we will
|
||||
recognizes certain specific types to apply pagination and sorting to
|
||||
your queries dynamically.</para>
|
||||
|
||||
<example>
|
||||
<title>Using Pageable and Sort in query methods</title>
|
||||
|
||||
<programlisting>Page<User> findByLastname(String lastname, Pageable pageable);
|
||||
|
||||
List<User> findByLastname(String lastname, Sort sort);
|
||||
|
||||
List<User> findByLastname(String lastname, Pageable pageable);</programlisting>
|
||||
</example>
|
||||
|
||||
<para>The first method allows you to pass a <code>Pageable</code>
|
||||
instance to the query method to dynamically add paging to your
|
||||
statically defined query. <code>Sorting</code> options are handed via
|
||||
the <interfacename>Pageable</interfacename> instance, too. If you only
|
||||
need sorting, simply add a <code>Sort</code> parameter to your method.
|
||||
As you also can see, simply returning a
|
||||
<interfacename>List</interfacename> is possible as well. We will then
|
||||
not retrieve the additional metadata required to build the actual
|
||||
<interfacename>Page</interfacename> instance but rather simply
|
||||
restrict the query to lookup only the given range of entities.</para>
|
||||
|
||||
<note>
|
||||
<para>To find out how many pages you get for a query entirely we
|
||||
have to trigger an additional count query. This will be derived from
|
||||
the query you actually trigger by default.</para>
|
||||
</note>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Creating repository instances</title>
|
||||
|
||||
<para>So now the question is how to create instances and bean
|
||||
definitions for the repository interfaces defined.</para>
|
||||
|
||||
<section>
|
||||
<title>Spring</title>
|
||||
|
||||
<para>The easiest way to do so is by using the Spring namespace that
|
||||
is shipped with each Spring Data module that supports the repository
|
||||
mechanism. Each of those includes a repositories element that allows
|
||||
you to simply define a base packge Spring shall scan for you.</para>
|
||||
|
||||
<programlisting language="java"><?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://www.springframework.org/schema/data/jpa
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/data/jpa
|
||||
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
|
||||
|
||||
<repositories base-package="com.acme.repositories" />
|
||||
|
||||
</beans:beans></programlisting>
|
||||
|
||||
<para>In this case we instruct Spring to scan
|
||||
<package>com.acme.repositories</package> and all it's sub packages for
|
||||
interfaces extending the appropriate
|
||||
<interfacename>Repository</interfacename> sub-interface (in this case
|
||||
<interfacename>JpaRepository</interfacename>). For each interface
|
||||
found it will register the presistence technology specific
|
||||
<interfacename>FactoryBean</interfacename> to create the according
|
||||
proxies that handle invocations of the query methods. Each of these
|
||||
beans will be registered under a bean name that is derived from the
|
||||
interface name, so an interface of
|
||||
<interfacename>UserRepository</interfacename> would be registered
|
||||
under <code>userRepository</code>. The <code>base-package</code>
|
||||
attribute allows to use wildcards, so that you can have a pattern of
|
||||
packages parsed. </para>
|
||||
|
||||
<simplesect>
|
||||
<title>Using filters</title>
|
||||
|
||||
<para>By default we will pick up every interface extending the
|
||||
persistence technology specific
|
||||
<interfacename>Repository</interfacename> sub-interface located
|
||||
underneath the configured base package and create a bean instance
|
||||
for it. However, you might want to gain finer grained control over
|
||||
which interfaces bean instances get created for. To do this we
|
||||
support the use of <code><include-filter /></code> and
|
||||
<code><exclude-filter /></code> elements inside
|
||||
<code><repositories /></code>. The semantics are exactly
|
||||
equivalent to the elements in Spring's context namespace. For
|
||||
details see <ulink
|
||||
url="http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-scanning-filters"
|
||||
vendor="">Spring reference documentation</ulink> on these
|
||||
elements.</para>
|
||||
|
||||
<para>E.g. to exclude certain interfaces from instantiation as
|
||||
repository, you could use the following configuration:</para>
|
||||
|
||||
<example>
|
||||
<title>Using exclude-filter element</title>
|
||||
|
||||
<programlisting language="xml"><repositories base-package="com.acme.repositories">
|
||||
<context:exclude-filter type="regex" expression=".*SomeRepository" />
|
||||
</repositories>
|
||||
</programlisting>
|
||||
|
||||
<para>This would exclude all interface ending on
|
||||
<interfacename>SomeRepository</interfacename> from being
|
||||
instantiated.</para>
|
||||
</example>
|
||||
</simplesect>
|
||||
|
||||
<simplesect>
|
||||
<title>Manual configuration</title>
|
||||
|
||||
<para>If you'd rather like to manually define which repository
|
||||
instances to create you can do this with nested <code><repository
|
||||
/></code> elements.</para>
|
||||
|
||||
<programlisting language="java"><repositories base-package="com.acme.repositories">
|
||||
<repository id="userRepository" />
|
||||
</repositories>
|
||||
</programlisting>
|
||||
</simplesect>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Standalone usage</title>
|
||||
|
||||
<para>You can also use the repository infrastructure outside of a
|
||||
Spring container usage. You will still need to have some of the Spring
|
||||
libraries on your classpath but you can generally setup repositories
|
||||
programatically as well. The Spring Data modules providing repository
|
||||
support ship a persistence technology specific RepositoryFactory that
|
||||
can be used as follows:</para>
|
||||
|
||||
<example>
|
||||
<title>Standalone usage of repository factory</title>
|
||||
|
||||
<programlisting>RepositoryFactorySupport factory = … // Instantiate factory here
|
||||
UserRepository repository = factory.getRepository(UserRepository.class</programlisting>
|
||||
</example>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id="custom-implementations">
|
||||
<title>Custom implementations</title>
|
||||
|
||||
<section id="single-repository-behaviour">
|
||||
<title>Adding behaviour to single repositories</title>
|
||||
|
||||
<para>Often it is necessary to provide a custom implementation for a few
|
||||
repository methods. Spring Data repositories easily allow provide custom
|
||||
repository code and integrate it with generic CRUD abstraction and query
|
||||
method functionality. To enrich a repository with custom functionality
|
||||
you have to define an interface and an implementation for that
|
||||
functionality first and let the repository interface you provided so far
|
||||
extend that custom interface.</para>
|
||||
|
||||
<example>
|
||||
<title>Interface for custom repository functionality</title>
|
||||
|
||||
<programlisting language="java">interface UserRepositoryCustom {
|
||||
|
||||
public void someCustomMethod(User user);
|
||||
}</programlisting>
|
||||
</example>
|
||||
|
||||
<example>
|
||||
<title>Implementation of custom repository functionality</title>
|
||||
|
||||
<para><programlisting language="java">class UserRepositoryImpl implements UserRepositoryCustom {
|
||||
|
||||
public void someCustomMethod(User user) {
|
||||
// Your custom implementation
|
||||
}
|
||||
}</programlisting>Note that the implementation itself does not depend on
|
||||
Spring Data and can be a regular Spring bean. So you can either use
|
||||
standard dependency injection behaviour to inject references to other
|
||||
beans, take part in aspects and so on.</para>
|
||||
</example>
|
||||
|
||||
<example>
|
||||
<title>Changes to the your basic repository interface</title>
|
||||
|
||||
<para><programlisting language="java">public interface UserRepository extends JpaRepository<User, Long>, UserRepositoryCustom {
|
||||
|
||||
// Declare query methods here
|
||||
}</programlisting>Let your standard repository interface extend the custom
|
||||
one. This makes CRUD and custom functionality available to
|
||||
clients.</para>
|
||||
</example>
|
||||
|
||||
<simplesect>
|
||||
<title>Configuration</title>
|
||||
|
||||
<para>If you use namespace configuration the repository infrastructure
|
||||
tries to autodetect custom implementations by looking up classes in
|
||||
the package we found a repository using the naming conventions
|
||||
appending the namespace element's attribute
|
||||
<code>repository-impl-postfix</code> to the classname. This suffix
|
||||
defaults to <code>Impl</code>.</para>
|
||||
|
||||
<example>
|
||||
<title>Configuration example</title>
|
||||
|
||||
<para><programlisting language="xml"><repositories base-package="com.acme.repository">
|
||||
<repository id="userRepository" />
|
||||
</repositories>
|
||||
|
||||
<repositories base-package="com.acme.repository" repository-impl-postfix="FooBar">
|
||||
<repository id="userRepository" />
|
||||
</repositories></programlisting></para>
|
||||
</example>
|
||||
|
||||
<para>The first configuration example will try to lookup a class
|
||||
<classname>com.acme.repository.UserRepositoryImpl</classname> to act
|
||||
as custom repository implementation, where the second example will try
|
||||
to lookup
|
||||
<classname>com.acme.repository.UserRepositoryFooBar</classname>.</para>
|
||||
</simplesect>
|
||||
|
||||
<simplesect>
|
||||
<title>Manual wiring</title>
|
||||
|
||||
<para>The approach above works perfectly well if your custom
|
||||
implementation uses annotation based configuration and autowring
|
||||
entirely as will be trated as any other Spring bean. If your customly
|
||||
implemented bean needs some special wiring you simply declare the bean
|
||||
and name it after the conventions just descibed. We will then pick up
|
||||
the custom bean by name rather than creating an own instance.</para>
|
||||
|
||||
<example>
|
||||
<title>Manual wiring of custom implementations (I)</title>
|
||||
|
||||
<programlisting language="xml"><repositories base-package="com.acme.repository">
|
||||
<repository id="userRepository" />
|
||||
</repositories>
|
||||
|
||||
<beans:bean id="userRepositoryImpl" class="…">
|
||||
<!-- further configuration -->
|
||||
</beans:bean></programlisting>
|
||||
|
||||
<para>This also works if you use automatic repository lookup without
|
||||
defining single <code><repository /></code> elements.</para>
|
||||
</example>
|
||||
|
||||
<para>In case you are not in control of the implementation bean name
|
||||
(e.g. if you wrap a generic repository facade around an existing
|
||||
repository implementation) you can explicitly tell the
|
||||
<code><repository /></code> element which bean to use as custom
|
||||
implementation by using the <code>repository-impl-ref</code>
|
||||
attribute.</para>
|
||||
|
||||
<example>
|
||||
<title>Manual wiring of custom implementations (II)</title>
|
||||
|
||||
<para><programlisting language="xml"><repositories base-package="com.acme.repository">
|
||||
<repository id="userRepository" repository-impl-ref="customRepositoryImplementation" />
|
||||
</repositories>
|
||||
|
||||
<bean id="customRepositoryImplementation" class="…">
|
||||
<!-- further configuration -->
|
||||
</bean></programlisting></para>
|
||||
</example>
|
||||
</simplesect>
|
||||
</section>
|
||||
|
||||
<section id="custom-behaviour-for-all-repositories">
|
||||
<title>Adding custom behaviour to all repositories</title>
|
||||
|
||||
<para>In other cases you might want to add a single method to all of
|
||||
your repository interfaces. So the approach just shown is not feasible.
|
||||
The first step to achieve this is adding and intermediate interface to
|
||||
declare the shared behaviour</para>
|
||||
|
||||
<example>
|
||||
<title>An interface declaring custom shared behaviour</title>
|
||||
|
||||
<para><programlisting language="java">public interface MyRepository<T, ID extends Serializable>
|
||||
extends JpaRepository<T, ID> {
|
||||
|
||||
void sharedCustomMethod(ID id);
|
||||
}</programlisting></para>
|
||||
</example>
|
||||
|
||||
<para>Now your individual repository interfaces will extend this
|
||||
intermediate interface to include the functionality declared. The second
|
||||
step is to create an implementation of this interface that extends the
|
||||
persistence technology specific repository base class which will act as
|
||||
custom base class for the repository proxies then.</para>
|
||||
|
||||
<note>
|
||||
<para>If you're using automatic repository interface detection using
|
||||
the Spring namespace using the interface just as is will cause Spring
|
||||
trying to create an instance of
|
||||
<interfacename>MyRepository</interfacename>. This is of course not
|
||||
desired as it just acts as indermediate between
|
||||
<interfacename>Repository</interfacename> and the actual repository
|
||||
interfaces you want to define for each entity. To exclude an interface
|
||||
extending <interfacename>Repository</interfacename> from being
|
||||
instantiated as repository instance annotate it with
|
||||
<interfacename>@NoRepositoryBean</interfacename>.</para>
|
||||
</note>
|
||||
|
||||
<example>
|
||||
<title>Custom repository base class</title>
|
||||
|
||||
<programlisting language="java">public class MyRepositoryImpl<T, ID extends Serializable>
|
||||
extends SimpleJpaRepository<T, ID> implements MyRepository<T, ID> {
|
||||
|
||||
public void sharedCustomMethod(ID id) {
|
||||
// implementation goes here
|
||||
}
|
||||
}</programlisting>
|
||||
</example>
|
||||
|
||||
<para>The last step to get this implementation used as base class for
|
||||
Spring Data repositores is replacing the standard
|
||||
<classname>RepositoryFactoryBean</classname> with a custom one using a
|
||||
custom <classname>RepositoryFactory</classname> that in turn creates
|
||||
instances of your <classname>MyRepositoryImpl</classname> class.</para>
|
||||
|
||||
<example>
|
||||
<title>Custom repository factory bean</title>
|
||||
|
||||
<programlisting language="java">public class MyRepositoryFactoryBean<T extends JpaRepository<?, ?>
|
||||
extends JpaRepositoryFactoryBean<T> {
|
||||
|
||||
protected RepositoryFactorySupport getRepositoryFactory(…) {
|
||||
return new MyRepositoryFactory(…);
|
||||
}
|
||||
|
||||
private static class MyRepositoryFactory extends JpaRepositoryFactory{
|
||||
|
||||
public MyRepositoryImpl getTargetRepository(…) {
|
||||
return new MyRepositoryImpl(…);
|
||||
}
|
||||
|
||||
public Class<? extends RepositorySupport> getRepositoryClass() {
|
||||
return MyRepositoryImpl.class;
|
||||
}
|
||||
}
|
||||
}</programlisting>
|
||||
</example>
|
||||
|
||||
<para>Finally you can either declare beans of the custom factory
|
||||
directly or use the <code>factory-class</code> attribute of the Spring
|
||||
namespace to tell the repository infrastructure to use your custom
|
||||
factory implementation.</para>
|
||||
|
||||
<example>
|
||||
<title>Using the custom factory with the namespace</title>
|
||||
|
||||
<programlisting language="xml"><repositories base-package="com.acme.repository"
|
||||
factory-class="com.acme.MyRepositoryFactoryBean" /></programlisting>
|
||||
</example>
|
||||
</section>
|
||||
</section>
|
||||
</chapter>
|
||||
680
src/docbkx/reference/jpa.xml
Normal file
@@ -0,0 +1,680 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
|
||||
<chapter id="jpa.repositories">
|
||||
<title>JPA Repositories</title>
|
||||
|
||||
<abstract>
|
||||
<para>This chapter includes details of the JPA repository
|
||||
implementation.</para>
|
||||
</abstract>
|
||||
|
||||
<section id="jpa.query-methods">
|
||||
<title>Query methods</title>
|
||||
|
||||
<section id="jpa.sample-app.finders.strategies">
|
||||
<title>Query lookup strategies</title>
|
||||
|
||||
<para>The JPA module supports defining a query manually as String or
|
||||
have it being derived from the method name.</para>
|
||||
|
||||
<simplesect>
|
||||
<title>Declared queries</title>
|
||||
|
||||
<para>Although getting a query derived from the method name is quite
|
||||
convenient one might face the situation in which either the method
|
||||
name parser does not support the keyword one wants to use or the
|
||||
method name would get unnecessarily ugly. So you can either use JPA
|
||||
named queries through a naming convention (see <xref
|
||||
linkend="jpa.query-methods.named-queries" /> for more information) or
|
||||
rather annotate your query method with
|
||||
<interfacename>@Query</interfacename> (see as for details).</para>
|
||||
</simplesect>
|
||||
|
||||
<simplesect>
|
||||
<title>Strategies</title>
|
||||
|
||||
<para>This strategy tries to find a declared query that can either be
|
||||
defined using JPA <code>@NamedQuery</code> means or Hades
|
||||
<code>@Query</code> annotation (see <xref
|
||||
linkend="jpa.query-methods.named-queries" /> and <xref
|
||||
linkend="jpa.query-methods.at-query" /> for details). If no declared
|
||||
query is found execution of the query will fail.</para>
|
||||
</simplesect>
|
||||
|
||||
<simplesect>
|
||||
<title>CREATE_IF_NOT_FOUND (default)</title>
|
||||
|
||||
<para>This strategy is actually a combination of the both mentioned
|
||||
above. It will try to lookup a declared query first but create a
|
||||
custom method name based query if no named query was found. This is
|
||||
default lookup strategy and thus will be used if you don't configure
|
||||
anything explicitly. It allows quick query definition by method names
|
||||
but also custom tuning of these queries by introducing declared
|
||||
queries for those who need explicit tuning.</para>
|
||||
</simplesect>
|
||||
</section>
|
||||
|
||||
<section id="jpa.query-methods.query-creation">
|
||||
<title>Query creation</title>
|
||||
|
||||
<para>Generally the query creation mechanism for JPA works as described
|
||||
in <xref linkend="repositories.query-methods" />. Here's a short example
|
||||
of what a JPA query method translates into:<example>
|
||||
<title>Query creation from method names</title>
|
||||
|
||||
<para><programlisting language="java">public interface UserRepository extends Repository<User, Long> {
|
||||
|
||||
List<User> findByEmailAddressAndLastname(String emailAddress, String lastname);
|
||||
}</programlisting>We will create a query using the JPA criteria API from this
|
||||
but essentially this translates into the following query:</para>
|
||||
|
||||
<programlisting>select u from User u where u.emailAddress = ?1 and u.lastname = ?2</programlisting>
|
||||
|
||||
<para>Spring Data JPA will do a property check and traverse nested
|
||||
properties like described in <xref
|
||||
linkend="repositories.query-methods.property-expressions" />. Here's
|
||||
an overview of the keywords supported for JPA and what a method
|
||||
containing that keyword essentially translates to.</para>
|
||||
</example></para>
|
||||
|
||||
<para><table>
|
||||
<title>Supported keywords inside method names</title>
|
||||
|
||||
<tgroup cols="3">
|
||||
<colspec colwidth="1*" />
|
||||
|
||||
<colspec colwidth="2*" />
|
||||
|
||||
<colspec colwidth="3*" />
|
||||
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Keyword</entry>
|
||||
|
||||
<entry>Sample</entry>
|
||||
|
||||
<entry>JPQL snippet</entry>
|
||||
</row>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<row>
|
||||
<entry><code>And</code></entry>
|
||||
|
||||
<entry><code>findByLastnameAndFirstname</code></entry>
|
||||
|
||||
<entry><code>… where x.lastname = ?1 and x.firstname =
|
||||
?2</code></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><code>Or</code></entry>
|
||||
|
||||
<entry><code>findByLastnameOrFirstname</code></entry>
|
||||
|
||||
<entry><code>… where x.lastname = ?1 or x.firstname =
|
||||
?2</code></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><code>Between</code></entry>
|
||||
|
||||
<entry><code>findByStartDateBetween</code></entry>
|
||||
|
||||
<entry><code>… where x.startDate between 1? and
|
||||
?2</code></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><code>LessThan</code></entry>
|
||||
|
||||
<entry><code>findByAgeLessThan</code></entry>
|
||||
|
||||
<entry><code>… where x.age < ?1</code></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><code>GreaterThan</code></entry>
|
||||
|
||||
<entry><code>findByAgeGreaterThan</code></entry>
|
||||
|
||||
<entry><code>… where x.age > ?1</code></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><code>IsNull</code></entry>
|
||||
|
||||
<entry><code>findByAgeIsNull</code></entry>
|
||||
|
||||
<entry><code>… where x.age is null</code></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><code>IsNotNull,NotNull</code></entry>
|
||||
|
||||
<entry><code>findByAge(Is)NotNull</code></entry>
|
||||
|
||||
<entry><code>… where x.age not null</code></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><code>Like</code></entry>
|
||||
|
||||
<entry><code>findByFirstnameLike</code></entry>
|
||||
|
||||
<entry><code>… where x.firstname like ?1</code></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><code>NotLike</code></entry>
|
||||
|
||||
<entry><code>findByFirstnameNotLike</code></entry>
|
||||
|
||||
<entry><code>… where x.firstname not like ?1</code></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><code>OrderBy</code></entry>
|
||||
|
||||
<entry><code>findByAgeOrderByLastnameDesc</code></entry>
|
||||
|
||||
<entry><code>… where x.age > ?1 order by x.lastname
|
||||
desc</code></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><code>Not</code></entry>
|
||||
|
||||
<entry><code>findByLastnameNot</code></entry>
|
||||
|
||||
<entry><code>… where x.lastname <> ?1</code></entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table></para>
|
||||
</section>
|
||||
|
||||
<section id="jpa.query-methods.named-queries">
|
||||
<title>Using JPA NamedQueries</title>
|
||||
|
||||
<note>
|
||||
<para>The examples use simple <code><named-query /></code>
|
||||
element and <code>@NamedQuery</code> annotation. The queries for these
|
||||
configuration elements have to be defined in JPA query language. Of
|
||||
course you can use <code><named-native-query /></code> or
|
||||
<code>@NamedNativeQuery</code>, too. These elements allow you to
|
||||
define the query in native SQL by losing the database platform
|
||||
independence.</para>
|
||||
</note>
|
||||
|
||||
<simplesect>
|
||||
<title>XML named query definition</title>
|
||||
|
||||
<para>To use XML configuration simply add the necessary
|
||||
<code><named-query /></code> element to the
|
||||
<filename>orm.xml</filename> JPA configuration file located in
|
||||
<filename>META-INF</filename> folder of your classpath. Automatic
|
||||
invocation of named queries is enabled by using some defined naming
|
||||
convention. For more details see below.</para>
|
||||
|
||||
<example>
|
||||
<title>XML named query configuration</title>
|
||||
|
||||
<programlisting language="xml"><named-query name="User.findByLastname">
|
||||
<query>select u from User u where u.lastname = ?1</query>
|
||||
</named-query></programlisting>
|
||||
</example>
|
||||
|
||||
<para>As you can see the query has a special name which will be used
|
||||
to resolve it at runtime.</para>
|
||||
</simplesect>
|
||||
|
||||
<simplesect>
|
||||
<title>Annotation configuration</title>
|
||||
|
||||
<para>Annotation configuration has the advantage not to need another
|
||||
config file to be edited, probably lowering maintenance cost. You pay
|
||||
for that benefit by the need to recompile your domain class for every
|
||||
new query declaration.</para>
|
||||
|
||||
<example>
|
||||
<title>Annotation based named query configuration</title>
|
||||
|
||||
<programlisting language="java">@Entity
|
||||
@NamedQuery(name = "User.findByEmailAddress",
|
||||
query = "select u from User u where u.emailAddress = ?1")
|
||||
public class User {
|
||||
|
||||
}</programlisting>
|
||||
</example>
|
||||
</simplesect>
|
||||
|
||||
<simplesect>
|
||||
<title>Declaring interfaces</title>
|
||||
|
||||
<para>To allow execution of this named query all you need to do is to
|
||||
specify the <interfacename>UserRepository</interfacename> as
|
||||
follows:</para>
|
||||
|
||||
<example>
|
||||
<title>Query method declaration in UserRepository</title>
|
||||
|
||||
<programlisting language="java">public interface UserRepository extends JpaRepository<User, Long> {
|
||||
|
||||
List<User> findByLastname(String lastname);
|
||||
|
||||
User findByEmailAddress(String emailAddress);
|
||||
}</programlisting>
|
||||
</example>
|
||||
|
||||
<para>Declaring this method we will try to resolve a call to this
|
||||
method to a named query starting with the simple name of the
|
||||
configured domain class followed by the method name separated by a
|
||||
dot. So the example here would use the named queries defined above
|
||||
instead of trying to create a query from the method name.</para>
|
||||
</simplesect>
|
||||
</section>
|
||||
|
||||
<section id="jpa.query-methods.at-query">
|
||||
<title>Using @Query</title>
|
||||
|
||||
<para>Using named queries to declare queries for entities is a valid
|
||||
approach and works fine for a small number amount of queries. As the
|
||||
queries themselves are tied to a Java method to execute them you
|
||||
actually can bind them to the query executing methods using Spring Data
|
||||
JPA <code>@Query</code> annotation rather than annotating them to the
|
||||
domain class. This will free the domain class from persistence specific
|
||||
information and colocate the query to the repository interface.</para>
|
||||
|
||||
<para>Querys annotated to the query method will trump queries defined
|
||||
using <code>@NamedQuery</code> or named queries declared in in
|
||||
<filename>orm.xml</filename>.</para>
|
||||
|
||||
<example>
|
||||
<title>Declare query at the query method using @Query</title>
|
||||
|
||||
<programlisting language="java">public interface UserRepository extends JpaRepository<User, Long> {
|
||||
|
||||
@Query("select u from User u where u.emailAddress = ?1")
|
||||
User findByEmailAddress(String emailAddress);
|
||||
}</programlisting>
|
||||
</example>
|
||||
</section>
|
||||
|
||||
<section id="jpa.named-parameters">
|
||||
<title>Using named parameters</title>
|
||||
|
||||
<para>By default Sprign Data JPA will use position based parameter
|
||||
binding as described in all the samples above. This makes query methods
|
||||
a little error prone to refactorings regarding the parameter position.
|
||||
To solve this issue you can use <code>@Param</code> annotation to give a
|
||||
method parameter a concrete name and bind the name in the query:</para>
|
||||
|
||||
<example>
|
||||
<title>Using named parameters</title>
|
||||
|
||||
<programlisting language="java">public interface UserRepository extends JpaRepository<User, Long> {
|
||||
|
||||
@Query("select u from User u where u.firstname = :firstname or u.lastname = :lastname")
|
||||
User findByLastnameOrFirstname(@Param("lastname") String lastname,
|
||||
@Param("firstname") String firstname);
|
||||
}</programlisting>
|
||||
|
||||
<para>Note that the method parameters are switched according to the
|
||||
occurrence in the query defined.</para>
|
||||
</example>
|
||||
</section>
|
||||
|
||||
<section id="jpa.modifying-queries">
|
||||
<title>Modifying queries</title>
|
||||
|
||||
<para>All the sections before described how to declare queries to access
|
||||
a given entity or collection of entitites. Of course you can add custom
|
||||
modifying behaviour by using facilities described in <xref
|
||||
linkend="custom-implementations" />. As this approach is feasible for
|
||||
comprehensive custom functionality, you can achieve the execution of
|
||||
modifying queries that actually only need parameter binding by
|
||||
annotating the query method with <code>@Modifying</code>:</para>
|
||||
|
||||
<example>
|
||||
<title>Declaring manipulating queries</title>
|
||||
|
||||
<programlisting language="java">@Modifying
|
||||
@Query("update User u set u.firstname = ?1 where u.lastname = ?2")
|
||||
int setFixedFirstnameFor(String firstname, String lastname);</programlisting>
|
||||
</example>
|
||||
|
||||
<para>This will trigger the query annotated to the method as updating
|
||||
query instead of a selecting one. As the
|
||||
<interfacename>EntityManager</interfacename> might contain outdated
|
||||
entities after the execution of the modifying query, we automatically
|
||||
clear it (see JavaDoc of
|
||||
<interfacename>EntityManager</interfacename>.<methodname>clear()</methodname>
|
||||
for details). This will effectively drop all non-flushed changes still
|
||||
pending in the <interfacename>EntityManager</interfacename>. If you
|
||||
don't wish the <interfacename>EntityManager</interfacename> to be
|
||||
cleared automatically you can set
|
||||
<interfacename>@Modifying</interfacename> annotation's
|
||||
<code>clearAutomatically</code> attribute to
|
||||
<literal>false</literal>;</para>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id="specifications">
|
||||
<title>Specifications</title>
|
||||
|
||||
<para>JPA 2 introduces a criteria API that can be used to build queries
|
||||
programatically. Writing a criteria you actually define the where-clause
|
||||
of a query for a query of the handled domain class. Taking another step
|
||||
back these criterias can be regarded as predicate over the entity that is
|
||||
verbalized by the JPA criteria API constraints.</para>
|
||||
|
||||
<para>Spring Data JPA now takes the concept of a specification from Eric
|
||||
Evans' book Domain Driven Design, that carries the same semantics and
|
||||
provides an API to define such
|
||||
<interfacename>Specification</interfacename>s using the JPA criteria API.
|
||||
Thus you find methods like this in
|
||||
<interfacename>JpaRepository</interfacename>:</para>
|
||||
|
||||
<programlisting language="java">List<T> readAll(Specification<T> spec);</programlisting>
|
||||
|
||||
<para>The <interfacename>Specification</interfacename> interface now looks
|
||||
as follows:</para>
|
||||
|
||||
<programlisting language="java">public interface Specification<T> {
|
||||
Predicate toPredicate(Root<T> root, CriteriaQuery<?> query,
|
||||
CriteriaBuilder builder);
|
||||
}</programlisting>
|
||||
|
||||
<para>Okay, so what is the typical use case?
|
||||
<interfacename>Specification</interfacename>s can easily be used to build
|
||||
an extensible set of predicates on top of an entity that then can be
|
||||
combined and used with <interfacename>JpaRepository</interfacename>
|
||||
without the need of declaring a query (method) for every needed
|
||||
combination of those. Here's an example:</para>
|
||||
|
||||
<example>
|
||||
<title>Specifications for a Customer</title>
|
||||
|
||||
<programlisting language="java">public class CustomerSpecs {
|
||||
|
||||
public static Specification<Customer> isLongTermCustomer() {
|
||||
return new Specification<Customer>() {
|
||||
Predicate toPredicate(Root<T> root, CriteriaQuery<?> query,
|
||||
CriteriaBuilder builder) {
|
||||
|
||||
LocalDate date = new LocalDate().minusYears(2);
|
||||
return builder.lessThan(root.get(Customer_.createdAt), date);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static Specification<Customer> hasSalesOfMoreThan(MontaryAmount value) {
|
||||
return new Specification<Customer>() {
|
||||
Predicate toPredicate(Root<T> root, CriteriaQuery<?> query,
|
||||
CriteriaBuilder builder) {
|
||||
|
||||
// build query here
|
||||
}
|
||||
};
|
||||
}
|
||||
}</programlisting>
|
||||
</example>
|
||||
|
||||
<para>Admittedly the amount of boilerplate leaves room for improvement
|
||||
(that will hopefully be reduced by Java 8 closures) but the client side
|
||||
becomes much nicer as you will see below. Besides that we have expressed
|
||||
some criteria on a business requirement abstraction level and created
|
||||
executable <interfacename>Specification</interfacename>s. So a client
|
||||
might use a <interfacename>Specification</interfacename> as
|
||||
follows:</para>
|
||||
|
||||
<example>
|
||||
<title>Using a simple Specification</title>
|
||||
|
||||
<programlisting language="java">List<Customer> customers = customerRepository.findAll(isLongTermCustomer());</programlisting>
|
||||
</example>
|
||||
|
||||
<para>Okay, why not simply creating a query for this kind of data access?
|
||||
You're right. Using a single <interfacename>Specification</interfacename>
|
||||
does not gain a lot of benefit over a plain query declaration. The power
|
||||
of <interfacename>Specification</interfacename>s really shines when you
|
||||
combine them to create new <interfacename>Specification</interfacename>
|
||||
objects. You can achieve this through the
|
||||
<classname>Specifications</classname> helper class we provide to build
|
||||
expressions like this:</para>
|
||||
|
||||
<example>
|
||||
<title>Combined Specifications</title>
|
||||
|
||||
<para><programlisting language="java">MonetaryAmount amount = new MonetaryAmount(200.0, Currencies.DOLLAR);
|
||||
List<Customer> customers = customerRepository.readAll(
|
||||
where(isLongTermCustomer()).or(hasSalesOfMoreThan(amount)));</programlisting>As
|
||||
you can see, <classname>Specifications</classname> offers some gluecode
|
||||
methods to chain and combine
|
||||
<interfacename>Specification</interfacename>s. Thus extending your data
|
||||
access layer is just a matter of creating new
|
||||
<interfacename>Specification</interfacename> implementations and
|
||||
combining them with ones already existing.</para>
|
||||
</example>
|
||||
</section>
|
||||
|
||||
<section id="transactions">
|
||||
<title>Transactionality</title>
|
||||
|
||||
<para>CRUD methods on repository instances are transactional by default.
|
||||
For reading operations the transaction configuration <code>readOnly</code>
|
||||
flag is set to true, all others are configured with a plain
|
||||
<classname>@Transactional</classname> so that default transaction
|
||||
configuration applies. For details see JavaDoc of
|
||||
<classname>Repository</classname>. If you need to tweak transaction
|
||||
configuration for one of the methods declared in
|
||||
<interfacename>Repository</interfacename> simply redeclare the method in
|
||||
your repository interface as follows:</para>
|
||||
|
||||
<example>
|
||||
<title>Custom transaction configuration for CRUD</title>
|
||||
|
||||
<programlisting language="java">public interface UserRepository extends JpaRepository<User, Long> {
|
||||
|
||||
@Override
|
||||
@Transactional(timeout = 10)
|
||||
public List<User> findAll();
|
||||
|
||||
// Further query method declarations
|
||||
}</programlisting>
|
||||
|
||||
<para>This will cause the <methodname>findAll()</methodname> method to
|
||||
be executed with a timeout of 10 seconds and without the
|
||||
<code>readOnly</code> flag.</para>
|
||||
</example>
|
||||
|
||||
<para>Another possibility to alter transactional behaviour is using a
|
||||
facade or service implementation that typically covers more than one
|
||||
repository. Its purpose is to define transactional boundaries for non-CRUD
|
||||
operations:</para>
|
||||
|
||||
<example>
|
||||
<title>Using a facade to define transactions for multiple repository
|
||||
calls</title>
|
||||
|
||||
<programlisting language="java">@Service
|
||||
class UserManagementImpl implements UserManagement {
|
||||
|
||||
private final UserRepository userRepository;
|
||||
private final RoleRepository roleRepository;
|
||||
|
||||
@Autowired
|
||||
public UserManagementImpl(UserRepository userRepository,
|
||||
RoleRepository roleRepository) {
|
||||
this.userRepository = userRepository;
|
||||
this.roleRepository = roleRepository;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void addRoleToAllUsers(String roleName) {
|
||||
|
||||
Role role = roleRepository.findByName(roleName);
|
||||
|
||||
for (User user : userRepository.readAll()) {
|
||||
user.addRole(role);
|
||||
userRepository.save(user);
|
||||
}
|
||||
}</programlisting>
|
||||
|
||||
<para>This will cause call to
|
||||
<methodname>addRoleToAllUsers(…)</methodname> to run inside a
|
||||
transaction (participating in an existing one or create a new one if
|
||||
none already running). The transaction configuration at the repositories
|
||||
will be neglected then as the outer transaction configuration determines
|
||||
the actual one used. Note that you will have to activate
|
||||
<code><tx:annotation-driven /></code> explicitly to get annotation
|
||||
based configuration at facades working. The example above assumes you're
|
||||
using component scanning.</para>
|
||||
</example>
|
||||
|
||||
<section id="transactional-query-methods">
|
||||
<title>Transactional query methods</title>
|
||||
|
||||
<para>To let your query methods be transactional simply use
|
||||
<interfacename>@Transactional</interfacename> at the repository
|
||||
interface you define.</para>
|
||||
|
||||
<example>
|
||||
<title>Using @Transactional at query methods</title>
|
||||
|
||||
<programlisting language="java">@Transactional(readOnly = true)
|
||||
public interface UserRepository extends JpaRepository<User, Long> {
|
||||
|
||||
List<User> findByLastname(String lastname);
|
||||
|
||||
@Modifying
|
||||
@Transactional
|
||||
@Query("delete from User u where u.active = false")
|
||||
void deleteInactiveUsers();
|
||||
}</programlisting>
|
||||
|
||||
<para>Typically you will use the <code>readOnly</code> flag set to
|
||||
true as most of the query methods will be reading ones. In contrast to
|
||||
that <methodname>deleteInactiveUsers()</methodname> makes use of the
|
||||
<interfacename>@Modifying</interfacename> annotation and overrides the
|
||||
transaction configuration. Thus the method will be executed with
|
||||
<code>readOnly</code> flag set to false.</para>
|
||||
</example>
|
||||
|
||||
<note>
|
||||
<para>It's definitely reasonable to use transactions for read only
|
||||
queries as we can mark them as such by setting the
|
||||
<code>readOnly</code> flag. This will not act as check that you do not
|
||||
trigger a manipulating query nevertheless (although some databases
|
||||
reject e.g. <literal>INSERT</literal> or <literal>UPDATE</literal>
|
||||
statements inside a transaction set to be read only) but gets
|
||||
propagated as hint to the underlying JDBC driver to do performance
|
||||
optimizations. Furthermore Spring will do some optimizations to the
|
||||
underlying JPA provider. E.g. when used with Hibernate the flush mode
|
||||
is set to <code>NEVER</code> when you configure a transaction as read
|
||||
only which causes Hibernate to skip dirty checks that gets quite
|
||||
noticeable on large object trees.</para>
|
||||
</note>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id="jpa.auditing">
|
||||
<title>Auditing</title>
|
||||
|
||||
<para>Most applications will require some auditability for entities
|
||||
allowing to track creation date and user and modification date and user.
|
||||
Spring Data JPA provides facilities to add this audition information to
|
||||
entity transparently by AOP means. To take part in this functionality your
|
||||
domain classes have to implement a more advanced interface:</para>
|
||||
|
||||
<example>
|
||||
<title><interfacename>Auditable</interfacename> interface</title>
|
||||
|
||||
<programlisting language="java">public interface Auditable<U, ID extends Serializable>
|
||||
extends Persistable<ID> {
|
||||
|
||||
U getCreatedBy();
|
||||
|
||||
void setCreatedBy(U createdBy);
|
||||
|
||||
DateTime getCreatedDate();
|
||||
|
||||
void setCreated(Date creationDate);
|
||||
|
||||
U getLastModifiedBy();
|
||||
|
||||
void setLastModifiedBy(U lastModifiedBy);
|
||||
|
||||
DateTime getLastModifiedDate();
|
||||
|
||||
void setLastModified(Date lastModifiedDate);
|
||||
}</programlisting>
|
||||
</example>
|
||||
|
||||
<para>As you can see the modifying entity itself only has to be an entity.
|
||||
Mostly this will be some sort of User entity, so we chose U as parameter
|
||||
type.</para>
|
||||
|
||||
<note>
|
||||
<para>To minimize boilerplate code Spring Data JPA offers
|
||||
<classname>AbstractPersistable</classname> and
|
||||
<classname>AbstractAuditable</classname> base classes that implement and
|
||||
preconfigure entities. Thus you can decide to only implement the
|
||||
interface or enjoy more sophisticated support by extending the base
|
||||
class.</para>
|
||||
</note>
|
||||
|
||||
<simplesect>
|
||||
<title>General auditing configuration</title>
|
||||
|
||||
<para>Spring Data JPA ships with an entity listener that can be used to
|
||||
trigger capturing auditing information. So first you have to register
|
||||
the <classname>AuditingEntityListener</classname> inside your
|
||||
<filename>orm.xml</filename> to be used for all entities in your
|
||||
persistence contexts:</para>
|
||||
|
||||
<example>
|
||||
<title>Auditing configuration orm.xml</title>
|
||||
|
||||
<programlisting language="xml"><persistence-unit-metadata>
|
||||
<persistence-unit-defaults>
|
||||
<entity-listeners>
|
||||
<entity-listener class="….data.jpa.domain.support.AuditingEntityListener" />
|
||||
</entity-listeners>
|
||||
</persistence-unit-defaults>
|
||||
</persistence-unit-metadata></programlisting>
|
||||
</example>
|
||||
|
||||
<para>Now activating auditing functionlity is just a matter of adding
|
||||
the Spring Data JPA <literal>auditing</literal> namespace element to
|
||||
your configuration:</para>
|
||||
|
||||
<example>
|
||||
<title>Activating auditing in the Spring configuration</title>
|
||||
|
||||
<programlisting language="xml"><jpa:auditing auditor-aware-ref="yourAuditorAwareBean" /></programlisting>
|
||||
</example>
|
||||
|
||||
<para>As you can see you have to provide a bean that implements the
|
||||
<interfacename>AuditorAware</interfacename> interface which looks as
|
||||
follows:</para>
|
||||
|
||||
<example>
|
||||
<title><interfacename>AuditorAware</interfacename> interface</title>
|
||||
|
||||
<programlisting language="java">public interface AuditorAware<T, ID extends Serializable> {
|
||||
|
||||
T getCurrentAuditor();
|
||||
}</programlisting>
|
||||
</example>
|
||||
|
||||
<para>Usually you will have some kind of authentication component in
|
||||
your application that tracks the user currently working with the system.
|
||||
This component should be <interfacename>AuditorAware</interfacename> and
|
||||
thus allow seemless tracking of the auditor.</para>
|
||||
</simplesect>
|
||||
</section>
|
||||
</chapter>
|
||||
35
src/docbkx/resources/css/highlight.css
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
code highlight CSS resemblign the Eclipse IDE default color schema
|
||||
@author Costin Leau
|
||||
*/
|
||||
|
||||
.hl-keyword {
|
||||
color: #7F0055;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hl-comment {
|
||||
color: #3F5F5F;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hl-multiline-comment {
|
||||
color: #3F5FBF;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hl-tag {
|
||||
color: #3F7F7F;
|
||||
}
|
||||
|
||||
.hl-attribute {
|
||||
color: #7F007F;
|
||||
}
|
||||
|
||||
.hl-value {
|
||||
color: #2A00FF;
|
||||
}
|
||||
|
||||
.hl-string {
|
||||
color: #2A00FF;
|
||||
}
|
||||
421
src/docbkx/resources/css/html.css
Normal file
@@ -0,0 +1,421 @@
|
||||
body {
|
||||
text-align: justify;
|
||||
margin-right: 2em;
|
||||
margin-left: 2em;
|
||||
}
|
||||
|
||||
a,
|
||||
a[accesskey^
|
||||
|
||||
=
|
||||
"h"
|
||||
]
|
||||
,
|
||||
a[accesskey^
|
||||
|
||||
=
|
||||
"n"
|
||||
]
|
||||
,
|
||||
a[accesskey^
|
||||
|
||||
=
|
||||
"u"
|
||||
]
|
||||
,
|
||||
a[accesskey^
|
||||
|
||||
=
|
||||
"p"
|
||||
]
|
||||
{
|
||||
font-family: Verdana, Arial, helvetica, sans-serif
|
||||
|
||||
;
|
||||
font-size:
|
||||
|
||||
12
|
||||
px
|
||||
|
||||
;
|
||||
color: #003399
|
||||
|
||||
;
|
||||
}
|
||||
|
||||
a:active {
|
||||
color: #003399;
|
||||
}
|
||||
|
||||
a:visited {
|
||||
color: #888888;
|
||||
}
|
||||
|
||||
p {
|
||||
font-family: Verdana, Arial, sans-serif;
|
||||
}
|
||||
|
||||
dt {
|
||||
font-family: Verdana, Arial, sans-serif;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
p, dl, dt, dd, blockquote {
|
||||
color: #000000;
|
||||
margin-bottom: 3px;
|
||||
margin-top: 3px;
|
||||
padding-top: 0px;
|
||||
}
|
||||
|
||||
ol, ul, p {
|
||||
margin-top: 6px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
p, blockquote {
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
p.releaseinfo {
|
||||
font-size: 100%;
|
||||
font-weight: bold;
|
||||
font-family: Verdana, Arial, helvetica, sans-serif;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
p.pubdate {
|
||||
font-size: 120%;
|
||||
font-weight: bold;
|
||||
font-family: Verdana, Arial, helvetica, sans-serif;
|
||||
}
|
||||
|
||||
td {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
td, th, span {
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
td[width^
|
||||
|
||||
=
|
||||
"40%"
|
||||
]
|
||||
{
|
||||
font-family: Verdana, Arial, helvetica, sans-serif
|
||||
|
||||
;
|
||||
font-size:
|
||||
|
||||
12
|
||||
px
|
||||
|
||||
;
|
||||
color: #003399
|
||||
|
||||
;
|
||||
}
|
||||
|
||||
table[summary^
|
||||
|
||||
=
|
||||
"Navigation header"
|
||||
]
|
||||
tbody tr th[colspan^
|
||||
|
||||
=
|
||||
"3"
|
||||
]
|
||||
{
|
||||
font-family: Verdana, Arial, helvetica, sans-serif
|
||||
|
||||
;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h6, H6 {
|
||||
color: #000000;
|
||||
font-weight: 500;
|
||||
margin-top: 0px;
|
||||
padding-top: 14px;
|
||||
font-family: Verdana, Arial, helvetica, sans-serif;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
h2.title {
|
||||
font-weight: 800;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
h2.subtitle {
|
||||
font-weight: 800;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.firstname, .surname {
|
||||
font-size: 12px;
|
||||
font-family: Verdana, Arial, helvetica, sans-serif;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
border: 1px black;
|
||||
empty-cells: hide;
|
||||
margin: 10px 0px 30px 50px;
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
div.table {
|
||||
margin: 30px 0px 30px 0px;
|
||||
border: 1px dashed gray;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
div .table-contents table {
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
div.table > p.title {
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
table[summary^
|
||||
|
||||
=
|
||||
"Navigation footer"
|
||||
]
|
||||
{
|
||||
border-collapse: collapse
|
||||
|
||||
;
|
||||
border-spacing:
|
||||
|
||||
0
|
||||
;
|
||||
border:
|
||||
|
||||
1
|
||||
px black
|
||||
|
||||
;
|
||||
empty-cells: hide
|
||||
|
||||
;
|
||||
margin:
|
||||
|
||||
0
|
||||
px
|
||||
|
||||
;
|
||||
width:
|
||||
|
||||
100
|
||||
%
|
||||
;
|
||||
}
|
||||
|
||||
table[summary^
|
||||
|
||||
=
|
||||
"Note"
|
||||
]
|
||||
,
|
||||
table[summary^
|
||||
|
||||
=
|
||||
"Warning"
|
||||
]
|
||||
,
|
||||
table[summary^
|
||||
|
||||
=
|
||||
"Tip"
|
||||
]
|
||||
{
|
||||
border-collapse: collapse
|
||||
|
||||
;
|
||||
border-spacing:
|
||||
|
||||
0
|
||||
;
|
||||
border:
|
||||
|
||||
1
|
||||
px black
|
||||
|
||||
;
|
||||
empty-cells: hide
|
||||
|
||||
;
|
||||
margin:
|
||||
|
||||
10
|
||||
px
|
||||
|
||||
0
|
||||
px
|
||||
|
||||
10
|
||||
px
|
||||
|
||||
-
|
||||
20
|
||||
px
|
||||
|
||||
;
|
||||
width:
|
||||
|
||||
100
|
||||
%
|
||||
;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 4pt;
|
||||
font-family: Verdana, Arial, helvetica, sans-serif;
|
||||
}
|
||||
|
||||
div.warning TD {
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 150%;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 110%;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 100%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 90%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 90%;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 100%;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
tt {
|
||||
font-size: 110%;
|
||||
font-family: "Courier New", Courier, monospace;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.navheader, .navfooter {
|
||||
border: none;
|
||||
}
|
||||
|
||||
div.navfooter table {
|
||||
border: dashed gray;
|
||||
border-width: 1px 1px 1px 1px;
|
||||
background-color: #cde48d;
|
||||
}
|
||||
|
||||
pre {
|
||||
font-size: 110%;
|
||||
padding: 5px;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
border-color: #CCCCCC;
|
||||
background-color: #f3f5e9;
|
||||
}
|
||||
|
||||
ul, ol, li {
|
||||
list-style: disc;
|
||||
}
|
||||
|
||||
hr {
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
background-color: #CCCCCC;
|
||||
border-width: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.variablelist {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.term {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.mediaobject {
|
||||
padding-top: 30px;
|
||||
padding-bottom: 30px;
|
||||
}
|
||||
|
||||
.legalnotice {
|
||||
font-family: Verdana, Arial, helvetica, sans-serif;
|
||||
font-size: 12px;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
float: right;
|
||||
margin: 10px 0px 10px 30px;
|
||||
padding: 10px 20px 20px 20px;
|
||||
width: 33%;
|
||||
border: 1px solid black;
|
||||
background-color: #F4F4F4;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.property {
|
||||
font-family: "Courier New", Courier, monospace;
|
||||
}
|
||||
|
||||
a code {
|
||||
font-family: Verdana, Arial, monospace;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
td code {
|
||||
font-size: 110%;
|
||||
}
|
||||
|
||||
div.note * td,
|
||||
div.tip * td,
|
||||
div.warning * td,
|
||||
div.calloutlist * td {
|
||||
text-align: justify;
|
||||
font-size: 100%;
|
||||
}
|
||||
|
||||
.programlisting .interfacename,
|
||||
.programlisting .literal,
|
||||
.programlisting .classname {
|
||||
font-size: 95%;
|
||||
}
|
||||
|
||||
.title .interfacename,
|
||||
.title .literal,
|
||||
.title .classname {
|
||||
font-size: 130%;
|
||||
}
|
||||
|
||||
/* everything in a <lineannotation/> is displayed in a coloured, comment-like font */
|
||||
.programlisting * .lineannotation,
|
||||
.programlisting * .lineannotation * {
|
||||
color: green;
|
||||
}
|
||||
99
src/docbkx/resources/css/stylesheet.css
Normal file
@@ -0,0 +1,99 @@
|
||||
@IMPORT url("highlight.css");
|
||||
|
||||
html {
|
||||
padding: 0pt;
|
||||
margin: 0pt;
|
||||
}
|
||||
|
||||
body {
|
||||
margin-left: 10%;
|
||||
margin-right: 10%;
|
||||
font-family: Arial, Sans-serif;
|
||||
}
|
||||
|
||||
div {
|
||||
margin: 0pt;
|
||||
}
|
||||
|
||||
p {
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: 1px solid gray;
|
||||
background: gray;
|
||||
}
|
||||
|
||||
h1,h2,h3,h4 {
|
||||
color: #234623;
|
||||
font-family: Arial, Sans-serif;
|
||||
}
|
||||
|
||||
pre {
|
||||
line-height: 1.0;
|
||||
color: black;
|
||||
}
|
||||
|
||||
pre.programlisting {
|
||||
font-size: 10pt;
|
||||
padding: 7pt 3pt;
|
||||
border: 1pt solid black;
|
||||
background: #eeeeee;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
div.table {
|
||||
margin: 1em;
|
||||
padding: 0.5em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
div.table table {
|
||||
display: table;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div.table td {
|
||||
padding-left: 7px;
|
||||
padding-right: 7px;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
float: right;
|
||||
margin: 10px 0 10px 30px;
|
||||
padding: 10px 20px 20px 20px;
|
||||
width: 33%;
|
||||
border: 1px solid black;
|
||||
background-color: #F4F4F4;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.mediaobject {
|
||||
padding-top: 30px;
|
||||
padding-bottom: 30px;
|
||||
}
|
||||
|
||||
.legalnotice {
|
||||
font-family: Verdana, Arial, helvetica, sans-serif;
|
||||
font-size: 12px;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
p.releaseinfo {
|
||||
font-size: 100%;
|
||||
font-weight: bold;
|
||||
font-family: Verdana, Arial, helvetica, sans-serif;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
p.pubdate {
|
||||
font-size: 120%;
|
||||
font-weight: bold;
|
||||
font-family: Verdana, Arial, helvetica, sans-serif;
|
||||
}
|
||||
|
||||
span.productname {
|
||||
font-size: 200%;
|
||||
font-weight: bold;
|
||||
font-family: Verdana, Arial, helvetica, sans-serif;
|
||||
}
|
||||
BIN
src/docbkx/resources/images/admons/blank.png
Normal file
|
After Width: | Height: | Size: 374 B |
BIN
src/docbkx/resources/images/admons/caution.gif
Normal file
|
After Width: | Height: | Size: 743 B |
BIN
src/docbkx/resources/images/admons/caution.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
src/docbkx/resources/images/admons/caution.tif
Normal file
BIN
src/docbkx/resources/images/admons/draft.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
src/docbkx/resources/images/admons/home.gif
Normal file
|
After Width: | Height: | Size: 321 B |
BIN
src/docbkx/resources/images/admons/home.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/docbkx/resources/images/admons/important.gif
Normal file
|
After Width: | Height: | Size: 1003 B |
BIN
src/docbkx/resources/images/admons/important.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
src/docbkx/resources/images/admons/important.tif
Normal file
BIN
src/docbkx/resources/images/admons/next.gif
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/docbkx/resources/images/admons/next.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/docbkx/resources/images/admons/note.gif
Normal file
|
After Width: | Height: | Size: 580 B |
BIN
src/docbkx/resources/images/admons/note.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
src/docbkx/resources/images/admons/note.tif
Normal file
BIN
src/docbkx/resources/images/admons/prev.gif
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/docbkx/resources/images/admons/prev.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/docbkx/resources/images/admons/tip.gif
Normal file
|
After Width: | Height: | Size: 598 B |
BIN
src/docbkx/resources/images/admons/tip.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
src/docbkx/resources/images/admons/tip.tif
Normal file
BIN
src/docbkx/resources/images/admons/toc-blank.png
Normal file
|
After Width: | Height: | Size: 318 B |
BIN
src/docbkx/resources/images/admons/toc-minus.png
Normal file
|
After Width: | Height: | Size: 259 B |
BIN
src/docbkx/resources/images/admons/toc-plus.png
Normal file
|
After Width: | Height: | Size: 264 B |
BIN
src/docbkx/resources/images/admons/up.gif
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/docbkx/resources/images/admons/up.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/docbkx/resources/images/admons/warning.gif
Normal file
|
After Width: | Height: | Size: 613 B |
BIN
src/docbkx/resources/images/admons/warning.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
src/docbkx/resources/images/admons/warning.tif
Normal file
BIN
src/docbkx/resources/images/callouts/1.png
Normal file
|
After Width: | Height: | Size: 329 B |
BIN
src/docbkx/resources/images/callouts/10.png
Normal file
|
After Width: | Height: | Size: 361 B |
BIN
src/docbkx/resources/images/callouts/11.png
Normal file
|
After Width: | Height: | Size: 565 B |
BIN
src/docbkx/resources/images/callouts/12.png
Normal file
|
After Width: | Height: | Size: 617 B |
BIN
src/docbkx/resources/images/callouts/13.png
Normal file
|
After Width: | Height: | Size: 623 B |
BIN
src/docbkx/resources/images/callouts/14.png
Normal file
|
After Width: | Height: | Size: 411 B |
BIN
src/docbkx/resources/images/callouts/15.png
Normal file
|
After Width: | Height: | Size: 640 B |
BIN
src/docbkx/resources/images/callouts/2.png
Normal file
|
After Width: | Height: | Size: 353 B |
BIN
src/docbkx/resources/images/callouts/3.png
Normal file
|
After Width: | Height: | Size: 350 B |
BIN
src/docbkx/resources/images/callouts/4.png
Normal file
|
After Width: | Height: | Size: 345 B |
BIN
src/docbkx/resources/images/callouts/5.png
Normal file
|
After Width: | Height: | Size: 348 B |
BIN
src/docbkx/resources/images/callouts/6.png
Normal file
|
After Width: | Height: | Size: 355 B |
BIN
src/docbkx/resources/images/callouts/7.png
Normal file
|
After Width: | Height: | Size: 344 B |
BIN
src/docbkx/resources/images/callouts/8.png
Normal file
|
After Width: | Height: | Size: 357 B |
BIN
src/docbkx/resources/images/callouts/9.png
Normal file
|
After Width: | Height: | Size: 357 B |
BIN
src/docbkx/resources/images/logo.png
Normal file
|
After Width: | Height: | Size: 9.4 KiB |
BIN
src/docbkx/resources/images/xdev-spring_logo.jpg
Normal file
|
After Width: | Height: | Size: 36 KiB |
418
src/docbkx/resources/xsl/fopdf.xsl
Normal file
@@ -0,0 +1,418 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
|
||||
This is the XSL FO (PDF) stylesheet for the Spring reference
|
||||
documentation.
|
||||
|
||||
Thanks are due to Christian Bauer of the Hibernate project
|
||||
team for writing the original stylesheet upon which this one
|
||||
is based.
|
||||
-->
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:fo="http://www.w3.org/1999/XSL/Format"
|
||||
version="1.0">
|
||||
|
||||
|
||||
<xsl:import href="urn:docbkx:stylesheet"/>
|
||||
|
||||
<!--###################################################
|
||||
Custom Title Page
|
||||
################################################### -->
|
||||
|
||||
<xsl:template name="book.titlepage.recto">
|
||||
<fo:block>
|
||||
<fo:table table-layout="fixed" width="175mm">
|
||||
<fo:table-column column-width="175mm"/>
|
||||
<fo:table-body>
|
||||
<fo:table-row>
|
||||
<fo:table-cell text-align="center">
|
||||
<fo:block>
|
||||
<fo:block font-family="Helvetica" font-size="24pt" padding-before="10mm">
|
||||
<xsl:value-of select="bookinfo/title"/>
|
||||
</fo:block>
|
||||
</fo:block>
|
||||
<fo:block font-family="Helvetica" font-size="22pt" padding-before="10mm">
|
||||
<xsl:value-of select="bookinfo/subtitle"/>
|
||||
</fo:block>
|
||||
<fo:block font-family="Helvetica" font-size="12pt" padding="10mm">
|
||||
<xsl:value-of select="bookinfo/releaseinfo"/>
|
||||
</fo:block>
|
||||
</fo:table-cell>
|
||||
</fo:table-row>
|
||||
<fo:table-row>
|
||||
<fo:table-cell text-align="center">
|
||||
<fo:block font-family="Helvetica" font-size="14pt" padding="10mm">
|
||||
<xsl:value-of select="bookinfo/pubdate"/>
|
||||
</fo:block>
|
||||
</fo:table-cell>
|
||||
</fo:table-row>
|
||||
<fo:table-row>
|
||||
<fo:table-cell text-align="center">
|
||||
<fo:block font-family="Helvetica" font-size="12pt" padding="10mm">
|
||||
<xsl:text>Copyright © 2010 </xsl:text>
|
||||
<xsl:for-each select="bookinfo/authorgroup/author">
|
||||
<xsl:if test="position() > 1">
|
||||
<xsl:text>, </xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:value-of select="firstname"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="surname"/>
|
||||
</xsl:for-each>
|
||||
</fo:block>
|
||||
<fo:block font-family="Helvetica" font-size="10pt" padding="1mm">
|
||||
<xsl:value-of select="bookinfo/legalnotice"/>
|
||||
</fo:block>
|
||||
</fo:table-cell>
|
||||
</fo:table-row>
|
||||
</fo:table-body>
|
||||
</fo:table>
|
||||
</fo:block>
|
||||
</xsl:template>
|
||||
|
||||
<!-- Prevent blank pages in output -->
|
||||
<xsl:template name="book.titlepage.before.verso">
|
||||
</xsl:template>
|
||||
<xsl:template name="book.titlepage.verso">
|
||||
</xsl:template>
|
||||
<xsl:template name="book.titlepage.separator">
|
||||
</xsl:template>
|
||||
|
||||
<!--###################################################
|
||||
Header
|
||||
################################################### -->
|
||||
|
||||
<!-- More space in the center header for long text -->
|
||||
<xsl:attribute-set name="header.content.properties">
|
||||
<xsl:attribute name="font-family">
|
||||
<xsl:value-of select="$body.font.family"/>
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="margin-left">-5em</xsl:attribute>
|
||||
<xsl:attribute name="margin-right">-5em</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!--###################################################
|
||||
Custom Footer
|
||||
################################################### -->
|
||||
<xsl:template name="footer.content">
|
||||
<xsl:param name="pageclass" select="''"/>
|
||||
<xsl:param name="sequence" select="''"/>
|
||||
<xsl:param name="position" select="''"/>
|
||||
<xsl:param name="gentext-key" select="''"/>
|
||||
<xsl:variable name="Version">
|
||||
<xsl:if test="//releaseinfo">
|
||||
<xsl:text>Spring Data JPA (</xsl:text>
|
||||
<xsl:value-of select="//releaseinfo"/>
|
||||
<xsl:text>)</xsl:text>
|
||||
</xsl:if>
|
||||
</xsl:variable>
|
||||
<xsl:choose>
|
||||
<xsl:when test="$sequence='blank'">
|
||||
<xsl:if test="$position = 'center'">
|
||||
<xsl:value-of select="$Version"/>
|
||||
</xsl:if>
|
||||
</xsl:when>
|
||||
<!-- for double sided printing, print page numbers on alternating sides (of the page) -->
|
||||
<xsl:when test="$double.sided != 0">
|
||||
<xsl:choose>
|
||||
<xsl:when test="$sequence = 'even' and $position='left'">
|
||||
<fo:page-number/>
|
||||
</xsl:when>
|
||||
<xsl:when test="$sequence = 'odd' and $position='right'">
|
||||
<fo:page-number/>
|
||||
</xsl:when>
|
||||
<xsl:when test="$position='center'">
|
||||
<xsl:value-of select="$Version"/>
|
||||
</xsl:when>
|
||||
</xsl:choose>
|
||||
</xsl:when>
|
||||
<!-- for single sided printing, print all page numbers on the right (of the page) -->
|
||||
<xsl:when test="$double.sided = 0">
|
||||
<xsl:choose>
|
||||
<xsl:when test="$position='center'">
|
||||
<xsl:value-of select="$Version"/>
|
||||
</xsl:when>
|
||||
<xsl:when test="$position='right'">
|
||||
<fo:page-number/>
|
||||
</xsl:when>
|
||||
</xsl:choose>
|
||||
</xsl:when>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
<!--###################################################
|
||||
Extensions
|
||||
################################################### -->
|
||||
|
||||
<!-- These extensions are required for table printing and other stuff -->
|
||||
<xsl:param name="use.extensions">1</xsl:param>
|
||||
<xsl:param name="tablecolumns.extension">0</xsl:param>
|
||||
<xsl:param name="callout.extensions">1</xsl:param>
|
||||
<!-- FOP provide only PDF Bookmarks at the moment -->
|
||||
<xsl:param name="fop.extensions">1</xsl:param>
|
||||
|
||||
<!--###################################################
|
||||
Table Of Contents
|
||||
################################################### -->
|
||||
|
||||
<!-- Generate the TOCs for named components only -->
|
||||
<xsl:param name="generate.toc">
|
||||
book toc
|
||||
</xsl:param>
|
||||
|
||||
<!-- Show only Sections up to level 3 in the TOCs -->
|
||||
<xsl:param name="toc.section.depth">2</xsl:param>
|
||||
|
||||
<!-- Dot and Whitespace as separator in TOC between Label and Title-->
|
||||
<xsl:param name="autotoc.label.separator" select="'. '"/>
|
||||
|
||||
|
||||
<!--###################################################
|
||||
Paper & Page Size
|
||||
################################################### -->
|
||||
|
||||
<!-- Paper type, no headers on blank pages, no double sided printing -->
|
||||
<xsl:param name="paper.type" select="'A4'"/>
|
||||
<xsl:param name="double.sided">0</xsl:param>
|
||||
<xsl:param name="headers.on.blank.pages">0</xsl:param>
|
||||
<xsl:param name="footers.on.blank.pages">0</xsl:param>
|
||||
|
||||
<!-- Space between paper border and content (chaotic stuff, don't touch) -->
|
||||
<xsl:param name="page.margin.top">5mm</xsl:param>
|
||||
<xsl:param name="region.before.extent">10mm</xsl:param>
|
||||
<xsl:param name="body.margin.top">10mm</xsl:param>
|
||||
|
||||
<xsl:param name="body.margin.bottom">15mm</xsl:param>
|
||||
<xsl:param name="region.after.extent">10mm</xsl:param>
|
||||
<xsl:param name="page.margin.bottom">0mm</xsl:param>
|
||||
|
||||
<xsl:param name="page.margin.outer">18mm</xsl:param>
|
||||
<xsl:param name="page.margin.inner">18mm</xsl:param>
|
||||
|
||||
<!-- No intendation of Titles -->
|
||||
<xsl:param name="title.margin.left">0pc</xsl:param>
|
||||
|
||||
<!--###################################################
|
||||
Fonts & Styles
|
||||
################################################### -->
|
||||
|
||||
<!-- Left aligned text and no hyphenation -->
|
||||
<xsl:param name="alignment">justify</xsl:param>
|
||||
<xsl:param name="hyphenate">false</xsl:param>
|
||||
|
||||
<!-- Default Font size -->
|
||||
<xsl:param name="body.font.master">11</xsl:param>
|
||||
<xsl:param name="body.font.small">8</xsl:param>
|
||||
|
||||
<!-- Line height in body text -->
|
||||
<xsl:param name="line-height">1.4</xsl:param>
|
||||
|
||||
<!-- Monospaced fonts are smaller than regular text -->
|
||||
<xsl:attribute-set name="monospace.properties">
|
||||
<xsl:attribute name="font-family">
|
||||
<xsl:value-of select="$monospace.font.family"/>
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="font-size">0.8em</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!--###################################################
|
||||
Tables
|
||||
################################################### -->
|
||||
|
||||
<!-- The table width should be adapted to the paper size -->
|
||||
<xsl:param name="default.table.width">17.4cm</xsl:param>
|
||||
|
||||
<!-- Some padding inside tables -->
|
||||
<xsl:attribute-set name="table.cell.padding">
|
||||
<xsl:attribute name="padding-left">4pt</xsl:attribute>
|
||||
<xsl:attribute name="padding-right">4pt</xsl:attribute>
|
||||
<xsl:attribute name="padding-top">4pt</xsl:attribute>
|
||||
<xsl:attribute name="padding-bottom">4pt</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- Only hairlines as frame and cell borders in tables -->
|
||||
<xsl:param name="table.frame.border.thickness">0.1pt</xsl:param>
|
||||
<xsl:param name="table.cell.border.thickness">0.1pt</xsl:param>
|
||||
|
||||
<!--###################################################
|
||||
Labels
|
||||
################################################### -->
|
||||
|
||||
<!-- Label Chapters and Sections (numbering) -->
|
||||
<xsl:param name="chapter.autolabel">1</xsl:param>
|
||||
<xsl:param name="section.autolabel" select="1"/>
|
||||
<xsl:param name="section.label.includes.component.label" select="1"/>
|
||||
|
||||
<!--###################################################
|
||||
Titles
|
||||
################################################### -->
|
||||
|
||||
<!-- Chapter title size -->
|
||||
<xsl:attribute-set name="chapter.titlepage.recto.style">
|
||||
<xsl:attribute name="text-align">left</xsl:attribute>
|
||||
<xsl:attribute name="font-weight">bold</xsl:attribute>
|
||||
<xsl:attribute name="font-size">
|
||||
<xsl:value-of select="$body.font.master * 1.8"/>
|
||||
<xsl:text>pt</xsl:text>
|
||||
</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- Why is the font-size for chapters hardcoded in the XSL FO templates?
|
||||
Let's remove it, so this sucker can use our attribute-set only... -->
|
||||
<xsl:template match="title" mode="chapter.titlepage.recto.auto.mode">
|
||||
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format"
|
||||
xsl:use-attribute-sets="chapter.titlepage.recto.style">
|
||||
<xsl:call-template name="component.title">
|
||||
<xsl:with-param name="node" select="ancestor-or-self::chapter[1]"/>
|
||||
</xsl:call-template>
|
||||
</fo:block>
|
||||
</xsl:template>
|
||||
|
||||
<!-- Sections 1, 2 and 3 titles have a small bump factor and padding -->
|
||||
<xsl:attribute-set name="section.title.level1.properties">
|
||||
<xsl:attribute name="space-before.optimum">0.8em</xsl:attribute>
|
||||
<xsl:attribute name="space-before.minimum">0.8em</xsl:attribute>
|
||||
<xsl:attribute name="space-before.maximum">0.8em</xsl:attribute>
|
||||
<xsl:attribute name="font-size">
|
||||
<xsl:value-of select="$body.font.master * 1.5"/>
|
||||
<xsl:text>pt</xsl:text>
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="space-after.optimum">0.1em</xsl:attribute>
|
||||
<xsl:attribute name="space-after.minimum">0.1em</xsl:attribute>
|
||||
<xsl:attribute name="space-after.maximum">0.1em</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
<xsl:attribute-set name="section.title.level2.properties">
|
||||
<xsl:attribute name="space-before.optimum">0.6em</xsl:attribute>
|
||||
<xsl:attribute name="space-before.minimum">0.6em</xsl:attribute>
|
||||
<xsl:attribute name="space-before.maximum">0.6em</xsl:attribute>
|
||||
<xsl:attribute name="font-size">
|
||||
<xsl:value-of select="$body.font.master * 1.25"/>
|
||||
<xsl:text>pt</xsl:text>
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="space-after.optimum">0.1em</xsl:attribute>
|
||||
<xsl:attribute name="space-after.minimum">0.1em</xsl:attribute>
|
||||
<xsl:attribute name="space-after.maximum">0.1em</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
<xsl:attribute-set name="section.title.level3.properties">
|
||||
<xsl:attribute name="space-before.optimum">0.4em</xsl:attribute>
|
||||
<xsl:attribute name="space-before.minimum">0.4em</xsl:attribute>
|
||||
<xsl:attribute name="space-before.maximum">0.4em</xsl:attribute>
|
||||
<xsl:attribute name="font-size">
|
||||
<xsl:value-of select="$body.font.master * 1.0"/>
|
||||
<xsl:text>pt</xsl:text>
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="space-after.optimum">0.1em</xsl:attribute>
|
||||
<xsl:attribute name="space-after.minimum">0.1em</xsl:attribute>
|
||||
<xsl:attribute name="space-after.maximum">0.1em</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- Titles of formal objects (tables, examples, ...) -->
|
||||
<xsl:attribute-set name="formal.title.properties" use-attribute-sets="normal.para.spacing">
|
||||
<xsl:attribute name="font-weight">bold</xsl:attribute>
|
||||
<xsl:attribute name="font-size">
|
||||
<xsl:value-of select="$body.font.master"/>
|
||||
<xsl:text>pt</xsl:text>
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="hyphenate">false</xsl:attribute>
|
||||
<xsl:attribute name="space-after.minimum">0.4em</xsl:attribute>
|
||||
<xsl:attribute name="space-after.optimum">0.6em</xsl:attribute>
|
||||
<xsl:attribute name="space-after.maximum">0.8em</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!--###################################################
|
||||
Programlistings
|
||||
################################################### -->
|
||||
|
||||
<!-- Verbatim text formatting (programlistings) -->
|
||||
<xsl:attribute-set name="monospace.verbatim.properties">
|
||||
<xsl:attribute name="font-size">
|
||||
<xsl:value-of select="$body.font.small * 1.0"/>
|
||||
<xsl:text>pt</xsl:text>
|
||||
</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<xsl:attribute-set name="verbatim.properties">
|
||||
<xsl:attribute name="space-before.minimum">1em</xsl:attribute>
|
||||
<xsl:attribute name="space-before.optimum">1em</xsl:attribute>
|
||||
<xsl:attribute name="space-before.maximum">1em</xsl:attribute>
|
||||
<xsl:attribute name="border-color">#444444</xsl:attribute>
|
||||
<xsl:attribute name="border-style">solid</xsl:attribute>
|
||||
<xsl:attribute name="border-width">0.1pt</xsl:attribute>
|
||||
<xsl:attribute name="padding-top">0.5em</xsl:attribute>
|
||||
<xsl:attribute name="padding-left">0.5em</xsl:attribute>
|
||||
<xsl:attribute name="padding-right">0.5em</xsl:attribute>
|
||||
<xsl:attribute name="padding-bottom">0.5em</xsl:attribute>
|
||||
<xsl:attribute name="margin-left">0.5em</xsl:attribute>
|
||||
<xsl:attribute name="margin-right">0.5em</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- Shade (background) programlistings -->
|
||||
<xsl:param name="shade.verbatim">1</xsl:param>
|
||||
<xsl:attribute-set name="shade.verbatim.style">
|
||||
<xsl:attribute name="background-color">#F0F0F0</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!--###################################################
|
||||
Callouts
|
||||
################################################### -->
|
||||
|
||||
<!-- Use images for callouts instead of (1) (2) (3) -->
|
||||
<xsl:param name="callout.graphics">0</xsl:param>
|
||||
<xsl:param name="callout.unicode">1</xsl:param>
|
||||
|
||||
<!-- Place callout marks at this column in annotated areas -->
|
||||
<xsl:param name="callout.defaultcolumn">90</xsl:param>
|
||||
|
||||
<!--###################################################
|
||||
Admonitions
|
||||
################################################### -->
|
||||
|
||||
<!-- Use nice graphics for admonitions -->
|
||||
<xsl:param name="admon.graphics">'1'</xsl:param>
|
||||
<!-- <xsl:param name="admon.graphics.path">&admon_gfx_path;</xsl:param> -->
|
||||
|
||||
<!--###################################################
|
||||
Misc
|
||||
################################################### -->
|
||||
|
||||
<!-- Placement of titles -->
|
||||
<xsl:param name="formal.title.placement">
|
||||
figure after
|
||||
example before
|
||||
equation before
|
||||
table before
|
||||
procedure before
|
||||
</xsl:param>
|
||||
|
||||
<!-- Format Variable Lists as Blocks (prevents horizontal overflow) -->
|
||||
<xsl:param name="variablelist.as.blocks">1</xsl:param>
|
||||
|
||||
<!-- The horrible list spacing problems -->
|
||||
<xsl:attribute-set name="list.block.spacing">
|
||||
<xsl:attribute name="space-before.optimum">0.8em</xsl:attribute>
|
||||
<xsl:attribute name="space-before.minimum">0.8em</xsl:attribute>
|
||||
<xsl:attribute name="space-before.maximum">0.8em</xsl:attribute>
|
||||
<xsl:attribute name="space-after.optimum">0.1em</xsl:attribute>
|
||||
<xsl:attribute name="space-after.minimum">0.1em</xsl:attribute>
|
||||
<xsl:attribute name="space-after.maximum">0.1em</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!--###################################################
|
||||
colored and hyphenated links
|
||||
################################################### -->
|
||||
<xsl:template match="ulink">
|
||||
<fo:basic-link external-destination="{@url}"
|
||||
xsl:use-attribute-sets="xref.properties"
|
||||
text-decoration="underline"
|
||||
color="blue">
|
||||
<xsl:choose>
|
||||
<xsl:when test="count(child::node())=0">
|
||||
<xsl:value-of select="@url"/>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:apply-templates/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</fo:basic-link>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
||||
91
src/docbkx/resources/xsl/html.xsl
Normal file
@@ -0,0 +1,91 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
This is the XSL HTML configuration file for the Spring
|
||||
Reference Documentation.
|
||||
-->
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:fo="http://www.w3.org/1999/XSL/Format"
|
||||
version="1.0">
|
||||
|
||||
<xsl:import href="urn:docbkx:stylesheet"/>
|
||||
|
||||
<!--###################################################
|
||||
HTML Settings
|
||||
################################################### -->
|
||||
|
||||
<xsl:param name="html.stylesheet">html.css</xsl:param>
|
||||
|
||||
<!-- These extensions are required for table printing and other stuff -->
|
||||
<xsl:param name="use.extensions">1</xsl:param>
|
||||
<xsl:param name="tablecolumns.extension">0</xsl:param>
|
||||
<xsl:param name="callout.extensions">1</xsl:param>
|
||||
<xsl:param name="graphicsize.extension">0</xsl:param>
|
||||
|
||||
<!--###################################################
|
||||
Table Of Contents
|
||||
################################################### -->
|
||||
|
||||
<!-- Generate the TOCs for named components only -->
|
||||
<xsl:param name="generate.toc">
|
||||
book toc
|
||||
</xsl:param>
|
||||
|
||||
<!-- Show only Sections up to level 3 in the TOCs -->
|
||||
<xsl:param name="toc.section.depth">3</xsl:param>
|
||||
|
||||
<!--###################################################
|
||||
Labels
|
||||
################################################### -->
|
||||
|
||||
<!-- Label Chapters and Sections (numbering) -->
|
||||
<xsl:param name="chapter.autolabel">1</xsl:param>
|
||||
<xsl:param name="section.autolabel" select="1"/>
|
||||
<xsl:param name="section.label.includes.component.label" select="1"/>
|
||||
|
||||
<!--###################################################
|
||||
Callouts
|
||||
################################################### -->
|
||||
|
||||
<!-- Use images for callouts instead of (1) (2) (3) -->
|
||||
<xsl:param name="callout.graphics">0</xsl:param>
|
||||
|
||||
<!-- Place callout marks at this column in annotated areas -->
|
||||
<xsl:param name="callout.defaultcolumn">90</xsl:param>
|
||||
|
||||
<!--###################################################
|
||||
Admonitions
|
||||
################################################### -->
|
||||
|
||||
<!-- Use nice graphics for admonitions -->
|
||||
<xsl:param name="admon.graphics">0</xsl:param>
|
||||
|
||||
<!--###################################################
|
||||
Misc
|
||||
################################################### -->
|
||||
<!-- Placement of titles -->
|
||||
<xsl:param name="formal.title.placement">
|
||||
figure after
|
||||
example before
|
||||
equation before
|
||||
table before
|
||||
procedure before
|
||||
</xsl:param>
|
||||
<xsl:template match="author" mode="titlepage.mode">
|
||||
<xsl:if test="name(preceding-sibling::*[1]) = 'author'">
|
||||
<xsl:text>, </xsl:text>
|
||||
</xsl:if>
|
||||
<span class="{name(.)}">
|
||||
<xsl:call-template name="person.name"/>
|
||||
<xsl:apply-templates mode="titlepage.mode" select="./contrib"/>
|
||||
<xsl:apply-templates mode="titlepage.mode" select="./affiliation"/>
|
||||
</span>
|
||||
</xsl:template>
|
||||
<xsl:template match="authorgroup" mode="titlepage.mode">
|
||||
<div class="{name(.)}">
|
||||
<h2>Authors</h2>
|
||||
<p/>
|
||||
<xsl:apply-templates mode="titlepage.mode"/>
|
||||
</div>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
||||
136
src/docbkx/resources/xsl/html/html_chunk.xsl
Normal file
@@ -0,0 +1,136 @@
|
||||
<?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.
|
||||
-->
|
||||
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:xslthl="http://xslthl.sf.net"
|
||||
exclude-result-prefixes="xslthl"
|
||||
version='1.0'>
|
||||
|
||||
<xsl:param name="chunk.section.depth">'5'</xsl:param>
|
||||
<xsl:param name="use.id.as.filename" select="1"/>
|
||||
|
||||
<!-- Extensions -->
|
||||
<xsl:param name="use.extensions">1</xsl:param>
|
||||
<xsl:param name="tablecolumns.extension">0</xsl:param>
|
||||
<xsl:param name="callout.extensions">1</xsl:param>
|
||||
|
||||
<!-- Activate Graphics -->
|
||||
<xsl:param name="admon.graphics" select="1"/>
|
||||
<xsl:param name="admon.graphics.path">images/</xsl:param>
|
||||
<xsl:param name="admon.graphics.extension">.gif</xsl:param>
|
||||
<xsl:param name="callout.graphics" select="1" />
|
||||
<xsl:param name="callout.defaultcolumn">120</xsl:param>
|
||||
<xsl:param name="callout.graphics.path">images/callouts/</xsl:param>
|
||||
<xsl:param name="callout.graphics.extension">.gif</xsl:param>
|
||||
|
||||
<xsl:param name="table.borders.with.css" select="1"/>
|
||||
<xsl:param name="html.stylesheet">css/stylesheet.css</xsl:param>
|
||||
<xsl:param name="html.stylesheet.type">text/css</xsl:param>
|
||||
<xsl:param name="generate.toc">book toc,title</xsl:param>
|
||||
|
||||
<xsl:param name="admonition.title.properties">text-align: left</xsl:param>
|
||||
|
||||
<!-- Label Chapters and Sections (numbering) -->
|
||||
<xsl:param name="chapter.autolabel" select="1"/>
|
||||
<xsl:param name="section.autolabel" select="1"/>
|
||||
<xsl:param name="section.autolabel.max.depth" select="3"/>
|
||||
|
||||
<xsl:param name="section.label.includes.component.label" select="1"/>
|
||||
<xsl:param name="table.footnote.number.format" select="'1'"/>
|
||||
|
||||
<!-- Show only Sections up to level 3 in the TOCs -->
|
||||
<xsl:param name="toc.section.depth">3</xsl:param>
|
||||
|
||||
<!-- Remove "Chapter" from the Chapter titles... -->
|
||||
<xsl:param name="local.l10n.xml" select="document('')"/>
|
||||
<l:i18n xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0">
|
||||
<l:l10n language="en">
|
||||
<l:context name="title-numbered">
|
||||
<l:template name="chapter" text="%n. %t"/>
|
||||
<l:template name="section" text="%n %t"/>
|
||||
</l:context>
|
||||
</l:l10n>
|
||||
</l:i18n>
|
||||
|
||||
<!-- Use code syntax highlighting -->
|
||||
<xsl:param name="highlight.source" select="1"/>
|
||||
|
||||
<xsl:template match='xslthl:keyword'>
|
||||
<span class="hl-keyword"><xsl:value-of select='.'/></span>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match='xslthl:comment'>
|
||||
<span class="hl-comment"><xsl:value-of select='.'/></span>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match='xslthl:oneline-comment'>
|
||||
<span class="hl-comment"><xsl:value-of select='.'/></span>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match='xslthl:multiline-comment'>
|
||||
<span class="hl-multiline-comment"><xsl:value-of select='.'/></span>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match='xslthl:tag'>
|
||||
<span class="hl-tag"><xsl:value-of select='.'/></span>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match='xslthl:attribute'>
|
||||
<span class="hl-attribute"><xsl:value-of select='.'/></span>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match='xslthl:value'>
|
||||
<span class="hl-value"><xsl:value-of select='.'/></span>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match='xslthl:string'>
|
||||
<span class="hl-string"><xsl:value-of select='.'/></span>
|
||||
</xsl:template>
|
||||
|
||||
<!-- Google Analytics -->
|
||||
<xsl:template name="user.head.content">
|
||||
<xsl:comment>Begin Google Analytics code</xsl:comment>
|
||||
<script type="text/javascript">
|
||||
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
|
||||
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
var pageTracker = _gat._getTracker("UA-2728886-3");
|
||||
pageTracker._setDomainName("none");
|
||||
pageTracker._setAllowLinker(true);
|
||||
pageTracker._trackPageview();
|
||||
</script>
|
||||
<xsl:comment>End Google Analytics code</xsl:comment>
|
||||
</xsl:template>
|
||||
|
||||
<!-- Loopfuse -->
|
||||
<xsl:template name="user.footer.content">
|
||||
<xsl:comment>Begin LoopFuse code</xsl:comment>
|
||||
<script src="http://loopfuse.net/webrecorder/js/listen.js" type="text/javascript">
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
_lf_cid = "LF_48be82fa";
|
||||
_lf_remora();
|
||||
</script>
|
||||
<xsl:comment>End LoopFuse code</xsl:comment>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
||||
61
src/docbkx/resources/xsl/html/titlepage.xml
Normal file
@@ -0,0 +1,61 @@
|
||||
<?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.
|
||||
-->
|
||||
|
||||
<t:templates xmlns:t="http://nwalsh.com/docbook/xsl/template/1.0"
|
||||
xmlns:param="http://nwalsh.com/docbook/xsl/template/1.0/param"
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
|
||||
<!-- ==================================================================== -->
|
||||
|
||||
<t:titlepage t:element="book" t:wrapper="div" class="titlepage">
|
||||
<t:titlepage-content t:side="recto">
|
||||
<productname/>
|
||||
<title/>
|
||||
<subtitle/>
|
||||
<!-- <corpauthor/>
|
||||
<authorgroup/>
|
||||
<author/>
|
||||
<mediaobject/> -->
|
||||
<othercredit/>
|
||||
<releaseinfo/>
|
||||
<copyright/>
|
||||
<legalnotice/>
|
||||
<pubdate/>
|
||||
<revision/>
|
||||
<revhistory/>
|
||||
<abstract/>
|
||||
</t:titlepage-content>
|
||||
|
||||
<t:titlepage-content t:side="verso">
|
||||
</t:titlepage-content>
|
||||
|
||||
<t:titlepage-separator>
|
||||
<hr/>
|
||||
</t:titlepage-separator>
|
||||
|
||||
<t:titlepage-before t:side="recto">
|
||||
</t:titlepage-before>
|
||||
|
||||
<t:titlepage-before t:side="verso">
|
||||
</t:titlepage-before>
|
||||
</t:titlepage>
|
||||
|
||||
</t:templates>
|
||||
208
src/docbkx/resources/xsl/html_chunk.xsl
Normal file
@@ -0,0 +1,208 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
This is the XSL HTML configuration file for the Spring Reference Documentation.
|
||||
-->
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:fo="http://www.w3.org/1999/XSL/Format"
|
||||
version="1.0">
|
||||
|
||||
<xsl:import href="urn:docbkx:stylesheet"/>
|
||||
<!--###################################################
|
||||
HTML Settings
|
||||
################################################### -->
|
||||
<xsl:param name="chunk.section.depth">'5'</xsl:param>
|
||||
<xsl:param name="use.id.as.filename">'1'</xsl:param>
|
||||
<!-- These extensions are required for table printing and other stuff -->
|
||||
<xsl:param name="use.extensions">1</xsl:param>
|
||||
<xsl:param name="tablecolumns.extension">0</xsl:param>
|
||||
<xsl:param name="callout.extensions">1</xsl:param>
|
||||
<xsl:param name="graphicsize.extension">0</xsl:param>
|
||||
<!--###################################################
|
||||
Table Of Contents
|
||||
################################################### -->
|
||||
<!-- Generate the TOCs for named components only -->
|
||||
<xsl:param name="generate.toc">
|
||||
book toc
|
||||
</xsl:param>
|
||||
<!-- Show only Sections up to level 3 in the TOCs -->
|
||||
<xsl:param name="toc.section.depth">3</xsl:param>
|
||||
<!--###################################################
|
||||
Labels
|
||||
################################################### -->
|
||||
<!-- Label Chapters and Sections (numbering) -->
|
||||
<xsl:param name="chapter.autolabel">1</xsl:param>
|
||||
<xsl:param name="section.autolabel" select="1"/>
|
||||
<xsl:param name="section.label.includes.component.label" select="1"/>
|
||||
<!--###################################################
|
||||
Callouts
|
||||
################################################### -->
|
||||
<!-- Place callout marks at this column in annotated areas -->
|
||||
<xsl:param name="callout.graphics">1</xsl:param>
|
||||
<xsl:param name="callout.defaultcolumn">90</xsl:param>
|
||||
<!--###################################################
|
||||
Misc
|
||||
################################################### -->
|
||||
<!-- Placement of titles -->
|
||||
<xsl:param name="formal.title.placement">
|
||||
figure after
|
||||
example before
|
||||
equation before
|
||||
table before
|
||||
procedure before
|
||||
</xsl:param>
|
||||
<xsl:template match="author" mode="titlepage.mode">
|
||||
<xsl:if test="name(preceding-sibling::*[1]) = 'author'">
|
||||
<xsl:text>, </xsl:text>
|
||||
</xsl:if>
|
||||
<span class="{name(.)}">
|
||||
<xsl:call-template name="person.name"/>
|
||||
<xsl:apply-templates mode="titlepage.mode" select="./contrib"/>
|
||||
<xsl:apply-templates mode="titlepage.mode" select="./affiliation"/>
|
||||
</span>
|
||||
</xsl:template>
|
||||
<xsl:template match="authorgroup" mode="titlepage.mode">
|
||||
<div class="{name(.)}">
|
||||
<h2>Authors</h2>
|
||||
<p/>
|
||||
<xsl:apply-templates mode="titlepage.mode"/>
|
||||
</div>
|
||||
</xsl:template>
|
||||
<!--###################################################
|
||||
Headers and Footers
|
||||
################################################### -->
|
||||
<!-- let's have a Spring and SpringSource banner across the top of each page -->
|
||||
<xsl:template name="user.header.navigation">
|
||||
<div style="background-color:white;border:none;height:73px;border:1px solid black;">
|
||||
<a style="border:none;" href="http://static.springframework.org/spring-ws/site/"
|
||||
title="The Spring Framework - Spring Web Services">
|
||||
<img style="border:none;" src="images/xdev-spring_logo.jpg"/>
|
||||
</a>
|
||||
<a style="border:none;" href="http://www.springsource.com/" title="SpringSource">
|
||||
<img style="border:none;position:absolute;padding-top:5px;right:42px;" src="images/s2_box_logo.png"/>
|
||||
</a>
|
||||
</div>
|
||||
</xsl:template>
|
||||
<!-- no other header navigation (prev, next, etc.) -->
|
||||
<xsl:template name="header.navigation"/>
|
||||
<xsl:param name="navig.showtitles">1</xsl:param>
|
||||
<!-- let's have a 'Sponsored by SpringSource' strapline (or somesuch) across the bottom of each page -->
|
||||
<xsl:template name="footer.navigation">
|
||||
<xsl:param name="prev" select="/foo"/>
|
||||
<xsl:param name="next" select="/foo"/>
|
||||
<xsl:param name="nav.context"/>
|
||||
<xsl:variable name="home" select="/*[1]"/>
|
||||
<xsl:variable name="up" select="parent::*"/>
|
||||
<xsl:variable name="row1" select="count($prev) > 0
|
||||
or count($up) > 0
|
||||
or count($next) > 0"/>
|
||||
<xsl:variable name="row2" select="($prev and $navig.showtitles != 0)
|
||||
or (generate-id($home) != generate-id(.)
|
||||
or $nav.context = 'toc')
|
||||
or ($chunk.tocs.and.lots != 0
|
||||
and $nav.context != 'toc')
|
||||
or ($next and $navig.showtitles != 0)"/>
|
||||
<xsl:if test="$suppress.navigation = '0' and $suppress.footer.navigation = '0'">
|
||||
<div class="navfooter">
|
||||
<xsl:if test="$footer.rule != 0">
|
||||
<hr/>
|
||||
</xsl:if>
|
||||
<xsl:if test="$row1 or $row2">
|
||||
<table width="100%" summary="Navigation footer">
|
||||
<xsl:if test="$row1">
|
||||
<tr>
|
||||
<td width="40%" align="left">
|
||||
<xsl:if test="count($prev)>0">
|
||||
<a accesskey="p">
|
||||
<xsl:attribute name="href">
|
||||
<xsl:call-template name="href.target">
|
||||
<xsl:with-param name="object" select="$prev"/>
|
||||
</xsl:call-template>
|
||||
</xsl:attribute>
|
||||
<xsl:call-template name="navig.content">
|
||||
<xsl:with-param name="direction" select="'prev'"/>
|
||||
</xsl:call-template>
|
||||
</a>
|
||||
</xsl:if>
|
||||
<xsl:text> </xsl:text>
|
||||
</td>
|
||||
|
||||
<td width="20%" align="center">
|
||||
<xsl:choose>
|
||||
<xsl:when test="$home != . or $nav.context = 'toc'">
|
||||
<a accesskey="h">
|
||||
<xsl:attribute name="href">
|
||||
<xsl:call-template name="href.target">
|
||||
<xsl:with-param name="object" select="$home"/>
|
||||
</xsl:call-template>
|
||||
</xsl:attribute>
|
||||
<xsl:call-template name="navig.content">
|
||||
<xsl:with-param name="direction" select="'home'"/>
|
||||
</xsl:call-template>
|
||||
</a>
|
||||
<xsl:if test="$chunk.tocs.and.lots != 0 and $nav.context != 'toc'">
|
||||
<xsl:text> | </xsl:text>
|
||||
</xsl:if>
|
||||
</xsl:when>
|
||||
<xsl:otherwise> </xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:if test="$chunk.tocs.and.lots != 0 and $nav.context != 'toc'">
|
||||
<a accesskey="t">
|
||||
<xsl:attribute name="href">
|
||||
<xsl:apply-templates select="/*[1]" mode="recursive-chunk-filename">
|
||||
<xsl:with-param name="recursive" select="true()"/>
|
||||
</xsl:apply-templates>
|
||||
<xsl:text>-toc</xsl:text>
|
||||
<xsl:value-of select="$html.ext"/>
|
||||
</xsl:attribute>
|
||||
<xsl:call-template name="gentext">
|
||||
<xsl:with-param name="key" select="'nav-toc'"/>
|
||||
</xsl:call-template>
|
||||
</a>
|
||||
</xsl:if>
|
||||
</td>
|
||||
<td width="40%" align="right">
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:if test="count($next)>0">
|
||||
<a accesskey="n">
|
||||
<xsl:attribute name="href">
|
||||
<xsl:call-template name="href.target">
|
||||
<xsl:with-param name="object" select="$next"/>
|
||||
</xsl:call-template>
|
||||
</xsl:attribute>
|
||||
<xsl:call-template name="navig.content">
|
||||
<xsl:with-param name="direction" select="'next'"/>
|
||||
</xsl:call-template>
|
||||
</a>
|
||||
</xsl:if>
|
||||
</td>
|
||||
</tr>
|
||||
</xsl:if>
|
||||
<xsl:if test="$row2">
|
||||
<tr>
|
||||
<td width="40%" align="left" valign="top">
|
||||
<xsl:if test="$navig.showtitles != 0">
|
||||
<xsl:apply-templates select="$prev" mode="object.title.markup"/>
|
||||
</xsl:if>
|
||||
<xsl:text> </xsl:text>
|
||||
</td>
|
||||
<td width="20%" align="center">
|
||||
<span style="color:white;font-size:90%;">
|
||||
<a href="http://www.springsource.com/"
|
||||
title="SpringSource">Sponsored by SpringSource
|
||||
</a>
|
||||
</span>
|
||||
</td>
|
||||
<td width="40%" align="right" valign="top">
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:if test="$navig.showtitles != 0">
|
||||
<xsl:apply-templates select="$next" mode="object.title.markup"/>
|
||||
</xsl:if>
|
||||
</td>
|
||||
</tr>
|
||||
</xsl:if>
|
||||
</table>
|
||||
</xsl:if>
|
||||
</div>
|
||||
</xsl:if>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
518
src/docbkx/resources/xsl/pdf/fopdf.xsl
Normal file
@@ -0,0 +1,518 @@
|
||||
<?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.
|
||||
-->
|
||||
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:fo="http://www.w3.org/1999/XSL/Format"
|
||||
xmlns:xslthl="http://xslthl.sf.net"
|
||||
exclude-result-prefixes="xslthl"
|
||||
version='1.0'>
|
||||
|
||||
<!-- Use nice graphics for admonitions -->
|
||||
<xsl:param name="admon.graphics">'1'</xsl:param>
|
||||
<xsl:param name="admon.graphics.path">@file.prefix@@dbf.xsl@/images/</xsl:param>
|
||||
<xsl:param name="draft.watermark.image" select="'@file.prefix@@dbf.xsl@/images/draft.png'"/>
|
||||
<xsl:param name="paper.type" select="'@paper.type@'"/>
|
||||
|
||||
<xsl:param name="page.margin.top" select="'1cm'"/>
|
||||
<xsl:param name="region.before.extent" select="'1cm'"/>
|
||||
<xsl:param name="body.margin.top" select="'1.5cm'"/>
|
||||
|
||||
<xsl:param name="body.margin.bottom" select="'1.5cm'"/>
|
||||
<xsl:param name="region.after.extent" select="'1cm'"/>
|
||||
<xsl:param name="page.margin.bottom" select="'1cm'"/>
|
||||
<xsl:param name="title.margin.left" select="'0cm'"/>
|
||||
|
||||
<!--###################################################
|
||||
Header
|
||||
################################################### -->
|
||||
|
||||
<!-- More space in the center header for long text -->
|
||||
<xsl:attribute-set name="header.content.properties">
|
||||
<xsl:attribute name="font-family">
|
||||
<xsl:value-of select="$body.font.family"/>
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="margin-left">-5em</xsl:attribute>
|
||||
<xsl:attribute name="margin-right">-5em</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!--###################################################
|
||||
Table of Contents
|
||||
################################################### -->
|
||||
|
||||
<xsl:param name="generate.toc">
|
||||
book toc,title
|
||||
</xsl:param>
|
||||
|
||||
<!--###################################################
|
||||
Custom Header
|
||||
################################################### -->
|
||||
|
||||
<xsl:template name="header.content">
|
||||
<xsl:param name="pageclass" select="''"/>
|
||||
<xsl:param name="sequence" select="''"/>
|
||||
<xsl:param name="position" select="''"/>
|
||||
<xsl:param name="gentext-key" select="''"/>
|
||||
|
||||
<xsl:variable name="Version">
|
||||
<xsl:choose>
|
||||
<xsl:when test="//productname">
|
||||
<xsl:value-of select="//productname"/><xsl:text> </xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:text>please define productname in your docbook file!</xsl:text>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:variable>
|
||||
|
||||
<xsl:choose>
|
||||
<xsl:when test="$sequence='blank'">
|
||||
<xsl:choose>
|
||||
<xsl:when test="$position='center'">
|
||||
<xsl:value-of select="$Version"/>
|
||||
</xsl:when>
|
||||
|
||||
<xsl:otherwise>
|
||||
<!-- nop -->
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:when>
|
||||
|
||||
<xsl:when test="$pageclass='titlepage'">
|
||||
<!-- nop: other titlepage sequences have no header -->
|
||||
</xsl:when>
|
||||
|
||||
<xsl:when test="$position='center'">
|
||||
<xsl:value-of select="$Version"/>
|
||||
</xsl:when>
|
||||
|
||||
<xsl:otherwise>
|
||||
<!-- nop -->
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
<!--###################################################
|
||||
Custom Footer
|
||||
################################################### -->
|
||||
|
||||
<xsl:template name="footer.content">
|
||||
<xsl:param name="pageclass" select="''"/>
|
||||
<xsl:param name="sequence" select="''"/>
|
||||
<xsl:param name="position" select="''"/>
|
||||
<xsl:param name="gentext-key" select="''"/>
|
||||
|
||||
<xsl:variable name="Version">
|
||||
<xsl:choose>
|
||||
<xsl:when test="//releaseinfo">
|
||||
<xsl:value-of select="//releaseinfo"/>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<!-- nop -->
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:variable>
|
||||
|
||||
<xsl:variable name="Title">
|
||||
<xsl:value-of select="//title"/>
|
||||
</xsl:variable>
|
||||
|
||||
<xsl:choose>
|
||||
<xsl:when test="$sequence='blank'">
|
||||
<xsl:choose>
|
||||
<xsl:when test="$double.sided != 0 and $position = 'left'">
|
||||
<xsl:value-of select="$Version"/>
|
||||
</xsl:when>
|
||||
|
||||
<xsl:when test="$double.sided = 0 and $position = 'center'">
|
||||
<!-- nop -->
|
||||
</xsl:when>
|
||||
|
||||
<xsl:otherwise>
|
||||
<fo:page-number/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:when>
|
||||
|
||||
<xsl:when test="$pageclass='titlepage'">
|
||||
<!-- nop: other titlepage sequences have no footer -->
|
||||
</xsl:when>
|
||||
|
||||
<xsl:when test="$double.sided != 0 and $sequence = 'even' and $position='left'">
|
||||
<fo:page-number/>
|
||||
</xsl:when>
|
||||
|
||||
<xsl:when test="$double.sided != 0 and $sequence = 'odd' and $position='right'">
|
||||
<fo:page-number/>
|
||||
</xsl:when>
|
||||
|
||||
<xsl:when test="$double.sided = 0 and $position='right'">
|
||||
<fo:page-number/>
|
||||
</xsl:when>
|
||||
|
||||
<xsl:when test="$double.sided != 0 and $sequence = 'odd' and $position='left'">
|
||||
<xsl:value-of select="$Version"/>
|
||||
</xsl:when>
|
||||
|
||||
<xsl:when test="$double.sided != 0 and $sequence = 'even' and $position='right'">
|
||||
<xsl:value-of select="$Version"/>
|
||||
</xsl:when>
|
||||
|
||||
<xsl:when test="$double.sided = 0 and $position='left'">
|
||||
<xsl:value-of select="$Version"/>
|
||||
</xsl:when>
|
||||
|
||||
<xsl:when test="$position='center'">
|
||||
<xsl:value-of select="$Title"/>
|
||||
</xsl:when>
|
||||
|
||||
<xsl:otherwise>
|
||||
<!-- nop -->
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="processing-instruction('hard-pagebreak')">
|
||||
<fo:block break-before='page'/>
|
||||
</xsl:template>
|
||||
|
||||
<!--###################################################
|
||||
Extensions
|
||||
################################################### -->
|
||||
|
||||
<!-- These extensions are required for table printing and other stuff -->
|
||||
<xsl:param name="use.extensions">1</xsl:param>
|
||||
<xsl:param name="tablecolumns.extension">0</xsl:param>
|
||||
<xsl:param name="callout.extensions">1</xsl:param>
|
||||
<xsl:param name="fop.extensions">1</xsl:param>
|
||||
|
||||
<!--###################################################
|
||||
Paper & Page Size
|
||||
################################################### -->
|
||||
|
||||
<!-- Paper type, no headers on blank pages, no double sided printing -->
|
||||
<xsl:param name="double.sided">0</xsl:param>
|
||||
<xsl:param name="headers.on.blank.pages">0</xsl:param>
|
||||
<xsl:param name="footers.on.blank.pages">0</xsl:param>
|
||||
|
||||
<!--###################################################
|
||||
Fonts & Styles
|
||||
################################################### -->
|
||||
|
||||
<xsl:param name="hyphenate">false</xsl:param>
|
||||
|
||||
<!-- Default Font size -->
|
||||
<xsl:param name="body.font.master">11</xsl:param>
|
||||
<xsl:param name="body.font.small">8</xsl:param>
|
||||
|
||||
<!-- Line height in body text -->
|
||||
<xsl:param name="line-height">1.4</xsl:param>
|
||||
|
||||
<!-- Chapter title size -->
|
||||
<xsl:attribute-set name="chapter.titlepage.recto.style">
|
||||
<xsl:attribute name="text-align">left</xsl:attribute>
|
||||
<xsl:attribute name="font-weight">bold</xsl:attribute>
|
||||
<xsl:attribute name="font-size">
|
||||
<xsl:value-of select="$body.font.master * 1.8"/>
|
||||
<xsl:text>pt</xsl:text>
|
||||
</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- Why is the font-size for chapters hardcoded in the XSL FO templates?
|
||||
Let's remove it, so this sucker can use our attribute-set only... -->
|
||||
<xsl:template match="title" mode="chapter.titlepage.recto.auto.mode">
|
||||
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format"
|
||||
xsl:use-attribute-sets="chapter.titlepage.recto.style">
|
||||
<xsl:call-template name="component.title">
|
||||
<xsl:with-param name="node" select="ancestor-or-self::chapter[1]"/>
|
||||
</xsl:call-template>
|
||||
</fo:block>
|
||||
</xsl:template>
|
||||
|
||||
<!-- Sections 1, 2 and 3 titles have a small bump factor and padding -->
|
||||
<xsl:attribute-set name="section.title.level1.properties">
|
||||
<xsl:attribute name="space-before.optimum">0.8em</xsl:attribute>
|
||||
<xsl:attribute name="space-before.minimum">0.8em</xsl:attribute>
|
||||
<xsl:attribute name="space-before.maximum">0.8em</xsl:attribute>
|
||||
<xsl:attribute name="font-size">
|
||||
<xsl:value-of select="$body.font.master * 1.5"/>
|
||||
<xsl:text>pt</xsl:text>
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="space-after.optimum">0.1em</xsl:attribute>
|
||||
<xsl:attribute name="space-after.minimum">0.1em</xsl:attribute>
|
||||
<xsl:attribute name="space-after.maximum">0.1em</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
<xsl:attribute-set name="section.title.level2.properties">
|
||||
<xsl:attribute name="space-before.optimum">0.6em</xsl:attribute>
|
||||
<xsl:attribute name="space-before.minimum">0.6em</xsl:attribute>
|
||||
<xsl:attribute name="space-before.maximum">0.6em</xsl:attribute>
|
||||
<xsl:attribute name="font-size">
|
||||
<xsl:value-of select="$body.font.master * 1.25"/>
|
||||
<xsl:text>pt</xsl:text>
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="space-after.optimum">0.1em</xsl:attribute>
|
||||
<xsl:attribute name="space-after.minimum">0.1em</xsl:attribute>
|
||||
<xsl:attribute name="space-after.maximum">0.1em</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
<xsl:attribute-set name="section.title.level3.properties">
|
||||
<xsl:attribute name="space-before.optimum">0.4em</xsl:attribute>
|
||||
<xsl:attribute name="space-before.minimum">0.4em</xsl:attribute>
|
||||
<xsl:attribute name="space-before.maximum">0.4em</xsl:attribute>
|
||||
<xsl:attribute name="font-size">
|
||||
<xsl:value-of select="$body.font.master * 1.0"/>
|
||||
<xsl:text>pt</xsl:text>
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="space-after.optimum">0.1em</xsl:attribute>
|
||||
<xsl:attribute name="space-after.minimum">0.1em</xsl:attribute>
|
||||
<xsl:attribute name="space-after.maximum">0.1em</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
<xsl:attribute-set name="section.title.level4.properties">
|
||||
<xsl:attribute name="space-before.optimum">0.3em</xsl:attribute>
|
||||
<xsl:attribute name="space-before.minimum">0.3em</xsl:attribute>
|
||||
<xsl:attribute name="space-before.maximum">0.3em</xsl:attribute>
|
||||
<xsl:attribute name="font-size">
|
||||
<xsl:value-of select="$body.font.master * 0.9"/>
|
||||
<xsl:text>pt</xsl:text>
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="space-after.optimum">0.1em</xsl:attribute>
|
||||
<xsl:attribute name="space-after.minimum">0.1em</xsl:attribute>
|
||||
<xsl:attribute name="space-after.maximum">0.1em</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- Use code syntax highlighting -->
|
||||
<xsl:param name="highlight.source" select="1"/>
|
||||
<xsl:param name="highlight.default.language" select="xml" />
|
||||
|
||||
<xsl:template match='xslthl:keyword'>
|
||||
<fo:inline font-weight="bold" color="#7F0055"><xsl:apply-templates/></fo:inline>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match='xslthl:comment'>
|
||||
<fo:inline font-style="italic" color="#3F5F5F"><xsl:apply-templates/></fo:inline>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match='xslthl:oneline-comment'>
|
||||
<fo:inline font-style="italic" color="#3F5F5F"><xsl:apply-templates/></fo:inline>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match='xslthl:multiline-comment'>
|
||||
<fo:inline font-style="italic" color="#3F5FBF"><xsl:apply-templates/></fo:inline>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match='xslthl:tag'>
|
||||
<fo:inline color="#3F7F7F"><xsl:apply-templates/></fo:inline>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match='xslthl:attribute'>
|
||||
<fo:inline color="#7F007F"><xsl:apply-templates/></fo:inline>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match='xslthl:value'>
|
||||
<fo:inline color="#2A00FF"><xsl:apply-templates/></fo:inline>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match='xslthl:string'>
|
||||
<fo:inline color="#2A00FF"><xsl:apply-templates/></fo:inline>
|
||||
</xsl:template>
|
||||
|
||||
<!--###################################################
|
||||
Tables
|
||||
################################################### -->
|
||||
|
||||
<!-- Some padding inside tables -->
|
||||
<xsl:attribute-set name="table.cell.padding">
|
||||
<xsl:attribute name="padding-left">4pt</xsl:attribute>
|
||||
<xsl:attribute name="padding-right">4pt</xsl:attribute>
|
||||
<xsl:attribute name="padding-top">4pt</xsl:attribute>
|
||||
<xsl:attribute name="padding-bottom">4pt</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- Only hairlines as frame and cell borders in tables -->
|
||||
<xsl:param name="table.frame.border.thickness">0.1pt</xsl:param>
|
||||
<xsl:param name="table.cell.border.thickness">0.1pt</xsl:param>
|
||||
|
||||
<!--###################################################
|
||||
Labels
|
||||
################################################### -->
|
||||
|
||||
<!-- Label Chapters and Sections (numbering) -->
|
||||
<xsl:param name="chapter.autolabel" select="1"/>
|
||||
<xsl:param name="section.autolabel" select="1"/>
|
||||
<xsl:param name="section.autolabel.max.depth" select="1"/>
|
||||
|
||||
<xsl:param name="section.label.includes.component.label" select="1"/>
|
||||
<xsl:param name="table.footnote.number.format" select="'1'"/>
|
||||
|
||||
<!--###################################################
|
||||
Programlistings
|
||||
################################################### -->
|
||||
|
||||
<!-- Verbatim text formatting (programlistings) -->
|
||||
<xsl:attribute-set name="monospace.verbatim.properties">
|
||||
<xsl:attribute name="font-size">
|
||||
<xsl:value-of select="$body.font.small * 1.0"/>
|
||||
<xsl:text>pt</xsl:text>
|
||||
</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<xsl:attribute-set name="verbatim.properties">
|
||||
<xsl:attribute name="space-before.minimum">1em</xsl:attribute>
|
||||
<xsl:attribute name="space-before.optimum">1em</xsl:attribute>
|
||||
<xsl:attribute name="space-before.maximum">1em</xsl:attribute>
|
||||
<xsl:attribute name="space-after.minimum">0.1em</xsl:attribute>
|
||||
<xsl:attribute name="space-after.optimum">0.1em</xsl:attribute>
|
||||
<xsl:attribute name="space-after.maximum">0.1em</xsl:attribute>
|
||||
|
||||
<xsl:attribute name="border-color">#444444</xsl:attribute>
|
||||
<xsl:attribute name="border-style">solid</xsl:attribute>
|
||||
<xsl:attribute name="border-width">0.1pt</xsl:attribute>
|
||||
<xsl:attribute name="padding-top">0.5em</xsl:attribute>
|
||||
<xsl:attribute name="padding-left">0.5em</xsl:attribute>
|
||||
<xsl:attribute name="padding-right">0.5em</xsl:attribute>
|
||||
<xsl:attribute name="padding-bottom">0.5em</xsl:attribute>
|
||||
<xsl:attribute name="margin-left">0.5em</xsl:attribute>
|
||||
<xsl:attribute name="margin-right">0.5em</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- Shade (background) programlistings -->
|
||||
<xsl:param name="shade.verbatim">1</xsl:param>
|
||||
<xsl:attribute-set name="shade.verbatim.style">
|
||||
<xsl:attribute name="background-color">#F0F0F0</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<xsl:attribute-set name="list.block.spacing">
|
||||
<xsl:attribute name="space-before.optimum">0.1em</xsl:attribute>
|
||||
<xsl:attribute name="space-before.minimum">0.1em</xsl:attribute>
|
||||
<xsl:attribute name="space-before.maximum">0.1em</xsl:attribute>
|
||||
<xsl:attribute name="space-after.optimum">0.1em</xsl:attribute>
|
||||
<xsl:attribute name="space-after.minimum">0.1em</xsl:attribute>
|
||||
<xsl:attribute name="space-after.maximum">0.1em</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<xsl:attribute-set name="example.properties">
|
||||
<xsl:attribute name="space-before.minimum">0.5em</xsl:attribute>
|
||||
<xsl:attribute name="space-before.optimum">0.5em</xsl:attribute>
|
||||
<xsl:attribute name="space-before.maximum">0.5em</xsl:attribute>
|
||||
<xsl:attribute name="space-after.minimum">0.1em</xsl:attribute>
|
||||
<xsl:attribute name="space-after.optimum">0.1em</xsl:attribute>
|
||||
<xsl:attribute name="space-after.maximum">0.1em</xsl:attribute>
|
||||
<xsl:attribute name="keep-together.within-column">always</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!--###################################################
|
||||
Title information for Figures, Examples etc.
|
||||
################################################### -->
|
||||
|
||||
<xsl:attribute-set name="formal.title.properties" use-attribute-sets="normal.para.spacing">
|
||||
<xsl:attribute name="font-weight">normal</xsl:attribute>
|
||||
<xsl:attribute name="font-style">italic</xsl:attribute>
|
||||
<xsl:attribute name="font-size">
|
||||
<xsl:value-of select="$body.font.master"/>
|
||||
<xsl:text>pt</xsl:text>
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="hyphenate">false</xsl:attribute>
|
||||
<xsl:attribute name="space-before.minimum">0.1em</xsl:attribute>
|
||||
<xsl:attribute name="space-before.optimum">0.1em</xsl:attribute>
|
||||
<xsl:attribute name="space-before.maximum">0.1em</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!--###################################################
|
||||
Callouts
|
||||
################################################### -->
|
||||
|
||||
<!-- don't use images for callouts -->
|
||||
<xsl:param name="callout.graphics">0</xsl:param>
|
||||
<xsl:param name="callout.unicode">1</xsl:param>
|
||||
|
||||
<!-- Place callout marks at this column in annotated areas -->
|
||||
<xsl:param name="callout.defaultcolumn">90</xsl:param>
|
||||
|
||||
<!--###################################################
|
||||
Misc
|
||||
################################################### -->
|
||||
|
||||
<!-- Placement of titles -->
|
||||
<xsl:param name="formal.title.placement">
|
||||
figure after
|
||||
example after
|
||||
equation before
|
||||
table before
|
||||
procedure before
|
||||
</xsl:param>
|
||||
|
||||
<!-- Format Variable Lists as Blocks (prevents horizontal overflow) -->
|
||||
<xsl:param name="variablelist.as.blocks">1</xsl:param>
|
||||
|
||||
<xsl:param name="body.start.indent">0pt</xsl:param>
|
||||
|
||||
<!-- Show only Sections up to level 3 in the TOCs -->
|
||||
<xsl:param name="toc.section.depth">3</xsl:param>
|
||||
|
||||
<!-- Remove "Chapter" from the Chapter titles... -->
|
||||
<xsl:param name="local.l10n.xml" select="document('')"/>
|
||||
<l:i18n xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0">
|
||||
<l:l10n language="en">
|
||||
<l:context name="title-numbered">
|
||||
<l:template name="chapter" text="%n. %t"/>
|
||||
<l:template name="section" text="%n %t"/>
|
||||
</l:context>
|
||||
<l:context name="title">
|
||||
<l:template name="example" text="Example %n %t"/>
|
||||
</l:context>
|
||||
</l:l10n>
|
||||
</l:i18n>
|
||||
|
||||
<!--###################################################
|
||||
colored and hyphenated links
|
||||
################################################### -->
|
||||
|
||||
<xsl:template match="ulink">
|
||||
<fo:basic-link external-destination="{@url}"
|
||||
xsl:use-attribute-sets="xref.properties"
|
||||
text-decoration="underline"
|
||||
color="blue">
|
||||
<xsl:choose>
|
||||
<xsl:when test="count(child::node())=0">
|
||||
<xsl:value-of select="@url"/>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:apply-templates/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</fo:basic-link>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="link">
|
||||
<fo:basic-link internal-destination="{@linkend}"
|
||||
xsl:use-attribute-sets="xref.properties"
|
||||
text-decoration="underline"
|
||||
color="blue">
|
||||
<xsl:choose>
|
||||
<xsl:when test="count(child::node())=0">
|
||||
<xsl:value-of select="@linkend"/>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:apply-templates/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</fo:basic-link>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
||||
101
src/docbkx/resources/xsl/pdf/titlepage.xml
Normal file
@@ -0,0 +1,101 @@
|
||||
<?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.
|
||||
-->
|
||||
|
||||
<!DOCTYPE t:templates [
|
||||
<!ENTITY hsize0 "10pt">
|
||||
<!ENTITY hsize1 "12pt">
|
||||
<!ENTITY hsize2 "14.4pt">
|
||||
<!ENTITY hsize3 "17.28pt">
|
||||
<!ENTITY hsize4 "20.736pt">
|
||||
<!ENTITY hsize5 "24.8832pt">
|
||||
<!ENTITY hsize0space "7.5pt"> <!-- 0.75 * hsize0 -->
|
||||
<!ENTITY hsize1space "9pt"> <!-- 0.75 * hsize1 -->
|
||||
<!ENTITY hsize2space "10.8pt"> <!-- 0.75 * hsize2 -->
|
||||
<!ENTITY hsize3space "12.96pt"> <!-- 0.75 * hsize3 -->
|
||||
<!ENTITY hsize4space "15.552pt"> <!-- 0.75 * hsize4 -->
|
||||
<!ENTITY hsize5space "18.6624pt"> <!-- 0.75 * hsize5 -->
|
||||
]>
|
||||
<t:templates xmlns:t="http://nwalsh.com/docbook/xsl/template/1.0"
|
||||
xmlns:param="http://nwalsh.com/docbook/xsl/template/1.0/param"
|
||||
xmlns:fo="http://www.w3.org/1999/XSL/Format"
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
|
||||
<t:titlepage t:element="book" t:wrapper="fo:block">
|
||||
<t:titlepage-content t:side="recto">
|
||||
<title
|
||||
t:named-template="division.title"
|
||||
param:node="ancestor-or-self::book[1]"
|
||||
text-align="center"
|
||||
font-size="&hsize5;"
|
||||
space-before="&hsize5space;"
|
||||
font-weight="bold"
|
||||
font-family="{$title.fontset}"/>
|
||||
<subtitle
|
||||
text-align="center"
|
||||
font-size="&hsize4;"
|
||||
space-before="&hsize4space;"
|
||||
font-family="{$title.fontset}"/>
|
||||
|
||||
<!-- <corpauthor space-before="0.5em"
|
||||
font-size="&hsize2;"/>
|
||||
<authorgroup space-before="0.5em"
|
||||
font-size="&hsize2;"/>
|
||||
<author space-before="0.5em"
|
||||
font-size="&hsize2;"/> -->
|
||||
|
||||
<mediaobject space-before="2em" space-after="2em"/>
|
||||
<releaseinfo space-before="5em" font-size="&hsize2;"/>
|
||||
<copyright space-before="1.5em"
|
||||
font-weight="normal"
|
||||
font-size="8"/>
|
||||
<legalnotice space-before="5em"
|
||||
font-weight="normal"
|
||||
font-style="italic"
|
||||
font-size="8"/>
|
||||
<othercredit space-before="2em"
|
||||
font-weight="normal"
|
||||
font-size="8"/>
|
||||
<pubdate space-before="0.5em"/>
|
||||
<revision space-before="0.5em"/>
|
||||
<revhistory space-before="0.5em"/>
|
||||
<abstract space-before="0.5em"
|
||||
text-align="start"
|
||||
margin-left="0.5in"
|
||||
margin-right="0.5in"
|
||||
font-family="{$body.fontset}"/>
|
||||
</t:titlepage-content>
|
||||
|
||||
<t:titlepage-content t:side="verso">
|
||||
</t:titlepage-content>
|
||||
|
||||
<t:titlepage-separator>
|
||||
</t:titlepage-separator>
|
||||
|
||||
<t:titlepage-before t:side="recto">
|
||||
</t:titlepage-before>
|
||||
|
||||
<t:titlepage-before t:side="verso">
|
||||
</t:titlepage-before>
|
||||
</t:titlepage>
|
||||
|
||||
<!-- ==================================================================== -->
|
||||
|
||||
</t:templates>
|
||||