DATACMNS-266 - Use new common Maven build infrastructure.
Simplified project setup to be a single module build again. Using Spring Data Build parent POM to simplify project setup. See https://github.com/SpringSource/spring-data-build#spring-data-build-infrastructure
@@ -1,48 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<project name="upload-dist-tasks">
|
||||
|
||||
<!-- can be run independent of maven as follows
|
||||
- classpath must be uncommented below. when run from maven,
|
||||
- the classpath is set up for you
|
||||
|
||||
ant -f src/ant/upload-dist.xml \
|
||||
-Ddist.id=spring-data-commons \
|
||||
-Ddist.name='Spring Datas Commons' \
|
||||
-Ddist.key=DATADOC \
|
||||
-Ddist.releaseType=milestone \
|
||||
-Ddist.accessKey=<access key> \
|
||||
-Ddist.secretKey=<secret key> \
|
||||
-Ddist.bucketName=dist.springframework.org \
|
||||
-Ddist.fileName=spring-data-commons-1.0.0.M1.zip \
|
||||
-Ddist.filePath=../../spring-data-commons-1.0.0.M1.zip \
|
||||
-Ddist.version=1.0.0.M1 \
|
||||
upload-dist
|
||||
-->
|
||||
|
||||
<taskdef resource="org/springframework/build/aws/ant/antlib.xml">
|
||||
<!-- see comment above
|
||||
<classpath>
|
||||
<pathelement location="/Users/cbeams/Desktop/org.springframework.build.aws.ant-3.0.5.RELEASE.jar"/>
|
||||
<pathelement location="/Users/cbeams/.m2/repository/net/java/dev/jets3t/jets3t/0.7.2/jets3t-0.7.2.jar"/>
|
||||
<pathelement location="/Users/cbeams/.m2/repository/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar"/>
|
||||
<pathelement location="/Users/cbeams/.m2/repository/commons-httpclient/commons-httpclient/3.1/commons-httpclient-3.1.jar"/>
|
||||
<pathelement location="/Users/cbeams/.m2/repository/commons-codec/commons-codec/1.3/commons-codec-1.3.jar"/>
|
||||
</classpath>
|
||||
-->
|
||||
</taskdef>
|
||||
<target name="upload-dist">
|
||||
<checksum file="${dist.filePath}" algorithm="sha1"/>
|
||||
<s3 accessKey="${dist.accessKey}" secretKey="${dist.secretKey}">
|
||||
<upload bucketName="${dist.bucketName}" file="${dist.filePath}"
|
||||
toFile="${dist.releaseType}/${dist.key}/${dist.fileName}" publicRead="true">
|
||||
<metadata name="project.name" value="${dist.name}"/>
|
||||
<metadata name="release.type" value="${dist.releaseType}"/>
|
||||
<metadata name="bundle.version" value="${dist.version}"/>
|
||||
<metadata name="package.file.name" value="${dist.fileName}"/>
|
||||
</upload>
|
||||
<upload bucketName="${dist.bucketName}" file="${dist.filePath}.sha1"
|
||||
toFile="${dist.releaseType}/${dist.key}/${dist.fileName}.sha1" publicRead="true">
|
||||
</upload>
|
||||
</s3>
|
||||
</target>
|
||||
</project>
|
||||
@@ -1,67 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<assembly>
|
||||
<!-- distribution assembly descriptor. packages up jars, source jars, documentation,
|
||||
dependencies and other resources into a single archive suitable for download and
|
||||
standalone use.
|
||||
see pom.xml 'maven-assembly-plugin' declaration
|
||||
see src/main/scripts/build-distribution.sh
|
||||
see http://www.sonatype.com/books/mvnref-book/reference/assemblies-set-dist-assemblies.html -->
|
||||
<id>distribution</id>
|
||||
<formats>
|
||||
<format>zip</format>
|
||||
</formats>
|
||||
<includeBaseDirectory>true</includeBaseDirectory>
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<!-- adds readme and other textfiles to the root of the distribution archive -->
|
||||
<directory>src/main/resources</directory>
|
||||
<includes>
|
||||
<include>readme.txt</include>
|
||||
<include>license.txt</include>
|
||||
<include>notice.txt</include>
|
||||
<include>changelog.txt</include>
|
||||
</includes>
|
||||
<outputDirectory/>
|
||||
<lineEnding>dos</lineEnding>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<!-- adds reference manual (html and pdf) to the distribution archive under the
|
||||
'docs/reference' directory
|
||||
see pom.xml 'maven-javadoc-plugin' declaration -->
|
||||
<directory>target/site/reference</directory>
|
||||
<outputDirectory>docs/reference</outputDirectory>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<!-- adds javadoc html to the distribution archive under the 'docs/javadoc' directory
|
||||
see pom.xml 'maven-javadoc-plugin' declaration -->
|
||||
<directory>target/site/apidocs</directory>
|
||||
<outputDirectory>docs/javadoc</outputDirectory>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
<moduleSets>
|
||||
<moduleSet>
|
||||
<!-- adds module jars to the distribution archive under the 'dist' directory -->
|
||||
<includes>
|
||||
<include>org.springframework.data:spring-data-commons-core</include>
|
||||
</includes>
|
||||
<binaries>
|
||||
<outputDirectory>dist</outputDirectory>
|
||||
<includeDependencies>false</includeDependencies>
|
||||
<unpack>false</unpack>
|
||||
</binaries>
|
||||
</moduleSet>
|
||||
<moduleSet>
|
||||
<!-- adds module source jars to the distribution archive under the 'src' directory
|
||||
see pom.xml 'maven-source-plugin' declaration -->
|
||||
<includes>
|
||||
<include>org.springframework.data:spring-data-commons-core</include>
|
||||
</includes>
|
||||
<binaries>
|
||||
<attachmentClassifier>sources</attachmentClassifier>
|
||||
<outputDirectory>src</outputDirectory>
|
||||
<includeDependencies>false</includeDependencies>
|
||||
<unpack>false</unpack>
|
||||
</binaries>
|
||||
</moduleSet>
|
||||
</moduleSets>
|
||||
</assembly>
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
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;
|
||||
}
|
||||
@@ -1,421 +0,0 @@
|
||||
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;
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
@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;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 329 B |
|
Before Width: | Height: | Size: 361 B |
|
Before Width: | Height: | Size: 565 B |
|
Before Width: | Height: | Size: 617 B |
|
Before Width: | Height: | Size: 623 B |
|
Before Width: | Height: | Size: 411 B |
|
Before Width: | Height: | Size: 640 B |
|
Before Width: | Height: | Size: 353 B |
|
Before Width: | Height: | Size: 350 B |
|
Before Width: | Height: | Size: 345 B |
|
Before Width: | Height: | Size: 348 B |
|
Before Width: | Height: | Size: 355 B |
|
Before Width: | Height: | Size: 344 B |
|
Before Width: | Height: | Size: 357 B |
|
Before Width: | Height: | Size: 357 B |
|
Before Width: | Height: | Size: 9.4 KiB |
|
Before Width: | Height: | Size: 36 KiB |
@@ -1,418 +0,0 @@
|
||||
<?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 Commons (</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>
|
||||
@@ -1,91 +0,0 @@
|
||||
<?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>
|
||||
@@ -1,136 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
-->
|
||||
|
||||
<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>
|
||||
@@ -1,61 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
-->
|
||||
|
||||
<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>
|
||||
@@ -1,208 +0,0 @@
|
||||
<?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>
|
||||
@@ -1,518 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
-->
|
||||
|
||||
<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>
|
||||
@@ -1,101 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
-->
|
||||
|
||||
<!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>
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Declares a field as the one representing the principal that created the entity containing the field.
|
||||
*
|
||||
* @author Ranie Jade Ramiso
|
||||
* @author Oliver Gierke
|
||||
* @since 1.5
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(value = { ElementType.FIELD, ElementType.ANNOTATION_TYPE })
|
||||
public @interface CreatedBy {
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Declares a field as the one representing the date the entity containing the field was created.
|
||||
*
|
||||
* @author Ranie Jade Ramiso
|
||||
* @author Oliver Gierke
|
||||
* @since 1.5
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(value = { ElementType.FIELD, ElementType.ANNOTATION_TYPE })
|
||||
public @interface CreatedDate {
|
||||
}
|
||||
30
src/main/java/org/springframework/data/annotation/Id.java
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @author J. Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(value = { ElementType.FIELD })
|
||||
public @interface Id {
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Declares a field as the one representing the principal that recently modified the entity containing the field.
|
||||
*
|
||||
* @author Ranie Jade Ramiso
|
||||
* @author Oliver Gierke
|
||||
* @since 1.5
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(value = { ElementType.FIELD, ElementType.ANNOTATION_TYPE })
|
||||
public @interface LastModifiedBy {
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Declares a field as the one representing the date the entity containing the field was recently modified.
|
||||
*
|
||||
* @author Ranie Jade Ramiso
|
||||
* @author Oliver Gierke
|
||||
* @since 1.5
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(value = { ElementType.FIELD, ElementType.ANNOTATION_TYPE })
|
||||
public @interface LastModifiedDate {
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.CONSTRUCTOR)
|
||||
public @interface PersistenceConstructor {
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @author J. Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(value = { ElementType.TYPE, ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.PARAMETER })
|
||||
public @interface Persistent {
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2011-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Meta-annotation to be used to annotate annotations that mark references to other objects.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Jon Brisbin
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.ANNOTATION_TYPE, ElementType.FIELD })
|
||||
public @interface Reference {
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 20011-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Marks a field to be transient for the mapping framework. Thus the property will not be persisted and not further
|
||||
* inspected by the mapping framework.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Jon Brisbin
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface Transient {
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2011 by the original author(s).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
|
||||
/**
|
||||
* Annotation to allow {@link String} based type aliases to be used when writing type information for
|
||||
* {@link PersistentEntity}s.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Documented
|
||||
@Inherited
|
||||
@Target({ ElementType.TYPE })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface TypeAlias {
|
||||
|
||||
/**
|
||||
* The type alias to be used when persisting
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String value();
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.annotation;
|
||||
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
import static java.lang.annotation.RetentionPolicy.*;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Demarcates a property to be used as version field to implement optimistic locking on entities.
|
||||
*
|
||||
* @since 1.5
|
||||
* @author Patryk Wasik
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Documented
|
||||
@Target({ FIELD, ANNOTATION_TYPE })
|
||||
@Retention(RUNTIME)
|
||||
public @interface Version {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* Core annotations being used by Spring Data.
|
||||
*/
|
||||
package org.springframework.data.annotation;
|
||||
@@ -0,0 +1,139 @@
|
||||
package org.springframework.data.auditing;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.springframework.data.annotation.CreatedBy;
|
||||
import org.springframework.data.annotation.CreatedDate;
|
||||
import org.springframework.data.annotation.LastModifiedBy;
|
||||
import org.springframework.data.annotation.LastModifiedDate;
|
||||
import org.springframework.data.util.ReflectionUtils;
|
||||
import org.springframework.data.util.ReflectionUtils.AnnotationFieldFilter;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Inspects the given {@link Class} for fields annotated by {@link CreatedBy}, {@link CreatedDate},
|
||||
* {@link LastModifiedBy} , and {@link LastModifiedDate}. Only one field per annotation is stored.
|
||||
*
|
||||
* @author Ranie Jade Ramiso
|
||||
* @author Oliver Gierke
|
||||
* @since 1.5
|
||||
*/
|
||||
class AnnotationAuditingMetadata {
|
||||
|
||||
private static final AnnotationFieldFilter CREATED_BY_FILTER = new AnnotationFieldFilter(CreatedBy.class);
|
||||
private static final AnnotationFieldFilter CREATED_DATE_FILTER = new AnnotationFieldFilter(CreatedDate.class);
|
||||
private static final AnnotationFieldFilter LAST_MODIFIED_BY_FILTER = new AnnotationFieldFilter(LastModifiedBy.class);
|
||||
private static final AnnotationFieldFilter LAST_MODIFIED_DATE_FILTER = new AnnotationFieldFilter(
|
||||
LastModifiedDate.class);
|
||||
|
||||
private static final Map<Class<?>, AnnotationAuditingMetadata> METADATA_CACHE = new ConcurrentHashMap<Class<?>, AnnotationAuditingMetadata>();
|
||||
|
||||
static final List<Class<?>> SUPPORTED_DATE_TYPES;
|
||||
|
||||
static {
|
||||
|
||||
List<Class<?>> types = new ArrayList<Class<?>>(4);
|
||||
types.add(DateTime.class);
|
||||
types.add(Date.class);
|
||||
types.add(Long.class);
|
||||
types.add(long.class);
|
||||
|
||||
SUPPORTED_DATE_TYPES = Collections.unmodifiableList(types);
|
||||
}
|
||||
|
||||
private final Field createdByField;
|
||||
private final Field createdDateField;
|
||||
private final Field lastModifiedByField;
|
||||
private final Field lastModifiedDateField;
|
||||
|
||||
private AnnotationAuditingMetadata(Class<?> type) {
|
||||
|
||||
Assert.notNull(type, "Given type must not be null!");
|
||||
|
||||
this.createdByField = ReflectionUtils.findField(type, CREATED_BY_FILTER);
|
||||
this.createdDateField = ReflectionUtils.findField(type, CREATED_DATE_FILTER);
|
||||
this.lastModifiedByField = ReflectionUtils.findField(type, LAST_MODIFIED_BY_FILTER);
|
||||
this.lastModifiedDateField = ReflectionUtils.findField(type, LAST_MODIFIED_DATE_FILTER);
|
||||
|
||||
assertValidDateFieldType(createdDateField);
|
||||
assertValidDateFieldType(lastModifiedDateField);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given field has a type that is a supported date type.
|
||||
*
|
||||
* @param field
|
||||
*/
|
||||
private void assertValidDateFieldType(Field field) {
|
||||
|
||||
if (field == null || SUPPORTED_DATE_TYPES.contains(field.getType())) {
|
||||
return;
|
||||
}
|
||||
|
||||
throw new IllegalStateException(String.format(
|
||||
"Found created/modified date field with type %s but only %s are supported!", field.getType(),
|
||||
SUPPORTED_DATE_TYPES));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a {@link AnnotationAuditingMetadata} for the given {@link Class}.
|
||||
*
|
||||
* @param type the type to inspect, must not be {@literal null}.
|
||||
*/
|
||||
public static AnnotationAuditingMetadata getMetadata(Class<?> type) {
|
||||
|
||||
if (METADATA_CACHE.containsKey(type)) {
|
||||
return METADATA_CACHE.get(type);
|
||||
}
|
||||
|
||||
AnnotationAuditingMetadata metadata = new AnnotationAuditingMetadata(type);
|
||||
METADATA_CACHE.put(type, metadata);
|
||||
return metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the {@link Class} represented in this instance is auditable or not.
|
||||
*/
|
||||
public boolean isAuditable() {
|
||||
if (createdByField == null && createdDateField == null && lastModifiedByField == null
|
||||
&& lastModifiedDateField == null) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the field annotated by {@link CreatedBy}, or {@literal null}.
|
||||
*/
|
||||
public Field getCreatedByField() {
|
||||
return createdByField;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the field annotated by {@link CreatedDate}, or {@literal null}.
|
||||
*/
|
||||
public Field getCreatedDateField() {
|
||||
return createdDateField;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the field annotated by {@link LastModifiedBy}, or {@literal null}.
|
||||
*/
|
||||
public Field getLastModifiedByField() {
|
||||
return lastModifiedByField;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the field annotated by {@link LastModifiedDate}, or {@literal null}.
|
||||
*/
|
||||
public Field getLastModifiedDateField() {
|
||||
return lastModifiedDateField;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.auditing;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
/**
|
||||
* Interface to abstract the ways setting the auditing information can be implemented.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @since 1.5
|
||||
*/
|
||||
public interface AuditableBeanWrapper {
|
||||
|
||||
/**
|
||||
* Set the creator of the object.
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
void setCreatedBy(Object value);
|
||||
|
||||
/**
|
||||
* Set the date the object was created.
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
void setCreatedDate(DateTime value);
|
||||
|
||||
/**
|
||||
* Set the last modifier of the object.
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
void setLastModifiedBy(Object value);
|
||||
|
||||
/**
|
||||
* Set the last modification date.
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
void setLastModifiedDate(DateTime value);
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.auditing;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Date;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.springframework.data.domain.Auditable;
|
||||
import org.springframework.data.util.ReflectionUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A factory class to {@link AuditableBeanWrapper} instances.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @since 1.5
|
||||
*/
|
||||
class AuditableBeanWrapperFactory {
|
||||
|
||||
/**
|
||||
* Returns an {@link AuditableBeanWrapper} if the given object is capable of being equipped with auditing information.
|
||||
*
|
||||
* @param source the auditing candidate.
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public AuditableBeanWrapper getBeanWrapperFor(Object source) {
|
||||
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (source instanceof Auditable) {
|
||||
return new AuditableInterfaceBeanWrapper((Auditable<Object, ?>) source);
|
||||
}
|
||||
|
||||
AnnotationAuditingMetadata metadata = AnnotationAuditingMetadata.getMetadata(source.getClass());
|
||||
|
||||
if (metadata.isAuditable()) {
|
||||
return new ReflectionAuditingBeanWrapper(source);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* An {@link AuditableBeanWrapper} that works with objects implementing
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
static class AuditableInterfaceBeanWrapper implements AuditableBeanWrapper {
|
||||
|
||||
private final Auditable<Object, ?> auditable;
|
||||
|
||||
public AuditableInterfaceBeanWrapper(Auditable<Object, ?> auditable) {
|
||||
this.auditable = auditable;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.auditing.AuditableBeanWrapper#setCreatedBy(java.lang.Object)
|
||||
*/
|
||||
public void setCreatedBy(Object value) {
|
||||
auditable.setCreatedBy(value);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.auditing.AuditableBeanWrapper#setCreatedDate(org.joda.time.DateTime)
|
||||
*/
|
||||
public void setCreatedDate(DateTime value) {
|
||||
auditable.setCreatedDate(value);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.auditing.AuditableBeanWrapper#setLastModifiedBy(java.lang.Object)
|
||||
*/
|
||||
public void setLastModifiedBy(Object value) {
|
||||
auditable.setLastModifiedBy(value);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.auditing.AuditableBeanWrapper#setLastModifiedDate(org.joda.time.DateTime)
|
||||
*/
|
||||
public void setLastModifiedDate(DateTime value) {
|
||||
auditable.setLastModifiedDate(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An {@link AuditableBeanWrapper} implementation that sets values on the target object using refelction.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
static class ReflectionAuditingBeanWrapper implements AuditableBeanWrapper {
|
||||
|
||||
private final AnnotationAuditingMetadata metadata;
|
||||
private final Object target;
|
||||
|
||||
/**
|
||||
* Creates a new {@link ReflectionAuditingBeanWrapper} to set auditing data on the given target object.
|
||||
*
|
||||
* @param target must not be {@literal null}.
|
||||
*/
|
||||
public ReflectionAuditingBeanWrapper(Object target) {
|
||||
|
||||
Assert.notNull(target, "Target object must not be null!");
|
||||
|
||||
this.metadata = AnnotationAuditingMetadata.getMetadata(target.getClass());
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.auditing.AuditableBeanWrapper#setCreatedBy(java.lang.Object)
|
||||
*/
|
||||
public void setCreatedBy(Object value) {
|
||||
setField(metadata.getCreatedByField(), value);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.auditing.AuditableBeanWrapper#setCreatedDate(org.joda.time.DateTime)
|
||||
*/
|
||||
public void setCreatedDate(DateTime value) {
|
||||
setDateField(metadata.getCreatedDateField(), value);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.auditing.AuditableBeanWrapper#setLastModifiedBy(java.lang.Object)
|
||||
*/
|
||||
public void setLastModifiedBy(Object value) {
|
||||
setField(metadata.getLastModifiedByField(), value);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.auditing.AuditableBeanWrapper#setLastModifiedDate(org.joda.time.DateTime)
|
||||
*/
|
||||
public void setLastModifiedDate(DateTime value) {
|
||||
setDateField(metadata.getLastModifiedDateField(), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the given field to the given value if the field is not {@literal null}.
|
||||
*
|
||||
* @param field
|
||||
* @param value
|
||||
*/
|
||||
private void setField(Field field, Object value) {
|
||||
|
||||
if (field != null) {
|
||||
ReflectionUtils.setField(field, target, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the given field to the given value if the field is not {@literal null}.
|
||||
*
|
||||
* @param field
|
||||
* @param value
|
||||
*/
|
||||
private void setDateField(Field field, DateTime value) {
|
||||
|
||||
if (field == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ReflectionUtils.setField(field, target, getDateValueToSet(value, field));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link DateTime} in a type compatible to the given field.
|
||||
*
|
||||
* @param value
|
||||
* @param field must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
private Object getDateValueToSet(DateTime value, Field field) {
|
||||
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Class<?> targetType = field.getType();
|
||||
|
||||
if (DateTime.class.equals(targetType)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (Date.class.equals(targetType)) {
|
||||
return value.toDate();
|
||||
}
|
||||
|
||||
if (Long.class.equals(targetType) || long.class.equals(targetType)) {
|
||||
return value.getMillis();
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(String.format("Invalid date type for field %s! Supported types are %s.",
|
||||
field, AnnotationAuditingMetadata.SUPPORTED_DATE_TYPES));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.auditing;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.data.domain.Auditable;
|
||||
import org.springframework.data.domain.AuditorAware;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Auditing handler to mark entity objects created and modified.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @since 1.5
|
||||
*/
|
||||
public class AuditingHandler<T> implements InitializingBean {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(AuditingHandler.class);
|
||||
|
||||
private final AuditableBeanWrapperFactory factory = new AuditableBeanWrapperFactory();
|
||||
private DateTimeProvider dateTimeProvider = CurrentDateTimeProvider.INSTANCE;
|
||||
private AuditorAware<T> auditorAware;
|
||||
private boolean dateTimeForNow = true;
|
||||
private boolean modifyOnCreation = true;
|
||||
|
||||
/**
|
||||
* Setter to inject a {@code AuditorAware} component to retrieve the current auditor.
|
||||
*
|
||||
* @param auditorAware the auditorAware to set
|
||||
*/
|
||||
public void setAuditorAware(final AuditorAware<T> auditorAware) {
|
||||
|
||||
Assert.notNull(auditorAware);
|
||||
this.auditorAware = auditorAware;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter do determine if {@link Auditable#setCreatedDate(DateTime)} and
|
||||
* {@link Auditable#setLastModifiedDate(DateTime)} shall be filled with the current Java time. Defaults to
|
||||
* {@code true}. One might set this to {@code false} to use database features to set entity time.
|
||||
*
|
||||
* @param dateTimeForNow the dateTimeForNow to set
|
||||
*/
|
||||
public void setDateTimeForNow(boolean dateTimeForNow) {
|
||||
this.dateTimeForNow = dateTimeForNow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this to false if you want to treat entity creation as modification and thus set the current date as
|
||||
* modification date, too. Defaults to {@code true}.
|
||||
*
|
||||
* @param modifyOnCreation if modification information shall be set on creation, too
|
||||
*/
|
||||
public void setModifyOnCreation(boolean modifyOnCreation) {
|
||||
this.modifyOnCreation = modifyOnCreation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link DateTimeProvider} to be used to determine the dates to be set.
|
||||
*
|
||||
* @param dateTimeProvider
|
||||
*/
|
||||
public void setDateTimeProvider(DateTimeProvider dateTimeProvider) {
|
||||
this.dateTimeProvider = dateTimeProvider == null ? CurrentDateTimeProvider.INSTANCE : dateTimeProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the given object as created.
|
||||
*
|
||||
* @param source
|
||||
*/
|
||||
public void markCreated(Object source) {
|
||||
touch(source, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the given object as modified.
|
||||
*
|
||||
* @param source
|
||||
*/
|
||||
public void markModified(Object source) {
|
||||
touch(source, false);
|
||||
}
|
||||
|
||||
private void touch(Object target, boolean isNew) {
|
||||
|
||||
AuditableBeanWrapper wrapper = factory.getBeanWrapperFor(target);
|
||||
|
||||
if (wrapper == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
T auditor = touchAuditor(wrapper, isNew);
|
||||
DateTime now = dateTimeForNow ? touchDate(wrapper, isNew) : null;
|
||||
|
||||
Object defaultedNow = now == null ? "not set" : now;
|
||||
Object defaultedAuditor = auditor == null ? "unknown" : auditor;
|
||||
|
||||
LOGGER.debug("Touched {} - Last modification at {} by {}", new Object[] { target, defaultedNow, defaultedAuditor });
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets modifying and creating auditioner. Creating auditioner is only set on new auditables.
|
||||
*
|
||||
* @param auditable
|
||||
* @return
|
||||
*/
|
||||
private T touchAuditor(AuditableBeanWrapper wrapper, boolean isNew) {
|
||||
|
||||
if (null == auditorAware) {
|
||||
return null;
|
||||
}
|
||||
|
||||
T auditor = auditorAware.getCurrentAuditor();
|
||||
|
||||
if (isNew) {
|
||||
wrapper.setCreatedBy(auditor);
|
||||
if (!modifyOnCreation) {
|
||||
return auditor;
|
||||
}
|
||||
}
|
||||
|
||||
wrapper.setLastModifiedBy(auditor);
|
||||
return auditor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Touches the auditable regarding modification and creation date. Creation date is only set on new auditables.
|
||||
*
|
||||
* @param wrapper
|
||||
* @return
|
||||
*/
|
||||
private DateTime touchDate(AuditableBeanWrapper wrapper, boolean isNew) {
|
||||
|
||||
DateTime now = dateTimeProvider.getDateTime();
|
||||
|
||||
if (isNew) {
|
||||
wrapper.setCreatedDate(now);
|
||||
if (!modifyOnCreation) {
|
||||
return now;
|
||||
}
|
||||
}
|
||||
|
||||
wrapper.setLastModifiedDate(now);
|
||||
return now;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
|
||||
*/
|
||||
public void afterPropertiesSet() {
|
||||
|
||||
if (auditorAware == null) {
|
||||
LOGGER.debug("No AuditorAware set! Auditing will not be applied!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.auditing;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
/**
|
||||
* Default {@link DateTimeProvider} simply creating new {@link DateTime} instances for each method call.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @since 1.5
|
||||
*/
|
||||
public enum CurrentDateTimeProvider implements DateTimeProvider {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.jpa.domain.support.DateTimeProvider#getDateTime()
|
||||
*/
|
||||
public DateTime getDateTime() {
|
||||
return new DateTime();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.auditing;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
/**
|
||||
* SPI to calculate the {@link DateTime} instance to be used when auditing.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @since 1.5
|
||||
*/
|
||||
public interface DateTimeProvider {
|
||||
|
||||
/**
|
||||
* Returns the {@link DateTime} to be used as modification date.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
DateTime getDateTime();
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.auditing;
|
||||
|
||||
import org.springframework.data.support.IsNewStrategy;
|
||||
import org.springframework.data.support.IsNewStrategyFactory;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link AuditingHandler} extension that uses an {@link IsNewStrategyFactory} to expose a generic
|
||||
* {@link #markAudited(Object)} method that will route calls to {@link #markCreated(Object)} or
|
||||
* {@link #markModified(Object)} based on the {@link IsNewStrategy} determined from the factory.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @since 1.5
|
||||
*/
|
||||
public class IsNewAwareAuditingHandler<T> extends AuditingHandler<T> {
|
||||
|
||||
private final IsNewStrategyFactory isNewStrategyFactory;
|
||||
|
||||
/**
|
||||
* Creates a new {@link IsNewAwareAuditingHandler} using the given {@link IsNewStrategyFactory}.
|
||||
*
|
||||
* @param isNewStrategyFactory must not be {@literal null}.
|
||||
*/
|
||||
public IsNewAwareAuditingHandler(IsNewStrategyFactory isNewStrategyFactory) {
|
||||
|
||||
Assert.notNull(isNewStrategyFactory, "IsNewStrategy must not be null!");
|
||||
this.isNewStrategyFactory = isNewStrategyFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the given object created or modified based on the {@link IsNewStrategy} returned by the
|
||||
* {@link IsNewStrategyFactory} configured. Will rout the calls to {@link #markCreated(Object)} and
|
||||
* {@link #markModified(Object)} accordingly.
|
||||
*
|
||||
* @param object
|
||||
*/
|
||||
public void markAudited(Object object) {
|
||||
|
||||
if (object == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
IsNewStrategy strategy = isNewStrategyFactory.getIsNewStrategy(object.getClass());
|
||||
|
||||
if (strategy.isNew(object)) {
|
||||
markCreated(object);
|
||||
} else {
|
||||
markModified(object);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright 2011-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.authentication;
|
||||
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Class used to provide credentials for username/password authentication
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class UserCredentials {
|
||||
|
||||
public static final UserCredentials NO_CREDENTIALS = new UserCredentials(null, null);
|
||||
|
||||
private final String username;
|
||||
private final String password;
|
||||
|
||||
/**
|
||||
* Creates a new {@link UserCredentials} instance from the given username and password. Empty {@link String}s provided
|
||||
* will be treated like no username or password set.
|
||||
*
|
||||
* @param username
|
||||
* @param password
|
||||
*/
|
||||
public UserCredentials(String username, String password) {
|
||||
this.username = StringUtils.hasText(username) ? username : null;
|
||||
this.password = StringUtils.hasText(password) ? password : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the username to use for authentication.
|
||||
*
|
||||
* @return the username
|
||||
*/
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the password to use for authentication.
|
||||
*
|
||||
* @return the password
|
||||
*/
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the credentials contain a username.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean hasUsername() {
|
||||
return this.username != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the credentials contain a password.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean hasPassword() {
|
||||
return this.password != null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj == null || !getClass().equals(obj.getClass())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
UserCredentials that = (UserCredentials) obj;
|
||||
|
||||
return ObjectUtils.nullSafeEquals(this.username, that.username)
|
||||
&& ObjectUtils.nullSafeEquals(this.password, that.password);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
int result = 17;
|
||||
|
||||
result += 31 * ObjectUtils.nullSafeHashCode(username);
|
||||
result += 31 * ObjectUtils.nullSafeHashCode(password);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* Types to abstract authentication concepts.
|
||||
*/
|
||||
package org.springframework.data.authentication;
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.config;
|
||||
|
||||
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.*;
|
||||
|
||||
import org.springframework.aop.framework.ProxyFactoryBean;
|
||||
import org.springframework.aop.target.LazyInitTargetSource;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||
import org.springframework.data.auditing.AuditingHandler;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* {@link BeanDefinitionParser} that parses an {@link AuditingHandler} {@link BeanDefinition}
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @since 1.5
|
||||
*/
|
||||
public class AuditingHandlerBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
|
||||
|
||||
private static final String AUDITOR_AWARE_REF = "auditor-aware-ref";
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser#getBeanClass(org.w3c.dom.Element)
|
||||
*/
|
||||
@Override
|
||||
protected Class<?> getBeanClass(Element element) {
|
||||
return AuditingHandler.class;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#shouldGenerateId()
|
||||
*/
|
||||
@Override
|
||||
protected boolean shouldGenerateId() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser#doParse(org.w3c.dom.Element, org.springframework.beans.factory.support.BeanDefinitionBuilder)
|
||||
*/
|
||||
@Override
|
||||
protected void doParse(Element element, BeanDefinitionBuilder builder) {
|
||||
|
||||
String auditorAwareRef = element.getAttribute(AUDITOR_AWARE_REF);
|
||||
if (StringUtils.hasText(auditorAwareRef)) {
|
||||
builder.addPropertyValue("auditorAware", createLazyInitTargetSourceBeanDefinition(auditorAwareRef));
|
||||
}
|
||||
|
||||
ParsingUtils.setPropertyValue(builder, element, "set-dates", "dateTimeForNow");
|
||||
ParsingUtils.setPropertyReference(builder, element, "date-time-provider-ref", "dateTimeProvider");
|
||||
|
||||
}
|
||||
|
||||
private BeanDefinition createLazyInitTargetSourceBeanDefinition(String auditorAwareRef) {
|
||||
|
||||
BeanDefinitionBuilder targetSourceBuilder = rootBeanDefinition(LazyInitTargetSource.class);
|
||||
targetSourceBuilder.addPropertyValue("targetBeanName", auditorAwareRef);
|
||||
|
||||
BeanDefinitionBuilder builder = rootBeanDefinition(ProxyFactoryBean.class);
|
||||
builder.addPropertyValue("targetSource", targetSourceBuilder.getBeanDefinition());
|
||||
|
||||
return builder.getBeanDefinition();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.config;
|
||||
|
||||
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* Helper to create {@link BeanComponentDefinition} more easily.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class BeanComponentDefinitionBuilder {
|
||||
|
||||
private final Element defaultSource;
|
||||
private final ParserContext context;
|
||||
|
||||
/**
|
||||
* Creates a new {@link BeanComponentDefinitionBuilder} using the given {@link Element} as default source and the
|
||||
* given {@link ParserContext}.
|
||||
*
|
||||
* @param defaultSource must not be {@literal null}.
|
||||
* @param context must not be {@literal null}.
|
||||
*/
|
||||
public BeanComponentDefinitionBuilder(Element defaultSource, ParserContext context) {
|
||||
|
||||
Assert.notNull(defaultSource);
|
||||
Assert.notNull(context);
|
||||
|
||||
this.defaultSource = defaultSource;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link BeanComponentDefinition} from the given {@link BeanDefinitionBuilder}. Will generate a bean name.
|
||||
*
|
||||
* @param builder must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public BeanComponentDefinition getComponent(BeanDefinitionBuilder builder) {
|
||||
|
||||
Assert.notNull(builder);
|
||||
|
||||
AbstractBeanDefinition definition = builder.getRawBeanDefinition();
|
||||
String name = BeanDefinitionReaderUtils.generateBeanName(definition, context.getRegistry(), context.isNested());
|
||||
|
||||
return getComponent(builder, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link BeanComponentDefinition} from the given {@link BeanDefinitionBuilder} and inspects the backing
|
||||
* {@link Element}s id attribute for a name. It will use this one if found or the given fallback if not.
|
||||
*
|
||||
* @param builder must not be {@literal null}.
|
||||
* @param fallback must not be {@literal null} or empty.
|
||||
* @return
|
||||
*/
|
||||
public BeanComponentDefinition getComponentIdButFallback(BeanDefinitionBuilder builder, String fallback) {
|
||||
|
||||
Assert.hasText(fallback);
|
||||
|
||||
String id = defaultSource.getAttribute("id");
|
||||
return getComponent(builder, StringUtils.hasText(id) ? id : fallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link BeanComponentDefinition} from the given {@link BeanDefinitionBuilder} using the given name.
|
||||
*
|
||||
* @param builder must not be {@literal null}.
|
||||
* @param name must not be {@literal null} or empty.
|
||||
* @return
|
||||
*/
|
||||
public BeanComponentDefinition getComponent(BeanDefinitionBuilder builder, String name) {
|
||||
return getComponent(builder, name, defaultSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link BeanComponentDefinition} from the given {@link BeanDefinitionBuilder} using the given name and
|
||||
* raw source object.
|
||||
*
|
||||
* @param builder must not be {@literal null}.
|
||||
* @param name must not be {@literal null}.
|
||||
* @param rawSource
|
||||
* @return
|
||||
*/
|
||||
public BeanComponentDefinition getComponent(BeanDefinitionBuilder builder, String name, Object rawSource) {
|
||||
|
||||
Assert.notNull(builder);
|
||||
Assert.hasText(name);
|
||||
|
||||
AbstractBeanDefinition definition = builder.getRawBeanDefinition();
|
||||
definition.setSource(context.extractSource(rawSource));
|
||||
|
||||
return new BeanComponentDefinition(definition, name);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.config;
|
||||
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.data.auditing.IsNewAwareAuditingHandler;
|
||||
import org.springframework.util.Assert;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* {@link AuditingHandlerBeanDefinitionParser} that will register am {@link IsNewAwareAuditingHandler}. Needs to get the
|
||||
* bean id of the
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class IsNewAwareAuditingHandlerBeanDefinitionParser extends AuditingHandlerBeanDefinitionParser {
|
||||
|
||||
private final String isNewStrategyFactoryBeanId;
|
||||
|
||||
/**
|
||||
* Creates a new {@link IsNewAwareAuditingHandlerBeanDefinitionParser}.
|
||||
*
|
||||
* @param isNewStrategyFactoryBeanId must not be {@literal null} or empty.
|
||||
*/
|
||||
public IsNewAwareAuditingHandlerBeanDefinitionParser(String isNewStrategyFactoryBeanId) {
|
||||
|
||||
Assert.hasText(isNewStrategyFactoryBeanId);
|
||||
this.isNewStrategyFactoryBeanId = isNewStrategyFactoryBeanId;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.config.AuditingHandlerBeanDefinitionParser#getBeanClass(org.w3c.dom.Element)
|
||||
*/
|
||||
@Override
|
||||
protected Class<?> getBeanClass(Element element) {
|
||||
return IsNewAwareAuditingHandler.class;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.config.AuditingHandlerBeanDefinitionParser#doParse(org.w3c.dom.Element, org.springframework.beans.factory.support.BeanDefinitionBuilder)
|
||||
*/
|
||||
@Override
|
||||
protected void doParse(Element element, BeanDefinitionBuilder builder) {
|
||||
|
||||
builder.addConstructorArgReference(isNewStrategyFactoryBeanId);
|
||||
|
||||
super.doParse(element, builder);
|
||||
}
|
||||
}
|
||||
130
src/main/java/org/springframework/data/config/ParsingUtils.java
Normal file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright 2011-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.config;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* Utility methods for {@link BeanDefinitionParser} implementations.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public abstract class ParsingUtils {
|
||||
|
||||
private ParsingUtils() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures a property value for the given property name reading the attribute of the given name from the given
|
||||
* {@link Element} if the attribute is configured.
|
||||
*
|
||||
* @param builder must not be {@literal null}.
|
||||
* @param element must not be {@literal null}.
|
||||
* @param attrName must not be {@literal null} or empty.
|
||||
* @param propertyName must not be {@literal null} or empty.
|
||||
*/
|
||||
public static void setPropertyValue(BeanDefinitionBuilder builder, Element element, String attrName,
|
||||
String propertyName) {
|
||||
|
||||
Assert.notNull(builder, "BeanDefinitionBuilder must not be null!");
|
||||
Assert.notNull(element, "Element must not be null!");
|
||||
Assert.hasText(attrName, "Attribute name must not be null!");
|
||||
Assert.hasText(propertyName, "Property name must not be null!");
|
||||
|
||||
String attr = element.getAttribute(attrName);
|
||||
|
||||
if (StringUtils.hasText(attr)) {
|
||||
builder.addPropertyValue(propertyName, attr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the property with the given attribute name on the given {@link BeanDefinitionBuilder} to the value of the
|
||||
* attribute with the given name if the attribute is configured.
|
||||
*
|
||||
* @param builder must not be {@literal null}.
|
||||
* @param element must not be {@literal null}.
|
||||
* @param attribute must not be {@literal null} or empty.
|
||||
*/
|
||||
public static void setPropertyValue(BeanDefinitionBuilder builder, Element element, String attribute) {
|
||||
setPropertyValue(builder, element, attribute, attribute);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures a bean property reference with the value of the attribute of the given name if it is configured.
|
||||
*
|
||||
* @param builder must not be {@literal null}.
|
||||
* @param element must not be {@literal null}.
|
||||
* @param attribute must not be {@literal null} or empty.
|
||||
* @param property must not be {@literal null}or empty.
|
||||
*/
|
||||
public static void setPropertyReference(BeanDefinitionBuilder builder, Element element, String attribute,
|
||||
String property) {
|
||||
|
||||
Assert.notNull(builder, "BeanDefinitionBuilder must not be null!");
|
||||
Assert.notNull(element, "Element must not be null!");
|
||||
Assert.hasText(attribute, "Attribute name must not be null!");
|
||||
Assert.hasText(property, "Property name must not be null!");
|
||||
|
||||
String value = element.getAttribute(attribute);
|
||||
|
||||
if (StringUtils.hasText(value)) {
|
||||
builder.addPropertyReference(property, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link BeanDefinition} built by the given {@link BeanDefinitionBuilder} enriched with source
|
||||
* information derived from the given {@link Element}.
|
||||
*
|
||||
* @param builder must not be {@literal null}.
|
||||
* @param context must not be {@literal null}.
|
||||
* @param element must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static AbstractBeanDefinition getSourceBeanDefinition(BeanDefinitionBuilder builder, ParserContext context,
|
||||
Element element) {
|
||||
|
||||
Assert.notNull(element, "Element must not be null!");
|
||||
Assert.notNull(context, "ParserContext must not be null!");
|
||||
|
||||
return getSourceBeanDefinition(builder, context.extractSource(element));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link AbstractBeanDefinition} built by the given builder with the given extracted source applied.
|
||||
*
|
||||
* @param builder must not be {@literal null}.
|
||||
* @param source
|
||||
* @return
|
||||
*/
|
||||
public static AbstractBeanDefinition getSourceBeanDefinition(BeanDefinitionBuilder builder, Object source) {
|
||||
|
||||
Assert.notNull(builder, "Builder must not be null!");
|
||||
|
||||
AbstractBeanDefinition definition = builder.getRawBeanDefinition();
|
||||
definition.setSource(source);
|
||||
return definition;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
* Copyright 2010-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.config;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.FatalBeanException;
|
||||
import org.springframework.beans.factory.parsing.ReaderContext;
|
||||
import org.springframework.beans.factory.xml.XmlReaderContext;
|
||||
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
|
||||
import org.springframework.core.type.filter.AnnotationTypeFilter;
|
||||
import org.springframework.core.type.filter.AspectJTypeFilter;
|
||||
import org.springframework.core.type.filter.AssignableTypeFilter;
|
||||
import org.springframework.core.type.filter.RegexPatternTypeFilter;
|
||||
import org.springframework.core.type.filter.TypeFilter;
|
||||
import org.springframework.util.Assert;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
/**
|
||||
* Parser to populate the given {@link ClassPathScanningCandidateComponentProvider} with {@link TypeFilter}s parsed from
|
||||
* the given {@link Element}'s children.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class TypeFilterParser {
|
||||
|
||||
private static final String FILTER_TYPE_ATTRIBUTE = "type";
|
||||
private static final String FILTER_EXPRESSION_ATTRIBUTE = "expression";
|
||||
|
||||
private final ReaderContext readerContext;
|
||||
private final ClassLoader classLoader;
|
||||
|
||||
/**
|
||||
* Creates a new {@link TypeFilterParser} with the given {@link ReaderContext}.
|
||||
*
|
||||
* @param readerContext must not be {@literal null}.
|
||||
*/
|
||||
public TypeFilterParser(XmlReaderContext readerContext) {
|
||||
this(readerContext, readerContext.getResourceLoader().getClassLoader());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor to ease testing as {@link XmlReaderContext#getBeanClassLoader()} is final and thus cannot be mocked
|
||||
* easily.
|
||||
*
|
||||
* @param readerContext must not be {@literal null}.
|
||||
* @param classLoader must not be {@literal null}.
|
||||
*/
|
||||
TypeFilterParser(ReaderContext readerContext, ClassLoader classLoader) {
|
||||
|
||||
Assert.notNull(readerContext, "ReaderContext must not be null!");
|
||||
Assert.notNull(classLoader, "ClassLoader must not be null!");
|
||||
|
||||
this.readerContext = readerContext;
|
||||
this.classLoader = classLoader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all {@link TypeFilter} declared in nested elements of the given {@link Element}. Allows to selectively
|
||||
* retrieve including or excluding filters based on the given {@link Type}.
|
||||
*
|
||||
* @param element must not be {@literal null}.
|
||||
* @param type must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public Iterable<TypeFilter> parseTypeFilters(Element element, Type type) {
|
||||
|
||||
NodeList nodeList = element.getChildNodes();
|
||||
Collection<TypeFilter> filters = new HashSet<TypeFilter>();
|
||||
|
||||
for (int i = 0; i < nodeList.getLength(); i++) {
|
||||
|
||||
Node node = nodeList.item(i);
|
||||
Element childElement = type.getElement(node);
|
||||
|
||||
if (childElement != null) {
|
||||
|
||||
try {
|
||||
filters.add(createTypeFilter(childElement, classLoader));
|
||||
} catch (RuntimeException e) {
|
||||
readerContext.error(e.getMessage(), readerContext.extractSource(element), e.getCause());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return filters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Createsa a {@link TypeFilter} instance from the given {@link Element} and {@link ClassLoader}.
|
||||
*
|
||||
* @param element must not be {@literal null}.
|
||||
* @param classLoader must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
protected TypeFilter createTypeFilter(Element element, ClassLoader classLoader) {
|
||||
|
||||
String filterType = element.getAttribute(FILTER_TYPE_ATTRIBUTE);
|
||||
String expression = element.getAttribute(FILTER_EXPRESSION_ATTRIBUTE);
|
||||
|
||||
try {
|
||||
|
||||
FilterType filter = FilterType.fromString(filterType);
|
||||
return filter.getFilter(expression, classLoader);
|
||||
|
||||
} catch (ClassNotFoundException ex) {
|
||||
throw new FatalBeanException("Type filter class not found: " + expression, ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum representing all the filter types available for {@code include} and {@code exclude} elements. This acts as
|
||||
* factory for {@link TypeFilter} instances.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @see #getFilter(String, ClassLoader)
|
||||
*/
|
||||
private static enum FilterType {
|
||||
|
||||
ANNOTATION {
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public TypeFilter getFilter(String expression, ClassLoader classLoader) throws ClassNotFoundException {
|
||||
return new AnnotationTypeFilter((Class<Annotation>) classLoader.loadClass(expression));
|
||||
}
|
||||
},
|
||||
|
||||
ASSIGNABLE {
|
||||
@Override
|
||||
public TypeFilter getFilter(String expression, ClassLoader classLoader) throws ClassNotFoundException {
|
||||
return new AssignableTypeFilter(classLoader.loadClass(expression));
|
||||
}
|
||||
},
|
||||
|
||||
ASPECTJ {
|
||||
@Override
|
||||
public TypeFilter getFilter(String expression, ClassLoader classLoader) {
|
||||
return new AspectJTypeFilter(expression, classLoader);
|
||||
}
|
||||
},
|
||||
|
||||
REGEX {
|
||||
@Override
|
||||
public TypeFilter getFilter(String expression, ClassLoader classLoader) {
|
||||
return new RegexPatternTypeFilter(Pattern.compile(expression));
|
||||
}
|
||||
},
|
||||
|
||||
CUSTOM {
|
||||
@Override
|
||||
public TypeFilter getFilter(String expression, ClassLoader classLoader) throws ClassNotFoundException {
|
||||
|
||||
Class<?> filterClass = classLoader.loadClass(expression);
|
||||
if (!TypeFilter.class.isAssignableFrom(filterClass)) {
|
||||
throw new IllegalArgumentException("Class is not assignable to [" + TypeFilter.class.getName() + "]: "
|
||||
+ expression);
|
||||
}
|
||||
return (TypeFilter) BeanUtils.instantiateClass(filterClass);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the {@link TypeFilter} for the given expression and {@link ClassLoader}.
|
||||
*
|
||||
* @param expression
|
||||
* @param classLoader
|
||||
* @return
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
abstract TypeFilter getFilter(String expression, ClassLoader classLoader) throws ClassNotFoundException;
|
||||
|
||||
/**
|
||||
* Returns the {@link FilterType} for the given type as {@link String}.
|
||||
*
|
||||
* @param typeString
|
||||
* @return
|
||||
* @throws IllegalArgumentException if no {@link FilterType} could be found for the given argument.
|
||||
*/
|
||||
static FilterType fromString(String typeString) {
|
||||
|
||||
for (FilterType filter : FilterType.values()) {
|
||||
if (filter.name().equalsIgnoreCase(typeString)) {
|
||||
return filter;
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Unsupported filter type: " + typeString);
|
||||
}
|
||||
}
|
||||
|
||||
public static enum Type {
|
||||
|
||||
INCLUDE("include-filter"), EXCLUDE("exclude-filter");
|
||||
|
||||
private String elementName;
|
||||
|
||||
private Type(String elementName) {
|
||||
this.elementName = elementName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Element} if the given {@link Node} is an {@link Element} and it's name equals the one of the
|
||||
* type.
|
||||
*
|
||||
* @param node
|
||||
* @return
|
||||
*/
|
||||
Element getElement(Node node) {
|
||||
|
||||
if (node.getNodeType() == Node.ELEMENT_NODE) {
|
||||
String localName = node.getLocalName();
|
||||
if (elementName.equals(localName)) {
|
||||
return (Element) node;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2011-12 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.convert;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.util.ClassTypeInformation;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link TypeInformationMapper} implementation that can be either set up using a {@link MappingContext} or manually set
|
||||
* up {@link Map} of {@link String} aliases to types. If a {@link MappingContext} is used the {@link Map} will be build
|
||||
* inspecting the {@link PersistentEntity} instances for type alias information.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class ConfigurableTypeInformationMapper implements TypeInformationMapper {
|
||||
|
||||
private final Map<TypeInformation<?>, Object> typeMap;
|
||||
|
||||
/**
|
||||
* Creates a new {@link ConfigurableTypeMapper} for the given type map.
|
||||
*
|
||||
* @param sourceTypeMap must not be {@literal null}.
|
||||
*/
|
||||
public ConfigurableTypeInformationMapper(Map<? extends Class<?>, String> sourceTypeMap) {
|
||||
|
||||
Assert.notNull(sourceTypeMap);
|
||||
this.typeMap = new HashMap<TypeInformation<?>, Object>(sourceTypeMap.size());
|
||||
|
||||
for (Entry<? extends Class<?>, String> entry : sourceTypeMap.entrySet()) {
|
||||
TypeInformation<?> key = ClassTypeInformation.from(entry.getKey());
|
||||
String value = entry.getValue();
|
||||
|
||||
if (typeMap.containsValue(value)) {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"Detected mapping ambiguity! String %s cannot be mapped to more than one type!", value));
|
||||
}
|
||||
|
||||
this.typeMap.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.convert.TypeInformationMapper#createAliasFor(org.springframework.data.util.TypeInformation)
|
||||
*/
|
||||
public Object createAliasFor(TypeInformation<?> type) {
|
||||
return typeMap.get(type);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.convert.TypeInformationMapper#resolveTypeFrom(java.lang.Object)
|
||||
*/
|
||||
public TypeInformation<?> resolveTypeFrom(Object alias) {
|
||||
|
||||
if (alias == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (Entry<TypeInformation<?>, Object> entry : typeMap.entrySet()) {
|
||||
if (entry.getValue().equals(alias)) {
|
||||
return entry.getKey();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.convert;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.util.ClassTypeInformation;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link MongoTypeMapper} allowing configuration of the key to lookup and store type
|
||||
* information in {@link DBObject}. The key defaults to {@link #DEFAULT_TYPE_KEY}. Actual type-to-{@link String}
|
||||
* conversion and back is done in {@link #getTypeString(TypeInformation)} or {@link #getTypeInformation(String)}
|
||||
* respectively.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class DefaultTypeMapper<S> implements TypeMapper<S> {
|
||||
|
||||
private final TypeAliasAccessor<S> accessor;
|
||||
private final List<? extends TypeInformationMapper> mappers;
|
||||
|
||||
/**
|
||||
* Creates a new {@link DefaultTypeMapper} using the given {@link TypeAliasAccessor}. It will use a
|
||||
* {@link SimpleTypeInformationMapper} to calculate type aliases.
|
||||
*
|
||||
* @param accessor must not be {@literal null}.
|
||||
*/
|
||||
public DefaultTypeMapper(TypeAliasAccessor<S> accessor) {
|
||||
this(accessor, Arrays.asList(SimpleTypeInformationMapper.INSTANCE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link DefaultTypeMapper} using the given {@link TypeAliasAccessor} and {@link TypeInformationMapper}
|
||||
* s.
|
||||
*
|
||||
* @param accessor must not be {@literal null}.
|
||||
* @param mappers must not be {@literal null}.
|
||||
*/
|
||||
public DefaultTypeMapper(TypeAliasAccessor<S> accessor, List<? extends TypeInformationMapper> mappers) {
|
||||
this(accessor, null, mappers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link DefaultTypeMapper} using the given {@link TypeAliasAccessor}, {@link MappingContext} and
|
||||
* additional {@link TypeInformationMapper}s. Will register a {@link MappingContextTypeInformationMapper} before the
|
||||
* given additional mappers.
|
||||
*
|
||||
* @param accessor must not be {@literal null}.
|
||||
* @param mappingContext
|
||||
* @param additionalMappers must not be {@literal null}.
|
||||
*/
|
||||
public DefaultTypeMapper(TypeAliasAccessor<S> accessor,
|
||||
MappingContext<? extends PersistentEntity<?, ?>, ?> mappingContext,
|
||||
List<? extends TypeInformationMapper> additionalMappers) {
|
||||
|
||||
Assert.notNull(accessor);
|
||||
Assert.notNull(additionalMappers);
|
||||
|
||||
List<TypeInformationMapper> mappers = new ArrayList<TypeInformationMapper>(additionalMappers.size() + 1);
|
||||
if (mappingContext != null) {
|
||||
mappers.add(new MappingContextTypeInformationMapper(mappingContext));
|
||||
}
|
||||
mappers.addAll(additionalMappers);
|
||||
|
||||
this.mappers = Collections.unmodifiableList(mappers);
|
||||
this.accessor = accessor;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.convert.TypeMapper#readType(java.lang.Object)
|
||||
*/
|
||||
public TypeInformation<?> readType(S source) {
|
||||
|
||||
Assert.notNull(source);
|
||||
Object alias = accessor.readAliasFrom(source);
|
||||
|
||||
if (alias == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (TypeInformationMapper mapper : mappers) {
|
||||
TypeInformation<?> type = mapper.resolveTypeFrom(alias);
|
||||
|
||||
if (type != null) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.convert.TypeMapper#readType(java.lang.Object, org.springframework.data.util.TypeInformation)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> TypeInformation<? extends T> readType(S source, TypeInformation<T> basicType) {
|
||||
|
||||
Assert.notNull(source);
|
||||
Class<?> documentsTargetType = getDefaultedTypeToBeUsed(source);
|
||||
|
||||
if (documentsTargetType == null) {
|
||||
return basicType;
|
||||
}
|
||||
|
||||
Class<T> rawType = basicType == null ? null : basicType.getType();
|
||||
|
||||
boolean isMoreConcreteCustomType = rawType == null ? true : rawType.isAssignableFrom(documentsTargetType)
|
||||
&& !rawType.equals(documentsTargetType);
|
||||
return isMoreConcreteCustomType ? (TypeInformation<? extends T>) ClassTypeInformation.from(documentsTargetType)
|
||||
: basicType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type discovered through {@link #readType(Object)} but defaulted to the one returned by
|
||||
* {@link #getFallbackTypeFor(Object)}.
|
||||
*
|
||||
* @param source
|
||||
* @return
|
||||
*/
|
||||
private Class<?> getDefaultedTypeToBeUsed(S source) {
|
||||
|
||||
TypeInformation<?> documentsTargetTypeInformation = readType(source);
|
||||
documentsTargetTypeInformation = documentsTargetTypeInformation == null ? getFallbackTypeFor(source)
|
||||
: documentsTargetTypeInformation;
|
||||
return documentsTargetTypeInformation == null ? null : documentsTargetTypeInformation.getType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type fallback {@link TypeInformation} in case none could be extracted from the given source.
|
||||
*
|
||||
* @param source will never be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
protected TypeInformation<?> getFallbackTypeFor(S source) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.convert.TypeMapper#writeType(java.lang.Class, java.lang.Object)
|
||||
*/
|
||||
public void writeType(Class<?> type, S dbObject) {
|
||||
writeType(ClassTypeInformation.from(type), dbObject);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.convert.TypeMapper#writeType(org.springframework.data.util.TypeInformation, java.lang.Object)
|
||||
*/
|
||||
public void writeType(TypeInformation<?> info, S sink) {
|
||||
|
||||
Assert.notNull(info);
|
||||
|
||||
for (TypeInformationMapper mapper : mappers) {
|
||||
Object alias = mapper.createAliasFor(info);
|
||||
if (alias != null) {
|
||||
accessor.writeTypeTo(sink, alias);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2011-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.convert;
|
||||
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
|
||||
/**
|
||||
* Combined {@link EntityReader} and {@link EntityWriter} and add the ability to access a {@link MappingContext} and
|
||||
* {@link ConversionService}.
|
||||
*
|
||||
* @param <E> the concrete {@link PersistentEntity} implementation the converter is based on.
|
||||
* @param <P> the concrete {@link PersistentProperty} implementation the converter is based on.
|
||||
* @param <T> the most common type the {@link EntityConverter} can actually convert.
|
||||
* @param <S> the store specific source and sink an {@link EntityConverter} can deal with.
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface EntityConverter<E extends PersistentEntity<?, P>, P extends PersistentProperty<P>, T, S> extends
|
||||
EntityReader<T, S>, EntityWriter<T, S> {
|
||||
|
||||
/**
|
||||
* Returns the underlying {@link MappingContext} used by the converter.
|
||||
*
|
||||
* @return never {@literal null}
|
||||
*/
|
||||
MappingContext<? extends E, P> getMappingContext();
|
||||
|
||||
/**
|
||||
* Returns the underlying {@link ConversionService} used by the converter.
|
||||
*
|
||||
* @return never {@literal null}.
|
||||
*/
|
||||
ConversionService getConversionService();
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.convert;
|
||||
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.data.mapping.model.ParameterValueProvider;
|
||||
|
||||
/**
|
||||
* SPI to abstract strategies to create instances for {@link PersistentEntity}s.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface EntityInstantiator {
|
||||
|
||||
/**
|
||||
* Creates a new instance of the given entity using the given source to pull data from.
|
||||
*
|
||||
* @param entity will not be {@literal null}.
|
||||
* @param provider will not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
<T, E extends PersistentEntity<? extends T, P>, P extends PersistentProperty<P>> T createInstance(E entity,
|
||||
ParameterValueProvider<P> provider);
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.convert;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Simple value object allowing access to {@link EntityInstantiator} instances for a given type falling back to a
|
||||
* default one.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class EntityInstantiators {
|
||||
|
||||
private final EntityInstantiator fallback;
|
||||
private final Map<Class<?>, EntityInstantiator> customInstantiators;
|
||||
|
||||
/**
|
||||
* Creates a new {@link EntityInstantiators} using the default fallback instantiator and no custom ones.
|
||||
*/
|
||||
public EntityInstantiators() {
|
||||
this(Collections.<Class<?>, EntityInstantiator> emptyMap());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link EntityInstantiators} using the given {@link EntityInstantiator} as fallback.
|
||||
*
|
||||
* @param fallback must not be {@literal null}.
|
||||
*/
|
||||
public EntityInstantiators(EntityInstantiator fallback) {
|
||||
this(fallback, Collections.<Class<?>, EntityInstantiator> emptyMap());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link EntityInstantiators} using the default fallback instantiator and the given custom ones.
|
||||
*
|
||||
* @param customInstantiators must not be {@literal null}.
|
||||
*/
|
||||
public EntityInstantiators(Map<Class<?>, EntityInstantiator> customInstantiators) {
|
||||
this(ReflectionEntityInstantiator.INSTANCE, customInstantiators);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link EntityInstantiator} using the given fallback {@link EntityInstantiator} and the given custom
|
||||
* ones.
|
||||
*
|
||||
* @param fallback must not be {@literal null}.
|
||||
* @param customInstantiators must not be {@literal null}.
|
||||
*/
|
||||
public EntityInstantiators(EntityInstantiator defaultInstantiator,
|
||||
Map<Class<?>, EntityInstantiator> customInstantiators) {
|
||||
|
||||
Assert.notNull(defaultInstantiator);
|
||||
Assert.notNull(customInstantiators);
|
||||
|
||||
this.fallback = defaultInstantiator;
|
||||
this.customInstantiators = customInstantiators;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link EntityInstantiator} to be used to create the given {@link PersistentEntity}.
|
||||
*
|
||||
* @param entity must not be {@literal null}.
|
||||
* @return will never be {@literal null}.
|
||||
*/
|
||||
public EntityInstantiator getInstantiatorFor(PersistentEntity<?, ?> entity) {
|
||||
|
||||
Assert.notNull(entity);
|
||||
Class<?> type = entity.getType();
|
||||
|
||||
if (!customInstantiators.containsKey(type)) {
|
||||
return fallback;
|
||||
}
|
||||
|
||||
EntityInstantiator instantiator = customInstantiators.get(entity.getType());
|
||||
return instantiator == null ? fallback : instantiator;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.convert;
|
||||
|
||||
/**
|
||||
* Interface to read object from store specific sources.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface EntityReader<T, S> {
|
||||
|
||||
/**
|
||||
* Reads the given source into the given type.
|
||||
*
|
||||
* @param type they type to convert the given source to.
|
||||
* @param source the source to create an object of the given type from.
|
||||
* @return
|
||||
*/
|
||||
<R extends T> R read(Class<R> type, S source);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.convert;
|
||||
|
||||
/**
|
||||
* Interface to write objects into store specific sinks.
|
||||
*
|
||||
* @param <T> the entity type the converter can handle
|
||||
* @param <S> the store specific sink the converter is able to write to
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface EntityWriter<T, S> {
|
||||
|
||||
void write(T source, S sink);
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright 2011-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.convert;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link TypeInformationMapper} implementation that can be either set up using a {@link MappingContext} or manually set
|
||||
* up {@link Map} of {@link String} aliases to types. If a {@link MappingContext} is used the {@link Map} will be build
|
||||
* inspecting the {@link PersistentEntity} instances for type alias information.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MappingContextTypeInformationMapper implements TypeInformationMapper {
|
||||
|
||||
private final Map<TypeInformation<?>, Object> typeMap;
|
||||
private final MappingContext<? extends PersistentEntity<?, ?>, ?> mappingContext;
|
||||
|
||||
/**
|
||||
* Creates a {@link MappingContextTypeInformationMapper} from the given {@link MappingContext}. Inspects all
|
||||
* {@link PersistentEntity} instances for alias information and builds a {@link Map} of aliases to types from it.
|
||||
*
|
||||
* @param mappingContext must not be {@literal null}.
|
||||
*/
|
||||
public MappingContextTypeInformationMapper(MappingContext<? extends PersistentEntity<?, ?>, ?> mappingContext) {
|
||||
|
||||
Assert.notNull(mappingContext);
|
||||
|
||||
this.typeMap = new HashMap<TypeInformation<?>, Object>();
|
||||
this.mappingContext = mappingContext;
|
||||
|
||||
for (PersistentEntity<?, ?> entity : mappingContext.getPersistentEntities()) {
|
||||
safelyAddToCache(entity.getTypeInformation(), entity.getTypeAlias());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.convert.TypeInformationMapper#createAliasFor(org.springframework.data.util.TypeInformation)
|
||||
*/
|
||||
public Object createAliasFor(TypeInformation<?> type) {
|
||||
|
||||
Object key = typeMap.get(type);
|
||||
|
||||
if (key != null) {
|
||||
return key;
|
||||
}
|
||||
|
||||
PersistentEntity<?, ?> entity = mappingContext.getPersistentEntity(type);
|
||||
|
||||
if (entity == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Object alias = entity.getTypeAlias();
|
||||
safelyAddToCache(type, alias);
|
||||
|
||||
return alias;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given alias to the cache in a {@literal null}-safe manner.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param alias can be {@literal null}.
|
||||
*/
|
||||
private void safelyAddToCache(TypeInformation<?> key, Object alias) {
|
||||
|
||||
if (alias == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeMap.containsValue(alias)) {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"Detected mapping ambiguity! String %s cannot be mapped to more than one type!", alias));
|
||||
}
|
||||
|
||||
typeMap.put(key, alias);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.convert.TypeInformationMapper#resolveTypeFrom(java.lang.Object)
|
||||
*/
|
||||
public TypeInformation<?> resolveTypeFrom(Object alias) {
|
||||
|
||||
if (alias == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (Entry<TypeInformation<?>, Object> entry : typeMap.entrySet()) {
|
||||
if (entry.getValue().equals(alias)) {
|
||||
return entry.getKey();
|
||||
}
|
||||
}
|
||||
|
||||
for (PersistentEntity<?, ?> entity : mappingContext.getPersistentEntities()) {
|
||||
if (alias.equals(entity.getTypeAlias())) {
|
||||
return entity.getTypeInformation();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.convert;
|
||||
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
|
||||
/**
|
||||
* Annotation to clarify intended usage of a {@link Converter} as reading converter in case the conversion types leave
|
||||
* room for disambiguation.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Target(TYPE)
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface ReadingConverter {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.convert;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.BeanInstantiationException;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.data.mapping.PreferredConstructor;
|
||||
import org.springframework.data.mapping.PreferredConstructor.Parameter;
|
||||
import org.springframework.data.mapping.model.MappingInstantiationException;
|
||||
import org.springframework.data.mapping.model.ParameterValueProvider;
|
||||
|
||||
/**
|
||||
* {@link EntityInstantiator} that uses the {@link PersistentEntity}'s {@link PreferredConstructor} to instantiate an
|
||||
* instance of the entity via reflection.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public enum ReflectionEntityInstantiator implements EntityInstantiator {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T, E extends PersistentEntity<? extends T, P>, P extends PersistentProperty<P>> T createInstance(E entity,
|
||||
ParameterValueProvider<P> provider) {
|
||||
|
||||
PreferredConstructor<? extends T, P> constructor = entity.getPersistenceConstructor();
|
||||
|
||||
if (constructor == null) {
|
||||
|
||||
try {
|
||||
Class<?> clazz = entity.getType();
|
||||
if (clazz.isArray()) {
|
||||
Class<?> ctype = clazz;
|
||||
int dims = 0;
|
||||
while (ctype.isArray()) {
|
||||
ctype = ctype.getComponentType();
|
||||
dims++;
|
||||
}
|
||||
return (T) Array.newInstance(clazz, dims);
|
||||
} else {
|
||||
return BeanUtils.instantiateClass(entity.getType());
|
||||
}
|
||||
} catch (BeanInstantiationException e) {
|
||||
throw new MappingInstantiationException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
List<Object> params = new ArrayList<Object>();
|
||||
if (null != provider && constructor.hasParameters()) {
|
||||
for (Parameter<?, P> parameter : constructor.getParameters()) {
|
||||
params.add(provider.getParameterValue(parameter));
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return BeanUtils.instantiateClass(constructor.getConstructor(), params.toArray());
|
||||
} catch (BeanInstantiationException e) {
|
||||
throw new MappingInstantiationException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.convert;
|
||||
|
||||
import org.springframework.data.util.ClassTypeInformation;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Basic {@link TypeInformationMapper} implementation that interprets the alias handles as fully qualified class name
|
||||
* and tries to load a class with the given name to build {@link TypeInformation}. Returns the fully qualified class
|
||||
* name for alias creation.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class SimpleTypeInformationMapper implements TypeInformationMapper {
|
||||
|
||||
public static final SimpleTypeInformationMapper INSTANCE = new SimpleTypeInformationMapper();
|
||||
|
||||
/**
|
||||
* Returns the {@link TypeInformation} that shall be used when the given {@link String} value is found as type hint.
|
||||
* The implementation will simply interpret the given value as fully-qualified class name and try to load the class.
|
||||
* Will return {@literal null} in case the given {@link String} is empty.
|
||||
*
|
||||
* @param value the type to load, must not be {@literal null}.
|
||||
* @return the type to be used for the given {@link String} representation or {@literal null} if nothing found or the
|
||||
* class cannot be loaded.
|
||||
*/
|
||||
public TypeInformation<?> resolveTypeFrom(Object alias) {
|
||||
|
||||
if (!(alias instanceof String)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String value = (String) alias;
|
||||
|
||||
if (!StringUtils.hasText(value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return ClassTypeInformation.from(ClassUtils.forName(value, null));
|
||||
} catch (ClassNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn the given type information into the String representation that shall be stored. Default implementation simply
|
||||
* returns the fully-qualified class name.
|
||||
*
|
||||
* @param typeInformation must not be {@literal null}.
|
||||
* @return the String representation to be stored or {@literal null} if no type information shall be stored.
|
||||
*/
|
||||
public String createAliasFor(TypeInformation<?> type) {
|
||||
|
||||
return type.getType().getName();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.convert;
|
||||
|
||||
/**
|
||||
* Interface to abstract implementations of how to access a type alias from a given source or sink.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface TypeAliasAccessor<S> {
|
||||
|
||||
/**
|
||||
* Reads the type alias to be used from the given source.
|
||||
*
|
||||
* @param source
|
||||
* @return can be {@literal null} in case no alias was found.
|
||||
*/
|
||||
Object readAliasFrom(S source);
|
||||
|
||||
/**
|
||||
* Writes the given type alias to the given sink.
|
||||
*
|
||||
* @param sink
|
||||
* @param alias
|
||||
*/
|
||||
void writeTypeTo(S sink, Object alias);
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.convert;
|
||||
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
|
||||
/**
|
||||
* Interface to abstract the mapping from a type alias to the actual type.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface TypeInformationMapper {
|
||||
|
||||
/**
|
||||
* Returns the actual {@link TypeInformation} to be used for the given alias.
|
||||
*
|
||||
* @param alias can be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
TypeInformation<?> resolveTypeFrom(Object alias);
|
||||
|
||||
/**
|
||||
* Returns the alias to be used for the given {@link TypeInformation}.
|
||||
*
|
||||
* @param type
|
||||
* @return
|
||||
*/
|
||||
Object createAliasFor(TypeInformation<?> type);
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.convert;
|
||||
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
|
||||
/**
|
||||
* Interface to define strategies how to store type information in a store specific sink or source.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface TypeMapper<S> {
|
||||
|
||||
/**
|
||||
* Reads the {@link TypeInformation} from the given source.
|
||||
*
|
||||
* @param source must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
TypeInformation<?> readType(S source);
|
||||
|
||||
/**
|
||||
* Returns the {@link TypeInformation} from the given source if it is a more concrete type than the given default one.
|
||||
*
|
||||
* @param source must not be {@literal null}.
|
||||
* @param defaultType
|
||||
* @return
|
||||
*/
|
||||
<T> TypeInformation<? extends T> readType(S source, TypeInformation<T> defaultType);
|
||||
|
||||
/**
|
||||
* Writes type information for the given type into the given sink.
|
||||
*
|
||||
* @param type must not be {@literal null}.
|
||||
* @param dbObject must not be {@literal null}.
|
||||
*/
|
||||
void writeType(Class<?> type, S dbObject);
|
||||
|
||||
/**
|
||||
* Writes type information for the given {@link TypeInformation} into the given sink.
|
||||
*
|
||||
* @param type must not be {@literal null}.
|
||||
* @param dbObject must not be {@literal null}.
|
||||
*/
|
||||
void writeType(TypeInformation<?> type, S dbObject);
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.convert;
|
||||
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
|
||||
/**
|
||||
* Annotation to clarify intended usage of a {@link Converter} as writing converter in case the conversion types leave
|
||||
* room for disambiguation.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Target(TYPE)
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface WritingConverter {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* General purpose conversion framework to read objects from a data store abstraction and write it back.
|
||||
*
|
||||
* @see org.springframework.data.convert.EntityConverter
|
||||
*/
|
||||
package org.springframework.data.convert;
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.crossstore;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
|
||||
/**
|
||||
* Interface representing the set of changes in an entity.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Thomas Risberg
|
||||
*/
|
||||
public interface ChangeSet {
|
||||
|
||||
<T> T get(String key, Class<T> requiredClass, ConversionService cs);
|
||||
|
||||
void set(String key, Object o);
|
||||
|
||||
Map<String, Object> getValues();
|
||||
|
||||
Object removeProperty(String k);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.crossstore;
|
||||
|
||||
/**
|
||||
* Interface introduced to objects exposing ChangeSet information
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Thomas Risberg
|
||||
*/
|
||||
public interface ChangeSetBacked {
|
||||
|
||||
ChangeSet getChangeSet();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.crossstore;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
|
||||
public class ChangeSetBackedTransactionSynchronization implements TransactionSynchronization {
|
||||
|
||||
protected final Logger log = LoggerFactory.getLogger(getClass());
|
||||
|
||||
private final ChangeSetPersister<Object> changeSetPersister;
|
||||
private final ChangeSetBacked entity;
|
||||
private int changeSetTxStatus = -1;
|
||||
|
||||
public ChangeSetBackedTransactionSynchronization(ChangeSetPersister<Object> changeSetPersister, ChangeSetBacked entity) {
|
||||
this.changeSetPersister = changeSetPersister;
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
public void afterCommit() {
|
||||
log.debug("After Commit called for " + entity);
|
||||
changeSetPersister.persistState(entity, entity.getChangeSet());
|
||||
changeSetTxStatus = 0;
|
||||
}
|
||||
|
||||
public void afterCompletion(int status) {
|
||||
log.debug("After Completion called with status = " + status);
|
||||
if (changeSetTxStatus == 0) {
|
||||
if (status == STATUS_COMMITTED) {
|
||||
// this is good
|
||||
log.debug("ChangedSetBackedTransactionSynchronization completed successfully for " + this.entity);
|
||||
} else {
|
||||
// this could be bad - TODO: compensate
|
||||
log.error("ChangedSetBackedTransactionSynchronization failed for " + this.entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void beforeCommit(boolean readOnly) {
|
||||
}
|
||||
|
||||
public void beforeCompletion() {
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
}
|
||||
|
||||
public void resume() {
|
||||
throw new IllegalStateException(
|
||||
"ChangedSetBackedTransactionSynchronization does not support transaction suspension currently.");
|
||||
}
|
||||
|
||||
public void suspend() {
|
||||
throw new IllegalStateException(
|
||||
"ChangedSetBackedTransactionSynchronization does not support transaction suspension currently.");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.crossstore;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
|
||||
/**
|
||||
* Interface to be implemented by classes that can synchronize between data stores and ChangeSets.
|
||||
*
|
||||
* @param <K> entity key
|
||||
* @author Rod Johnson
|
||||
*/
|
||||
public interface ChangeSetPersister<K> {
|
||||
|
||||
String ID_KEY = "_id";
|
||||
String CLASS_KEY = "_class";
|
||||
|
||||
/**
|
||||
* TODO how to tell when not found? throw exception?
|
||||
*/
|
||||
void getPersistentState(Class<? extends ChangeSetBacked> entityClass, K key, ChangeSet changeSet)
|
||||
throws DataAccessException, NotFoundException;
|
||||
|
||||
/**
|
||||
* Return id
|
||||
*
|
||||
* @param entity
|
||||
* @param cs
|
||||
* @return
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
K getPersistentId(ChangeSetBacked entity, ChangeSet cs) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Return key
|
||||
*
|
||||
* @param entity
|
||||
* @param cs Key may be null if not persistent
|
||||
* @return
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
K persistState(ChangeSetBacked entity, ChangeSet cs) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Exception thrown in alternate control flow if getPersistentState finds no entity data.
|
||||
*/
|
||||
class NotFoundException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = -8604207973816331140L;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.crossstore;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
|
||||
/**
|
||||
* Simple ChangeSet implementation backed by a HashMap.
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
* @author Rod Johnson
|
||||
*/
|
||||
public class HashMapChangeSet implements ChangeSet {
|
||||
|
||||
private final Map<String, Object> values;
|
||||
|
||||
public HashMapChangeSet(Map<String, Object> values) {
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
public HashMapChangeSet() {
|
||||
this(new HashMap<String, Object>());
|
||||
}
|
||||
|
||||
public void set(String key, Object o) {
|
||||
values.put(key, o);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "HashMapChangeSet: values=[" + values + "]";
|
||||
}
|
||||
|
||||
public Map<String, Object> getValues() {
|
||||
return Collections.unmodifiableMap(values);
|
||||
}
|
||||
|
||||
public Object removeProperty(String k) {
|
||||
return this.values.remove(k);
|
||||
}
|
||||
|
||||
public <T> T get(String key, Class<T> requiredClass, ConversionService conversionService) {
|
||||
return conversionService.convert(values.get(key), requiredClass);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* Support for cross-store persistence.
|
||||
*/
|
||||
package org.springframework.data.crossstore;
|
||||
87
src/main/java/org/springframework/data/domain/Auditable.java
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 2008-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
/**
|
||||
* Interface for auditable entities. Allows storing and retrieving creation and modification information. The changing
|
||||
* instance (typically some user) is to be defined by a generics definition.
|
||||
*
|
||||
* @param <U> the auditing type. Typically some kind of user.
|
||||
* @param <ID> the type of the audited type's identifier
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface Auditable<U, ID extends Serializable> extends Persistable<ID> {
|
||||
|
||||
/**
|
||||
* Returns the user who created this entity.
|
||||
*
|
||||
* @return the createdBy
|
||||
*/
|
||||
U getCreatedBy();
|
||||
|
||||
/**
|
||||
* Sets the user who created this entity.
|
||||
*
|
||||
* @param createdBy the creating entity to set
|
||||
*/
|
||||
void setCreatedBy(final U createdBy);
|
||||
|
||||
/**
|
||||
* Returns the creation date of the entity.
|
||||
*
|
||||
* @return the createdDate
|
||||
*/
|
||||
DateTime getCreatedDate();
|
||||
|
||||
/**
|
||||
* Sets the creation date of the entity.
|
||||
*
|
||||
* @param creationDate the creation date to set
|
||||
*/
|
||||
void setCreatedDate(final DateTime creationDate);
|
||||
|
||||
/**
|
||||
* Returns the user who modified the entity lastly.
|
||||
*
|
||||
* @return the lastModifiedBy
|
||||
*/
|
||||
U getLastModifiedBy();
|
||||
|
||||
/**
|
||||
* Sets the user who modified the entity lastly.
|
||||
*
|
||||
* @param lastModifiedBy the last modifying entity to set
|
||||
*/
|
||||
void setLastModifiedBy(final U lastModifiedBy);
|
||||
|
||||
/**
|
||||
* Returns the date of the last modification.
|
||||
*
|
||||
* @return the lastModifiedDate
|
||||
*/
|
||||
DateTime getLastModifiedDate();
|
||||
|
||||
/**
|
||||
* Sets the date of the last modification.
|
||||
*
|
||||
* @param lastModifiedDate the date of the last modification to set
|
||||
*/
|
||||
void setLastModifiedDate(final DateTime lastModifiedDate);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2008-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.domain;
|
||||
|
||||
/**
|
||||
* Interface for components that are aware of the application's current auditor. This will be some kind of user mostly.
|
||||
*
|
||||
* @param <T> the type of the auditing instance
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface AuditorAware<T> {
|
||||
|
||||
/**
|
||||
* Returns the current auditor of the application.
|
||||
*
|
||||
* @return the current auditor
|
||||
*/
|
||||
T getCurrentAuditor();
|
||||
}
|
||||
120
src/main/java/org/springframework/data/domain/Page.java
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright 2008-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.domain;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A page is a sublist of a list of objects. It allows gain information about the position of it in the containing
|
||||
* entire list.
|
||||
*
|
||||
* @param <T>
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface Page<T> extends Iterable<T> {
|
||||
|
||||
/**
|
||||
* Returns the number of the current page. Is always positive and less that {@code Page#getTotalPages()}.
|
||||
*
|
||||
* @return the number of the current page
|
||||
*/
|
||||
int getNumber();
|
||||
|
||||
/**
|
||||
* Returns the size of the page.
|
||||
*
|
||||
* @return the size of the page
|
||||
*/
|
||||
int getSize();
|
||||
|
||||
/**
|
||||
* Returns the number of total pages.
|
||||
*
|
||||
* @return the number of toral pages
|
||||
*/
|
||||
int getTotalPages();
|
||||
|
||||
/**
|
||||
* Returns the number of elements currently on this page.
|
||||
*
|
||||
* @return the number of elements currently on this page
|
||||
*/
|
||||
int getNumberOfElements();
|
||||
|
||||
/**
|
||||
* Returns the total amount of elements.
|
||||
*
|
||||
* @return the total amount of elements
|
||||
*/
|
||||
long getTotalElements();
|
||||
|
||||
/**
|
||||
* Returns if there is a previous page.
|
||||
*
|
||||
* @return if there is a previous page
|
||||
*/
|
||||
boolean hasPreviousPage();
|
||||
|
||||
/**
|
||||
* Returns whether the current page is the first one.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean isFirstPage();
|
||||
|
||||
/**
|
||||
* Returns if there is a next page.
|
||||
*
|
||||
* @return if there is a next page
|
||||
*/
|
||||
boolean hasNextPage();
|
||||
|
||||
/**
|
||||
* Returns whether the current page is the last one.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean isLastPage();
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Iterable#iterator()
|
||||
*/
|
||||
Iterator<T> iterator();
|
||||
|
||||
/**
|
||||
* Returns the page content as {@link List}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<T> getContent();
|
||||
|
||||
/**
|
||||
* Returns whether the {@link Page} has content at all.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean hasContent();
|
||||
|
||||
/**
|
||||
* Returns the sorting parameters for the page.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Sort getSort();
|
||||
}
|
||||
255
src/main/java/org/springframework/data/domain/PageImpl.java
Normal file
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* Copyright 2008-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Basic {@code Page} implementation.
|
||||
*
|
||||
* @param <T> the type of which the page consists.
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class PageImpl<T> implements Page<T>, Serializable {
|
||||
|
||||
private static final long serialVersionUID = 867755909294344406L;
|
||||
|
||||
private final List<T> content = new ArrayList<T>();
|
||||
private final Pageable pageable;
|
||||
private final long total;
|
||||
|
||||
/**
|
||||
* Constructor of {@code PageImpl}.
|
||||
*
|
||||
* @param content the content of this page
|
||||
* @param pageable the paging information
|
||||
* @param total the total amount of items available
|
||||
*/
|
||||
public PageImpl(List<T> content, Pageable pageable, long total) {
|
||||
|
||||
if (null == content) {
|
||||
throw new IllegalArgumentException("Content must not be null!");
|
||||
}
|
||||
|
||||
this.content.addAll(content);
|
||||
this.total = total;
|
||||
this.pageable = pageable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link PageImpl} with the given content. This will result in the created {@link Page} being identical
|
||||
* to the entire {@link List}.
|
||||
*
|
||||
* @param content
|
||||
*/
|
||||
public PageImpl(List<T> content) {
|
||||
|
||||
this(content, null, (null == content) ? 0 : content.size());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.domain.Page#getNumber()
|
||||
*/
|
||||
public int getNumber() {
|
||||
|
||||
return pageable == null ? 0 : pageable.getPageNumber();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.domain.Page#getSize()
|
||||
*/
|
||||
public int getSize() {
|
||||
|
||||
return pageable == null ? 0 : pageable.getPageSize();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.domain.Page#getTotalPages()
|
||||
*/
|
||||
public int getTotalPages() {
|
||||
|
||||
return getSize() == 0 ? 0 : (int) Math.ceil((double) total / (double) getSize());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.domain.Page#getNumberOfElements()
|
||||
*/
|
||||
public int getNumberOfElements() {
|
||||
|
||||
return content.size();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.domain.Page#getTotalElements()
|
||||
*/
|
||||
public long getTotalElements() {
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.domain.Page#hasPreviousPage()
|
||||
*/
|
||||
public boolean hasPreviousPage() {
|
||||
|
||||
return getNumber() > 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.domain.Page#isFirstPage()
|
||||
*/
|
||||
public boolean isFirstPage() {
|
||||
|
||||
return !hasPreviousPage();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.domain.Page#hasNextPage()
|
||||
*/
|
||||
public boolean hasNextPage() {
|
||||
|
||||
return ((getNumber() + 1) * getSize()) < total;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.domain.Page#isLastPage()
|
||||
*/
|
||||
public boolean isLastPage() {
|
||||
|
||||
return !hasNextPage();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.domain.Page#iterator()
|
||||
*/
|
||||
public Iterator<T> iterator() {
|
||||
|
||||
return content.iterator();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.domain.Page#asList()
|
||||
*/
|
||||
public List<T> getContent() {
|
||||
|
||||
return Collections.unmodifiableList(content);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.domain.Page#hasContent()
|
||||
*/
|
||||
public boolean hasContent() {
|
||||
|
||||
return !content.isEmpty();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.domain.Page#getSort()
|
||||
*/
|
||||
public Sort getSort() {
|
||||
|
||||
return pageable == null ? null : pageable.getSort();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
String contentType = "UNKNOWN";
|
||||
|
||||
if (content.size() > 0) {
|
||||
contentType = content.get(0).getClass().getName();
|
||||
}
|
||||
|
||||
return String.format("Page %s of %d containing %s instances", getNumber(), getTotalPages(), contentType);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof PageImpl<?>)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PageImpl<?> that = (PageImpl<?>) obj;
|
||||
|
||||
boolean totalEqual = this.total == that.total;
|
||||
boolean contentEqual = this.content.equals(that.content);
|
||||
boolean pageableEqual = this.pageable == null ? that.pageable == null : this.pageable.equals(that.pageable);
|
||||
|
||||
return totalEqual && contentEqual && pageableEqual;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
int result = 17;
|
||||
|
||||
result = 31 * result + (int) (total ^ total >>> 32);
|
||||
result = 31 * result + (pageable == null ? 0 : pageable.hashCode());
|
||||
result = 31 * result + content.hashCode();
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
164
src/main/java/org/springframework/data/domain/PageRequest.java
Normal file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright 2008-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
|
||||
/**
|
||||
* Basic Java Bean implementation of {@code Pageable}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class PageRequest implements Pageable, Serializable {
|
||||
|
||||
private static final long serialVersionUID = 8280485938848398236L;
|
||||
|
||||
private final int page;
|
||||
private final int size;
|
||||
private final Sort sort;
|
||||
|
||||
/**
|
||||
* Creates a new {@link PageRequest}. Pages are zero indexed, thus providing 0 for {@code page} will return the first
|
||||
* page.
|
||||
*
|
||||
* @param size
|
||||
* @param page
|
||||
*/
|
||||
public PageRequest(int page, int size) {
|
||||
|
||||
this(page, size, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link PageRequest} with sort parameters applied.
|
||||
*
|
||||
* @param page
|
||||
* @param size
|
||||
* @param direction
|
||||
* @param properties
|
||||
*/
|
||||
public PageRequest(int page, int size, Direction direction, String... properties) {
|
||||
|
||||
this(page, size, new Sort(direction, properties));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link PageRequest} with sort parameters applied.
|
||||
*
|
||||
* @param page
|
||||
* @param size
|
||||
* @param sort
|
||||
*/
|
||||
public PageRequest(int page, int size, Sort sort) {
|
||||
|
||||
if (0 > page) {
|
||||
throw new IllegalArgumentException("Page index must not be less than zero!");
|
||||
}
|
||||
|
||||
if (0 >= size) {
|
||||
throw new IllegalArgumentException("Page size must not be less than or equal to zero!");
|
||||
}
|
||||
|
||||
this.page = page;
|
||||
this.size = size;
|
||||
this.sort = sort;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.domain.Pageable#getPageSize()
|
||||
*/
|
||||
public int getPageSize() {
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.domain.Pageable#getPageNumber()
|
||||
*/
|
||||
public int getPageNumber() {
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.domain.Pageable#getFirstItem()
|
||||
*/
|
||||
public int getOffset() {
|
||||
|
||||
return page * size;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.domain.Pageable#getSort()
|
||||
*/
|
||||
public Sort getSort() {
|
||||
|
||||
return sort;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof PageRequest)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PageRequest that = (PageRequest) obj;
|
||||
|
||||
boolean pageEqual = this.page == that.page;
|
||||
boolean sizeEqual = this.size == that.size;
|
||||
|
||||
boolean sortEqual = this.sort == null ? that.sort == null : this.sort.equals(that.sort);
|
||||
|
||||
return pageEqual && sizeEqual && sortEqual;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
int result = 17;
|
||||
|
||||
result = 31 * result + page;
|
||||
result = 31 * result + size;
|
||||
result = 31 * result + (null == sort ? 0 : sort.hashCode());
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
52
src/main/java/org/springframework/data/domain/Pageable.java
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2008-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.domain;
|
||||
|
||||
/**
|
||||
* Abstract interface for pagination information.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface Pageable {
|
||||
|
||||
/**
|
||||
* Returns the page to be returned.
|
||||
*
|
||||
* @return the page to be returned.
|
||||
*/
|
||||
int getPageNumber();
|
||||
|
||||
/**
|
||||
* Returns the number of items to be returned.
|
||||
*
|
||||
* @return the number of items of that page
|
||||
*/
|
||||
int getPageSize();
|
||||
|
||||
/**
|
||||
* Returns the offset to be taken according to the underlying page and page size.
|
||||
*
|
||||
* @return the offset to be taken
|
||||
*/
|
||||
int getOffset();
|
||||
|
||||
/**
|
||||
* Returns the sorting parameters.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Sort getSort();
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2008-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Simple interface for entities.
|
||||
*
|
||||
* @param <ID> the type of the identifier
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface Persistable<ID extends Serializable> extends Serializable {
|
||||
|
||||
/**
|
||||
* Returns the id of the entity.
|
||||
*
|
||||
* @return the id
|
||||
*/
|
||||
ID getId();
|
||||
|
||||
/**
|
||||
* Returns if the {@code Persistable} is new or was persisted already.
|
||||
*
|
||||
* @return if the object is new
|
||||
*/
|
||||
boolean isNew();
|
||||
}
|
||||
359
src/main/java/org/springframework/data/domain/Sort.java
Normal file
@@ -0,0 +1,359 @@
|
||||
/*
|
||||
* Copyright 2008-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Sort option for queries. You have to provide at least a list of properties to sort for that must not include
|
||||
* {@literal null} or empty strings. The direction defaults to {@link Sort#DEFAULT_DIRECTION}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class Sort implements Iterable<org.springframework.data.domain.Sort.Order>, Serializable {
|
||||
|
||||
private static final long serialVersionUID = 5737186511678863905L;
|
||||
public static final Direction DEFAULT_DIRECTION = Direction.ASC;
|
||||
|
||||
private final List<Order> orders;
|
||||
|
||||
/**
|
||||
* Creates a new {@link Sort} instance using the given {@link Order}s.
|
||||
*
|
||||
* @param orders must not be {@literal null}.
|
||||
*/
|
||||
public Sort(Order... orders) {
|
||||
this(Arrays.asList(orders));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Sort} instance.
|
||||
*
|
||||
* @param orders must not be {@literal null} or contain {@literal null}.
|
||||
*/
|
||||
public Sort(List<Order> orders) {
|
||||
|
||||
if (null == orders || orders.isEmpty()) {
|
||||
throw new IllegalArgumentException("You have to provide at least one sort property to sort by!");
|
||||
}
|
||||
|
||||
this.orders = orders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Sort} instance. Order defaults to {@value Direction#ASC}.
|
||||
*
|
||||
* @param properties must not be {@literal null} or contain {@literal null} or empty strings
|
||||
*/
|
||||
public Sort(String... properties) {
|
||||
this(DEFAULT_DIRECTION, properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Sort} instance.
|
||||
*
|
||||
* @param direction defaults to {@linke Sort#DEFAULT_DIRECTION} (for {@literal null} cases, too)
|
||||
* @param properties must not be {@literal null} or contain {@literal null} or empty strings
|
||||
*/
|
||||
public Sort(Direction direction, String... properties) {
|
||||
this(direction, properties == null ? new ArrayList<String>() : Arrays.asList(properties));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Sort} instance.
|
||||
*
|
||||
* @param direction
|
||||
* @param properties
|
||||
*/
|
||||
public Sort(Direction direction, List<String> properties) {
|
||||
|
||||
if (properties == null || properties.isEmpty()) {
|
||||
throw new IllegalArgumentException("You have to provide at least one property to sort by!");
|
||||
}
|
||||
|
||||
this.orders = new ArrayList<Order>(properties.size());
|
||||
|
||||
for (String property : properties) {
|
||||
this.orders.add(new Order(direction, property));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@link Sort} consisting of the {@link Order}s of the current {@link Sort} combined with the given
|
||||
* ones.
|
||||
*
|
||||
* @param sort can be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public Sort and(Sort sort) {
|
||||
|
||||
if (sort == null) {
|
||||
return this;
|
||||
}
|
||||
|
||||
ArrayList<Order> these = new ArrayList<Order>(this.orders);
|
||||
|
||||
for (Order order : sort) {
|
||||
these.add(order);
|
||||
}
|
||||
|
||||
return new Sort(these);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the order registered for the given property.
|
||||
*
|
||||
* @param property
|
||||
* @return
|
||||
*/
|
||||
public Order getOrderFor(String property) {
|
||||
|
||||
for (Order order : this) {
|
||||
if (order.getProperty().equals(property)) {
|
||||
return order;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Iterable#iterator()
|
||||
*/
|
||||
public Iterator<Order> iterator() {
|
||||
return this.orders.iterator();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof Sort)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Sort that = (Sort) obj;
|
||||
|
||||
return this.orders.equals(that.orders);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
int result = 17;
|
||||
result = 31 * result + orders.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return StringUtils.collectionToCommaDelimitedString(orders);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enumeration for sort directions.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public static enum Direction {
|
||||
|
||||
ASC, DESC;
|
||||
|
||||
/**
|
||||
* Returns the {@link Direction} enum for the given {@link String} value.
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static Direction fromString(String value) {
|
||||
|
||||
try {
|
||||
return Direction.valueOf(value.toUpperCase(Locale.US));
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"Invalid value '%s' for orders given! Has to be either 'desc' or 'asc' (case insensitive).", value), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* PropertyPath implements the pairing of an {@link Direction} and a property. It is used to provide input for
|
||||
* {@link Sort}
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public static class Order implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1522511010900108987L;
|
||||
|
||||
private final Direction direction;
|
||||
private final String property;
|
||||
|
||||
/**
|
||||
* Creates a new {@link Order} instance. if order is {@literal null} then order defaults to
|
||||
* {@link Sort#DEFAULT_DIRECTION}
|
||||
*
|
||||
* @param direction can be {@literal null}, will default to {@link Sort#DEFAULT_DIRECTION}
|
||||
* @param property must not be {@literal null} or empty.
|
||||
*/
|
||||
public Order(Direction direction, String property) {
|
||||
|
||||
if (!StringUtils.hasText(property)) {
|
||||
throw new IllegalArgumentException("Property must not null or empty!");
|
||||
}
|
||||
|
||||
this.direction = direction == null ? DEFAULT_DIRECTION : direction;
|
||||
this.property = property;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Order} instance. Takes a single property. Direction defaults to
|
||||
* {@link Sort#DEFAULT_DIRECTION}.
|
||||
*
|
||||
* @param property must not be {@literal null} or empty.
|
||||
*/
|
||||
public Order(String property) {
|
||||
this(DEFAULT_DIRECTION, property);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link Sort#Sort(Direction, List)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public static List<Order> create(Direction direction, Iterable<String> properties) {
|
||||
|
||||
List<Order> orders = new ArrayList<Sort.Order>();
|
||||
for (String property : properties) {
|
||||
orders.add(new Order(direction, property));
|
||||
}
|
||||
return orders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the order the property shall be sorted for.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Direction getDirection() {
|
||||
return direction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the property to order for.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getProperty() {
|
||||
return property;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether sorting for this property shall be ascending.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isAscending() {
|
||||
return this.direction.equals(Direction.ASC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@link Order} with the given {@link Order}.
|
||||
*
|
||||
* @param order
|
||||
* @return
|
||||
*/
|
||||
public Order with(Direction order) {
|
||||
return new Order(order, this.property);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@link Sort} instance for the given properties.
|
||||
*
|
||||
* @param properties
|
||||
* @return
|
||||
*/
|
||||
public Sort withProperties(String... properties) {
|
||||
return new Sort(this.direction, properties);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
int result = 17;
|
||||
|
||||
result = 31 * result + direction.hashCode();
|
||||
result = 31 * result + property.hashCode();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof Order)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Order that = (Order) obj;
|
||||
|
||||
return this.direction.equals(that.direction) && this.property.equals(that.property);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s: %s", property, direction);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.domain.jaxb;
|
||||
|
||||
import javax.xml.bind.annotation.adapters.XmlAdapter;
|
||||
|
||||
import org.springframework.data.domain.Sort.Order;
|
||||
import org.springframework.data.domain.jaxb.SpringDataJaxb.OrderDto;
|
||||
|
||||
/**
|
||||
* XmlAdapter to convert {@link Order} instances into {@link OrderDto}s and vice versa.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class OrderAdapter extends XmlAdapter<OrderDto, Order> {
|
||||
|
||||
public static final OrderAdapter INSTANCE = new OrderAdapter();
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see javax.xml.bind.annotation.adapters.XmlAdapter#marshal(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public OrderDto marshal(Order order) throws Exception {
|
||||
|
||||
if (order == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
OrderDto dto = new OrderDto();
|
||||
dto.direction = order.getDirection();
|
||||
dto.property = order.getProperty();
|
||||
return dto;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see javax.xml.bind.annotation.adapters.XmlAdapter#unmarshal(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public Order unmarshal(OrderDto source) throws Exception {
|
||||
return source == null ? null : new Order(source.direction, source.property);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.domain.jaxb;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.bind.annotation.adapters.XmlAdapter;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.jaxb.SpringDataJaxb.PageDto;
|
||||
import org.springframework.hateoas.Link;
|
||||
|
||||
/**
|
||||
* {@link XmlAdapter} to convert {@link Page} instances into {@link PageDto} instances and vice versa.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class PageAdapter extends XmlAdapter<PageDto, Page<Object>> {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see javax.xml.bind.annotation.adapters.XmlAdapter#marshal(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public PageDto marshal(Page<Object> source) throws Exception {
|
||||
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
PageDto dto = new PageDto();
|
||||
dto.content = source.getContent();
|
||||
dto.add(getLinks(source));
|
||||
|
||||
return dto;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see javax.xml.bind.annotation.adapters.XmlAdapter#unmarshal(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public Page<Object> unmarshal(PageDto v) throws Exception {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return additional links that shall be added to the {@link PageDto}.
|
||||
*
|
||||
* @param source the source {@link Page}.
|
||||
* @return
|
||||
*/
|
||||
protected List<Link> getLinks(Page<?> source) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.domain.jaxb;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import javax.xml.bind.annotation.adapters.XmlAdapter;
|
||||
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.jaxb.SpringDataJaxb.OrderDto;
|
||||
import org.springframework.data.domain.jaxb.SpringDataJaxb.PageRequestDto;
|
||||
import org.springframework.data.domain.jaxb.SpringDataJaxb.SortDto;
|
||||
|
||||
/**
|
||||
* {@link XmlAdapter} to convert {@link Pageable} instances int a {@link PageRequestDto} and vice versa.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
class PageableAdapter extends XmlAdapter<PageRequestDto, Pageable> {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see javax.xml.bind.annotation.adapters.XmlAdapter#marshal(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public PageRequestDto marshal(Pageable request) throws Exception {
|
||||
|
||||
SortDto sortDto = SortAdapter.INSTANCE.marshal(request.getSort());
|
||||
|
||||
PageRequestDto dto = new PageRequestDto();
|
||||
dto.orders = sortDto == null ? Collections.<OrderDto> emptyList() : sortDto.orders;
|
||||
dto.page = request.getPageNumber();
|
||||
dto.size = request.getPageSize();
|
||||
|
||||
return dto;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see javax.xml.bind.annotation.adapters.XmlAdapter#unmarshal(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public Pageable unmarshal(PageRequestDto v) throws Exception {
|
||||
|
||||
if (v.orders.isEmpty()) {
|
||||
return new PageRequest(v.page, v.size);
|
||||
}
|
||||
|
||||
SortDto sortDto = new SortDto();
|
||||
sortDto.orders = v.orders;
|
||||
Sort sort = SortAdapter.INSTANCE.unmarshal(sortDto);
|
||||
|
||||
return new PageRequest(v.page, v.size, sort);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package org.springframework.data.domain.jaxb;
|
||||
|
||||
import javax.xml.bind.annotation.adapters.XmlAdapter;
|
||||
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.jaxb.SpringDataJaxb.SortDto;
|
||||
|
||||
/**
|
||||
* {@link XmlAdapter} to convert {@link Sort} instances into {@link SortDto} instances and vice versa.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class SortAdapter extends XmlAdapter<SortDto, Sort> {
|
||||
|
||||
public static final SortAdapter INSTANCE = new SortAdapter();
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see javax.xml.bind.annotation.adapters.XmlAdapter#marshal(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public SortDto marshal(Sort source) throws Exception {
|
||||
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
SortDto dto = new SortDto();
|
||||
dto.orders = SpringDataJaxb.marshal(source, OrderAdapter.INSTANCE);
|
||||
|
||||
return dto;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see javax.xml.bind.annotation.adapters.XmlAdapter#unmarshal(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public Sort unmarshal(SortDto source) throws Exception {
|
||||
return source == null ? null : new Sort(SpringDataJaxb.unmarshal(source.orders, OrderAdapter.INSTANCE));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.domain.jaxb;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAnyElement;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlElementWrapper;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.adapters.XmlAdapter;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.domain.Sort.Order;
|
||||
import org.springframework.hateoas.ResourceSupport;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Helper class containing utility methods to implement JAXB {@link XmlAdapter}s as well as the DTO types to be
|
||||
* marshalled by JAXB.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class SpringDataJaxb {
|
||||
|
||||
public static final String NAMESPACE = "http://www.springframework.org/schema/data/jaxb";
|
||||
|
||||
/**
|
||||
* The DTO for {@link Pageable}s/{@link PageRequest}s.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@XmlRootElement(name = "page-request", namespace = NAMESPACE)
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public static class PageRequestDto {
|
||||
|
||||
@XmlAttribute
|
||||
int page, size;
|
||||
@XmlElement(name = "order", namespace = NAMESPACE)
|
||||
List<OrderDto> orders = new ArrayList<OrderDto>();
|
||||
}
|
||||
|
||||
/**
|
||||
* The DTO for {@link Sort}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@XmlRootElement(name = "sort", namespace = NAMESPACE)
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public static class SortDto {
|
||||
|
||||
@XmlElement(name = "order", namespace = SpringDataJaxb.NAMESPACE)
|
||||
List<OrderDto> orders = new ArrayList<OrderDto>();
|
||||
}
|
||||
|
||||
/**
|
||||
* The DTO for {@link Order}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@XmlRootElement(name = "order", namespace = NAMESPACE)
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public static class OrderDto {
|
||||
|
||||
@XmlAttribute
|
||||
String property;
|
||||
@XmlAttribute
|
||||
Direction direction;
|
||||
}
|
||||
|
||||
/**
|
||||
* The DTO for {@link Page}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@XmlRootElement(name = "page", namespace = NAMESPACE)
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public static class PageDto extends ResourceSupport {
|
||||
|
||||
@XmlAnyElement
|
||||
@XmlElementWrapper(name = "content")
|
||||
List<Object> content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmarshals each element of the given {@link Collection} using the given {@link XmlAdapter}.
|
||||
*
|
||||
* @param source
|
||||
* @param adapter must not be {@literal null}.
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static <T, S> List<T> unmarshal(Collection<S> source, XmlAdapter<S, T> adapter) throws Exception {
|
||||
|
||||
Assert.notNull(adapter);
|
||||
|
||||
if (source == null || source.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<T> result = new ArrayList<T>(source.size());
|
||||
for (S element : source) {
|
||||
result.add(adapter.unmarshal(element));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marshals each of the elements of the given {@link Iterable} using the given {@link XmlAdapter}.
|
||||
*
|
||||
* @param source
|
||||
* @param adapter must not be {@literal null}.
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static <T, S> List<S> marshal(Iterable<T> source, XmlAdapter<S, T> adapter) throws Exception {
|
||||
|
||||
Assert.notNull(adapter);
|
||||
|
||||
if (source == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<S> result = new ArrayList<S>();
|
||||
for (T element : source) {
|
||||
result.add(adapter.marshal(element));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Central domain abstractions especially to be used in combination with the {@link org.springframework.data.repository.Repository} abstraction.
|
||||
*
|
||||
* @see org.springframework.data.repository.Repository
|
||||
*/
|
||||
@XmlSchema(xmlns = { @XmlNs(prefix = "sd", namespaceURI = org.springframework.data.domain.jaxb.SpringDataJaxb.NAMESPACE) })
|
||||
@XmlJavaTypeAdapters({
|
||||
@XmlJavaTypeAdapter(value = org.springframework.data.domain.jaxb.PageableAdapter.class, type = Pageable.class),
|
||||
@XmlJavaTypeAdapter(value = org.springframework.data.domain.jaxb.SortAdapter.class, type = Sort.class),
|
||||
@XmlJavaTypeAdapter(value = org.springframework.data.domain.jaxb.PageAdapter.class, type = Page.class) })
|
||||
package org.springframework.data.domain.jaxb;
|
||||
|
||||
import javax.xml.bind.annotation.XmlNs;
|
||||
import javax.xml.bind.annotation.XmlSchema;
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* Central domain abstractions especially to be used in combination with the {@link org.springframework.data.repository.Repository} abstraction.
|
||||
*
|
||||
* @see org.springframework.data.repository.Repository
|
||||
*/
|
||||
package org.springframework.data.domain;
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.history;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.springframework.data.util.AnnotationDetectionFieldCallback;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* A {@link RevisionMetadata} implementation that inspects the given object for fields with the configured annotations
|
||||
* and returns the field's values on calls to {@link #getRevisionDate()} and {@link #getRevisionNumber()}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class AnnotationRevisionMetadata<N extends Number & Comparable<N>> implements RevisionMetadata<N> {
|
||||
|
||||
private final Object entity;
|
||||
private final N revisionNumber;
|
||||
private final DateTime revisionDate;
|
||||
|
||||
/**
|
||||
* Creates a new {@link AnnotationRevisionMetadata} inspecing the given entity for the given annotations. If no
|
||||
* annotations will be provided these values will not be looked up from the entity and return {@literal null}.
|
||||
*
|
||||
* @param entity must not be {@literal null}.
|
||||
* @param revisionNumberAnnotation
|
||||
* @param revisionTimeStampAnnotation
|
||||
*/
|
||||
public AnnotationRevisionMetadata(final Object entity, Class<? extends Annotation> revisionNumberAnnotation,
|
||||
Class<? extends Annotation> revisionTimeStampAnnotation) {
|
||||
|
||||
Assert.notNull(entity);
|
||||
this.entity = entity;
|
||||
|
||||
if (revisionNumberAnnotation != null) {
|
||||
AnnotationDetectionFieldCallback numberCallback = new AnnotationDetectionFieldCallback(revisionNumberAnnotation);
|
||||
ReflectionUtils.doWithFields(entity.getClass(), numberCallback);
|
||||
this.revisionNumber = numberCallback.getValue(entity);
|
||||
} else {
|
||||
this.revisionNumber = null;
|
||||
}
|
||||
|
||||
if (revisionTimeStampAnnotation != null) {
|
||||
AnnotationDetectionFieldCallback revisionCallback = new AnnotationDetectionFieldCallback(
|
||||
revisionTimeStampAnnotation);
|
||||
ReflectionUtils.doWithFields(entity.getClass(), revisionCallback);
|
||||
this.revisionDate = new DateTime(revisionCallback.getValue(entity));
|
||||
} else {
|
||||
this.revisionDate = null;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.history.RevisionMetadata#getRevisionNumber()
|
||||
*/
|
||||
public N getRevisionNumber() {
|
||||
return revisionNumber;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.history.RevisionMetadata#getRevisionDate()
|
||||
*/
|
||||
public DateTime getRevisionDate() {
|
||||
return revisionDate;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.history.RevisionMetadata#getDelegate()
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getDelegate() {
|
||||
return (T) entity;
|
||||
}
|
||||
}
|
||||
132
src/main/java/org/springframework/data/history/Revision.java
Executable file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.history;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Wrapper to contain {@link RevisionMetadata} as well as the revisioned entity.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Philipp Huegelmeyer
|
||||
*/
|
||||
public final class Revision<N extends Number & Comparable<N>, T> implements Comparable<Revision<N, ?>> {
|
||||
|
||||
private final RevisionMetadata<N> metadata;
|
||||
private final T entity;
|
||||
|
||||
/**
|
||||
* Creates a new {@link Revision} consisting of the given {@link RevisionMetadata} and entity.
|
||||
*
|
||||
* @param metadata must not be {@literal null}.
|
||||
* @param entity must not be {@literal null}.
|
||||
*/
|
||||
public Revision(RevisionMetadata<N> metadata, T entity) {
|
||||
|
||||
Assert.notNull(metadata);
|
||||
Assert.notNull(entity);
|
||||
|
||||
this.metadata = metadata;
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the revision number of the revision.
|
||||
*
|
||||
* @return the revision number.
|
||||
*/
|
||||
public N getRevisionNumber() {
|
||||
return metadata.getRevisionNumber();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the revision date of the revision.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public DateTime getRevisionDate() {
|
||||
return metadata.getRevisionDate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the underlying entity.
|
||||
*
|
||||
* @return the entity
|
||||
*/
|
||||
public T getEntity() {
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link RevisionMetadata} for the current {@link Revision}.
|
||||
*
|
||||
* @return the metadata
|
||||
*/
|
||||
public RevisionMetadata<N> getMetadata() {
|
||||
return metadata;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Comparable#compareTo(java.lang.Object)
|
||||
*/
|
||||
public int compareTo(Revision<N, ?> that) {
|
||||
return getRevisionNumber().compareTo(that.getRevisionNumber());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public boolean equals(Object obj) {
|
||||
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof Revision)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Revision<N, T> that = (Revision<N, T>) obj;
|
||||
boolean sameRevisionNumber = this.metadata.getRevisionNumber().equals(that.metadata.getRevisionNumber());
|
||||
return !sameRevisionNumber ? false : this.entity.equals(that.entity);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
int result = 17;
|
||||
result += 31 * metadata.hashCode();
|
||||
result += 31 * entity.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Revision %s of entity %s - Revision metadata %s", getRevisionNumber(), entity, metadata);
|
||||
}
|
||||
}
|
||||
48
src/main/java/org/springframework/data/history/RevisionMetadata.java
Executable file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.history;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
/**
|
||||
* Metadata about a revision.
|
||||
*
|
||||
* @author Philipp Huegelmeyer
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface RevisionMetadata<N extends Number & Comparable<N>> {
|
||||
|
||||
/**
|
||||
* Returns the revision number of the revision.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
N getRevisionNumber();
|
||||
|
||||
/**
|
||||
* Returns the date of the revision.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
DateTime getRevisionDate();
|
||||
|
||||
/**
|
||||
* Returns the underlying revision metadata which might provider more detailed implementation specific information.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
<T> T getDelegate();
|
||||
}
|
||||
102
src/main/java/org/springframework/data/history/Revisions.java
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.history;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Simple wrapper class for a {@link List} of {@link Revisions} allowing to canonically access the latest revision.
|
||||
* Allows iterating over the underlying {@link Revisions} starting with older revisions.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class Revisions<N extends Number & Comparable<N>, T> implements Iterable<Revision<N, T>> {
|
||||
|
||||
private final List<Revision<N, T>> revisions;
|
||||
private final boolean latestLast;
|
||||
|
||||
/**
|
||||
* Creates a new {@link Revisions} instance containing the given revisions. Will make sure they are ordered
|
||||
* ascendingly.
|
||||
*
|
||||
* @param revisions must not be {@literal null}.
|
||||
*/
|
||||
public Revisions(List<? extends Revision<N, T>> revisions) {
|
||||
this(revisions, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Revisions} instance using the given revisions.
|
||||
*
|
||||
* @param revisions must not be {@literal null}.
|
||||
* @param latestLast
|
||||
*/
|
||||
private Revisions(List<? extends Revision<N, T>> revisions, boolean latestLast) {
|
||||
|
||||
Assert.notNull(revisions);
|
||||
this.revisions = new ArrayList<Revision<N, T>>(revisions);
|
||||
this.latestLast = latestLast;
|
||||
|
||||
Collections.sort(this.revisions);
|
||||
|
||||
if (!latestLast) {
|
||||
Collections.reverse(this.revisions);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the latest revision of the revisions backing the wrapper independently of the order.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Revision<N, T> getLatestRevision() {
|
||||
int index = latestLast ? revisions.size() - 1 : 0;
|
||||
return revisions.get(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverses the current {@link Revisions}. By default this will return the revisions with the latest revision first.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Revisions<N, T> reverse() {
|
||||
List<Revision<N, T>> result = new ArrayList<Revision<N, T>>(revisions);
|
||||
Collections.reverse(result);
|
||||
return new Revisions<N, T>(result, !latestLast);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Iterable#iterator()
|
||||
*/
|
||||
public Iterator<Revision<N, T>> iterator() {
|
||||
return revisions.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the content of the {@link Revisions} instance.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<Revision<N, T>> getContent() {
|
||||
return Collections.unmodifiableList(revisions);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
/**
|
||||
* Basic interfaces and value objects for historiography API.
|
||||
*/
|
||||
package org.springframework.data.history;
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.mapping;
|
||||
|
||||
/**
|
||||
* Value object to capture {@link Association}s.
|
||||
*
|
||||
* @param the {@link PersistentProperty}s the association connects.
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
public class Association<P extends PersistentProperty<P>> {
|
||||
|
||||
private final P inverse;
|
||||
private final P obverse;
|
||||
|
||||
/**
|
||||
* Creates a new {@link Association} between the two given {@link PersistentProperty}s.
|
||||
*
|
||||
* @param inverse
|
||||
* @param obverse
|
||||
*/
|
||||
public Association(P inverse, P obverse) {
|
||||
this.inverse = inverse;
|
||||
this.obverse = obverse;
|
||||
}
|
||||
|
||||
public P getInverse() {
|
||||
return inverse;
|
||||
}
|
||||
|
||||
public P getObverse() {
|
||||
return obverse;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.mapping;
|
||||
|
||||
/**
|
||||
* Callback interface to implement functionality to be applied to a collection of {@link Association}s.
|
||||
*
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface AssociationHandler<P extends PersistentProperty<P>> {
|
||||
|
||||
/**
|
||||
* Processes the given {@link Association}.
|
||||
*
|
||||
* @param association
|
||||
*/
|
||||
void doWithAssociation(Association<P> association);
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright 2011-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.mapping;
|
||||
|
||||
import org.springframework.data.convert.EntityInstantiator;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
|
||||
/**
|
||||
* Represents a persistent entity.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Graeme Rocher
|
||||
* @author Jon Brisbin
|
||||
* @author Patryk Wasik
|
||||
*/
|
||||
public interface PersistentEntity<T, P extends PersistentProperty<P>> {
|
||||
|
||||
/**
|
||||
* The entity name including any package prefix.
|
||||
*
|
||||
* @return must never return {@literal null}
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Returns the {@link PreferredConstructor} to be used to instantiate objects of this {@link PersistentEntity}.
|
||||
*
|
||||
* @return {@literal null} in case no suitable constructor for automatic construction can be found. This usually
|
||||
* indicates that the instantiation of the object of tthat persistent entity is done through either a customer
|
||||
* {@link EntityInstantiator} or handled by custom conversion mechanisms entirely.
|
||||
*/
|
||||
PreferredConstructor<T, P> getPersistenceConstructor();
|
||||
|
||||
/**
|
||||
* Returns whether the given {@link PersistentProperty} is referred to by a constructor argument of the
|
||||
* {@link PersistentEntity}.
|
||||
*
|
||||
* @param property
|
||||
* @return true if the given {@link PersistentProperty} is referred to by a constructor argument or {@literal false}
|
||||
* if not or {@literal null}.
|
||||
*/
|
||||
boolean isConstructorArgument(PersistentProperty<?> property);
|
||||
|
||||
/**
|
||||
* Returns whether the given {@link PersistentProperty} is the id property of the entity.
|
||||
*
|
||||
* @param property
|
||||
* @return
|
||||
*/
|
||||
boolean isIdProperty(PersistentProperty<?> property);
|
||||
|
||||
/**
|
||||
* Returns whether the given {@link PersistentProperty} is the version property of the entity.
|
||||
*
|
||||
* @param property
|
||||
* @return
|
||||
*/
|
||||
boolean isVersionProperty(PersistentProperty<?> property);
|
||||
|
||||
/**
|
||||
* Returns the id property of the {@link PersistentEntity}. Can be {@literal null} in case this is an entity
|
||||
* completely handled by a custom conversion.
|
||||
*
|
||||
* @return the id property of the {@link PersistentEntity}.
|
||||
*/
|
||||
P getIdProperty();
|
||||
|
||||
/**
|
||||
* Returns the version property of the {@link PersistentEntity}. Can be {@literal null} in case no version property is
|
||||
* available on the entity.
|
||||
*
|
||||
* @return the version property of the {@link PersistentEntity}.
|
||||
*/
|
||||
P getVersionProperty();
|
||||
|
||||
/**
|
||||
* Obtains a {@link PersistentProperty} instance by name.
|
||||
*
|
||||
* @param name The name of the property
|
||||
* @return the {@link PersistentProperty} or {@literal null} if it doesn't exist.
|
||||
*/
|
||||
P getPersistentProperty(String name);
|
||||
|
||||
/**
|
||||
* Returns whether the {@link PersistentEntity} has an id property. If this call returns {@literal true},
|
||||
* {@link #getIdProperty()} will return a non-{@literal null} value.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean hasIdProperty();
|
||||
|
||||
/**
|
||||
* Returns whether the {@link PersistentEntity} has a version property. If this call returns {@literal true},
|
||||
* {@link #getVersionProperty()} will return a non-{@literal null} value.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean hasVersionProperty();
|
||||
|
||||
/**
|
||||
* Returns the resolved Java type of this entity.
|
||||
*
|
||||
* @return The underlying Java class for this entity
|
||||
*/
|
||||
Class<T> getType();
|
||||
|
||||
/**
|
||||
* Returns the alias to be used when storing type information. Might be {@literal null} to indicate that there was no
|
||||
* alias defined through the mapping metadata.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Object getTypeAlias();
|
||||
|
||||
/**
|
||||
* Returns the {@link TypeInformation} backing this {@link PersistentEntity}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
TypeInformation<T> getTypeInformation();
|
||||
|
||||
/**
|
||||
* Applies the given {@link PropertyHandler} to all {@link PersistentProperty}s contained in this
|
||||
* {@link PersistentEntity}.
|
||||
*
|
||||
* @param handler must not be {@literal null}.
|
||||
*/
|
||||
void doWithProperties(PropertyHandler<P> handler);
|
||||
|
||||
/**
|
||||
* Applies the given {@link AssociationHandler} to all {@link Association} contained in this {@link PersistentEntity}.
|
||||
*
|
||||
* @param handler must not be {@literal null}.
|
||||
*/
|
||||
void doWithAssociations(AssociationHandler<P> handler);
|
||||
}
|
||||