Created new Neo4J ItemReader to support Spring Data 4
This adds a new ItemReader that works with the Spring Data 4 updated Neo4JOperations implementation as well as the updated data conversion techniques. Resolves BATCH-2473
This commit is contained in:
315
.gradletasknamecache
Normal file
315
.gradletasknamecache
Normal file
@@ -0,0 +1,315 @@
|
||||
All
|
||||
assemble
|
||||
spring-batch-core:assemble
|
||||
spring-batch-core-tests:assemble
|
||||
spring-batch-infrastructure:assemble
|
||||
spring-batch-infrastructure-neo4j4:assemble
|
||||
spring-batch-infrastructure-tests:assemble
|
||||
spring-batch-integration:assemble
|
||||
spring-batch-samples:assemble
|
||||
spring-batch-test:assemble
|
||||
spring-build-src:assemble
|
||||
build
|
||||
spring-batch-core:build
|
||||
spring-batch-core-tests:build
|
||||
spring-batch-infrastructure:build
|
||||
spring-batch-infrastructure-neo4j4:build
|
||||
spring-batch-infrastructure-tests:build
|
||||
spring-batch-integration:build
|
||||
spring-batch-samples:build
|
||||
spring-batch-test:build
|
||||
spring-build-src:build
|
||||
spring-batch-core:buildDependents
|
||||
spring-batch-core-tests:buildDependents
|
||||
spring-batch-infrastructure:buildDependents
|
||||
spring-batch-infrastructure-neo4j4:buildDependents
|
||||
spring-batch-infrastructure-tests:buildDependents
|
||||
spring-batch-integration:buildDependents
|
||||
spring-batch-samples:buildDependents
|
||||
spring-batch-test:buildDependents
|
||||
spring-build-src:buildDependents
|
||||
spring-batch-core:buildNeeded
|
||||
spring-batch-core-tests:buildNeeded
|
||||
spring-batch-infrastructure:buildNeeded
|
||||
spring-batch-infrastructure-neo4j4:buildNeeded
|
||||
spring-batch-infrastructure-tests:buildNeeded
|
||||
spring-batch-integration:buildNeeded
|
||||
spring-batch-samples:buildNeeded
|
||||
spring-batch-test:buildNeeded
|
||||
spring-build-src:buildNeeded
|
||||
spring-batch-core:classes
|
||||
spring-batch-core:compileJava
|
||||
spring-batch-core:processResources
|
||||
spring-batch-core-tests:classes
|
||||
spring-batch-core-tests:compileJava
|
||||
spring-batch-core-tests:processResources
|
||||
spring-batch-infrastructure:classes
|
||||
spring-batch-infrastructure:compileJava
|
||||
spring-batch-infrastructure:processResources
|
||||
spring-batch-infrastructure-neo4j4:classes
|
||||
spring-batch-infrastructure-neo4j4:compileJava
|
||||
spring-batch-infrastructure-neo4j4:processResources
|
||||
spring-batch-infrastructure-tests:classes
|
||||
spring-batch-infrastructure-tests:compileJava
|
||||
spring-batch-infrastructure-tests:processResources
|
||||
spring-batch-integration:classes
|
||||
spring-batch-integration:compileJava
|
||||
spring-batch-integration:processResources
|
||||
spring-batch-samples:classes
|
||||
spring-batch-samples:compileJava
|
||||
spring-batch-samples:processResources
|
||||
spring-batch-test:classes
|
||||
spring-batch-test:compileJava
|
||||
spring-batch-test:processResources
|
||||
spring-build-src:classes
|
||||
spring-build-src:compileGroovy
|
||||
spring-build-src:compileJava
|
||||
spring-build-src:processResources
|
||||
spring-batch-core:generateSql
|
||||
spring-batch-core:jar
|
||||
spring-batch-core-tests:jar
|
||||
spring-batch-infrastructure:jar
|
||||
spring-batch-infrastructure-neo4j4:jar
|
||||
spring-batch-infrastructure-tests:jar
|
||||
spring-batch-integration:jar
|
||||
spring-batch-samples:jar
|
||||
spring-batch-test:jar
|
||||
spring-build-src:jar
|
||||
spring-batch-core:testClasses
|
||||
spring-batch-core:compileTestJava
|
||||
spring-batch-core:processTestResources
|
||||
spring-batch-core-tests:testClasses
|
||||
spring-batch-core-tests:compileTestJava
|
||||
spring-batch-core-tests:processTestResources
|
||||
spring-batch-infrastructure:testClasses
|
||||
spring-batch-infrastructure:compileTestJava
|
||||
spring-batch-infrastructure:processTestResources
|
||||
spring-batch-infrastructure-neo4j4:testClasses
|
||||
spring-batch-infrastructure-neo4j4:compileTestJava
|
||||
spring-batch-infrastructure-neo4j4:processTestResources
|
||||
spring-batch-infrastructure-tests:testClasses
|
||||
spring-batch-infrastructure-tests:compileTestJava
|
||||
spring-batch-infrastructure-tests:processTestResources
|
||||
spring-batch-integration:testClasses
|
||||
spring-batch-integration:compileTestJava
|
||||
spring-batch-integration:processTestResources
|
||||
spring-batch-samples:testClasses
|
||||
spring-batch-samples:compileTestJava
|
||||
spring-batch-samples:processTestResources
|
||||
spring-batch-test:testClasses
|
||||
spring-batch-test:compileTestJava
|
||||
spring-batch-test:processTestResources
|
||||
spring-build-src:testClasses
|
||||
spring-build-src:compileTestGroovy
|
||||
spring-build-src:compileTestJava
|
||||
spring-build-src:processTestResources
|
||||
init
|
||||
depsZip
|
||||
dist
|
||||
distZip
|
||||
docsZip
|
||||
schemaZip
|
||||
api
|
||||
spring-build-src:groovydoc
|
||||
spring-batch-core:javadoc
|
||||
spring-batch-core-tests:javadoc
|
||||
spring-batch-infrastructure:javadoc
|
||||
spring-batch-infrastructure-neo4j4:javadoc
|
||||
spring-batch-infrastructure-tests:javadoc
|
||||
spring-batch-integration:javadoc
|
||||
spring-batch-samples:javadoc
|
||||
spring-batch-test:javadoc
|
||||
spring-build-src:javadoc
|
||||
reference
|
||||
referenceEpub
|
||||
referenceHtmlMulti
|
||||
referenceHtmlSingle
|
||||
referencePdf
|
||||
components
|
||||
spring-batch-core:components
|
||||
spring-batch-core-tests:components
|
||||
spring-batch-infrastructure:components
|
||||
spring-batch-infrastructure-neo4j4:components
|
||||
spring-batch-infrastructure-tests:components
|
||||
spring-batch-integration:components
|
||||
spring-batch-samples:components
|
||||
spring-batch-test:components
|
||||
spring-build-src:components
|
||||
dependencies
|
||||
spring-batch-core:dependencies
|
||||
spring-batch-core-tests:dependencies
|
||||
spring-batch-infrastructure:dependencies
|
||||
spring-batch-infrastructure-neo4j4:dependencies
|
||||
spring-batch-infrastructure-tests:dependencies
|
||||
spring-batch-integration:dependencies
|
||||
spring-batch-samples:dependencies
|
||||
spring-batch-test:dependencies
|
||||
spring-build-src:dependencies
|
||||
dependencyInsight
|
||||
spring-batch-core:dependencyInsight
|
||||
spring-batch-core-tests:dependencyInsight
|
||||
spring-batch-infrastructure:dependencyInsight
|
||||
spring-batch-infrastructure-neo4j4:dependencyInsight
|
||||
spring-batch-infrastructure-tests:dependencyInsight
|
||||
spring-batch-integration:dependencyInsight
|
||||
spring-batch-samples:dependencyInsight
|
||||
spring-batch-test:dependencyInsight
|
||||
spring-build-src:dependencyInsight
|
||||
help
|
||||
spring-batch-core:help
|
||||
spring-batch-core-tests:help
|
||||
spring-batch-infrastructure:help
|
||||
spring-batch-infrastructure-neo4j4:help
|
||||
spring-batch-infrastructure-tests:help
|
||||
spring-batch-integration:help
|
||||
spring-batch-samples:help
|
||||
spring-batch-test:help
|
||||
spring-build-src:help
|
||||
model
|
||||
spring-batch-core:model
|
||||
spring-batch-core-tests:model
|
||||
spring-batch-infrastructure:model
|
||||
spring-batch-infrastructure-neo4j4:model
|
||||
spring-batch-infrastructure-tests:model
|
||||
spring-batch-integration:model
|
||||
spring-batch-samples:model
|
||||
spring-batch-test:model
|
||||
spring-build-src:model
|
||||
projects
|
||||
spring-batch-core:projects
|
||||
spring-batch-core-tests:projects
|
||||
spring-batch-infrastructure:projects
|
||||
spring-batch-infrastructure-neo4j4:projects
|
||||
spring-batch-infrastructure-tests:projects
|
||||
spring-batch-integration:projects
|
||||
spring-batch-samples:projects
|
||||
spring-batch-test:projects
|
||||
spring-build-src:projects
|
||||
properties
|
||||
spring-batch-core:properties
|
||||
spring-batch-core-tests:properties
|
||||
spring-batch-infrastructure:properties
|
||||
spring-batch-infrastructure-neo4j4:properties
|
||||
spring-batch-infrastructure-tests:properties
|
||||
spring-batch-integration:properties
|
||||
spring-batch-samples:properties
|
||||
spring-batch-test:properties
|
||||
spring-build-src:properties
|
||||
tasks
|
||||
spring-batch-core:tasks
|
||||
spring-batch-core-tests:tasks
|
||||
spring-batch-infrastructure:tasks
|
||||
spring-batch-infrastructure-neo4j4:tasks
|
||||
spring-batch-infrastructure-tests:tasks
|
||||
spring-batch-integration:tasks
|
||||
spring-batch-samples:tasks
|
||||
spring-batch-test:tasks
|
||||
spring-build-src:tasks
|
||||
spring-batch-core:cleanEclipse
|
||||
spring-batch-core-tests:cleanEclipse
|
||||
spring-batch-infrastructure:cleanEclipse
|
||||
spring-batch-infrastructure-neo4j4:cleanEclipse
|
||||
spring-batch-infrastructure-tests:cleanEclipse
|
||||
spring-batch-integration:cleanEclipse
|
||||
spring-batch-samples:cleanEclipse
|
||||
spring-batch-test:cleanEclipse
|
||||
cleanIdea
|
||||
spring-batch-core:cleanIdea
|
||||
spring-batch-core-tests:cleanIdea
|
||||
spring-batch-infrastructure:cleanIdea
|
||||
spring-batch-infrastructure-neo4j4:cleanIdea
|
||||
spring-batch-infrastructure-tests:cleanIdea
|
||||
spring-batch-integration:cleanIdea
|
||||
spring-batch-samples:cleanIdea
|
||||
spring-batch-test:cleanIdea
|
||||
spring-batch-core:eclipse
|
||||
spring-batch-core:eclipseClasspath
|
||||
spring-batch-core:eclipseJdt
|
||||
spring-batch-core:eclipseProject
|
||||
spring-batch-core-tests:eclipse
|
||||
spring-batch-core-tests:eclipseClasspath
|
||||
spring-batch-core-tests:eclipseJdt
|
||||
spring-batch-core-tests:eclipseProject
|
||||
spring-batch-infrastructure:eclipse
|
||||
spring-batch-infrastructure:eclipseClasspath
|
||||
spring-batch-infrastructure:eclipseJdt
|
||||
spring-batch-infrastructure:eclipseProject
|
||||
spring-batch-infrastructure-neo4j4:eclipse
|
||||
spring-batch-infrastructure-neo4j4:eclipseClasspath
|
||||
spring-batch-infrastructure-neo4j4:eclipseJdt
|
||||
spring-batch-infrastructure-neo4j4:eclipseProject
|
||||
spring-batch-infrastructure-tests:eclipse
|
||||
spring-batch-infrastructure-tests:eclipseClasspath
|
||||
spring-batch-infrastructure-tests:eclipseJdt
|
||||
spring-batch-infrastructure-tests:eclipseProject
|
||||
spring-batch-integration:eclipse
|
||||
spring-batch-integration:eclipseClasspath
|
||||
spring-batch-integration:eclipseJdt
|
||||
spring-batch-integration:eclipseProject
|
||||
spring-batch-samples:eclipse
|
||||
spring-batch-samples:eclipseClasspath
|
||||
spring-batch-samples:eclipseJdt
|
||||
spring-batch-samples:eclipseProject
|
||||
spring-batch-test:eclipse
|
||||
spring-batch-test:eclipseClasspath
|
||||
spring-batch-test:eclipseJdt
|
||||
spring-batch-test:eclipseProject
|
||||
idea
|
||||
ideaModule
|
||||
ideaProject
|
||||
ideaWorkspace
|
||||
spring-batch-core:idea
|
||||
spring-batch-core:ideaModule
|
||||
spring-batch-core-tests:idea
|
||||
spring-batch-core-tests:ideaModule
|
||||
spring-batch-infrastructure:idea
|
||||
spring-batch-infrastructure:ideaModule
|
||||
spring-batch-infrastructure-neo4j4:idea
|
||||
spring-batch-infrastructure-neo4j4:ideaModule
|
||||
spring-batch-infrastructure-tests:idea
|
||||
spring-batch-infrastructure-tests:ideaModule
|
||||
spring-batch-integration:idea
|
||||
spring-batch-integration:ideaModule
|
||||
spring-batch-samples:idea
|
||||
spring-batch-samples:ideaModule
|
||||
spring-batch-test:idea
|
||||
spring-batch-test:ideaModule
|
||||
check
|
||||
spring-batch-core:check
|
||||
spring-batch-core-tests:check
|
||||
spring-batch-infrastructure:check
|
||||
spring-batch-infrastructure-neo4j4:check
|
||||
spring-batch-infrastructure-tests:check
|
||||
spring-batch-integration:check
|
||||
spring-batch-samples:check
|
||||
spring-batch-test:check
|
||||
spring-build-src:check
|
||||
clean
|
||||
spring-batch-core:clean
|
||||
spring-batch-core-tests:clean
|
||||
spring-batch-infrastructure:clean
|
||||
spring-batch-infrastructure-neo4j4:clean
|
||||
spring-batch-infrastructure-tests:clean
|
||||
spring-batch-integration:clean
|
||||
spring-batch-samples:clean
|
||||
spring-batch-test:clean
|
||||
spring-build-src:clean
|
||||
spring-batch-core:test
|
||||
spring-batch-core-tests:test
|
||||
spring-batch-infrastructure:test
|
||||
spring-batch-infrastructure-neo4j4:test
|
||||
spring-batch-infrastructure-tests:test
|
||||
spring-batch-integration:test
|
||||
spring-batch-samples:test
|
||||
spring-batch-test:test
|
||||
spring-build-src:test
|
||||
spring-batch-core:install
|
||||
spring-batch-core-tests:install
|
||||
spring-batch-infrastructure:install
|
||||
spring-batch-infrastructure-neo4j4:install
|
||||
spring-batch-infrastructure-tests:install
|
||||
spring-batch-integration:install
|
||||
spring-batch-samples:install
|
||||
spring-batch-test:install
|
||||
sonarRunner
|
||||
wrapper
|
||||
41
build.gradle
41
build.gradle
@@ -8,8 +8,8 @@ buildscript {
|
||||
maven { url 'https://repo.spring.io/plugins-release' }
|
||||
}
|
||||
dependencies {
|
||||
classpath 'org.springframework.build.gradle:docbook-reference-plugin:0.2.8'
|
||||
classpath 'org.springframework.build.gradle:propdeps-plugin:0.0.5'
|
||||
classpath 'io.spring.gradle:docbook-reference-plugin:0.3.1'
|
||||
classpath 'org.springframework.build.gradle:propdeps-plugin:0.0.7'
|
||||
classpath 'io.spring.gradle:spring-io-plugin:0.0.5.RELEASE'
|
||||
}
|
||||
}
|
||||
@@ -50,6 +50,7 @@ allprojects {
|
||||
springDataJpaVersion = '1.6.0.RELEASE'
|
||||
springDataMongodbVersion = '1.5.0.RELEASE'
|
||||
springDataNeo4jVersion = '3.1.0.RELEASE'
|
||||
springDataNeo4j4Version = '4.1.1.RELEASE'
|
||||
springIntegrationVersion = '4.0.1.RELEASE'
|
||||
springLdapVersion = '2.0.2.RELEASE'
|
||||
|
||||
@@ -62,7 +63,7 @@ allprojects {
|
||||
commonsLangVersion = '2.6'
|
||||
derbyVersion = '10.10.1.1'
|
||||
groovyVersion = '2.3.0'
|
||||
hamcrestVersion = '1.3'
|
||||
hamcrestVersion = '1.3'
|
||||
h2databaseVersion = '1.3.175'
|
||||
hibernateVersion = '4.2.12.Final'
|
||||
hibernateValidatorVersion = '4.3.1.Final'
|
||||
@@ -94,13 +95,14 @@ allprojects {
|
||||
}
|
||||
}
|
||||
|
||||
subprojects { subproject ->
|
||||
configure(subprojects - project(":spring-build-src")) { subproject ->
|
||||
|
||||
apply plugin: 'java'
|
||||
apply from: "${rootProject.projectDir}/publish-maven.gradle"
|
||||
apply plugin: 'jacoco'
|
||||
apply plugin: 'propdeps-idea'
|
||||
apply plugin: 'propdeps-eclipse'
|
||||
apply plugin: 'merge'
|
||||
|
||||
jacoco {
|
||||
toolVersion = "0.7.0.201403182114"
|
||||
@@ -231,6 +233,18 @@ configure(mainProjects) {
|
||||
}
|
||||
}
|
||||
|
||||
project("spring-build-src") {
|
||||
description = "Exposes gradle buildSrc for IDE support"
|
||||
apply plugin: "groovy"
|
||||
|
||||
dependencies {
|
||||
compile gradleApi()
|
||||
compile localGroovy()
|
||||
}
|
||||
|
||||
configurations.archives.artifacts.clear()
|
||||
}
|
||||
|
||||
project('spring-batch-core') {
|
||||
description = 'Spring Batch Core'
|
||||
|
||||
@@ -263,7 +277,7 @@ project('spring-batch-core') {
|
||||
optional "org.slf4j:slf4j-log4j12:$slf4jVersion"
|
||||
optional "log4j:log4j:$log4jVersion"
|
||||
|
||||
provided "javax.batch:javax.batch-api:$javaxBatchApiVersion"
|
||||
optional "javax.batch:javax.batch-api:$javaxBatchApiVersion"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,6 +363,17 @@ project('spring-batch-infrastructure') {
|
||||
}
|
||||
}
|
||||
|
||||
project('spring-batch-infrastructure-neo4j4') {
|
||||
|
||||
merge.into = project(':spring-batch-infrastructure')
|
||||
|
||||
dependencies {
|
||||
optional "org.springframework.data:spring-data-neo4j:$springDataNeo4j4Version"
|
||||
testCompile "org.mockito:mockito-core:$mockitoVersion"
|
||||
testCompile "junit:junit:${junitVersion}"
|
||||
}
|
||||
}
|
||||
|
||||
project('spring-batch-core-tests') {
|
||||
description = 'Spring Batch Core Tests'
|
||||
project.tasks.findByPath("artifactoryPublish")?.enabled = false
|
||||
@@ -504,6 +529,8 @@ project('spring-batch-integration') {
|
||||
optional "log4j:log4j:1.2.14"
|
||||
optional "org.springframework.integration:spring-integration-jms:$springIntegrationVersion"
|
||||
optional "org.springframework:spring-jms:$springVersion"
|
||||
|
||||
optional "javax.batch:javax.batch-api:$javaxBatchApiVersion"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -573,13 +600,13 @@ project('spring-batch-samples') {
|
||||
optional "org.springframework.amqp:spring-rabbit:$springAmqpVersion"
|
||||
optional "javax.inject:javax.inject:1"
|
||||
|
||||
optional "javax.batch:javax.batch-api:$javaxBatchApiVersion"
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'docbook-reference'
|
||||
|
||||
reference {
|
||||
//sourceDir = file('src/reference/docbook')
|
||||
sourceDir = file('src/site/docbook/reference')
|
||||
}
|
||||
|
||||
@@ -793,5 +820,5 @@ or specify the Gradle property `TCK_HOME`, e.g: ./gradlew runTck -PTCK_HOME=/pat
|
||||
|
||||
task wrapper(type: Wrapper) {
|
||||
description = 'Generates gradlew[.bat] scripts'
|
||||
gradleVersion = '1.11'
|
||||
gradleVersion = '2.12'
|
||||
}
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.build.gradle
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Action
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.invocation.Gradle
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.artifacts.ProjectDependency
|
||||
import org.gradle.api.artifacts.maven.Conf2ScopeMapping
|
||||
import org.gradle.api.plugins.MavenPlugin
|
||||
import org.gradle.plugins.ide.eclipse.EclipsePlugin
|
||||
import org.gradle.plugins.ide.idea.IdeaPlugin
|
||||
/**
|
||||
* Gradle plugin that allows projects to merged together. Primarily developed to
|
||||
* allow Spring to support multiple incompatible versions of third-party
|
||||
* dependencies (for example Hibernate v3 and v4).
|
||||
* <p>
|
||||
* The 'merge' extension should be used to define how projects are merged, for example:
|
||||
* <pre class="code">
|
||||
* configure(subprojects) {
|
||||
* apply plugin: MergePlugin
|
||||
* }
|
||||
*
|
||||
* project("myproject") {
|
||||
* }
|
||||
*
|
||||
* project("myproject-extra") {
|
||||
* merge.into = project("myproject")
|
||||
* }
|
||||
* </pre>
|
||||
* <p>
|
||||
* This plugin adds two new configurations:
|
||||
* <ul>
|
||||
* <li>merging - Contains the projects being merged into this project<li>
|
||||
* <li>runtimeMerge - Contains all dependencies that are merge projects. These are used
|
||||
* to allow an IDE to reference merge projects.</li>
|
||||
* <ul>
|
||||
*
|
||||
* @author Rob Winch
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class MergePlugin implements Plugin<Project> {
|
||||
|
||||
private static boolean attachedProjectsEvaluated;
|
||||
|
||||
public void apply(Project project) {
|
||||
project.plugins.apply(MavenPlugin)
|
||||
project.plugins.apply(EclipsePlugin)
|
||||
project.plugins.apply(IdeaPlugin)
|
||||
|
||||
MergeModel model = project.extensions.create("merge", MergeModel)
|
||||
project.configurations.create("merging")
|
||||
Configuration runtimeMerge = project.configurations.create("runtimeMerge")
|
||||
|
||||
// Ensure the IDE can reference merged projects
|
||||
project.eclipse.classpath.plusConfigurations += [ runtimeMerge ]
|
||||
project.idea.module.scopes.PROVIDED.plus += [ runtimeMerge ]
|
||||
|
||||
// Hook to perform the actual merge logic
|
||||
project.afterEvaluate{
|
||||
if (it.merge.into != null) {
|
||||
setup(it)
|
||||
}
|
||||
}
|
||||
|
||||
// Hook to build runtimeMerge dependencies
|
||||
if (!attachedProjectsEvaluated) {
|
||||
project.gradle.projectsEvaluated{
|
||||
postProcessProjects(it)
|
||||
}
|
||||
attachedProjectsEvaluated = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void setup(Project project) {
|
||||
project.merge.into.dependencies.add("merging", project)
|
||||
project.dependencies.add("provided", project.merge.into.sourceSets.main.output)
|
||||
project.dependencies.add("runtimeMerge", project.merge.into)
|
||||
setupTaskDependencies(project)
|
||||
setupMaven(project)
|
||||
}
|
||||
|
||||
private void setupTaskDependencies(Project project) {
|
||||
// invoking a task will invoke the task with the same name on 'into' project
|
||||
["sourcesJar", "jar", "javadocJar", "javadoc", "install", "artifactoryPublish"].each {
|
||||
def task = project.tasks.findByPath(it)
|
||||
if (task) {
|
||||
task.enabled = false
|
||||
task.dependsOn(project.merge.into.tasks.findByPath(it))
|
||||
}
|
||||
}
|
||||
|
||||
// update 'into' project artifacts to contain the source artifact contents
|
||||
project.merge.into.sourcesJar.from(project.sourcesJar.source)
|
||||
project.merge.into.jar.from(project.sourceSets.main.output)
|
||||
project.merge.into.javadoc {
|
||||
source += project.javadoc.source
|
||||
classpath += project.javadoc.classpath
|
||||
}
|
||||
}
|
||||
|
||||
private void setupMaven(Project project) {
|
||||
project.configurations.each { configuration ->
|
||||
Conf2ScopeMapping mapping = project.conf2ScopeMappings.getMapping([configuration])
|
||||
if (mapping.scope) {
|
||||
Configuration intoConfiguration = project.merge.into.configurations.create(
|
||||
project.name + "-" + configuration.name)
|
||||
configuration.excludeRules.each {
|
||||
configuration.exclude([
|
||||
(ExcludeRule.GROUP_KEY) : it.group,
|
||||
(ExcludeRule.MODULE_KEY) : it.module])
|
||||
}
|
||||
configuration.dependencies.each {
|
||||
def intoCompile = project.merge.into.configurations.getByName("compile")
|
||||
// Protect against changing a compile scope dependency (SPR-10218)
|
||||
if (!intoCompile.dependencies.contains(it)) {
|
||||
intoConfiguration.dependencies.add(it)
|
||||
}
|
||||
}
|
||||
def index = project.parent.childProjects.findIndexOf {p -> p.getValue() == project}
|
||||
project.merge.into.install.repositories.mavenInstaller.pom.scopeMappings.addMapping(
|
||||
mapping.priority + 100 + index, intoConfiguration, mapping.scope)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private postProcessProjects(Gradle gradle) {
|
||||
gradle.rootProject.subprojects(new Action<Project>() {
|
||||
public void execute(Project project) {
|
||||
project.configurations.getByName("runtime").allDependencies.withType(ProjectDependency).each{
|
||||
Configuration dependsOnMergedFrom = it.dependencyProject.configurations.getByName("merging");
|
||||
dependsOnMergedFrom.dependencies.each{ dep ->
|
||||
project.dependencies.add("runtimeMerge", dep.dependencyProject)
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class MergeModel {
|
||||
Project into;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
implementation-class=org.springframework.build.gradle.MergePlugin
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
||||
#Thu May 08 10:59:52 CDT 2014
|
||||
#Mon Apr 18 18:28:38 CDT 2016
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=http\://services.gradle.org/distributions/gradle-1.11-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.12-bin.zip
|
||||
|
||||
@@ -3,7 +3,11 @@ rootProject.name = 'spring-batch'
|
||||
include 'spring-batch-core'
|
||||
include 'spring-batch-core-tests'
|
||||
include 'spring-batch-infrastructure'
|
||||
include 'spring-batch-infrastructure-neo4j4'
|
||||
include 'spring-batch-infrastructure-tests'
|
||||
include 'spring-batch-test'
|
||||
include 'spring-batch-integration'
|
||||
include 'spring-batch-samples'
|
||||
|
||||
include "buildSrc"
|
||||
rootProject.children.find{ it.name == "buildSrc" }.name = "spring-build-src"
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2016 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.batch.item.data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Extensions of the {@link AbstractNeo4jItemReader} intended for use with versions of
|
||||
* Spring Data Neo4J > 4. Conversions of the results are done using logic based on the
|
||||
* target type.
|
||||
* </p>
|
||||
*
|
||||
* @author Michael Minella
|
||||
* @author Vince Bickers
|
||||
* @since 3.0.7
|
||||
*/
|
||||
public class Neo4j4ItemReader<T> extends AbstractNeo4jItemReader {
|
||||
|
||||
@Override
|
||||
protected Iterator<T> doPageRead() {
|
||||
Iterable queryResults = getTemplate().queryForObjects(
|
||||
getTargetType(), generateLimitCypherQuery(), getParameterValues());
|
||||
|
||||
if(queryResults != null) {
|
||||
return queryResults.iterator();
|
||||
}
|
||||
else {
|
||||
return new ArrayList<T>().iterator();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright 2013-2014 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.batch.item.data;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import org.springframework.data.neo4j.template.Neo4jOperations;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Matchers.isNull;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class Neo4j4ItemReaderTests {
|
||||
|
||||
private Neo4j4ItemReader<String> reader;
|
||||
@Mock
|
||||
private Neo4jOperations template;
|
||||
@Mock
|
||||
private Iterable<String> result;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
reader = new Neo4j4ItemReader<String>();
|
||||
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
reader.setTemplate(template);
|
||||
reader.setTargetType(String.class);
|
||||
reader.setStartStatement("n=node(*)");
|
||||
reader.setReturnStatement("*");
|
||||
reader.setOrderByStatement("n.age");
|
||||
reader.setPageSize(50);
|
||||
reader.afterPropertiesSet();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAfterPropertiesSet() throws Exception {
|
||||
reader = new Neo4j4ItemReader<String>();
|
||||
|
||||
try {
|
||||
reader.afterPropertiesSet();
|
||||
fail("Template was not set but exception was not thrown.");
|
||||
} catch (IllegalStateException iae) {
|
||||
assertEquals("A Neo4JOperations implementation is required", iae.getMessage());
|
||||
} catch (Throwable t) {
|
||||
fail("Wrong exception was thrown:" + t);
|
||||
}
|
||||
|
||||
reader.setTemplate(template);
|
||||
|
||||
try {
|
||||
reader.afterPropertiesSet();
|
||||
fail("type was not set but exception was not thrown.");
|
||||
} catch (IllegalStateException iae) {
|
||||
assertEquals("The type to be returned is required", iae.getMessage());
|
||||
} catch (Throwable t) {
|
||||
fail("Wrong exception was thrown:" + t);
|
||||
}
|
||||
|
||||
reader.setTargetType(String.class);
|
||||
|
||||
try {
|
||||
reader.afterPropertiesSet();
|
||||
fail("START was not set but exception was not thrown.");
|
||||
} catch (IllegalStateException iae) {
|
||||
assertEquals("A START statement is required", iae.getMessage());
|
||||
} catch (Throwable t) {
|
||||
fail("Wrong exception was thrown:" + t);
|
||||
}
|
||||
|
||||
reader.setStartStatement("n=node(*)");
|
||||
|
||||
try {
|
||||
reader.afterPropertiesSet();
|
||||
fail("RETURN was not set but exception was not thrown.");
|
||||
} catch (IllegalStateException iae) {
|
||||
assertEquals("A RETURN statement is required", iae.getMessage());
|
||||
} catch (Throwable t) {
|
||||
fail("Wrong exception was thrown:" + t);
|
||||
}
|
||||
|
||||
reader.setReturnStatement("n.name, n.phone");
|
||||
|
||||
try {
|
||||
reader.afterPropertiesSet();
|
||||
fail("ORDER BY was not set but exception was not thrown.");
|
||||
} catch (IllegalStateException iae) {
|
||||
assertEquals("A ORDER BY statement is required", iae.getMessage());
|
||||
} catch (Throwable t) {
|
||||
fail("Wrong exception was thrown:" + t);
|
||||
}
|
||||
|
||||
reader.setOrderByStatement("n.age");
|
||||
|
||||
reader.afterPropertiesSet();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void testNullResults() {
|
||||
ArgumentCaptor<String> query = ArgumentCaptor.forClass(String.class);
|
||||
|
||||
when(template.queryForObjects(eq(String.class), query.capture(), (Map<String, Object>) isNull())).thenReturn(null);
|
||||
|
||||
assertFalse(reader.doPageRead().hasNext());
|
||||
assertEquals("START n=node(*) RETURN * ORDER BY n.age SKIP 0 LIMIT 50", query.getValue());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void testNoResults() {
|
||||
ArgumentCaptor<String> query = ArgumentCaptor.forClass(String.class);
|
||||
|
||||
when(template.queryForObjects(eq(String.class), query.capture(), (Map<String, Object>) isNull())).thenReturn(result);
|
||||
when(result.iterator()).thenReturn(Collections.<String>emptyIterator());
|
||||
|
||||
assertFalse(reader.doPageRead().hasNext());
|
||||
assertEquals("START n=node(*) RETURN * ORDER BY n.age SKIP 0 LIMIT 50", query.getValue());
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
@Test
|
||||
public void testResultsWithMatchAndWhere() throws Exception {
|
||||
reader.setMatchStatement("n -- m");
|
||||
reader.setWhereStatement("has(n.name)");
|
||||
reader.setReturnStatement("m");
|
||||
reader.afterPropertiesSet();
|
||||
when(template.queryForObjects(String.class, "START n=node(*) MATCH n -- m WHERE has(n.name) RETURN m ORDER BY n.age SKIP 0 LIMIT 50", null)).thenReturn(result);
|
||||
when(result.iterator()).thenReturn(Arrays.asList("foo", "bar", "baz").iterator());
|
||||
|
||||
assertTrue(reader.doPageRead().hasNext());
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
@Test
|
||||
public void testResultsWithMatchAndWhereWithParameters() throws Exception {
|
||||
Map<String, Object> params = new HashMap<String, Object>();
|
||||
params.put("foo", "bar");
|
||||
reader.setParameterValues(params);
|
||||
reader.setMatchStatement("n -- m");
|
||||
reader.setWhereStatement("has(n.name)");
|
||||
reader.setReturnStatement("m");
|
||||
reader.afterPropertiesSet();
|
||||
when(template.queryForObjects(String.class, "START n=node(*) MATCH n -- m WHERE has(n.name) RETURN m ORDER BY n.age SKIP 0 LIMIT 50", params)).thenReturn(result);
|
||||
when(result.iterator()).thenReturn(Arrays.asList("foo", "bar", "baz").iterator());
|
||||
|
||||
assertTrue(reader.doPageRead().hasNext());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
* Copyright 2012-2016 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.batch.item.data;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.data.neo4j.template.Neo4jOperations;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Restartable {@link ItemReader} that reads objects from the graph database Neo4j
|
||||
* via a paging technique.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* It executes cypher queries built from the statement fragments provided to
|
||||
* retrieve the requested data. The query is executed using paged requests of
|
||||
* a size specified in {@link #setPageSize(int)}. Additional pages are requested
|
||||
* as needed when the {@link #read()} method is called. On restart, the reader
|
||||
* will begin again at the same number item it left off at.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Performance is dependent on your Neo4J configuration (embedded or remote) as
|
||||
* well as page size. Setting a fairly large page size and using a commit
|
||||
* interval that matches the page size should provide better performance.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* This implementation is thread-safe between calls to
|
||||
* {@link #open(org.springframework.batch.item.ExecutionContext)}, however you
|
||||
* should set <code>saveState=false</code> if used in a multi-threaded
|
||||
* environment (no restart available).
|
||||
* </p>
|
||||
*
|
||||
* @author Michael Minella
|
||||
* @since 3.07
|
||||
*/
|
||||
public abstract class AbstractNeo4jItemReader<T> extends
|
||||
AbstractPaginatedDataItemReader<T> implements InitializingBean {
|
||||
|
||||
protected Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private Neo4jOperations template;
|
||||
|
||||
private String startStatement;
|
||||
private String returnStatement;
|
||||
private String matchStatement;
|
||||
private String whereStatement;
|
||||
private String orderByStatement;
|
||||
|
||||
private Class<T> targetType;
|
||||
|
||||
private Map<String, Object> parameterValues;
|
||||
|
||||
/**
|
||||
* Optional parameters to be used in the cypher query.
|
||||
*
|
||||
* @param parameterValues the parameter values to be used in the cypher query
|
||||
*/
|
||||
public void setParameterValues(Map<String, Object> parameterValues) {
|
||||
this.parameterValues = parameterValues;
|
||||
}
|
||||
|
||||
protected final Map<String, Object> getParameterValues() {
|
||||
return this.parameterValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* The start segment of the cypher query. START is prepended
|
||||
* to the statement provided and should <em>not</em> be
|
||||
* included.
|
||||
*
|
||||
* @param startStatement the start fragment of the cypher query.
|
||||
*/
|
||||
public void setStartStatement(String startStatement) {
|
||||
this.startStatement = startStatement;
|
||||
}
|
||||
|
||||
/**
|
||||
* The return statement of the cypher query. RETURN is prepended
|
||||
* to the statement provided and should <em>not</em> be
|
||||
* included
|
||||
*
|
||||
* @param returnStatement the return fragment of the cypher query.
|
||||
*/
|
||||
public void setReturnStatement(String returnStatement) {
|
||||
this.returnStatement = returnStatement;
|
||||
}
|
||||
|
||||
/**
|
||||
* An optional match fragment of the cypher query. MATCH is
|
||||
* prepended to the statement provided and should <em>not</em>
|
||||
* be included.
|
||||
*
|
||||
* @param matchStatement the match fragment of the cypher query
|
||||
*/
|
||||
public void setMatchStatement(String matchStatement) {
|
||||
this.matchStatement = matchStatement;
|
||||
}
|
||||
|
||||
/**
|
||||
* An optional where fragment of the cypher query. WHERE is
|
||||
* prepended to the statement provided and should <em>not</em>
|
||||
* be included.
|
||||
*
|
||||
* @param whereStatement where fragment of the cypher query
|
||||
*/
|
||||
public void setWhereStatement(String whereStatement) {
|
||||
this.whereStatement = whereStatement;
|
||||
}
|
||||
|
||||
/**
|
||||
* A list of properties to order the results by. This is
|
||||
* required so that subsequent page requests pull back the
|
||||
* segment of results correctly. ORDER BY is prepended to
|
||||
* the statement provided and should <em>not</em> be included.
|
||||
*
|
||||
* @param orderByStatement order by fragment of the cypher query.
|
||||
*/
|
||||
public void setOrderByStatement(String orderByStatement) {
|
||||
this.orderByStatement = orderByStatement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to perform operations against the Neo4J database.
|
||||
*
|
||||
* @param template the Neo4jOperations instance to use
|
||||
* @see Neo4jOperations
|
||||
*/
|
||||
public void setTemplate(Neo4jOperations template) {
|
||||
this.template = template;
|
||||
}
|
||||
|
||||
protected final Neo4jOperations getTemplate() {
|
||||
return this.template;
|
||||
}
|
||||
|
||||
/**
|
||||
* The object type to be returned from each call to {@link #read()}
|
||||
*
|
||||
* @param targetType the type of object to return.
|
||||
*/
|
||||
public void setTargetType(Class<T> targetType) {
|
||||
this.targetType = targetType;
|
||||
}
|
||||
|
||||
protected final Class<T> getTargetType() {
|
||||
return this.targetType;
|
||||
}
|
||||
|
||||
protected String generateLimitCypherQuery() {
|
||||
StringBuilder query = new StringBuilder();
|
||||
|
||||
query.append("START ").append(startStatement);
|
||||
query.append(matchStatement != null ? " MATCH " + matchStatement : "");
|
||||
query.append(whereStatement != null ? " WHERE " + whereStatement : "");
|
||||
query.append(" RETURN ").append(returnStatement);
|
||||
query.append(" ORDER BY ").append(orderByStatement);
|
||||
query.append(" SKIP " + (pageSize * page));
|
||||
query.append(" LIMIT " + pageSize);
|
||||
|
||||
String resultingQuery = query.toString();
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(resultingQuery);
|
||||
}
|
||||
|
||||
return resultingQuery;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks mandatory properties
|
||||
*
|
||||
* @see InitializingBean#afterPropertiesSet()
|
||||
*/
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.state(template != null, "A Neo4JOperations implementation is required");
|
||||
Assert.state(targetType != null, "The type to be returned is required");
|
||||
Assert.state(StringUtils.hasText(startStatement), "A START statement is required");
|
||||
Assert.state(StringUtils.hasText(returnStatement), "A RETURN statement is required");
|
||||
Assert.state(StringUtils.hasText(orderByStatement), "A ORDER BY statement is required");
|
||||
}
|
||||
}
|
||||
@@ -22,153 +22,32 @@ import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
import org.springframework.data.neo4j.conversion.DefaultConverter;
|
||||
import org.springframework.data.neo4j.conversion.Result;
|
||||
import org.springframework.data.neo4j.conversion.ResultConverter;
|
||||
import org.springframework.data.neo4j.template.Neo4jOperations;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Restartable {@link ItemReader} that reads objects from the graph database Neo4j
|
||||
* via a paging technique.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* It executes cypher queries built from the statement fragments provided to
|
||||
* retrieve the requested data. The query is executed using paged requests of
|
||||
* a size specified in {@link #setPageSize(int)}. Additional pages are requested
|
||||
* as needed when the {@link #read()} method is called. On restart, the reader
|
||||
* will begin again at the same number item it left off at.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Performance is dependent on your Neo4J configuration (embedded or remote) as
|
||||
* well as page size. Setting a fairly large page size and using a commit
|
||||
* interval that matches the page size should provide better performance.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* This implementation is thread-safe between calls to
|
||||
* {@link #open(org.springframework.batch.item.ExecutionContext)}, however you
|
||||
* should set <code>saveState=false</code> if used in a multi-threaded
|
||||
* environment (no restart available).
|
||||
* Extensions of the {@link AbstractNeo4jItemReader} intended for use with versions of
|
||||
* Spring Data Neo4J < 4. Conversions of the results are done using an external
|
||||
* {@link ResultConverter}.
|
||||
* </p>
|
||||
*
|
||||
* @author Michael Minella
|
||||
*
|
||||
* @see org.springframework.batch.item.data.Neo4j4ItemReader
|
||||
*/
|
||||
public class Neo4jItemReader<T> extends AbstractPaginatedDataItemReader<T> implements
|
||||
InitializingBean {
|
||||
public class Neo4jItemReader<T> extends AbstractNeo4jItemReader {
|
||||
|
||||
protected Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private Neo4jOperations template;
|
||||
|
||||
private String startStatement;
|
||||
private String returnStatement;
|
||||
private String matchStatement;
|
||||
private String whereStatement;
|
||||
private String orderByStatement;
|
||||
|
||||
private Class<T> targetType;
|
||||
|
||||
private Map<String, Object> parameterValues;
|
||||
|
||||
private ResultConverter<Map<String, Object>, T> resultConverter;
|
||||
|
||||
public Neo4jItemReader() {
|
||||
setName(ClassUtils.getShortName(Neo4jItemReader.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional parameters to be used in the cypher query.
|
||||
*
|
||||
* @param parameterValues the parameter values to be used in the cypher query
|
||||
*/
|
||||
public void setParameterValues(Map<String, Object> parameterValues) {
|
||||
this.parameterValues = parameterValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* The start segment of the cypher query. START is prepended
|
||||
* to the statement provided and should <em>not</em> be
|
||||
* included.
|
||||
*
|
||||
* @param startStatement the start fragment of the cypher query.
|
||||
*/
|
||||
public void setStartStatement(String startStatement) {
|
||||
this.startStatement = startStatement;
|
||||
}
|
||||
|
||||
/**
|
||||
* The return statement of the cypher query. RETURN is prepended
|
||||
* to the statement provided and should <em>not</em> be
|
||||
* included
|
||||
*
|
||||
* @param returnStatement the return fragment of the cypher query.
|
||||
*/
|
||||
public void setReturnStatement(String returnStatement) {
|
||||
this.returnStatement = returnStatement;
|
||||
}
|
||||
|
||||
/**
|
||||
* An optional match fragment of the cypher query. MATCH is
|
||||
* prepended to the statement provided and should <em>not</em>
|
||||
* be included.
|
||||
*
|
||||
* @param matchStatement the match fragment of the cypher query
|
||||
*/
|
||||
public void setMatchStatement(String matchStatement) {
|
||||
this.matchStatement = matchStatement;
|
||||
}
|
||||
|
||||
/**
|
||||
* An optional where fragment of the cypher query. WHERE is
|
||||
* prepended to the statement provided and should <em>not</em>
|
||||
* be included.
|
||||
*
|
||||
* @param whereStatement where fragment of the cypher query
|
||||
*/
|
||||
public void setWhereStatement(String whereStatement) {
|
||||
this.whereStatement = whereStatement;
|
||||
}
|
||||
|
||||
/**
|
||||
* A list of properties to order the results by. This is
|
||||
* required so that subsequent page requests pull back the
|
||||
* segment of results correctly. ORDER BY is prepended to
|
||||
* the statement provided and should <em>not</em> be included.
|
||||
*
|
||||
* @param orderByStatement order by fragment of the cypher query.
|
||||
*/
|
||||
public void setOrderByStatement(String orderByStatement) {
|
||||
this.orderByStatement = orderByStatement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to perform operations against the Neo4J database.
|
||||
*
|
||||
* @param template the Neo4jOperations instance to use
|
||||
* @see Neo4jOperations
|
||||
*/
|
||||
public void setTemplate(Neo4jOperations template) {
|
||||
this.template = template;
|
||||
}
|
||||
|
||||
/**
|
||||
* The object type to be returned from each call to {@link #read()}
|
||||
*
|
||||
* @param targetType the type of object to return.
|
||||
*/
|
||||
public void setTargetType(Class<T> targetType) {
|
||||
this.targetType = targetType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the converter used to convert node to the targetType. By
|
||||
* default, {@link DefaultConverter} is used.
|
||||
@@ -181,53 +60,19 @@ InitializingBean {
|
||||
|
||||
@Override
|
||||
protected Iterator<T> doPageRead() {
|
||||
Result<Map<String, Object>> queryResults = template.query(
|
||||
generateLimitCypherQuery(), parameterValues);
|
||||
Result<Map<String, Object>> queryResults = getTemplate().query(
|
||||
generateLimitCypherQuery(), getParameterValues());
|
||||
|
||||
if(queryResults != null) {
|
||||
if (resultConverter != null) {
|
||||
return queryResults.to(targetType, resultConverter).iterator();
|
||||
return queryResults.to(getTargetType(), resultConverter).iterator();
|
||||
}
|
||||
else {
|
||||
return queryResults.to(targetType).iterator();
|
||||
return queryResults.to(getTargetType()).iterator();
|
||||
}
|
||||
}
|
||||
else {
|
||||
return new ArrayList<T>().iterator();
|
||||
}
|
||||
}
|
||||
|
||||
private String generateLimitCypherQuery() {
|
||||
StringBuilder query = new StringBuilder();
|
||||
|
||||
query.append("START ").append(startStatement);
|
||||
query.append(matchStatement != null ? " MATCH " + matchStatement : "");
|
||||
query.append(whereStatement != null ? " WHERE " + whereStatement : "");
|
||||
query.append(" RETURN ").append(returnStatement);
|
||||
query.append(" ORDER BY ").append(orderByStatement);
|
||||
query.append(" SKIP " + (pageSize * page));
|
||||
query.append(" LIMIT " + pageSize);
|
||||
|
||||
String resultingQuery = query.toString();
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(resultingQuery);
|
||||
}
|
||||
|
||||
return resultingQuery;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks mandatory properties
|
||||
*
|
||||
* @see InitializingBean#afterPropertiesSet()
|
||||
*/
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.state(template != null, "A Neo4JOperations implementation is required");
|
||||
Assert.state(targetType != null, "The type to be returned is required");
|
||||
Assert.state(StringUtils.hasText(startStatement), "A START statement is required");
|
||||
Assert.state(StringUtils.hasText(returnStatement), "A RETURN statement is required");
|
||||
Assert.state(StringUtils.hasText(orderByStatement), "A ORDER BY statement is required");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user