Merge branch 'gradle-build-ng' of github.com:SpringSource/spring-data-keyvalue into initial_merge

Conflicts:
	README.md
This commit is contained in:
Costin Leau
2011-07-04 22:14:39 +03:00
361 changed files with 39390 additions and 0 deletions

13
.gitignore vendored Normal file
View File

@@ -0,0 +1,13 @@
.DS_Store
target
bin
build
bin
.gradle
.springBeans
.ant-targets-build.xml
pom.xml
src/ant/.ant-targets-upload-dist.xml
*.iml
*.ipr
*.iws

View File

@@ -0,0 +1,9 @@
#Mon Oct 11 17:02:20 EDT 2010
activeProfiles=
eclipse.preferences.version=1
fullBuildGoals=process-test-resources
includeModules=false
resolveWorkspaceProjects=true
resourceFilterGoals=process-resources resources\:testResources
skipCompilerPlugin=true
version=1

140
build.gradle Normal file
View File

@@ -0,0 +1,140 @@
// used for artifact names, building doc upload urls, etc.
description = 'Spring Data Key Value'
abbreviation = 'DATAKV'
apply plugin: 'base'
apply plugin: 'idea'
buildscript {
repositories {
// add(new org.apache.ivy.plugins.resolver.FileSystemResolver()) {
// name = "local"
// addIvyPattern "e:/work/i21/gradle-plugins/build/repo/[organisation].[module]-ivy-[revision].xml"
// addArtifactPattern "e:/work/i21/gradle-plugins/build/repo/[organisation].[module]-[revision](-[classifier]).[ext]"
// }
add(new org.apache.ivy.plugins.resolver.URLResolver()) {
name = "GitHub"
addIvyPattern 'http://cloud.github.com/downloads/costin/gradle-stuff/[organization].[module]-[artifact]-[revision].[ext]'
addArtifactPattern 'http://cloud.github.com/downloads/costin/gradle-stuff/[organization].[module]-[revision].[ext]'
}
mavenCentral()
mavenRepo name: "springsource-org-release", urls: "http://repository.springsource.com/maven/bundles/release"
mavenRepo name: "springsource-org-external", urls: "http://repository.springsource.com/maven/bundles/external"
}
dependencies {
classpath 'org.springframework:gradle-stuff:0.1-20110421'
classpath 'net.sf.docbook:docbook-xsl:1.75.2:ns-resources@zip'
}
}
allprojects {
group = 'org.springframework.data'
version = '1.0.0.BUILD-SNAPSHOT'
releaseBuild = version.endsWith('RELEASE')
snapshotBuild = version.endsWith('SNAPSHOT')
repositories {
mavenLocal()
mavenCentral()
// Public Spring artefacts
mavenRepo name: "springsource-org-release", urls: "http://repository.springsource.com/maven/bundles/release"
mavenRepo name: "spring-release", urls: "http://maven.springframework.org/release"
mavenRepo name: "spring-milestone", urls: "http://maven.springframework.org/milestone"
mavenRepo name: "spring-snapshot", urls: "http://maven.springframework.org/snapshot"
mavenRepo name: "sonatype-snapshot", urls: "http://oss.sonatype.org/content/repositories/snapshots"
mavenRepo name: "jboss", urls: "http://repository.jboss.org/maven2/"
mavenRepo name: "java.net", urls: "http://download.java.net/maven/2/"
}
}
javaprojects = subprojects.findAll {
project -> project.path.startsWith(':spring-data-')
}
configure(javaprojects) {
apply plugin: "java"
apply plugin: "maven"
apply plugin: 'eclipse' // `gradle eclipse` to generate .classpath/.project
apply plugin: 'idea' // `gradle idea` to generate .ipr/.iml
apply plugin: 'docbook'
apply plugin: 'bundlor' // all core projects should be OSGi-compliant
bundlor.useProjectProps = true
[compileJava, compileTestJava]*.options*.compilerArgs = ["-Xlint:-serial"]
// Common dependencies
dependencies {
// Logging
compile "org.slf4j:slf4j-api:$slf4jVersion"
compile "org.slf4j:jcl-over-slf4j:$slf4jVersion"
runtime "log4j:log4j:$log4jVersion"
runtime "org.slf4j:slf4j-log4j12:$slf4jVersion"
// Spring Framework
compile("org.springframework:spring-core:$springVersion") {
exclude module: "commons-logging"
}
compile "org.springframework:spring-beans:$springVersion"
compile "org.springframework:spring-context:$springVersion"
compile "org.springframework:spring-context-support:$springVersion"
compile "org.springframework:spring-tx:$springVersion"
// Jackson JSON Mapper
compile "org.codehaus.jackson:jackson-mapper-asl:$jacksonVersion"
// Testing
testCompile "junit:junit:$junitVersion"
testCompile "org.springframework:spring-test:$springVersion"
testCompile "org.mockito:mockito-all:$mockitoVersion"
}
apply from: "$rootDir/maven.gradle"
}
ideaProject {
withXml { provider ->
provider.node.component.find { it.@name == 'VcsDirectoryMappings' }.mapping.@vcs = 'Git'
}
}
task wrapper(type: Wrapper) {
gradleVersion = '0.9.2'
description = "Generate the Gradle wrapper"
group = "Distribution"
}
// Distribution tasks
task dist(type: Zip) {
description = "Generate the ZIP Distribution"
group = "Distribution"
dependsOn subprojects*.tasks*.matching { task -> task.name == 'assemble' }
evaluationDependsOn(':docs')
def zipRootDir = "${project.name}-$version"
into(zipRootDir) {
from('/docs/src/info') {
include '*.txt'
}
from('/docs/build/') {
into 'docs'
include 'reference/**/*'
include 'api/**/*'
}
into('dist') {
from javaprojects.collect {project -> project.libsDir }
}
}
doLast {
ant.checksum(file: archivePath, algorithm: 'SHA1', fileext: '.sha1')
}
}
task uploadDist(type: org.springframework.gradle.tasks.S3DistroUpload, dependsOn: dist) {
description = "Upload the ZIP Distribution"
group = "Distribution"
archiveFile = dist.archivePath
projectKey = 'DATAKV'
projectName = 'Spring Data Key Value'
}

136
docs/build.gradle Normal file
View File

@@ -0,0 +1,136 @@
import org.apache.tools.ant.filters.FixCrLfFilter
import org.apache.tools.ant.filters.ReplaceTokens
// -----------------------------------------------------------------------------
// Configuration for the docs subproject
// -----------------------------------------------------------------------------
apply plugin: 'base'
apply plugin: 'docbook'
assemble.dependsOn = ['api', 'docbook']
[docbookHtml, docbookFoPdf, docbookHtmlSingle]*.group = 'Documentation'
[docbookHtml, docbookFoPdf, docbookHtmlSingle]*.sourceFileName = 'index.xml'
[docbookHtml, docbookFoPdf, docbookHtmlSingle]*.sourceDirectory = new File(projectDir, 'src/reference/docbook')
docbookHtml.stylesheet = new File(projectDir, 'src/reference/resources/xsl/html-custom.xsl')
docbookHtmlSingle.stylesheet = new File(projectDir, 'src/reference/resources/xsl/html-single-custom.xsl')
docbookFoPdf.stylesheet = new File(projectDir, 'src/reference/resources/xsl/pdf-custom.xsl')
def imagesDir = new File(projectDir, 'src/reference/resources/images');
docbookFoPdf.admonGraphicsPath = "${imagesDir}/admon"
docbookFoPdf.imgSrcPath = "${imagesDir}"
refSpec = copySpec {
into ('reference') {
from("$buildDir/docs")
from("$projectDir/src/reference/resources")
}
into ('reference/images') {
from (imagesDir)
}
p = new Properties()
for (e in project.properties) {
if (e.key != null && e.value != null)
p.setProperty(e.key, e.value.toString())
}
filter(ReplaceTokens, tokens: p)
}
task reference (type: Copy) {
dependsOn 'docbook'
description = "Builds aggregated DocBook"
group = "Documentation"
logger.info("Version is " + version)
destinationDir = buildDir
with(refSpec)
}
task api(type: Javadoc) {
group = "Documentation"
description = "Builds aggregated JavaDoc HTML for all core project classes."
// this task is a bit ugly to configure. it was a user contribution, and
// Hans tells me it's on the roadmap to redesign it.
srcDir = file("${projectDir}/src/api")
destinationDir = file("${buildDir}/api")
tmpDir = file("${buildDir}/api-work")
configure(options) {
stylesheetFile = file("${srcDir}/spring-javadoc.css")
links = ["http://static.springframework.org/spring/docs/3.0.x/javadoc-api"]
overview = "${srcDir}/overview.html"
docFilesSubDirs = true
outputLevel = org.gradle.external.javadoc.JavadocOutputLevel.QUIET
breakIterator = true
showFromProtected()
groups = [
'Spring Data Key Value Core': ['org.springframework.data.keyvalue*'],
'Spring Data Redis Support' : ['org.springframework.data.keyvalue.redis*'],
'Spring Data Riak Support' : ['org.springframework.data.keyvalue.riak*']
]
links = [
"http://static.springframework.org/spring/docs/3.0.x/javadoc-api",
"http://download.oracle.com/javase/6/docs/api/"
]
exclude "org/springframework/data/keyvalue/redis/config/**"
}
title = "${rootProject.description} ${version} API"
// collect all the sources that will be included in the javadoc output
source javaprojects.collect {project ->
project.sourceSets.main.allJava
}
// collect all main classpaths to be able to resolve @see refs, etc.
// this collection also determines the set of projects that this
// task dependsOn, thus the runtimeClasspath is used to ensure all
// projects are included, not just *dependencies* of all classes.
// this is awkward and took me a while to figure out.
classpath = files(javaprojects.collect {project ->
project.sourceSets.main.runtimeClasspath
})
// copy the images from the doc-files dir over to the target
doLast { task ->
copy {
from file("${task.srcDir}/doc-files")
into file("${task.destinationDir}/doc-files")
}
}
}
apiSpec = copySpec {
into('api') {
from(api.destinationDir)
}
}
task docSiteLogin(type: org.springframework.gradle.tasks.Login) {
if (project.hasProperty('sshHost')) {
host = project.property('sshHost')
username = project.property('sshUsername')
key = project.property('sshPrivateKey')
}
}
// upload task
task uploadApi(type: org.springframework.gradle.tasks.ScpUpload) {
dependsOn api, docbook
description = "Upload API Distribution"
group = "Distribution"
remoteDir = "./static.spring/spring-data/data-keyvalue/docs/${project.version}"
login = docSiteLogin
with(apiSpec)
with(refSpec)
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@@ -0,0 +1,13 @@
-breakiterator
-header "Spring Data Key-Value"
-source 1.6
-protected
-quiet
-docfilessubdirs
-group "Spring Data Key Value Core" "org.springframework.data.keyvalue*"
-group "Spring Data Redis Support" "org.springframework.data.keyvalue.redis*"
-group "Spring Data Riak Support" "org.springframework.data.keyvalue.riak*"
-link http://static.springframework.org/spring/docs/3.0.x/javadoc-api
-link http://download.oracle.com/javase/6/docs/api/
-exclude org.springframework.data.keyvalue.redis.config

View File

@@ -0,0 +1,24 @@
<html>
<body>
This document is the API specification for the Spring Data project.
<hr/>
<div id="overviewBody">
<!--
<p>
For further API reference and developer documentation, see the
<a href="http://static.springframework.org/spring/docs/2.0.x/reference/index.html" target="_top">Spring Framework reference documentation</a>.
That documentation contains more detailed, developer-targeted
descriptions, with conceptual overviews, definitions of terms,
workarounds, and working code examples.
</p>
-->
<p>
If you are interested in commercial training, consultancy and
support for the Spring Data Framework,
<a href="http://www.SpringSource.com/" target="_top">SpringSource</a> provides
such commercial support.
</p>
</div>
</body>
</html>

View File

@@ -0,0 +1,48 @@
/* Spring-specific Javadoc style sheet rules */
#overviewBody {
}
.code {
border: 1px solid black;
background-color: #F4F4F4;
padding: 5px;
}
/* Vanilla Javadoc style sheet rules */
body {
font-family: Helvetica, Arial, sans-serif;
background-color: white;
font-size: 10pt;
}
td { font-size: 10pt; font-family: Helvetica, Arial, sans-serif }/* Javadoc style sheet */
/* Define colors, fonts and other style attributes here to override the defaults */
/* Page background color */
body { background-color: #FFFFFF }
/* Headings */
h1 { font-size: 145% }
/* Table colors */
.TableHeadingColor { background: #CCCCFF } /* Dark mauve */
.TableSubHeadingColor { background: #EEEEFF } /* Light mauve */
.TableRowColor { background: #FFFFFF } /* White */
/* Font used in left-hand frame lists */
.FrameTitleFont { font-size: 100%; font-family: Helvetica, Arial, sans-serif }
.FrameHeadingFont { font-size: 90%; font-family: Helvetica, Arial, sans-serif }
.FrameItemFont { font-size: 90%; font-family: Helvetica, Arial, sans-serif }
/* Navigation bar fonts and colors */
.NavBarCell1 { background-color:#EEEEFF;} /* Light mauve */
.NavBarCell1Rev { background-color:#00008B;} /* Dark Blue */
.NavBarFont1 { font-family: Arial, Helvetica, sans-serif; color:#000000;}
.NavBarFont1Rev { font-family: Arial, Helvetica, sans-serif; color:#FFFFFF;}
.NavBarCell2 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF;}
.NavBarCell3 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF;}

View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.

View File

@@ -0,0 +1,92 @@
SPRING DATA KEY/VALUE INTEGRATION CHANGELOG
===========================================
http://www.springsource.org/spring-data
Changes in version 1.0.0.M3 (2011-04-06)
----------------------------------------
Redis
-----
General
* Added support for RJC (new Redis client)
* Added dedicated SORT and SORT/GET support
* Introduced HashMapper feature for mapping objects to and from maps
* Improved exception hierarchy to be more consistent with Spring DAO
* Made several Redis dependencies optional to eliminate unnecessary jars from the classpath
Package o.s.d.k.redis.connection
* Added support for indexes to RedisConnectionFactories
* Added new key operations to KeyOperations (formerly KeyBound)
* Improved handling of Jedis exceptions
Package o.s.d.k.redis.core
* Serializers are exposed to RedisCallback
* Added missing operations (move, select) to RedisTemplate
* Fixed the signature of various method
Package o.s.d.k.redis.support.atomic
* Fixed incorrect serialization leading to error for RedisAtomicInteger & RedisAtomicLong
Changes in version 1.0.0.M2 (2011-02-10)
----------------------------------------
Redis
-----
General
* Added PubSub support (message listener container and namespace)
* Added JSON and Object/XML Mapping serializers
* Completed support for Redis (2.2) commands
* Improved documentation
* Upgraded to Redis 2.2
* Updraded to Jedis 1.5.2
Package o.s.d.k.redis.connection
* Added sort support
* Added pipelining support
* Added StringRedisConnection for String-focused operations
* Renamed JedisConnectionFactory pooling to usePool
* Renamed JredisConnectionFactory pooling to usePool
Package o.s.d.k.redis.connection.jedis
* Added support for Jedis rich exceptions
* Added support for broken pooled connection
Package o.s.d.k.redis.core
* Fix serializationg bug for hash value inside RedisTemplate
* Added injection for Redis operations ("views")
Package o.s.d.k.redis.support
* Refined AtomicInteger and AtomicLong constructors to use the backing store value as initial counter
Riak
----
General
* Important bug fixes
* Fully asynchronous AsyncRiakTemplate object
* Groovy DSL for Riak access using async template underneath
Changes in version Riak 1.0.0.M1 (2010-12-15)
---------------------------------------------
General
* Generified RiakTemplate for exception translation, serialization, and data access
* Built-in HTTP REST client based on Spring 3.0 RestTemplate
* java.io and Spring IO resource abstractions for reading/writing streams
* java.io.File subclass that represents a Riak resource
Changes in version Redis 1.0.0.M1 (2010-12-13)
----------------------------------------------
General
* Configuration support for Redis Jedis and JRedis drivers/connectors
* Connection package as low-level abstraction across multiple drivers
* Exception translation
* Generified RedisTemplate for exception translation and serialization support
* Various serialization strategies
* Atomic counter support classes
* JDK Collection implementations on top of Redis

21
docs/src/info/notice.txt Normal file
View File

@@ -0,0 +1,21 @@
========================================================================
== NOTICE file corresponding to section 4 d of the Apache License, ==
== Version 2.0, in this case for the Spring Integration distribution. ==
========================================================================
This product includes software developed by
the Apache Software Foundation (http://www.apache.org).
The end-user documentation included with a redistribution, if any,
must include the following acknowledgement:
"This product includes software developed by the Spring Framework
Project (http://www.springframework.org)."
Alternatively, this acknowledgement may appear in the software itself,
if and wherever such third-party acknowledgements normally appear.
The names "Spring", "Spring Framework", and "Spring Data" must
not be used to endorse or promote products derived from this software
without prior written permission. For written permission, please contact
enquiries@springsource.com.

17
docs/src/info/readme.txt Normal file
View File

@@ -0,0 +1,17 @@
SPRING DATASTORE KEY-VALUE 1.0.0 M2 (2010 02 10)
------------------------------------------------
Spring Datastore Key-Value is released under the terms of the Apache Software License Version 2.0 (see license.txt).
DISTRIBUTION CONTENTS:
The JARs are available in the 'dist' directory, and the source JARs are in the 'src' directory.
The reference manual and javadoc are located in the 'docs' directory.
ADDITIONAL RESOURCES:
Spring Data Homepage: http://www.springsource.org/spring-data
Spring Data Forum : http://forum.springsource.org/forumdisplay.php?f=80

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<appendix xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="appendix-schema" xmlns:xi="http://www.w3.org/2001/XInclude">
<title>Spring Data Key Value Schema(s)</title>
<para>Spring Data - Redis support</para>
<programlisting language="xml"><xi:include href="../../../../../spring-data-redis/src/main/resources/org/springframework/data/keyvalue/redis/config/spring-redis-1.0.xsd" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:fallback>
<para><emphasis>FIXME: REDIS SCHEMA LOCATION/NAME CHANGED</emphasis></para>
</xi:fallback>
</xi:include>
</programlisting>
</appendix>

View File

@@ -0,0 +1,10 @@
<partintro>
<title>Document structure</title>
<para>
Various appendixes outside the reference documentation.
</para>
<para><xref linkend="appendix-schema"/> defines the schemas provided by Spring Data
Key Value.</para>
</partintro>

View File

@@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<book xmlns="http://docbook.org/ns/docbook" version="5.0"
xml:id="spring-data-keyvalue-reference"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:xlink="http://www.w3.org/1999/xlink">
<bookinfo>
<title>Spring Data Key-Value - Reference Documentation</title>
<titleabbrev>Spring Data Key-Value ${version}</titleabbrev>
<releaseinfo>@version@</releaseinfo>
<productname>Spring Data Key-Value</productname>
<authorgroup>
<author>
<firstname>Costin</firstname>
<surname>Leau</surname>
<affiliation>SpringSource</affiliation>
</author>
<author>
<firstname>Jon</firstname>
<surname>Brisbin</surname>
<affiliation>SpringSource</affiliation>
</author>
</authorgroup>
<legalnotice>
<para>
Copies of this document may be made for your own use and for distribution
to others, provided that you do not charge any fee for such copies and
further provided that each copy contains this Copyright Notice, whether
distributed in print or electronically.
</para>
</legalnotice>
</bookinfo>
<toc/>
<xi:include href="preface.xml"/>
<!--
<part id="introduction">
<title>Introduction</title>
<xi:include href="introduction/introduction.xml"/>
<xi:include href="introduction/why-sd-kv.xml"/>
<xi:include href="introduction/requirements.xml"/>
<xi:include href="introduction/getting-started.xml"/>
</part>
<part id="reference">
<title>Reference Documentation</title>
<xi:include href="reference/introduction.xml"/>
<xi:include href="reference/redis.xml"/>
<xi:include href="reference/riak.xml"/>
</part>
<part id="appendixes">
<title>Appendixes</title>
<xi:include href="appendix/introduction.xml"/>
<xi:include href="appendix/appendix-schema.xml"/>
</part>
-->
<!--
<part id="resources">
<title>Other Documentation</title>
<partintro>
<para>
In addition to this reference documentation, there are a number of
other resources that may help you learn how to use the various key value
stores and Spring Data. These additional, third-party resources are
enumerated in this section.
</para>
</partintro>
<xi:include href="links.xml"/>
</part>
-->
</book>

View File

@@ -0,0 +1,110 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="get-started">
<title>Getting Started</title>
<para>Learning a new framework is not always straight forward. In this section, we (the Spring Data team)
tried to provide, what we think is, an easy to follow guide for starting with Spring Data Key Value module.
Of course, feel free to create your own learning 'path' as you see fit and, if possible, please report back
any improvements to the documentation that can help others.</para>
<section id="get-started:first-steps">
<title>First Steps</title>
<para>As explained in <xref linkend="why-Spring Data-Key Value"/>, Spring Data Key Value (SDKV) provides integration
between Spring framework and key value (KV) stores. Thus, it is important to become acquainted with both of these
frameworks (storages or environments depending on how you want to name them). Throughout the SDKV documentation,
each section provides links to resources relevant however, it is best to become familiar with these topics beforehand.</para>
<section id="get-started:first-steps:spring">
<title>Knowing Spring</title>
<para>Spring Data uses heavily Spring framework's <ulink url="http://static.springframework.org/spring/docs/3.0.x/reference/spring-core.html">core</ulink> functionality,
such as the <ulink url="http://static.springframework.org/spring/docs/3.0.x/reference/beans.html">IoC</ulink> container,
<ulink url="http://static.springframework.org/spring/docs/3.0.x/reference/resources.html">resource</ulink> abstract or
<ulink url="http://static.springframework.org/spring/docs/3.0.x/reference/aop.html">AOP</ulink> infrastructure. While it is not important
to know the Spring APIs, understanding the concepts behind them is. At a minimum, the idea behind IoC should be familiar.
These being said, the more knowledge one has about the Spring, the faster she will pick Spring Data Key Value.
Besides the very comprehensive (and sometimes disarming) documentation that explains in detail the Spring Framework,
there are a lot of articles, blog entries and books on the matter - take a look at the Spring framework
<ulink url="http://www.springsource.org/documentation">home page</ulink> for more information. In general, this should be the starting point for
developers wanting to try Spring DKV.</para>
</section>
<section id="get-started:first-steps:nosql">
<title>Knowing NoSQL and Key Value stores</title>
<para>NoSQL stores have taken the storage world by storm. It is a vast domain with a plethora of solutions, terms and patterns (to make things worth even the
term itself has multiple <ulink url="http://www.google.com/search?q=nosoql+acronym">meanings</ulink>).
While some of the principles are common, it is crucial that the user is familiar to some degree with the stores supported by SDKV.
The best way to get acquainted to this solutions is to read their documentation and follow their examples - it usually doesn't take more then 5-10 minutes
to go through them and if you are coming from an RDMBS-only background many times these exercises can be an eye opener.
</para>
</section>
<section id="get-started:first-steps:samples">
<title>Trying Out The Samples</title>
<para>Unfortunately the SDKV project is very young and there are no samples available yet. However we are working on them and plan to make them available
as soon as possible. In the meantime however, one can use our test suite as a code example (assuming the documentation is not enough) - we provide extensive
integration tests for our code base.
</para>
<!--
<para>The current distribution contains:</para>
<itemizedlist>
<listitem>
<para>Simple Service Sample</para>
<para>A simple example that illustrates OSGi service publication and consumption through Spring DM. This is a good starting point
for users learning the basics.</para>
</listitem>
<listitem>
<para>Weather Sample</para>
<para>A demo that shows more advanced features of Spring DM and OSGi. The application creates a very simple weather information services
presenting some best practices in designing an application to take advantage of the modularity offered by OSGi.</para>
</listitem>
<listitem>
<para>Simple Web App Sample</para>
<para>As the name implies, this is a simple web application, containing Servlets, JSPs and JSP tags, that runs inside OSGi through Spring DM.</para>
</listitem>
<listitem>
<para>Web Console Sample</para>
<para>A more complicated sample that demos a Spring MVC annotation based, web application that runs inside OSGi through Spring DM, featuring
class path scanning and various Spring taglib. Additionally, the web application interacts with the OSGi environment through the web UI.</para>
</listitem>
</itemizedlist>
<para>Each project contains instructions regarding its content and startup procedure. Users are encouraged to experiment with the samples to get a better
understanding of the technologies used.</para>
-->
</section>
</section>
<section id="get-started:help">
<title>Need Help?</title>
<para>If you encounter issues or you are just looking for an advice, feel free to use one of the links below:</para>
<section id="get-started:help:community">
<title>Community Support</title>
<para>The Spring Data <ulink url="http://forum.springframework.org/forumdisplay.php?f=80">forum</ulink> is a message board for all Spring Data (not just Key Value) users to
share information and help each other. Note that registration is needed <emphasis>only</emphasis> for posting.
</para>
</section>
<section id="get-started:help:professional">
<title>Professional Support</title>
<para>Professional, from-the-source support, with guaranteed response time, is available from <ulink url="http://www.springsource.com">SpringSource</ulink>,
the company behind Spring Data and Spring.
</para>
</section>
</section>
<section id="get-started:up-to-date">
<title>Following Development</title>
<para>For information on the Spring Data source code repository, nightly builds and snapshot artifacts please see the Spring Data home
<ulink url="http://www.springsource.org/spring-data">page</ulink>.
</para>
<para>You can help make Spring Data best serve the needs of the Spring community by interacting with developers through the Spring Community
<ulink url="http://forum.springsource.org">forums</ulink>.</para>
<para>If you encounter a bug or want to suggest an improvement,
please create a ticket on the Spring Data issue <ulink url="https://jira.springframework.org/browse/DATAKV">tracker</ulink>.</para>
<para>To stay up to date with the latest news and announcements in the Spring eco system, subscribe to the
Spring Community <ulink url="http://www.springframework.org/">Portal</ulink>.</para>
<para>Lastly, you can follow the SpringSource Data <ulink url="http://blog.springsource.com/category/data-access/">blog</ulink> or the project team on Twitter
(<ulink url="http://twitter.com/costinl">Costin</ulink>)</para>
</section>
</chapter>

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<partintro xmlns="http://docbook.org/ns/docbook" version="5.0">
<para>
<para>This document is the reference guide for Spring Data - Key Value Support.
It explains Key Value module concepts and semantics and the syntax for various
stores namespaces.</para>
<para>For an introduction to key value stores or Spring, or Spring Data examples, please refer to
<xref linkend="get-started"/> - this documentation refers only to Spring Data Key Value Support and
assumes the user is familiar with the key value storages and Spring concepts.</para>
</para>
</partintro>

View File

@@ -0,0 +1,11 @@
<chapter xml:id="requirements" xmlns="http://docbook.org/ns/docbook" version="5.0">
<title>Requirements</title>
<para>Spring Data Key Value 1.x binaries requires JDK level 6.0 and above,
and <ulink url="http://www.springsource.org/documentation">Spring Framework</ulink>
3.0.x and above.</para>
<para>
In terms of key value stores, <ulink url="http://code.google.com/p/redis/">Redis</ulink> 2.0.x
and <ulink url="http://www.basho.com/Riak.html">Riak</ulink> 0.13 are required.
</para>
</chapter>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xml:id="why-Spring Data-Key Value" xmlns="http://docbook.org/ns/docbook" version="5.0">
<title>Why Spring Data - Key Value?</title>
<para>The Spring Framework is the leading full-stack Java/JEE
application framework. It provides a lightweight container and a
non-invasive programming model enabled by the use of dependency
injection, AOP, and portable service abstractions.</para>
<para><ulink url="http://en.wikipedia.org/wiki/NoSQL">NoSQL</ulink>
storages provide an alternative to classical RDBMS for horizontal scalability
and speed. In terms of implementation, Key Value stores represent one of the
largest (and oldest) member in the NoSQL space.</para>
<para>The Spring Data Key Value (or SDKV) framework makes it easy to
write Spring applications that use a Key Value store by eliminating the redundant
tasks and boiler place code required for interacting with the store through
Spring's excellent infrastructure support.</para>
</chapter>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<preface xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="preface">
<title>Preface</title>
<para>The Spring Data Key-Value project applies core Spring concepts to the development of solutions using a key-value style data store.
We provide a "template" as a high-level abstraction for sending and receiving messages.
You will notice similarities to the JDBC support in the Spring Framework.
</para>
</preface>

View File

@@ -0,0 +1,10 @@
<partintro>
<title>Document structure</title>
<para>This part of the reference documentation explains the core functionality
offered by Spring Data Key Value.</para>
<para><xref linkend="redis"/> introduces the Redis module feature set.</para>
<para><xref linkend="riak"/> introduces the Riak module feature set.</para>
</partintro>

View File

@@ -0,0 +1,200 @@
<?xml version="1.0" encoding="UTF-8"?>
<section xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="pubsub">
<title>Redis Messaging/PubSub</title>
<para>Spring Data provides dedicated messaging integration for Redis,
very similar in functionality and naming to the JMS integration in
Spring Framework; in fact, users familiar with the JMS support in Spring, should
feel right at home.</para>
<para>Redis messaging can be roughly divided into two areas of functionality, namely
the production or publication and consumption or subscription of messages, hence the shortcut
pubsub (Publish/Subscribe). The
<classname>RedisTemplate</classname> class is used for message production.
For asynchronous reception similar to
Java EE's message-driven bean style, Spring Data provides a dedicated message
listener containers that is used to create Message-Driven POJOs
(MDPs) and for synchronous reception, the <interfacename>RedisConnection</interfacename> contract.</para>
<para>The package <literal>org.springframework.data.keyvalue.redis.connection</literal> and
<literal>org.springframework.data.keyvalue.redis.listener</literal> provide
the core functionality for using Redis messaging.</para>
<section id="redis:pubsub:publish">
<title>Sending/Publishing messages</title>
<para>To publish a message, one can use, as with the other operations, either the low-level
<interfacename>RedisConnection</interfacename> or the high-level <classname>RedisTemplate</classname>.
Both entities offer the <methodname>publish</methodname> method that accepts as argument the message
that needs to be sent as well as the destination channel. While <interfacename>RedisConnection</interfacename>
requires raw-data (array of bytes), the <classname>RedisTemplate</classname> allow arbitrary objects to be passed
in as messages:</para>
<programlisting lang="java"><![CDATA[// send message through connection
RedisConnection con = ...
byte[] msg = ...
byte[] channel = ...
con.publish(msg, channel);
// send message through RedisTemplate
RedisTemplate template = ...
template.convertAndSend("hello!", "world");]]></programlisting>
</section>
<section id="redis:pubsub:subscribe">
<title>Receiving/Subscribing for messages</title>
<para>On the receiving side, one can subscribe to one or multiple channels either by naming them directly or by using
pattern matching. The latter approach is quite useful as it not only allows multiple subscriptions to be created with
one command but to also listen on channels not yet created at subscription time (as long as match the pattern).
</para>
<para>At the low-level, <interfacename>RedisConnection</interfacename> offers <methodname>subscribe</methodname> and
<methodname>pSubscribe</methodname> methods that map the Redis commands for subscribing by channel respectively by pattern.
Note that multiple channels or patterns can be used as arguments. To change the subscription of a connection or simply query
whether it is listening or not, <interfacename>RedisConnection</interfacename>
provides <methodname>getSubscription</methodname> and <methodname>isSubscribed</methodname> method.</para>
<important>Subscribing commands are synchronized and thus blocking. That is, calling subscribe on a connection will cause
the current thread to block as it will start waiting for messages - the thread will be released only if the subscription
is canceled, that is an additional thread invokes <methodname>unsubscribe</methodname> respectively <methodname>pUnsubscribe</methodname>
on the <emphasis>same</emphasis> connection. See <link linkend="redis:pubsub:subscribe:containers">message listener container</link> below
for a solution to these problem.</important>
<para>As mentioned above, one subscribed a connection starts waiting for messages - no other commands can be invoked on it except
for adding new subscriptions or modifying/canceling the existing ones, that is invoking anything else then <methodname>subscribe</methodname>,
<methodname>pSubscribe</methodname>, <methodname>unsubscribe</methodname>, <methodname>pUnsubscribe</methodname> or is illegal and will
through an exception.</para>
<para>In order to subscribe for messages, one needs to implement the <interfacename>MessageListener</interfacename> callback: each time
a new message arrives, the callback gets invoked and the user code executed through <methodname>onMessage</methodname> method.
The interface gives access not only to the actual message but to the channel it has been received through and the pattern (if any) used
by the subscription to match the channel. This information allows the callee to differentiate between various messages not just by content but
also through data.
</para>
<section id="redis:pubsub:subscribe:containers">
<title>Message Listener Containers</title>
<para>Due to its blocking nature, low-level subscription is not attractive as it requires connection and thread management for every single
listener. To alleviate this problem, Spring Data offers <classname>RedisMessageListenerContainer</classname> which does all the heavy lifting
on behalf of the user - users familiar with EJB and JMS should find the concepts familiar as it is designed as close as possible to the
support in Spring Framework and its message-driven POJOs (MDPs)</para>
<para><classname>RedisMessageListenerContainer</classname> acts as a message listener container; it is used to receive messages from a
Redis channel and drive the MessageListener that are injected into
it. The listener container is responsible for all threading of message
reception and dispatches into the listener for processing. A message
listener container is the intermediary between an MDP and a messaging
provider, and takes care of registering to receive messages, resource acquisition and release,
exception conversion and suchlike. This allows you as an application
developer to write the (possibly complex) business logic associated with
receiving a message (and reacting to it), and delegates
boilerplate Redis infrastructure concerns to the framework.
</para>
<para>Further more, to minimize the application footprint, <classname>RedisMessageListenerContainer</classname> performs allows one connection and one thread
to be shared by multiple listeners even though they do not share a subscription. Thus no matter how many listeners or channels an application tracks,
the runtime cost will remain the same through out its lifetime. Moreover, the container allows runtime configuration changes so one can add or remove
listeners while an application is running without the need for restart. Additionally, the container uses a lazy subscription approach, using a
<interfacename>RedisConnection</interfacename> only when needed - if all the listeners are unsubscribed, cleanup is automatically performed and the used
thread released.</para>
<para>To help with the asynch manner of messages, the container requires a <interfacename>java.util.concurrent.Executor</interfacename> (
or Spring's <interfacename>TaskExecutor</interfacename>) for dispatching the messages. Depending on the load, the number of listeners or the runtime
environment, one should change or tweak the executor to better serve her needs - in particular in managed environments (such as app servers), it is
highly recommended to pick a a proper <interfacename>TaskExecutor</interfacename> to take advantage of its runtime.</para>
</section>
<section id="redis:pubsub:subscribe:adapter">
<title>The <classname>MessageListenerAdapter</classname></title>
<para>The <classname>MessageListenerAdapter</classname> class is the
final component in Spring's asynchronous messaging support: in a
nutshell, it allows you to expose almost <emphasis>any</emphasis> class
as a MDP (there are of course some constraints).</para>
<para>Consider the following interface definition. Notice that although
the interface extends the
<interfacename>MessageListener</interfacename> interface,
it can still be used as a MDP via the use of the
<classname>MessageListenerAdapter</classname> class. Notice also how the
various message handling methods are strongly typed according to the
<emphasis>contents</emphasis> of the various
<interfacename>Message</interfacename> types that they can receive and
handle.</para>
<programlisting language="java">public interface MessageDelegate {
void handleMessage(String message);
void handleMessage(Map message);
void handleMessage(byte[] message);
void handleMessage(Serializable message);
}</programlisting>
<programlisting language="java">public class DefaultMessageDelegate implements MessageDelegate {
<lineannotation>// implementation elided for clarity...</lineannotation>
}</programlisting>
<para>In particular, note how the above implementation of the
<interfacename>MessageDelegate</interfacename> interface (the above
<classname>DefaultMessageDelegate</classname> class) has
<emphasis>no</emphasis> Redis dependencies at all. It truly is a POJO that
we will make into an MDP via the following configuration.</para>
<programlisting language="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<lineannotation>xmlns:redis="http://www.springframework.org/schema/redis"</lineannotation>
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
<lineannotation>http://www.springframework.org/schema/redis http://www.springframework.org/schema/redis/spring-redis.xsd"</lineannotation>&gt;
&lt;!-- the default ConnectionFactory --&gt;
&lt;redis:listener-container&gt;
&lt;!-- the method attribute can be skipped as the default method name is "handleMessage" --&gt;
&lt;redis:listener ref="listener" method="handleMessage" topic="chatroom" /&gt;
&lt;/redis:listener-container&gt;
&lt;bean class="redisexample.DefaultMessageDelegate"/&gt;
...
&lt;beans&gt;
</programlisting>
<note>The listener topic can be either a channel (e.g. <literal>topic="chatroom"</literal>) or a pattern (e.g. <literal>topic="*room"</literal>)</note>
<para>The example above uses the Redis namespace to declare the message listener container and automatically register the POJOs as listeners. The full blown, <emphasis>beans</emphasis> definition
is displayed below:</para>
<programlisting language="xml"><lineannotation>&lt;!-- this is the Message Driven POJO (MDP) --&gt;</lineannotation>
<emphasis role="bold">&lt;bean id="messageListener" class="org.springframework.data.keyvalue.redis.listener.adapter.MessageListenerAdapter"&gt;</emphasis>
&lt;constructor-arg&gt;
&lt;bean class="redisexample.DefaultMessageDelegate"/&gt;
&lt;/constructor-arg&gt;
&lt;/bean&gt;
<lineannotation>&lt;!-- and this is the message listener container... --&gt;</lineannotation>
&lt;bean id="redisContainer" class="org.springframework.data.keyvalue.redis.listener.RedisMessageListenerContainer"&gt;
&lt;property name="connectionFactory" ref="connectionFactory"/&gt;
&lt;property name="messageListeners"&gt;
<lineannotation>&lt;!-- map of listeners and their associated topics (channels or/and patterns) --&gt;</lineannotation>
&lt;map&gt;
<emphasis role="bold">&lt;entry key-ref="messageListener"&gt;</emphasis>
&lt;bean class="org.springframework.data.keyvalue.redis.listener.ChannelTopic">
&lt;constructor-arg value="chatroom"&gt;
&lt;/bean&gt;
&lt;/entry&gt;
&lt;/map&gt;
&lt;/property&gt;
&lt;/bean&gt;</programlisting>
<para>Each time a message is received, the adapter automatically performs
translation (using the configured <interfacename>RedisSerializer</interfacename>)
between the low-level format and the required object type transparently. Any exception caused by the method invocation
is caught and handled by the container (by default, being logged).
</para>
</section>
</section>
</section>

View File

@@ -0,0 +1,415 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xi="http://www.w3.org/2001/XInclude" xml:id="redis">
<title>Redis support</title>
<para>One of the key value stores supported by SDKV is <ulink url="http://redis.io">Redis</ulink>.
To quote the project home page:
<quote>
Redis is an advanced key-value store. It is similar to memcached but the dataset is not volatile, and values can be strings,
exactly like in memcached, but also lists, sets, and ordered sets. All this data types can be manipulated with atomic operations
to push/pop elements, add/remove elements, perform server side union, intersection, difference between sets, and so forth.
Redis supports different kind of sorting abilities.</quote>
<para>Spring Data Key Value provides easy configuration and access to Redis from Spring application. Offers both low-level and
high-level abstraction for interacting with the store, freeing the user from infrastructural concerns.</para>
</para>
<section id="redis:requirements">
<title>Redis Requirements</title>
<para>SDKV requires Redis 2.0 or above (Redis 2.2 is recommended) and Java SE 6.0 or above.
In terms of language bindings (or connectors), SDKV integrates with <ulink url="http://github.com/xetorthio/jedis">Jedis</ulink>,
<ulink url="http://github.com/alphazero/jredis">JRedis</ulink> and <ulink url="http://github.com/e-mzungu/rjc">RJC</ulink>, three popular open source Java libraries for Redis.
If you are aware of any other connector that we should be integrating is, please send us feedback.
</para>
</section>
<section id="redis:architecture">
<title>Redis Support High Level View</title>
<para>The Redis support provides several components (in order of dependencies):</para>
<itemizedlist>
<listitem><emphasis>Low-Level Abstractions</emphasis> - for configuring and handling communication with Redis through the various connector libraries supported as
described in <xref linkend="redis:connectors"/>. </listitem>
<listitem><emphasis>High-Level Abstractions</emphasis> - providing a generified, user friendly template classes for interacting with Redis.
<xref linkend="redis:template"/> explains the abstraction builds on top of the low-level <interfacename>Connection</interfacename> API to handle the
infrastructural concerns and object conversion.</listitem>
<listitem><emphasis>Support Classes</emphasis> - that offer reusable components (built on the aforementioned abstractions) such as
<interfacename>java.util.Collection</interfacename> backed by Redis as documented in <xref linkend="redis:support"/></listitem>
</itemizedlist>
<para>For most tasks, the high-level abstractions and support services are the best choice. Note that at any point, one can move between layers - for example, it's very
easy to get a hold of the low level connection (or even the native libray) to communicate directly with Redis.</para>
</section>
<section id="redis:connectors">
<title>Connecting to Redis</title>
<para>One of the first tasks when using Redis and Spring is to connect to the store through the IoC container. To do that, a Java connector (or binding) is required;
currently SDKV has support for Jedis and JRedis. No matter the library one chooses, there only one set of SDKV API that one needs to use that behaves consistently
across all connectors, namely the <literal>org.springframework.data.keyvalue.redis.connection</literal> package and its
<interfacename>RedisConnection</interfacename> and <interfacename>RedisConnectionFactory</interfacename> interfaces for working respectively for retrieving active
<literal>connection</literal> to Redis.</para>
<section id="redis:connectors:connection">
<title><interfacename>RedisConnection</interfacename> and <interfacename>RedisConnectionFactory</interfacename></title>
<para><interfacename>RedisConnection</interfacename> provides the building block for Redis communication as it handles the communication with the Redis back-end.
It also automatically translates the underlying connecting library exceptions to Spring's consistent DAO exception
<ulink url="http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/dao.html#dao-exceptions">hierarchy</ulink> so one can switch the connectors
without any code changes as the operation semantics remain the same.</para>
<note>For the corner cases where the native library API is required, <interfacename>RedisConnection</interfacename> provides a dedicated method
<methodname>getNativeConnection</methodname> which returns the raw, underlying object used for communication.</note>
<para>Active <interfacename>RedisConnection</interfacename> are created through <interfacename>RedisConnectionFactory</interfacename>. In addition, the factories act as
<interfacename>PersistenceExceptionTranslator</interfacename> meaning once declared, allow one to do transparent exception translation for example through the use of the
<literal>@Repository</literal> annotation and AOP. For more information see the dedicated
<ulink url="http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/orm.html#orm-exception-translation">section</ulink> in Spring Framework documentation.</para>
<note>Depending on the underlying configuration, the factory can return a new connection or an existing connection (in case a pool is used).</note>
</section>
<para>The easiest way to work with a <interfacename>RedisConnectionFactory</interfacename> is to configure the appropriate connector through the IoC container and
inject it into the using class.</para>
<sidebar>
<title>Connector features</title>
<para>Unfortunately, currently, not connectors support all of Redis features - in particular JRedis does not have support for hashes yet though this is currently being worked on.
When invoking a method on the <interfacename>Connection</interfacename> API that is unsupported by the underlying library, a <classname>UnsupportedOperationException</classname>
is thrown.
This situation is likely to be fixed in the future, as the various connectors mature.
</para>
</sidebar>
<section id="redis:connectors:jedis">
<title>Configuring Jedis connector</title>
<para><ulink url="http://github.com/xetorthio/jedis">Jedis</ulink> is one of the connectors supported by the Key Value module through the
<literal>org.springframework.data.keyvalue.redis.connection.jedis</literal> package. In its simples form, the Jedis configuration looks as follow:</para>
<programlisting language="xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Jedis ConnectionFactory -->
<bean id="jedisConnectionFactory" class="org.springframework.data.keyvalue.redis.connection.jedis.JedisConnectionFactory"/>
</beans>]]></programlisting>
<para>For production use however, one might want to tweak the settings such as the host or password:</para>
<programlisting language="xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="jedisConnectionFactory" class="org.springframework.data.keyvalue.redis.connection.jedis.JedisConnectionFactory"
p:host-name="server" p:port="6379"/>
</beans>]]></programlisting>
</section>
<section id="redis:connectors:jredis">
<title>Configuring JRedis connector</title>
<para><ulink url="http://github.com/alphazero/jredis">JRedis</ulink> is another popular, open-source connector supported by SDKV through the
<literal>org.springframework.data.keyvalue.redis.connection.jredis</literal> package.</para>
<note>Since JRedis itself does not support (yet) Redis 2.x commands, SDKV uses an updated fork available
<ulink url="http://github.com/anthonylauzon/jredis">here</ulink>.</note>
<para>A typical JRedis configuration can looks like this:</para>
<programlisting language="xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="jredisConnectionFactory" class="org.springframework.data.keyvalue.redis.connection.jredis.JredisConnectionFactory"
p:host-name="server" p:port="6379"/>
</beans>]]></programlisting>
<para>As one can note, the configuration is quite similar to the Jedis one.</para>
<important><para>Currently, JRedis does not have support for binary keys. This forces the <classname>JredisConnection</classname> to perform encoding internally
(through <ulink url="http://en.wikipedia.org/wiki/Base64">base64</ulink> schema). In practice, this means it's safe to read/write arbitrary data however
the Redis key stored values will differ from the decoded ones, even in the simplest cases, since everything (no matter the format) is encoded. This will not be
the case for Redis values.</para>
<para>This issue is currently being addressed in the JRedis project and once fixed, will be incorporated by Spring Data Redis.</para>
</important>
</section>
<section id="redis:connectors:rjc">
<title>Configuring RJC connector</title>
<para><ulink url="http://github.com/e-mzungu/rjc">RJC</ulink> is the third, open-source connector supported by SDKV through the
<literal>org.springframework.data.keyvalue.redis.connection.rjc</literal> package.</para>
<para>Similar to the other connectors, a typical RJC configuration can looks like this:</para>
<programlisting language="xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="jredisConnectionFactory" class="org.springframework.data.keyvalue.redis.connection.rjc.RjcConnectionFactory"
p:host-name="server" p:port="6379"/>
</beans>]]></programlisting>
<para>As one can note, the configuration is quite similar to the Jredis or Jedis one.</para>
<important><para>Currently, RJC does not have support for binary keys. This forces the <classname>RjcConnection</classname> to perform encoding internally
(through <ulink url="http://en.wikipedia.org/wiki/Base64">base64</ulink> schema). In practice, this means it's safe to read/write arbitrary data however
the Redis key stored values will differ from the decoded ones, even in the simplest cases, since everything (no matter the format) is encoded. This will not be
the case for Redis values.</para>
<para>This issue is currently being addressed in the RJC project and once fixed, will be incorporated by Spring Data Redis.</para>
</important>
</section>
</section>
<section id="redis:template">
<title>Working with Objects through <classname>RedisTemplate</classname></title>
<para>Most users are likely to use <classname>RedisTemplate</classname> and its coresponding package <literal>org.springframework.data.keyvalue.redis.core</literal> - the
template is in fact the central class of the Redis module due to its rich feature set.
The template offers a high-level abstraction for Redis interaction - while <interfacename>RedisConnection</interfacename> offer low level methods that accept and return
binary values (<literal>byte</literal> arrays), the template takes care of serialization and connection management, freeing the user from dealing with such details.</para>
<para>Moreover, the template provides operations views (following the grouping from Redis command <ulink url="http://redis.io/commands">reference</ulink>)
that offer rich, generified interfaces for working against a certain type or certain key (through the <interfacename>KeyBound</interfacename> interfaces) as described below:</para>
<table id="redis-template-operations-view" pgwide="1">
<title>Operational views</title>
<tgroup cols="2">
<colspec colname="c1" colwidth="1*" align="center"/>
<colspec colname="c2" colwidth="1*" align="center"/>
<spanspec spanname="both" namest="c1" nameend="c2" colsep="0" align="center" />
<thead>
<row>
<entry>Interface</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row rowsep="0">
<entry spanname="both"><emphasis><![CDATA[Key Type Operations]]></emphasis></entry>
</row>
<row>
<entry><interfacename>ValueOperations</interfacename></entry>
<entry>Redis string (or value) operations</entry>
</row>
<row>
<entry><interfacename>ListOperations</interfacename></entry>
<entry>Redis list operations</entry>
</row>
<row>
<entry><interfacename>SetOperations</interfacename></entry>
<entry>Redis set operations</entry>
</row>
<row>
<entry><interfacename>ZSetOperations</interfacename></entry>
<entry>Redis zset (or sorted set) operations</entry>
</row>
<row>
<entry><interfacename>HashOperations</interfacename></entry>
<entry>Redis hash operations</entry>
</row>
<row>
<entry spanname="both"><emphasis><![CDATA[Key Bound Operations]]></emphasis></entry>
</row>
<row>
<entry><interfacename>BoundValueOperations</interfacename></entry>
<entry>Redis string (or value) key bound operations</entry>
</row>
<row>
<entry><interfacename>BoundListOperations</interfacename></entry>
<entry>Redis list key bound operations</entry>
</row>
<row>
<entry><interfacename>BoundSetOperations</interfacename></entry>
<entry>Redis set key bound operations</entry>
</row>
<row>
<entry><interfacename>BoundZSetOperations</interfacename></entry>
<entry>Redis zset (or sorted set) key bound operations</entry>
</row>
<row>
<entry><interfacename>BoundHashOperations</interfacename></entry>
<entry>Redis hash key bound operations</entry>
</row>
</tbody>
</tgroup>
</table>
<para>Once configured, the template is thread-safe and can be reused across multiple instances.</para>
<para>Out of the box, <classname>RedisTemplate</classname> uses a Java-based serializer for most of its operations. This means that any object written or read by the template will be
serializer/deserialized through Java. The serialization mechanism can be easily changed on the template and the Redis module offers several implementations available in the
<literal>org.springframework.data.keyvalue.redis.serializer</literal> package - see <xref linkend="redis:serializer"/> for more information.
Note that the template requires all keys to be non-null - values can be null as long as the underlying
serializer accepts them; read the javadoc of each serializer for more information.</para>
<para>For cases where a certain template <emphasis>view</emphasis> is needed, one the view as a dependency and inject the template: the container will automatically perform the conversion
eliminating the <literal>opsFor[X]</literal> calls:</para>
<programlisting language="xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="jedisConnectionFactory" class="org.springframework.data.keyvalue.redis.connection.jedis.JedisConnectionFactory"
p:use-pool="true"/>
<!-- redis template definition -->
<bean id="redisTemplate" class="org.springframework.data.keyvalue.redis.core.RedisTemplate"
p:connection-factory-ref="jedisConnectionFactory"/>
...
</beans>]]></programlisting>
<programlisting language="java"><![CDATA[public class Example {
// inject the actual template
@Autowired
private RedisTemplate<String, String> template;
// inject the template as ListOperations
@Autowired
private ListOperations<String, String> listOps;
public void addLink(String userId, URL url) {
listOps.leftPush(userId, url.toExternalForm());
}
}]]></programlisting>
</section>
<section id="redis:string">
<title>String-focused convenience classes</title>
<para>Since it's quite the keys and values stored in Redis can be <classname>java.lang.String</classname>, the Redis modules provides two extensions to <interfacename>RedisConnection</interfacename>
and <classname>RedisTemplate</classname> respectively the <interfacename>StringRedisConnection</interfacename> (and its <classname>DefaultStringRedisConnection</classname> implementation)
and <classname>StringRedisTemplate</classname> as a convenient one-stop solution
for intensive String operations. In addition to be bound to <literal>String</literal> keys, the template and the connection use the
<classname>StringRedisSerializer</classname> underneath which means the stored keys and values are human readable (assuming the same encoding is used both in Redis and your code).
For example:
</para>
<programlisting language="xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="jedisConnectionFactory" class="org.springframework.data.keyvalue.redis.connection.jedis.JedisConnectionFactory"
p:use-pool="true"/>
<bean id="stringRedisTemplate" class="org.springframework.data.keyvalue.redis.core.StringRedisTemplate"
p:connection-factory-ref="jedisConnectionFactory"/>
...
</beans>]]></programlisting>
<programlisting language="java"><![CDATA[public class Example {
@Autowired
private StringRedisTemplate redisTemplate;
public void addLink(String userId, URL url) {
redisTemplate.opsForList().leftPush(userId, url.toExternalForm());
}
}]]></programlisting>
<para>As with the other Spring templates, <classname>RedisTemplate</classname> and <classname>StringRedisTemplate</classname> allow the developer to talk directly to Redis through
the <interfacename>RedisCallback</interfacename> interface: this gives complete control to the developer as it talks directly to the <interfacename>RedisConnection</interfacename>.
</para>
<programlisting language="java"><![CDATA[public void useCallback() {
redisTemplate.execute(new RedisCallback<Object>() {
public Object doInRedis(RedisConnection connection) throws DataAccessException {
Long size = connection.dbSize();
...
}
});
}]]></programlisting>
</section>
<section id="redis:serializer">
<title>Serializers</title>
<para>From the framework perspective, the data stored in Redis are just bytes. While Redis itself supports various types, for the most part these refer to the way the data is stored
rather then what it represents. It is up to the user to decide whether the information gets translated into Strings or any other objects. The conversion between the user (custom)
types and raw data (and vice-versa) is handled in SDKV Redis through the <interfacename>RedisSerializer</interfacename> interface
(package <literal>org.springframework.data.keyvalue.redis.serializer</literal>) which as the name implies, takes care of the serialization process. Multiple implementations are
available out of the box, two of which have been already mentioned before in this documentation: the <literal>StringRedisSerializer</literal> and
the <literal>JdkSerializationRedisSerializer</literal>. However one can use <classname>OxmSerializer</classname> for Object/XML mapping through Spring 3
<ulink url="http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/oxm.html">OXM</ulink> support or <classname>JacksonJsonRedisSerializer</classname> for storing
data in <ulink url="http://en.wikipedia.org/wiki/JSON">JSON</ulink> format. Do note that the storage format is not limited only to values - it can be used for keys, values or hashes
without any restrictions.</para>
</section>
<xi:include href="redis-messaging.xml"/>
<section id="redis:support">
<title>Support Classes</title>
<para>Package <literal>org.springframework.data.keyvalue.redis.support</literal> offers various reusable components that rely on Redis as a backing store. Curently the package contains
various JDK-based interface implementations on top of Redis such as <ulink url="http://download.oracle.com/javase/6/docs/api/java/util/concurrent/atomic/package-summary.html">atomic</ulink>
counters and JDK <interfacename><ulink url="http://download.oracle.com/javase/6/docs/api/java/util/Collection.html">Collections</ulink></interfacename>.</para>
<para>The atomic counters make it easy to wrap Redis key incrementation while the collections allow easy management of Redis keys with minimal storage exposure or API leakage: in particular
the <interfacename>RedisSet</interfacename> and <interfacename>RedisZSet</interfacename> interfaces offer easy access to the <emphasis>set</emphasis> operations supported by Redis such as
<literal>intersection</literal> and <literal>union</literal> while <interfacename>RedisList</interfacename> implements the <interfacename>List</interfacename>,
<interfacename>Queue</interfacename> and <interfacename>Deque</interfacename> contracts (and their equivalent blocking siblings) on top of Redis, exposing the storage as a
<emphasis>FIFO (First-In-First-Out)</emphasis>, <emphasis>LIFO (Last-In-First-Out)</emphasis> or <emphasis>capped collection</emphasis> with minimal configuration:</para>
<programlisting language="xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="queue" class="org.springframework.data.keyvalue.redis.support.collections.DefaultRedisList">
<constructor-arg ref="redisTemplat"/>
<constructor-arg value="queue-key"/>
</bean>
</beans>]]></programlisting>
<programlisting language="java"><![CDATA[public class AnotherExample {
// injected
private Deque<String> queue;
public void addTag(String tag) {
queue.push(tag);
}
}]]></programlisting>
<para>As shown in the example above, the consuming code is decoupled from the actual storage implementation - in fact there is no indication that Redis is used underneath. This makes moving from
development to production environments transparent and highly increases testability (the Redis implementation can just as well be replaced with an in-memory one).</para>
</section>
<section id="redis:future">
<title>Roadmap ahead</title>
<para>Spring Data Redis project is in its early stages. We are interested in feedback, knowing what your use cases are, what are the common patters you encounter so that the Redis module
better serves your needs. Do contact us using the channels <link linkend="get-started:help:community">mentioned</link> above, we are interested in hearing from you!</para>
</section>
</chapter>

View File

@@ -0,0 +1,547 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xml:id="riak" xmlns="http://docbook.org/ns/docbook" version="5.0">
<title>Riak Support</title>
<para><ulink url="https://wiki.basho.com/display/RIAK/Riak">Riak</ulink> is a Key/Value datastore that supports <ulink url="https://wiki.basho.com/pages/viewpage.action?pageId=1245320">Internet-scale data replication</ulink> for high performance and high availability. Spring Data Key/Value (SDKV) provides access to the Riak datastore over the <ulink url="https://wiki.basho.com/display/RIAK/REST+API">HTTP REST API</ulink> using a built-in driver based on Spring 3.0's <ulink url="http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/remoting.html#rest-resttemplate"><classname>RestTemplate</classname></ulink>. In addition to making Key/Value datastore access easier from Java, the <classname>RiakTemplate</classname> has been designed, from the ground up, to be used from alternative JVM languages like <ulink url="http://groovy.codehaus.org/">Groovy</ulink> or <ulink url="http://jruby.org/">JRuby</ulink>.</para>
<para>Since the SDKV support for Riak uses the stateless REST API, there are no connection factories to manage or other stateful objects to keep tabs on. The helper you'll spend the most time working with is likely the thread-safe <classname>RiakTemplate</classname> or <classname>RiakKeyValueTemplate</classname>. Your choice of which to use will depend on how you want to manage buckets and keys. SDKV supports two ways to interact with Riak. If you want to use the convention you're likely already familiar with, namely of storing an entry with a given key in a "bucket" by passing the bucket and key name separately, you'll want to use the <classname>RiakTemplate</classname>. If you want to use a single object to represent your bucket and key pair, you can use the <classname>RiakKeyValueTemplate</classname>. It supports a key object that is encoded using one of several different methods:
<itemizedlist>
<listitem><emphasis>Using a <classname>String</classname></emphasis> - You can concatenate two strings, separated by a colon: "mybucket:mykey".</listitem>
<listitem><emphasis>Using a <interfacename>BucketKeyPair</interfacename></emphasis> - You can pass an instance of <interfacename>BucketKeyPair</interfacename>, like <classname>SimpleBucketKeyPair</classname>.</listitem>
<listitem><emphasis>Using a <interfacename>Map</interfacename></emphasis> - You can pass a <interfacename>Map</interfacename> with keys for "bucket" and "key".</listitem>
</itemizedlist>
</para>
<section id="riak:template:config">
<title>Configuring the <classname>RiakTemplate</classname></title>
<para>This is likely the easiest path to using SDKV for Riak, as the bucket and key are passed separately. The examples that follow will assume you're using this version of the the template.</para>
<para>There are only two options you need to set to specify the Riak server to use in your <classname>RiakTemplate</classname> object: "defaultUri" and "mapReduceUri". Encoded with the URI should be placeholders for the bucket and the key, which will be filled in by the <classname>RestTemplate</classname> when the request is made.
<important><para>You can also turn the internal, ETag-based object cache off by setting <literal>useCache="false"</literal>. It's generally recommended, however, to leave the internal cache on as the ETag matching will pick up any changes made to the entry on the Riak side and your application will benefit from greatly-increased performance for often-requested objects.</para></important>
<programlisting language="xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="riakTemplate" class="org.springframework.data.keyvalue.riak.core.RiakTemplate"
p:defaultUri="http://localhost:8098/riak/{bucket}/{key}"
p:mapReduceUri="http://localhost:8098/mapred"
p:useCache="true"/>
</beans>]]></programlisting>
</para>
<section id="riak:template:config:advanced">
<title>Advanced Template Configuration</title>
<para>There are a couple additional properties on the <classname>RiakTemplate</classname> that can be changed from their defaults. If you want to specify your own <ulink url="http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/validation.html#core-convert-ConversionService-API">ConversionService</ulink> to use when converting objects for storage inside Riak, then set it on the "conversionService" property:
<programlisting language="xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="conversionService" class="com.mycompany.convert.MyConversionService"/>
<bean id="riakTemplate" class="org.springframework.data.keyvalue.riak.core.RiakTemplate"
p:defaultUri="http://localhost:8098/riak/{bucket}/{key}"
p:mapReduceUri="http://localhost:8098/mapred"
p:conversionService-ref="conversionService"/>
</beans>]]></programlisting>
</para>
<para>Depending on the application, it might be useful to set default Quality-of-Service parameters. In Riak paralance, these are the <ulink url="https://wiki.basho.com/display/RIAK/REST+API#RESTAPI-Setbucketproperties">"dw", "w", and "r" parameters</ulink>. They can be set to an integer representing the number of vnodes that need to report having received the data before declaring the operation a success, or the string "one", "all", or (the default) "quorum". These values can be overridden by passing a different set of <interfacename>QosParameters</interfacename> to the set/get operation you're performing.
<programlisting language="xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="qos" class="org.springframework.data.keyvalue.riak.core.RiakQosParameters"
p:durableWriteThreshold="all"
p:writeThreshold="all"/>
<bean id="riakTemplate" class="org.springframework.data.keyvalue.riak.core.RiakTemplate"
p:defaultUri="http://localhost:8098/riak/{bucket}/{key}"
p:mapReduceUri="http://localhost:8098/mapred"
p:defaultQosParameters-ref="qos"/>
</beans>]]></programlisting>
</para>
<para>You can also set a specific <literal>ClassLoader</literal> to use when loading objects from Riak. Just set the <literal>classLoader</literal> property:
<programlisting language="xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="riakTemplate" class="org.springframework.data.keyvalue.riak.core.RiakTemplate"
p:defaultUri="http://localhost:8098/riak/{bucket}/{key}"
p:mapReduceUri="http://localhost:8098/mapred"
p:classLoader-ref="customClassLoader"/>
</beans>]]></programlisting>
</para>
</section>
</section>
<section id="riak:template:objects">
<title>Working with Objects using the <classname>RiakTemplate</classname></title>
<para>One of the primary goals of the SDKV project is to make accessing Key/Value stores easier for the developer by taking away the mundane tasks of basic IO, buffering, type conversion, exception handling, and sundry other logistical concerns so the developer can focus on creating great applications. SDKV for Riak works toward this goal by making basic persistence and data access as easy as using a <classname>Map</classname>.</para>
<section id="riak:template:objects:set">
<title>Saving data into Riak</title>
<para>To store data in Riak, use one of the six different <literal>set</literal> methods:
<programlisting language="java"><![CDATA[import org.springframework.data.keyvalue.riak.core.RiakTemplate;
public class Example {
@Autowired
RiakTemplate riak;
public void setData(String bucket, String key, String data) throws Exception {
riak.set(bucket, key, data); // Set as Content-Type: text/plain
riak.setAsBytes(bucket, key, data.getBytes()); // Set as Content-Type: application/octet-stream
}
public void setData(String bucket, String key, MyPojo data) throws Exception {
riak.set(bucket, key, data); // Converted to JSON automatically, Content-Type: application/json
}
}
]]></programlisting>
</para>
<para>Additionally, there is a <literal>setWithMetaData</literal> method that takes a <classname>Map</classname> of metadata that will be set as the outgoing HTTP headers. To set <ulink url="https://wiki.basho.com/display/RIAK/REST+API#RESTAPI-Storeaneworexistingobjectwithakey">custom metadata</ulink>, your key should be prefixed with <literal>X-Riak-Meta-</literal> e.g. <literal>X-Riak-Meta-Custom-Header</literal>.</para>
<section id="riak:template:objects:set:genid">
<title>Letting Riak generate the key</title>
<para>Riak has the ability to generate random IDs for you when storing objects. The <classname>RiakTemplate</classname> exposes this capability via the <literal>put</literal> method. It will return the ID it generated for you as a <classname>String</classname>.
<programlisting language="java"><![CDATA[import org.springframework.data.keyvalue.riak.core.RiakTemplate;
public class Example {
@Autowired
RiakTemplate riak;
public String setData(String bucket, String data) throws Exception {
String id = riak.put(bucket, data); // Returns the generated ID
return id;
}
}
]]></programlisting>
</para>
</section>
</section>
<section id="riak:template:objects:get">
<title>Retrieving data from Riak</title>
<para>Retrieving data from Riak is just as easy. There are actually 13 different <literal>get</literal> methods on <classname>RiakTemplate</classname> that give the developer a wide range options for accessing and converting your data.</para>
<para>Assuming you've stored a POJO using an appropriate <literal>set</literal> method, you can retrieve that object from Riak using a <literal>get</literal>:
<programlisting language="java"><![CDATA[import org.springframework.data.keyvalue.riak.core.RiakTemplate;
public class Example {
@Autowired
RiakTemplate riak;
public void getData(String bucket, String key) throws Exception {
// What you get depends on Content-Type.
// application/json=Map, text/plain=String, etc...
Object o = riak.get(bucket, key);
// If your entry is Content-Type: application/json...
// It will automatically be converted when retrieved.
MyPojo s = riak.getAsType(bucket, key, MyPojo.class);
// If your entry is Content-Type: application/octet-stream,
// you can access the raw bytes.
byte[] b = riak.getAsBytes(bucket, key);
}
}
]]></programlisting>
</para>
</section>
</section>
<section id="riak:links">
<title>Linking Entries</title>
<para>Riak has the ability to <ulink url="https://wiki.basho.com/display/RIAK/Links">link entries together using an arbitrary tag</ulink>. This relationship information is stored in the <literal>Link</literal> header. The <classname>RiakTemplate</classname> exposes a method for linking entries together called <ulink url="../../api/org/springframework/data/keyvalue/riak/core/RiakTemplate.html#link(B1, K1, B2, K2, java.lang.String)"><literal>link</literal></ulink>. Its usage is quite simple:
<important><para>A link is uni-directional, so keep in mind that the bucket and key you pass first should be that of the child (or target) object and the second set of bucket/key pairs you pass to the <literal>link</literal> method is the source of the relationship. It's this second entry that will receive an updated <literal>Link</literal> header that points to the child or target entry.</para></important>
<programlisting language="java"><![CDATA[
@Autowired
RiakTemplate riak;
riak.link("childbucket", "childkey", "sourcebucket", "sourcekey", "tagname");
]]></programlisting>
<para>Now, querying the metadata on the entry at <literal>sourcebucket:sourcekey</literal> will result in a Link header that points to the child object: <literal>&lt;/riak/childbucket/childkey&gt;; riaktag="tagname"</literal></para>
</para>
<section id="riak:links:walking">
<title>Link Walking</title>
<para>When entries are linked together in Riak, those relationships can be efficiently traversed on the server using a feature called <ulink url="http://blog.basho.com/2010/02/24/link-walking-by-example/">Link Walking</ulink>. Rather than requesting each object in a link's relationship individually, a link walk pulls all the related objects at once and sends that data back to the client as MIME-encoded multipart data. As such, it requires special processing to convert those multiple entries into a <interfacename>List</interfacename> of objects, just as if you had used a <literal>get</literal> method. If you don't specify a type to convert the objects to, the <ulink url="../../api/org/springframework/data/keyvalue/riak/core/RiakTemplate.html#linkWalk(B, K, java.lang.String)"><literal>linkWalk</literal></ulink> method will try to infer it from the bucket name. If the bucket name is not a valid class name, it will default to using a <interfacename>java.util.Map</interfacename>.</para>
<para>To link walk a relationship and return a list of custom POJOs, you would do something like this:
<programlisting language="java"><![CDATA[
@Autowired
RiakTemplate riak;
List<MyPojo> result = riak.linkWalk("sourcebucket", "sourcekey", "tagname", MyPojo.class);
]]></programlisting>
</para>
</section>
</section>
<section id="riak:mapred">
<title>Map/Reduce</title>
<para>Riak supports Map/Reduce functionality in a couple different ways. You can specify the Javascript source to execute (termed "anonymous" Javascript), you can reference some Javascript already stored in Riak at a specfic bucket and key, or you can reference an Erlang module and function. The Map/Reduce support in SDKV covers all these bases by giving you meaningful abstractions over the Map/Reduce job that represent the various aspects of the Map/Reduce process.</para>
<para>At the highest level, every Map/Reduce request is represented by a <ulink url="../../api/org/springframework/data/keyvalue/riak/mapreduce/MapReduceJob.html">MapReduceJob</ulink>. The <literal>MapReduceJob</literal> represents the <literal>inputs</literal>, the <literal>phases</literal>, and the optional <literal>arg</literal> to send to Riak to execute the Map/Reduce job. The <literal>toJson</literal> method is responsible for serializing the entire job into the appropriate JSON data to send to Riak.</para>
<section id="riak:mapred:inputs">
<title>Specifying Inputs</title>
<para>Riak will accept either a string denoting the bucket in which to get the list of keys to operate on, or a <interfacename>List</interfacename> of <interfacename>List</interfacename>s denoting the bucket/key pairs to operate on while executing this Map/Reduce job. If you call the <literal>addInputs</literal> method on the job passing a <interfacename>List</interfacename> with a single string entry, the job will assume you want to operate on an entire bucket. Otherwise, you'll need to pass a multi-dimensional <interfacename>List</interfacename> of bucket/key pairs.</para>
<para>To operate on an entire bucket:
<programlisting language="java"><![CDATA[
@Autowired
RiakTemplate riak;
RiakMapReduceJob job = riak.createMapReduceJob();
List<String> bucket = new ArrayList<String>() {{
add("mybucket");
}};
job.addInputs(bucket); // Will M/R entire bucket
]]></programlisting>
</para>
<para>To operate on a set of keys:
<programlisting language="java"><![CDATA[import org.springframework.data.keyvalue.riak.mapreduce.*;
@Autowired
RiakTemplate riak;
RiakMapReduceJob job = riak.createMapReduceJob();
List<String> pair = new ArrayList<String>() {{
add("mybucket");
add("mykey");
}};
List<List<String>> keys = new ArrayList<List<String>>() {{
add(pair);
}};
job.addInputs(keys); // Will M/R only specified keys
]]></programlisting>
</para>
</section>
<section id="riak:mapred:phases">
<title>Defining Phases</title>
<para>Map/Reduce operations in Riak are broken up into phases. Phases contain a <ulink url="../../api/org/springframework/data/keyvalue/riak/mapreduce/MapReduceOperation.html"><interfacename>MapReduceOperation</interfacename></ulink>. There are currently two implementations to handle Javascript or Erlang M/R operations: <ulink url="../../api/org/springframework/data/keyvalue/riak/mapreduce/JavascriptMapReduceOperation.html"><classname>JavascriptMapReduceOperation</classname></ulink> and <ulink url="../../api/org/springframework/data/keyvalue/riak/mapreduce/ErlangMapReduceOperation.html"><classname>ErlangMapReduceOperation</classname></ulink>.</para>
<para>An example Map/Reduce job defining a single "map" phase defined in anonymous Javascript might look like this:
<programlisting language="java"><![CDATA[import org.springframework.data.keyvalue.riak.mapreduce.*;
@Autowired
RiakTemplate riak;
RiakMapReduceJob job = riak.createMapReduceJob();
List<String> bucket = new ArrayList<String>() {{
add("mybucket");
}};
job.addInputs(bucket); // M/R the entire bucket
MapReduceOperation mapOper = new JavascriptMapReduceOperation("function(v){ ...M/R function body... }");
MapReducePhase mapPhase = new RiakMapReducePhase("map", "javascript", mapOper);
job.addPhase(mapPhase);
]]></programlisting>
</para>
</section>
<section id="riak:mapred:exec">
<title>Executing and Working with the Result</title>
<para>To execute a configured job on your Riak server, use either the synchronous <literal>execute</literal> or asynchronous <literal>submit</literal> methods of your configured <classname>RiakTemplate</classname>:
<programlisting language="java"><![CDATA[
Object o = riak.execute(job); // Results of last Map or Reduce phase. Should be a List<?>
...or...
List<MyPojo> o = riak.execute(job, MyPojo.class); // Coerce to given type
...or...
Future<List<?>> f = riak.submit(job); // Job runs in a separate thread
]]></programlisting>
</para>
</section>
</section>
<section id="riak:buckets">
<title>Managing Bucket Properties</title>
<para>It's sometimes useful to manage settings like the Quality-of-Service parameters <literal>w</literal> and <literal>dw</literal> (write and durable write thresholds) and the <literal>n_val</literal> setting at the bucket level. It's also possible to list the keys in a particular bucket by calling the <literal>getBucketSchema</literal> method, passing <literal>true</literal> as the second parameter, which tells the <classname>RiakTemplate</classname> to list the keys.</para>
<para>To list the keys in a bucket, you would do something like this:
<programlisting language="java"><![CDATA[
@Autowired
RiakTemplate riak;
Map<String, Object> schema = riak.getBucketSchema("mybucket", true);
List<String> keys = schema.get("keys")
for(String key : keys) {
...do something with each key...
}
]]></programlisting>
</para>
<para>To update the bucket settings, pass a <interfacename>Map</interfacename> of properties:
<programlisting language="java"><![CDATA[
@Autowired
RiakTemplate riak;
Map<String, Integer> props = new HashMap<String, Integer>();
props.put("n_val", 6);
props.put("dw", 3);
riak.updateBucketSchema("mybucket", props);
]]></programlisting>
<para>Only the properties specified in the passed-in <interfacename>Map</interfacename> will be updated. Properties that have already been set in previous operations and not specified in this operation will be unaffected.</para>
</para>
</section>
<section id="riak:async">
<title>Asynchronous Access</title>
<para>SDKV for Riak also includes an asynchronous version of most of the methods available to the <classname>RiakTemplate</classname>, whose method calls are all synchronous. The asynchronous version of the template is called <classname>AsyncRiakTemplate</classname>.</para>
<section id="riak:async:config">
<title>Template Configuration</title>
<para>The <classname>AsyncRiakTemplate</classname> has the same basic configuration properties as the synchronous <classname>RiakTemplate</classname>. The only other property specific to the <classname>AsyncRiakTemplate</classname> you might want to configure is the thread pool the template uses to execute tasks asynchronously (by default a cached <ulink url="http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html">ThreadPoolExecutor</ulink>). Set your <classname>ExecutorService</classname> on the template's <literal>workerPool</literal> property.</para>
</section>
<section id="riak:async:callbacks">
<title>Callbacks</title>
<para>Using the asynchronous Riak support in SDKV means you'll be relying on callbacks to execute your business logic when the requested operation is completed. All asynchronous operations follow a similar pattern:
<itemizedlist>
<listitem>They are named similarly to their synchronous counterparts.</listitem>
<listitem>They take a <interfacename>AsyncKeyValueStoreOperation&lt;?, ?&gt;</interfacename> as a final parameter.</listitem>
<listitem>They return a <interfacename>Future&lt;?&gt;</interfacename>.</listitem>
</itemizedlist>
</para>
<para>To perform an asynchronous <literal>get</literal> on a JSON-serialized <interfacename>Map</interfacename> object which returns a custom object from the callback, you'd do something like:
<programlisting language="java"><![CDATA[@Autowired
AsyncRiakTemplate riak;
Future<MyObject> future = riak.get("mybucket", "mykey", new AsyncKeyValueStoreOperation<Map, MyObject>() {
MyObject obj = new MyObject();
MyObject completed(KeyValueStoreMetaData meta, Map result) {
obj.setName(result.get("name"));
return obj;
}
MyObject failed(Throwable error) {
obj.setError(error);
return obj;
}
});
// Maybe do other work while waiting...
MyObject obj = future.get();
]]></programlisting>
</para>
</section>
</section>
<section id="riak:groovy">
<title>Groovy Builder Support</title>
<para>If your application uses Groovy, either in a standalone context, or as part of a Grails application, then you could benefit from using the Groovy <ulink url="../../api/org/springframework/data/keyvalue/riak/groovy/RiakBuilder.html"><classname>RiakBuilder</classname></ulink> that comes with SDKV for Riak. Underneath, it uses the <classname>AsyncRiakTemplate</classname>. To use the <classname>RiakBuilder</classname>, pass the constructor a configured <classname>AsyncRiakTemplate</classname>.</para>
<important><para>Instances of <classname>RiakBuilder</classname> are NOT thread-safe and should not be shared across threads.</para></important>
<para>The <classname>RiakBuilder</classname> implements an easy-to-use DSL for interacting with Riak. It doesn't implement the full set of methods available on the underlying <classname>AsyncRiakTemplate</classname> but a subset. The methods that the <classname>RiakBuilder</classname> responds to are:
<itemizedlist>
<listitem>set</listitem>
<listitem>setAsBytes</listitem>
<listitem>put</listitem>
<listitem>get</listitem>
<listitem>getAsBytes</listitem>
<listitem>getAsType</listitem>
<listitem>containsKey</listitem>
<listitem>delete</listitem>
<listitem>foreach</listitem>
</itemizedlist>
</para>
<section id="riak:groovy:dsl">
<title>Riak DSL Usage</title>
<para>The following example illustrates the different uses of the Riak DSL, including batching requests together into a logical group, using a default bucket name (the node directly beneath <literal>riak</literal> will be considered the default bucket to use for the contained operations unless a different one is specified on the operation itself):
<programlisting language="java"><![CDATA[
def riak = new RiakBuilder(asyncRiakTemplate)
riak {
test {
put(value: [test: "value"]) { completed { v, meta -> meta.key }}
put(value: [test: "value"]) { completed { v, meta -> meta.key }}
put(value: [test: "value"]) { completed { v, meta -> meta.key }}
put(value: [test: "value"]) { completed { v, meta -> meta.key }}
mapreduce {
query {
map(arg: [test: "arg", alist: [1, 2, 3, 4]]) {
source "function(v, keyInfo, arg){ return [1]; }"
}
reduce {
source "function(v){ return Riak.reduceSum(v); }"
}
}
failed { it.printStackTrace() }
}
}
}
def results = riak.results
riak.foreach(bucket: "test") {
completed { v, meta ->
riak.delete(bucket: "test", key: meta.key)
}
}
]]></programlisting>
</para>
<para>Some important things to note from this example:
<itemizedlist>
<listitem>Each operation in the Riak DSL has two callbacks: <literal>completed</literal> and <literal>failed</literal>.</listitem>
<listitem>The <literal>completed</literal> closure is passed either the result object, or, if your closure is defined with two parameters, the result object and the <ulink url="../../api/org/springframework/data/keyvalue/riak/core/RiakMetaData.html">metadata</ulink> associated with that entry.</listitem>
<listitem>Operations can be enclosed in an arbitrarily-named closure which the builder interprets as a default bucket name (in this case, the node "test" tells the builder to use the bucket name "test" for a default, unless one is specified on one of the enclosed operations).</listitem>
<listitem>Each operation within a builder's execution will be accumulated inside the special <literal>results</literal> property. Code that needs to know the output of individual operations within the batch can get access to that object through this property. Note that this means that <classname>RiakBuilder</classname> instances are NOT thread-safe.</listitem>
</itemizedlist>
</para>
<important><para>Even though the Riak DSL uses an asynchronous template underneath, all operations performed through the DSL will, by default, block until complete. To get a truly asynchronous operation, pass the parameter <literal>wait: 0</literal> (or give a meaningful timeout in milliseconds to wait for the operation to complete) on the operation.</para></important>
<section id="riak:groovy:dsl:qos">
<title>QosParameters on Riak DSL Operations</title>
<para>You can pass <interfacename>QosParameters</interfacename> to Riak DSL operations by simply defining them as parameters to the operation:
<programlisting language="java"><![CDATA[
def riak = new RiakBuilder(asyncRiakTemplate)
def myobj = riak.set(bucket: "mybucket", key: "mykey", qos: ["dw": "all"])
]]></programlisting>
</para>
</section>
<section id="riak:groovy:dsl:output">
<title>Working with Riak DSL Output</title>
<para>The output of DSL operations will either be passed to the configured <literal>completed</literal> callback, or be returned to the caller if no callback is specified. In the example above, the <literal>mapreduce</literal> operation has no <literal>completed</literal> closure. Therefore, the return of the reduce phase is simply passed back to the builder, which makes that output available on the special <literal>results</literal> property.</para>
<para>To gain access to the operation's results immediately, simply assign it to a variable:
<programlisting language="java"><![CDATA[
def riak = new RiakBuilder(asyncRiakTemplate)
def myobj = riak.get(bucket: "mybucket", key: "mykey")
]]></programlisting>
<para>If you add a non-zero <literal>wait</literal> value to the operation, "myobj" will contain a <interfacename>Future&lt;?&gt;</interfacename> rather than the result object itself.</para>
</para>
</section>
</section>
</section>
<section id="riak:io">
<title>Working with streams</title>
<para>SDKV for Riak includes a couple of useful helper objects to make reading and writing plain text or binary data in Riak really easy. If you want to store a file in Riak, then you can create a <classname>RiakOutputStream</classname> and simply write your data to it (making sure to call the "flush" method, which actually sends the data to Riak).
<programlisting language="java"><![CDATA[import org.springframework.data.keyvalue.riak.core.RiakTemplate;
import org.springframework.data.keyvalue.riak.core.io.RiakOutputStream;
public class Example {
@Autowired
RiakTemplate riak;
public void writeToRiak(String bucket, String key, String data) throws Exception {
OutputStream out = new RiakOutputStream(riak, bucket, key);
try {
out.write(data.getBytes());
} finally {
out.flush();
out.close();
}
}
}
]]></programlisting>
<para>Reading data from Riak is similarly easy. SDKV provides a <literal>java.io.File</literal> subclass that represents a resource in Riak. There's also a Spring IO Resource abstraction called <classname>RiakResource</classname> that can be used anywhere a <ulink url="http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/resources.html"><interfacename>Resource</interfacename></ulink> is required. There's also an <classname>InputStream</classname> implementation called <classname>RiakInputStream</classname>.</para>
<programlisting language="java"><![CDATA[import org.springframework.data.keyvalue.riak.core.RiakTemplate;
import org.springframework.data.keyvalue.riak.core.io.RiakInputStream;
public class Example {
@Autowired
RiakTemplate riak;
public String readFromRiak(String bucket, String key) throws Exception {
InputStream in = new RiakInputStream(riak, bucket, key);
String data;
...read data and work with it...
return data;
}
}
]]></programlisting>
</para>
</section>
</chapter>

View File

@@ -0,0 +1,35 @@
/*
code highlight CSS resemblign the Eclipse IDE default color schema
@author Costin Leau
*/
.hl-keyword {
color: #7F0055;
font-weight: bold;
}
.hl-comment {
color: #3F5F5F;
font-style: italic;
}
.hl-multiline-comment {
color: #3F5FBF;
font-style: italic;
}
.hl-tag {
color: #3F7F7F;
}
.hl-attribute {
color: #7F007F;
}
.hl-value {
color: #2A00FF;
}
.hl-string {
color: #2A00FF;
}

View File

@@ -0,0 +1,99 @@
@IMPORT url("highlight.css");
html {
padding: 0pt;
margin: 0pt;
}
body {
margin-left: 10%;
margin-right: 10%;
font-family: Arial, Sans-serif;
}
div {
margin: 0pt;
}
p {
text-align: justify;
}
hr {
border: 1px solid gray;
background: gray;
}
h1,h2,h3,h4 {
color: #234623;
font-family: Arial, Sans-serif;
}
pre {
line-height: 1.0;
color: black;
}
pre.programlisting {
font-size: 10pt;
padding: 7pt 3pt;
border: 1pt solid black;
background: #eeeeee;
clear: both;
}
div.table {
margin: 1em;
padding: 0.5em;
text-align: center;
}
div.table table {
display: table;
width: 100%;
}
div.table td {
padding-left: 7px;
padding-right: 7px;
}
.sidebar {
float: right;
margin: 10px 0 10px 30px;
padding: 10px 20px 20px 20px;
width: 33%;
border: 1px solid black;
background-color: #F4F4F4;
font-size: 14px;
}
.mediaobject {
padding-top: 30px;
padding-bottom: 30px;
}
.legalnotice {
font-family: Verdana, Arial, helvetica, sans-serif;
font-size: 12px;
font-style: italic;
}
p.releaseinfo {
font-size: 100%;
font-weight: bold;
font-family: Verdana, Arial, helvetica, sans-serif;
padding-top: 10px;
}
p.pubdate {
font-size: 120%;
font-weight: bold;
font-family: Verdana, Arial, helvetica, sans-serif;
}
span.productname {
font-size: 200%;
font-weight: bold;
font-family: Verdana, Arial, helvetica, sans-serif;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 374 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 743 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1003 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 580 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 598 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 613 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 565 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 617 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 623 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 640 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 350 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 345 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 348 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 355 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

@@ -0,0 +1,449 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This is the XSL FO (PDF) stylesheet for the Spring Data 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"/>
<xsl:import href="highlight-fo.xsl"/>
<!--###################################################
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">
<!-- Logo
<fo:block>
<fo:external-graphic src="file:src/docbkx/resources/images/s2_box_logo.png"/>
</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="14pt" padding="10mm">
<xsl:value-of select="bookinfo/title"/>
</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: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:text> (</xsl:text>
<xsl:value-of select="affiliation"/>
<xsl:text>)</xsl:text>
</xsl:for-each>
</fo:block>
<fo:block font-family="Helvetica" font-size="12pt" padding="10mm">
<xsl:text>Copyright &#xA9; 2010-2011</xsl:text>
</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 Key Value (</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="tablecolumns.extension">0</xsl:param>
<!-- FOP provide only PDF Bookmarks at the moment -->
<xsl:param name="fop.extensions">1</xsl:param>
<xsl:param name="fop1.extensions">1</xsl:param>
<xsl:param name="ignore.image.scaling">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">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">src/docbkx/resources/images/admons/</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: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:template match="xref">
<fo:basic-link internal-destination="{@linkend}"
xsl:use-attribute-sets="xref.properties"
text-decoration="underline"
color="blue">
<xsl:apply-templates/>
</fo:basic-link>
</xsl:template>
-->
</xsl:stylesheet>

View File

@@ -0,0 +1,44 @@
<?xml version='1.0'?>
<!--
Simple highlighter for FO/PDF output. Follows the Eclipse color scheme.
-->
<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'>
<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 olor="#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>
</xsl:stylesheet>

View File

@@ -0,0 +1,42 @@
<?xml version='1.0'?>
<!--
Simple highlighter for HTML output. Follows the Eclipse color scheme.
-->
<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: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>
</xsl:stylesheet>

View File

@@ -0,0 +1,145 @@
<?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:import href="http://docbook.sourceforge.net/release/xsl/current/html/chunk.xsl"/>
<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/html/highlight.xsl"/>
<xsl:param name="chunk.section.depth">'5'</xsl:param>
<xsl:param name="use.id.as.filename">'1'</xsl:param>
<!-- Only use scaling in FO -->
<xsl:param name="ignore.image.scaling">1</xsl:param>
<!-- Use code syntax highlighting -->
<xsl:param name="highlight.source">1</xsl:param>
<!-- 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/admon/</xsl:param>
<xsl:param name="admon.graphics.extension">.png</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">.png</xsl:param>
<xsl:param name="table.borders.with.css" select="1"/>
<xsl:param name="html.stylesheet">css/manual.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>
<!-- Leave image paths as relative when navigating XInclude -->
<xsl:param name="keep.relative.image.uris" select="1"/>
<!-- 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="2"/>
<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.&#160;%t"/>
<l:template name="section" text="%n&#160;%t"/>
</l:context>
</l:l10n>
</l:i18n>
<xsl:template match='xslthl:keyword' mode="xslthl">
<span class="hl-keyword"><xsl:apply-templates mode="xslthl"/></span>
</xsl:template>
<xsl:template match='xslthl:comment' mode="xslthl">
<span class="hl-comment"><xsl:apply-templates mode="xslthl"/></span>
</xsl:template>
<xsl:template match='xslthl:oneline-comment' mode="xslthl">
<span class="hl-comment"><xsl:apply-templates mode="xslthl"/></span>
</xsl:template>
<xsl:template match='xslthl:multiline-comment' mode="xslthl">
<span class="hl-multiline-comment"><xsl:apply-templates mode="xslthl"/></span>
</xsl:template>
<xsl:template match='xslthl:tag' mode="xslthl">
<span class="hl-tag"><xsl:apply-templates mode="xslthl"/></span>
</xsl:template>
<xsl:template match='xslthl:attribute' mode="xslthl">
<span class="hl-attribute"><xsl:apply-templates mode="xslthl"/></span>
</xsl:template>
<xsl:template match='xslthl:value' mode="xslthl">
<span class="hl-value"><xsl:apply-templates mode="xslthl"/></span>
</xsl:template>
<xsl:template match='xslthl:string' mode="xslthl">
<span class="hl-string"><xsl:apply-templates mode="xslthl"/></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>

View File

@@ -0,0 +1,142 @@
<?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:import href="http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl"/>
<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/html/highlight.xsl"/>
<!-- Only use scaling in FO -->
<xsl:param name="ignore.image.scaling">1</xsl:param>
<!-- Use code syntax highlighting -->
<xsl:param name="highlight.source">1</xsl:param>
<!-- 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/admon/</xsl:param>
<xsl:param name="admon.graphics.extension">.png</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">.png</xsl:param>
<xsl:param name="table.borders.with.css" select="1"/>
<xsl:param name="html.stylesheet">css/manual.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>
<!-- Leave image paths as relative when navigating XInclude -->
<xsl:param name="keep.relative.image.uris" select="1"/>
<!-- 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="2"/>
<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 2 in the TOCs -->
<xsl:param name="toc.section.depth">2</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.&#160;%t"/>
<l:template name="section" text="%n&#160;%t"/>
</l:context>
</l:l10n>
</l:i18n>
<xsl:template match='xslthl:keyword' mode="xslthl">
<span class="hl-keyword"><xsl:apply-templates mode="xslthl"/></span>
</xsl:template>
<xsl:template match='xslthl:comment' mode="xslthl">
<span class="hl-comment"><xsl:apply-templates mode="xslthl"/></span>
</xsl:template>
<xsl:template match='xslthl:oneline-comment' mode="xslthl">
<span class="hl-comment"><xsl:apply-templates mode="xslthl"/></span>
</xsl:template>
<xsl:template match='xslthl:multiline-comment' mode="xslthl">
<span class="hl-multiline-comment"><xsl:apply-templates mode="xslthl"/></span>
</xsl:template>
<xsl:template match='xslthl:tag' mode="xslthl">
<span class="hl-tag"><xsl:apply-templates mode="xslthl"/></span>
</xsl:template>
<xsl:template match='xslthl:attribute' mode="xslthl">
<span class="hl-attribute"><xsl:apply-templates mode="xslthl"/></span>
</xsl:template>
<xsl:template match='xslthl:value' mode="xslthl">
<span class="hl-value"><xsl:apply-templates mode="xslthl"/></span>
</xsl:template>
<xsl:template match='xslthl:string' mode="xslthl">
<span class="hl-string"><xsl:apply-templates mode="xslthl"/></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>

View File

@@ -0,0 +1,107 @@
<?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"
xmlns:xslthl="http://xslthl.sf.net"
exclude-result-prefixes="xslthl"
version="1.0">
<xsl:import href="urn:docbkx:stylesheet"/>
<xsl:import href="highlight.xsl"/>
<!--###################################################
HTML Settings
################################################### -->
<!-- These extensions are required for table printing and other stuff -->
<xsl:param name="tablecolumns.extension">0</xsl:param>
<xsl:param name="graphicsize.extension">0</xsl:param>
<xsl:param name="ignore.image.scaling">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">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">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">images/admons/</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:value-of select="affiliation"/>)
<xsl:apply-templates mode="titlepage.mode" select="./contrib"/>
</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 I21 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://www.springframework.org/osgi/"
title="The Spring Framework - Spring Data">
<img style="border:none;" src="images/xdev-spring_logo.jpg"/>
</a>
<a style="border:none;" href="http://www.SpringSource.com/" title="SpringSource - Spring from the Source">
<img style="border:none;position:absolute;padding-top:5px;right:42px;" src="images/s2-banner-rhs.png"/>
</a>
</div>
</xsl:template>
</xsl:stylesheet>

View File

@@ -0,0 +1,221 @@
<?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"/>
<xsl:import href="highlight.xsl"/>
<!--###################################################
HTML Settings
################################################### -->
<xsl:param name="chunk.section.depth">'5'</xsl:param>
<xsl:param name="use.id.as.filename">'1'</xsl:param>
<xsl:param name="tablecolumns.extension">0</xsl:param>
<xsl:param name="graphicsize.extension">0</xsl:param>
<xsl:param name="ignore.image.scaling">1</xsl:param>
<!--###################################################
Table Of Contents
################################################### -->
<!-- Generate the TOCs for named components only -->
<xsl:param name="generate.toc">
book toc
qandaset 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>
<!--###################################################
Admonitions
################################################### -->
<!-- Use nice graphics for admonitions -->
<xsl:param name="admon.graphics">1</xsl:param>
<xsl:param name="admon.graphics.path">images/admons/</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:value-of select="affiliation"/>)
<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 I21 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://www.springframework.org/osgi/"
title="The Spring Framework - Spring Data">
<img style="border:none;" src="images/xdev-spring_logo.jpg"/>
</a>
<a style="border:none;" href="http://www.SpringSource.com/" title="SpringSource - Spring from the Source">
<img style="border:none;position:absolute;padding-top:5px;right:42px;" src="images/s2-banner-rhs.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) &gt; 0
or count($up) &gt; 0
or count($next) &gt; 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>&#160;</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>&#160;|&#160;</xsl:text>
</xsl:if>
</xsl:when>
<xsl:otherwise>&#160;</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>&#160;</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>&#160;</xsl:text>
</td>
<td width="20%" align="center">
<span style="color:white;font-size:90%;">
<a href="http://www.SpringSource.com/"
title="SpringSource - Spring from the Source">Sponsored by SpringSource
</a>
</span>
</td>
<td width="40%" align="right" valign="top">
<xsl:text>&#160;</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>

View File

@@ -0,0 +1,522 @@
<?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'>
<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/fo/docbook.xsl"/>
<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/fo/highlight.xsl"/>
<!-- Use nice graphics for admonitions -->
<xsl:param name="admon.graphics">'1'</xsl:param>
<xsl:param name="admon.graphics.path">images/admon/</xsl:param>
<xsl:param name="admon.graphics.extension">.png</xsl:param>
<!-- resize the admon graphics. they're width 36pt by default
even though the graphics that ship with docbook are 24x24 -->
<xsl:template match="*" mode="admon.graphic.width">
<xsl:param name="node" select="."/>
<xsl:text>24pt</xsl:text>
</xsl:template>
<xsl:param name="paper.type" select="'A4'"/>
<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>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$pageclass='titlepage'">
</xsl:when>
<xsl:when test="$position='center'">
<xsl:value-of select="$Version"/>
</xsl:when>
<xsl:otherwise>
</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>
</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'">
</xsl:when>
<xsl:otherwise>
<fo:page-number/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$pageclass='titlepage'">
</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>
</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="fop1.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.&#160;%t"/>
<l:template name="section" text="%n&#160;%t"/>
</l:context>
<l:context name="title">
<l:template name="example" text="Example&#160;%n&#160;%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>

20
gradle.properties Normal file
View File

@@ -0,0 +1,20 @@
## Dependecies Version
# Logging
log4jVersion = 1.2.16
slf4jVersion = 1.6.1
# Common libraries
springVersion = 3.0.5.RELEASE
jacksonVersion = 1.6.4
# Testing
junitVersion = 4.8.1
mockitoVersion = 1.8.5
# --------------------
# Project wide version
# --------------------
springDataKeyValueVersion=1.0.0.BUILD-SNAPSHOT
version = 'springDataKeyValueVersion'

168
gradlew vendored Executable file
View File

@@ -0,0 +1,168 @@
#!/bin/bash
##############################################################################
## ##
## Gradle wrapper script for UN*X ##
## ##
##############################################################################
# Uncomment those lines to set JVM options. GRADLE_OPTS and JAVA_OPTS can be used together.
# GRADLE_OPTS="$GRADLE_OPTS -Xmx512m"
# JAVA_OPTS="$JAVA_OPTS -Xmx512m"
GRADLE_APP_NAME=Gradle
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# Attempt to set JAVA_HOME if it's not already set.
if [ -z "$JAVA_HOME" ] ; then
if $darwin ; then
[ -z "$JAVA_HOME" -a -d "/Library/Java/Home" ] && export JAVA_HOME="/Library/Java/Home"
[ -z "$JAVA_HOME" -a -d "/System/Library/Frameworks/JavaVM.framework/Home" ] && export JAVA_HOME="/System/Library/Frameworks/JavaVM.framework/Home"
else
javaExecutable="`which javac`"
[ -z "$javaExecutable" -o "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ] && die "JAVA_HOME not set and cannot find javac to deduce location, please set JAVA_HOME."
# readlink(1) is not available as standard on Solaris 10.
readLink=`which readlink`
[ `expr "$readLink" : '\([^ ]*\)'` = "no" ] && die "JAVA_HOME not set and readlink not available, please set JAVA_HOME."
javaExecutable="`readlink -f \"$javaExecutable\"`"
javaHome="`dirname \"$javaExecutable\"`"
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
export JAVA_HOME="$javaHome"
fi
fi
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVACMD" ] && JAVACMD=`cygpath --unix "$JAVACMD"`
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
STARTER_MAIN_CLASS=org.gradle.wrapper.GradleWrapperMain
CLASSPATH=`dirname "$0"`/gradle/wrapper/gradle-wrapper.jar
WRAPPER_PROPERTIES=`dirname "$0"`/gradle/wrapper/gradle-wrapper.properties
# Determine the Java command to use to start the JVM.
if [ -z "$JAVACMD" ] ; then
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
else
JAVACMD="java"
fi
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
if [ -z "$JAVA_HOME" ] ; then
warn "JAVA_HOME environment variable is not set"
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query businessSystem maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add GRADLE_APP_NAME to the JAVA_OPTS as -Xdock:name
if $darwin; then
JAVA_OPTS="$JAVA_OPTS -Xdock:name=$GRADLE_APP_NAME"
# we may also want to set -Xdock:image
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
JAVA_HOME=`cygpath --path --mixed "$JAVA_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
GRADLE_APP_BASE_NAME=`basename "$0"`
exec "$JAVACMD" $JAVA_OPTS $GRADLE_OPTS \
-classpath "$CLASSPATH" \
-Dorg.gradle.appname="$GRADLE_APP_BASE_NAME" \
-Dorg.gradle.wrapper.properties="$WRAPPER_PROPERTIES" \
$STARTER_MAIN_CLASS \
"$@"

82
gradlew.bat vendored Normal file
View File

@@ -0,0 +1,82 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem ##
@rem Gradle startup script for Windows ##
@rem ##
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Uncomment those lines to set JVM options. GRADLE_OPTS and JAVA_OPTS can be used together.
@rem set GRADLE_OPTS=%GRADLE_OPTS% -Xmx512m
@rem set JAVA_OPTS=%JAVA_OPTS% -Xmx512m
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.\
@rem Find java.exe
set JAVA_EXE=java.exe
if not defined JAVA_HOME goto init
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo.
goto end
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set STARTER_MAIN_CLASS=org.gradle.wrapper.GradleWrapperMain
set CLASSPATH=%DIRNAME%\gradle\wrapper\gradle-wrapper.jar
set WRAPPER_PROPERTIES=%DIRNAME%\gradle\wrapper\gradle-wrapper.properties
set GRADLE_OPTS=%JAVA_OPTS% %GRADLE_OPTS% -Dorg.gradle.wrapper.properties="%WRAPPER_PROPERTIES%"
@rem Execute Gradle
"%JAVA_EXE%" %GRADLE_OPTS% -classpath "%CLASSPATH%" %STARTER_MAIN_CLASS% %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
if not "%OS%"=="Windows_NT" echo 1 > nul | choice /n /c:1
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit "%ERRORLEVEL%"
exit /b "%ERRORLEVEL%"
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

119
maven.gradle Normal file
View File

@@ -0,0 +1,119 @@
apply plugin: 'maven'
// Create a source jar for uploading
task sourceJar(type: Jar, dependsOn: classes) {
classifier = 'sources'
from sourceSets.main.allSource
}
// Create a javadoc jar for uploading
task javadocJar(type: Jar, dependsOn: javadoc) {
classifier = 'javadoc'
from javadoc.destinationDir
}
artifacts {
archives sourceJar
archives javadocJar
}
// Configuration for SpringSource s3 maven deployer
configurations {
deployerJars
}
dependencies {
deployerJars "org.springframework.build.aws:org.springframework.build.aws.maven:3.0.0.RELEASE"
}
// Remove the archive configuration from the runtime configuration, so that anything added to archives
// (such as the source jar) is no longer included in the runtime classpath
configurations.default.extendsFrom = [configurations.runtime] as Set
// Add the main jar into the default configuration
artifacts { 'default' jar }
gradle.taskGraph.whenReady {graph ->
if (graph.hasTask(uploadArchives)) {
// check properties defined and fail early
s3AccessKey
s3SecretAccessKey
}
}
def deployer = null
uploadArchives {
description = "Maven deploy of archives artifacts to SpringSource Maven repos" // url appended below
group = "Distribution"
// Maven deployment
def releaseRepositoryUrl = "file://${project.properties.mavenSyncRepoDir}"
def milestoneRepositoryUrl = 's3://maven.springframework.org/milestone'
def snapshotRepositoryUrl = 's3://maven.springframework.org/snapshot'
// add a configuration with a classpath that includes our s3 maven deployer
configurations { deployerJars }
dependencies {
deployerJars "org.springframework.build.aws:org.springframework.build.aws.maven:3.0.0.RELEASE"
}
deployer = repositories.mavenDeployer {
configuration = configurations.deployerJars
// releaseBuild
if (releaseBuild) {
logger.info("Deploying to local Maven repo " + releaseRepositoryUrl)
// "mavenSyncRepoDir" should be set in properties
repository(url: releaseRepositoryUrl)
} else {
s3credentials = [userName: project.properties.s3AccessKey, passphrase: project.properties.s3SecretAccessKey]
repository(url: milestoneRepositoryUrl) {
authentication(s3credentials)
}
snapshotRepository(url: snapshotRepositoryUrl) {
authentication(s3credentials)
}
}
}
customizePom(deployer.pom)
}
install {
customizePom(repositories.mavenInstaller.pom)
}
def customizePom(pom) {
def optionalDeps = ['log4j','jsr250-api']
//pom.scopeMappings.addMapping(10, configurations.provided, 'provided')
pom.whenConfigured { p ->
// Remove test scope dependencies from published poms
p.dependencies = p.dependencies.findAll {it.scope != 'test'}
// Flag optional deps
p.dependencies.findAll { dep ->
optionalDeps.contains(dep.artifactId) ||
dep.groupId.startsWith('org.slf4j')
}*.optional = true
}
pom.project {
licenses {
license {
name 'The Apache Software License, Version 2.0'
url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
distribution 'repo'
}
}
// similar to Spring's configuration
dependencies {
dependency {
artifactId = groupId = 'commons-logging'
scope = 'compile'
optional = 'true'
version = '1.1.1'
}
}
}
}

8
settings.gradle Normal file
View File

@@ -0,0 +1,8 @@
rootProject.name = 'spring-data-key-value'
include 'docs'
include "spring-data-keyvalue-core",
"spring-data-redis",
"spring-data-riak"
docs = findProject(':docs')

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="output" path="bin"/>
<classpathentry kind="src" path="src/main/java"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER" exported="true"/>
<classpathentry sourcepath="C:/Users/costin/.gradle/cache/org.codehaus.jackson/jackson-mapper-asl/sources/jackson-mapper-asl-1.6.4-sources.jar" kind="lib" path="C:/Users/costin/.gradle/cache/org.codehaus.jackson/jackson-mapper-asl/jars/jackson-mapper-asl-1.6.4.jar" exported="true"/>
<classpathentry sourcepath="C:/Users/costin/.gradle/cache/org.slf4j/slf4j-log4j12/sources/slf4j-log4j12-1.6.1-sources.jar" kind="lib" path="C:/Users/costin/.gradle/cache/org.slf4j/slf4j-log4j12/jars/slf4j-log4j12-1.6.1.jar" exported="true"/>
<classpathentry sourcepath="C:/Users/costin/.gradle/cache/org.springframework/spring-tx/sources/spring-tx-3.0.5.RELEASE-sources.jar" kind="lib" path="C:/Users/costin/.gradle/cache/org.springframework/spring-tx/jars/spring-tx-3.0.5.RELEASE.jar" exported="true"/>
<classpathentry sourcepath="C:/Users/costin/.gradle/cache/org.springframework/spring-context-support/sources/spring-context-support-3.0.5.RELEASE-sources.jar" kind="lib" path="C:/Users/costin/.gradle/cache/org.springframework/spring-context-support/jars/spring-context-support-3.0.5.RELEASE.jar" exported="true"/>
<classpathentry sourcepath="C:/Users/costin/.gradle/cache/org.springframework/spring-test/sources/spring-test-3.0.5.RELEASE-sources.jar" kind="lib" path="C:/Users/costin/.gradle/cache/org.springframework/spring-test/jars/spring-test-3.0.5.RELEASE.jar" exported="true"/>
<classpathentry sourcepath="C:/Users/costin/.gradle/cache/org.springframework/spring-aop/sources/spring-aop-3.0.5.RELEASE-sources.jar" kind="lib" path="C:/Users/costin/.gradle/cache/org.springframework/spring-aop/jars/spring-aop-3.0.5.RELEASE.jar" exported="true"/>
<classpathentry sourcepath="C:/Users/costin/.gradle/cache/org.springframework/spring-expression/sources/spring-expression-3.0.5.RELEASE-sources.jar" kind="lib" path="C:/Users/costin/.gradle/cache/org.springframework/spring-expression/jars/spring-expression-3.0.5.RELEASE.jar" exported="true"/>
<classpathentry sourcepath="C:/Users/costin/.gradle/cache/log4j/log4j/sources/log4j-1.2.16-sources.jar" kind="lib" path="C:/Users/costin/.gradle/cache/log4j/log4j/bundles/log4j-1.2.16.jar" exported="true"/>
<classpathentry sourcepath="C:/Users/costin/.gradle/cache/org.codehaus.jackson/jackson-core-asl/sources/jackson-core-asl-1.6.4-sources.jar" kind="lib" path="C:/Users/costin/.gradle/cache/org.codehaus.jackson/jackson-core-asl/jars/jackson-core-asl-1.6.4.jar" exported="true"/>
<classpathentry sourcepath="C:/Users/costin/.gradle/cache/aopalliance/aopalliance/sources/aopalliance-1.0-sources.jar" kind="lib" path="C:/Users/costin/.gradle/cache/aopalliance/aopalliance/jars/aopalliance-1.0.jar" exported="true"/>
<classpathentry sourcepath="C:/Users/costin/.gradle/cache/org.slf4j/slf4j-api/sources/slf4j-api-1.6.1-sources.jar" kind="lib" path="C:/Users/costin/.gradle/cache/org.slf4j/slf4j-api/jars/slf4j-api-1.6.1.jar" exported="true"/>
<classpathentry sourcepath="C:/Users/costin/.gradle/cache/org.springframework/spring-asm/sources/spring-asm-3.0.5.RELEASE-sources.jar" kind="lib" path="C:/Users/costin/.gradle/cache/org.springframework/spring-asm/jars/spring-asm-3.0.5.RELEASE.jar" exported="true"/>
<classpathentry sourcepath="C:/Users/costin/.gradle/cache/org.mockito/mockito-all/sources/mockito-all-1.8.5-sources.jar" kind="lib" path="C:/Users/costin/.gradle/cache/org.mockito/mockito-all/jars/mockito-all-1.8.5.jar" exported="true"/>
<classpathentry sourcepath="C:/Users/costin/.gradle/cache/junit/junit/sources/junit-4.8.1-sources.jar" kind="lib" path="C:/Users/costin/.gradle/cache/junit/junit/jars/junit-4.8.1.jar" exported="true"/>
<classpathentry sourcepath="C:/Users/costin/.gradle/cache/org.slf4j/jcl-over-slf4j/sources/jcl-over-slf4j-1.6.1-sources.jar" kind="lib" path="C:/Users/costin/.gradle/cache/org.slf4j/jcl-over-slf4j/jars/jcl-over-slf4j-1.6.1.jar" exported="true"/>
<classpathentry sourcepath="C:/Users/costin/.gradle/cache/org.springframework/spring-core/sources/spring-core-3.0.5.RELEASE-sources.jar" kind="lib" path="C:/Users/costin/.gradle/cache/org.springframework/spring-core/jars/spring-core-3.0.5.RELEASE.jar" exported="true"/>
<classpathentry sourcepath="C:/Users/costin/.gradle/cache/org.springframework/spring-context/sources/spring-context-3.0.5.RELEASE-sources.jar" kind="lib" path="C:/Users/costin/.gradle/cache/org.springframework/spring-context/jars/spring-context-3.0.5.RELEASE.jar" exported="true"/>
<classpathentry sourcepath="C:/Users/costin/.gradle/cache/org.springframework/spring-beans/sources/spring-beans-3.0.5.RELEASE-sources.jar" kind="lib" path="C:/Users/costin/.gradle/cache/org.springframework/spring-beans/jars/spring-beans-3.0.5.RELEASE.jar" exported="true"/>
</classpath>

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>spring-data-core</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@@ -0,0 +1,13 @@
#
#Thu Apr 21 21:26:44 EEST 2011
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.compliance=1.5
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.source=1.5
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error

View File

View File

@@ -0,0 +1,27 @@
/*
* Copyright 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.keyvalue;
import org.springframework.dao.UncategorizedDataAccessException;
public class UncategorizedKeyvalueStoreException extends UncategorizedDataAccessException {
public UncategorizedKeyvalueStoreException(String msg, Throwable cause) {
super(msg, cause);
}
}

View File

@@ -0,0 +1,19 @@
Bundle-SymbolicName: org.springframework.data.keyvalue
Bundle-Name: Spring data Key-Value
Bundle-Vendor: SpringSource
Bundle-ManifestVersion: 2
Import-Package:
sun.reflect;version="0";resolution:=optional
Import-Template:
org.springframework.beans.*;version="[3.0.0, 4.0.0)",
org.springframework.core.*;version="[3.0.0, 4.0.0)",
org.springframework.dao.*;version="[3.0.0, 4.0.0)",
org.springframework.util.*;version="[3.0.0, 4.0.0)",
org.springframework.data.core.*;version="[1.0.0, 2.0.0)",
org.springframework.data.core.*;version="[1.0.0, 2.0.0)",
org.springframework.data.persistence.*;version="[1.0.0, 2.0.0)",
org.aopalliance.*;version="[1.0.0, 2.0.0)";resolution:=optional,
org.apache.commons.logging.*;version="[1.1.1, 2.0.0)",
org.w3c.dom.*;version="0"

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/main/java"/>
<classpathentry kind="src" path="src/main/resources"/>
<classpathentry kind="src" path="src/test/java"/>
<classpathentry kind="src" path="src/test/resources"/>
<classpathentry exported="true" kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry exported="true" kind="lib" path="C:/Users/costin/.gradle/cache/org.slf4j/slf4j-log4j12/jars/slf4j-log4j12-1.6.1.jar" sourcepath="C:/Users/costin/.gradle/cache/org.slf4j/slf4j-log4j12/sources/slf4j-log4j12-1.6.1-sources.jar"/>
<classpathentry exported="true" kind="lib" path="C:/Users/costin/.gradle/cache/org.springframework/spring-context-support/jars/spring-context-support-3.0.5.RELEASE.jar" sourcepath="C:/Users/costin/.gradle/cache/org.springframework/spring-context-support/sources/spring-context-support-3.0.5.RELEASE-sources.jar"/>
<classpathentry exported="true" kind="lib" path="C:/Users/costin/.gradle/cache/org.springframework/spring-expression/jars/spring-expression-3.0.5.RELEASE.jar" sourcepath="C:/Users/costin/.gradle/cache/org.springframework/spring-expression/sources/spring-expression-3.0.5.RELEASE-sources.jar"/>
<classpathentry exported="true" kind="lib" path="C:/Users/costin/.gradle/cache/org.springframework/spring-oxm/jars/spring-oxm-3.0.5.RELEASE.jar" sourcepath="C:/Users/costin/.gradle/cache/org.springframework/spring-oxm/sources/spring-oxm-3.0.5.RELEASE-sources.jar"/>
<classpathentry exported="true" kind="lib" path="C:/Users/costin/.gradle/cache/log4j/log4j/bundles/log4j-1.2.16.jar" sourcepath="C:/Users/costin/.gradle/cache/log4j/log4j/sources/log4j-1.2.16-sources.jar"/>
<classpathentry exported="true" kind="lib" path="C:/Users/costin/.gradle/cache/org.idevlab/rjc/bundles/rjc-0.6.4.jar" sourcepath="C:/Users/costin/.gradle/cache/org.idevlab/rjc/sources/rjc-0.6.4-sources.jar"/>
<classpathentry exported="true" kind="lib" path="C:/Users/costin/.gradle/cache/org.jredis/jredis-anthonylauzon/jars/jredis-anthonylauzon-03122010.jar" sourcepath="C:/Users/costin/.gradle/cache/org.jredis/jredis-anthonylauzon/sources/jredis-anthonylauzon-03122010-sources.jar"/>
<classpathentry exported="true" kind="lib" path="C:/Users/costin/.gradle/cache/org.codehaus.jackson/jackson-core-asl/jars/jackson-core-asl-1.6.4.jar" sourcepath="C:/Users/costin/.gradle/cache/org.codehaus.jackson/jackson-core-asl/sources/jackson-core-asl-1.6.4-sources.jar"/>
<classpathentry exported="true" kind="lib" path="C:/Users/costin/.gradle/cache/aopalliance/aopalliance/jars/aopalliance-1.0.jar" sourcepath="C:/Users/costin/.gradle/cache/aopalliance/aopalliance/sources/aopalliance-1.0-sources.jar"/>
<classpathentry exported="true" kind="lib" path="C:/Users/costin/.gradle/cache/org.slf4j/slf4j-api/jars/slf4j-api-1.6.1.jar" sourcepath="C:/Users/costin/.gradle/cache/org.slf4j/slf4j-api/sources/slf4j-api-1.6.1-sources.jar"/>
<classpathentry exported="true" kind="lib" path="C:/Users/costin/.gradle/cache/org.springframework/spring-asm/jars/spring-asm-3.0.5.RELEASE.jar" sourcepath="C:/Users/costin/.gradle/cache/org.springframework/spring-asm/sources/spring-asm-3.0.5.RELEASE-sources.jar"/>
<classpathentry exported="true" kind="lib" path="C:/Users/costin/.gradle/cache/xpp3/xpp3_min/jars/xpp3_min-1.1.4c.jar" sourcepath="C:/Users/costin/.gradle/cache/xpp3/xpp3_min/sources/xpp3_min-1.1.4c-sources.jar"/>
<classpathentry exported="true" kind="lib" path="C:/Users/costin/.gradle/cache/org.springframework/spring-core/jars/spring-core-3.0.5.RELEASE.jar" sourcepath="C:/Users/costin/.gradle/cache/org.springframework/spring-core/sources/spring-core-3.0.5.RELEASE-sources.jar"/>
<classpathentry exported="true" kind="lib" path="C:/Users/costin/.gradle/cache/org.springframework/spring-context/jars/spring-context-3.0.5.RELEASE.jar" sourcepath="C:/Users/costin/.gradle/cache/org.springframework/spring-context/sources/spring-context-3.0.5.RELEASE-sources.jar"/>
<classpathentry exported="true" kind="lib" path="C:/Users/costin/.gradle/cache/org.springframework/spring-beans/jars/spring-beans-3.0.5.RELEASE.jar" sourcepath="C:/Users/costin/.gradle/cache/org.springframework/spring-beans/sources/spring-beans-3.0.5.RELEASE-sources.jar"/>
<classpathentry exported="true" kind="lib" path="C:/Users/costin/.gradle/cache/org.codehaus.jackson/jackson-mapper-asl/jars/jackson-mapper-asl-1.6.4.jar" sourcepath="C:/Users/costin/.gradle/cache/org.codehaus.jackson/jackson-mapper-asl/sources/jackson-mapper-asl-1.6.4-sources.jar"/>
<classpathentry exported="true" kind="lib" path="C:/Users/costin/.gradle/cache/org.springframework/spring-tx/jars/spring-tx-3.0.5.RELEASE.jar" sourcepath="C:/Users/costin/.gradle/cache/org.springframework/spring-tx/sources/spring-tx-3.0.5.RELEASE-sources.jar"/>
<classpathentry exported="true" kind="lib" path="C:/Users/costin/.gradle/cache/org.springframework/spring-test/jars/spring-test-3.0.5.RELEASE.jar" sourcepath="C:/Users/costin/.gradle/cache/org.springframework/spring-test/sources/spring-test-3.0.5.RELEASE-sources.jar"/>
<classpathentry exported="true" kind="lib" path="C:/Users/costin/.gradle/cache/org.springframework/spring-aop/jars/spring-aop-3.0.5.RELEASE.jar" sourcepath="C:/Users/costin/.gradle/cache/org.springframework/spring-aop/sources/spring-aop-3.0.5.RELEASE-sources.jar"/>
<classpathentry exported="true" kind="lib" path="C:/Users/costin/.gradle/cache/redis.clients/jedis/jars/jedis-2.0.0.jar" sourcepath="C:/Users/costin/.gradle/cache/redis.clients/jedis/sources/jedis-2.0.0-sources.jar"/>
<classpathentry exported="true" kind="lib" path="C:/Users/costin/.gradle/cache/commons-pool/commons-pool/jars/commons-pool-1.5.6.jar" sourcepath="C:/Users/costin/.gradle/cache/commons-pool/commons-pool/sources/commons-pool-1.5.6-sources.jar"/>
<classpathentry exported="true" kind="lib" path="C:/Users/costin/.gradle/cache/javax.annotation/jsr250-api/jars/jsr250-api-1.0.jar" sourcepath="C:/Users/costin/.gradle/cache/javax.annotation/jsr250-api/sources/jsr250-api-1.0-sources.jar"/>
<classpathentry exported="true" kind="lib" path="C:/Users/costin/.gradle/cache/commons-beanutils/commons-beanutils-core/jars/commons-beanutils-core-1.8.3.jar"/>
<classpathentry exported="true" kind="lib" path="C:/Users/costin/.gradle/cache/com.thoughtworks.xstream/xstream/jars/xstream-1.3.jar" sourcepath="C:/Users/costin/.gradle/cache/com.thoughtworks.xstream/xstream/sources/xstream-1.3-sources.jar"/>
<classpathentry exported="true" kind="lib" path="C:/Users/costin/.gradle/cache/org.mockito/mockito-all/jars/mockito-all-1.8.5.jar" sourcepath="C:/Users/costin/.gradle/cache/org.mockito/mockito-all/sources/mockito-all-1.8.5-sources.jar"/>
<classpathentry exported="true" kind="lib" path="C:/Users/costin/.gradle/cache/junit/junit/jars/junit-4.8.1.jar" sourcepath="C:/Users/costin/.gradle/cache/junit/junit/sources/junit-4.8.1-sources.jar"/>
<classpathentry exported="true" kind="lib" path="C:/Users/costin/.gradle/cache/org.slf4j/jcl-over-slf4j/jars/jcl-over-slf4j-1.6.1.jar" sourcepath="C:/Users/costin/.gradle/cache/org.slf4j/jcl-over-slf4j/sources/jcl-over-slf4j-1.6.1-sources.jar"/>
<classpathentry exported="true" kind="lib" path="C:/Users/costin/.gradle/cache/commons-logging/commons-logging/jars/commons-logging-1.1.1.jar" sourcepath="C:/Users/costin/.gradle/cache/commons-logging/commons-logging/sources/commons-logging-1.1.1-sources.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/spring-data-core"/>
<classpathentry kind="output" path="bin"/>
</classpath>

2
spring-data-redis/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
*.log

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>spring-data-redis</name>
<comment/>
<projects/>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments/>
</buildCommand>
</buildSpec>
<links/>
</projectDescription>

View File

@@ -0,0 +1,13 @@
#
#Fri Jul 01 15:44:20 EEST 2011
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.source=1.6
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error

View File

@@ -0,0 +1,17 @@
repositories {
mavenRepo name: "ext-snapshots", urls: "http://springframework.svn.sourceforge.net/svnroot/springframework/repos/repo-ext/"
}
dependencies {
compile project(":spring-data-keyvalue-core")
compile "redis.clients:jedis:$jedisVersion"
compile("org.jredis:jredis-anthonylauzon:$jredisVersion") { optional = true }
compile("org.idevlab:rjc:$rjcVersion") { optional = true }
compile("org.springframework:spring-oxm:$springVersion") { optional = true }
compile("commons-beanutils:commons-beanutils-core:1.8.3") { optional = true }
testCompile("javax.annotation:jsr250-api:1.0") { optional = true }
testCompile("com.thoughtworks.xstream:xstream:1.3") { optional = true }
}
sourceCompatibility = 1.6
targetCompatibility = 1.6

View File

@@ -0,0 +1,13 @@
# Dependencies properties
jedisVersion = 2.0.0
jredisVersion = 03122010
rjcVersion= 0.6.4
# Manifest properties
## OSGi ranges
spring.range = "[3.0.0, 4.0.0)"
jedis.range = "[2.0.0, 2.0.0]"
jackson.range = "[1.6, 2.0.0)"
rjc.range = "[0.6.4, 0.6.4]"

View File

@@ -0,0 +1,35 @@
/*
* Copyright 2010-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.keyvalue.redis;
import org.springframework.dao.DataAccessResourceFailureException;
/**
* Fatal exception thrown when the Redis connection fails completely.
*
* @author Mark Pollack
*/
public class RedisConnectionFailureException extends DataAccessResourceFailureException {
public RedisConnectionFailureException(String msg) {
super(msg);
}
public RedisConnectionFailureException(String msg, Throwable cause) {
super(msg, cause);
}
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2010-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.keyvalue.redis;
import org.springframework.data.keyvalue.UncategorizedKeyvalueStoreException;
/**
* Exception thrown when we can't classify a Redis exception into one of Spring generic data access exceptions.
*
* @author Costin Leau
*/
public class RedisSystemException extends UncategorizedKeyvalueStoreException {
public RedisSystemException(String msg, Throwable cause) {
super(msg, cause);
}
}

View File

@@ -0,0 +1,48 @@
/*
* 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.keyvalue.redis.config;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
import org.springframework.data.keyvalue.redis.support.collections.RedisCollectionFactoryBean;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
/**
* Parser for the Redis <code>&lt;collection&gt;</code> element.
*
* @author Costin Leau
*/
public class RedisCollectionParser extends AbstractSimpleBeanDefinitionParser {
@Override
protected Class<?> getBeanClass(Element element) {
return RedisCollectionFactoryBean.class;
}
@Override
protected void postProcess(BeanDefinitionBuilder beanDefinition, Element element) {
String template = element.getAttribute("template");
if (StringUtils.hasText(template)) {
beanDefinition.addPropertyReference("template", template);
}
}
@Override
protected boolean isEligibleAttribute(String attributeName) {
return super.isEligibleAttribute(attributeName) && (!"template".equals(attributeName));
}
}

View File

@@ -0,0 +1,139 @@
/*
* 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.keyvalue.redis.config;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.ManagedMap;
import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.data.keyvalue.redis.listener.ChannelTopic;
import org.springframework.data.keyvalue.redis.listener.PatternTopic;
import org.springframework.data.keyvalue.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.keyvalue.redis.listener.Topic;
import org.springframework.data.keyvalue.redis.listener.adapter.MessageListenerAdapter;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
/**
* Parser for the Redis <code>&lt;listener-container&gt;</code> element.
*
* @author Costin Leau
*/
class RedisListenerContainerParser extends AbstractSimpleBeanDefinitionParser {
@Override
protected Class<RedisMessageListenerContainer> getBeanClass(Element element) {
return RedisMessageListenerContainer.class;
}
@SuppressWarnings("unchecked")
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
// parse attributes (but replace the value assignment with references)
NamedNodeMap attributes = element.getAttributes();
for (int x = 0; x < attributes.getLength(); x++) {
Attr attribute = (Attr) attributes.item(x);
if (isEligibleAttribute(attribute, parserContext)) {
String propertyName = extractPropertyName(attribute.getLocalName());
Assert.state(StringUtils.hasText(propertyName),
"Illegal property name returned from 'extractPropertyName(String)': cannot be null or empty.");
builder.addPropertyReference(propertyName, attribute.getValue());
}
}
String phase = element.getAttribute("phase");
if (StringUtils.hasText(phase)) {
builder.addPropertyValue("phase", phase);
}
postProcess(builder, element);
// parse nested listeners
List<Element> listDefs = DomUtils.getChildElementsByTagName(element, "listener");
if (!listDefs.isEmpty()) {
ManagedMap<BeanDefinition, Collection<? extends BeanDefinition>> listeners = new ManagedMap<BeanDefinition, Collection<? extends BeanDefinition>>(
listDefs.size());
for (Element listElement : listDefs) {
Object[] listenerDefinition = parseListener(listElement);
listeners.put((BeanDefinition) listenerDefinition[0],
(Collection<? extends BeanDefinition>) listenerDefinition[1]);
}
builder.addPropertyValue("messageListeners", listeners);
}
}
@Override
protected boolean isEligibleAttribute(String attributeName) {
return (!"phase".equals(attributeName));
}
/**
* Parses a listener definition. Returns the listener bean reference definition (as the array first entry) and its associated topics (also as bean definitions).
*
* @param element
* @return
*/
private Object[] parseListener(Element element) {
Object[] ret = new Object[2];
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MessageListenerAdapter.class);
builder.addConstructorArgReference(element.getAttribute("ref"));
String method = element.getAttribute("method");
if (StringUtils.hasText(method)){
builder.addPropertyValue("defaultListenerMethod", method);
}
String serializer = element.getAttribute("serializer");
if (StringUtils.hasText(serializer)){
builder.addPropertyReference("serializer", serializer);
}
// assemble topics
Collection<Topic> topics = new ArrayList<Topic>();
// get topic
String xTopics = element.getAttribute("topic");
if (StringUtils.hasText(xTopics)) {
String[] array = StringUtils.delimitedListToStringArray(xTopics, " ");
for (String string : array) {
topics.add(string.contains("*") ? new PatternTopic(string) : new ChannelTopic(string));
}
}
ret[0] = builder.getBeanDefinition();
ret[1] = topics;
return ret;
}
@Override
protected boolean shouldGenerateId() {
return true;
}
}

Some files were not shown because too many files have changed in this diff Show More