diff --git a/build.gradle b/build.gradle index f876aa5a5..feffdaa4f 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ ext { // Spring springVersion = "3.2.3.RELEASE" - hateoasVersion = "0.7.0.BUILD-SNAPSHOT" + hateoasVersion = "0.8.0.BUILD-SNAPSHOT" springPluginVersion = "0.8.0.RELEASE" springSecurityVersion = "3.1.3.RELEASE" sdCommonsVersion = "1.6.0.BUILD-SNAPSHOT" @@ -124,7 +124,9 @@ configure(subprojects) { subproject -> } } + project("spring-data-rest-core") { + apply plugin: "maven" description = "Spring Data REST core components." @@ -134,63 +136,27 @@ project("spring-data-rest-core") { dependencies { + // Spring Data Commons + compile "org.springframework.data:spring-data-commons:$sdCommonsVersion" + compile "org.springframework.hateoas:spring-hateoas:$hateoasVersion" + compile "org.springframework.plugin:spring-plugin-core:$springPluginVersion" + // Spring compile "org.springframework:spring-aop:$springVersion" compile "org.springframework:spring-core:$springVersion" compile "org.springframework:spring-beans:$springVersion" - compile "org.springframework:spring-web:$springVersion" + compile "org.springframework:spring-tx:$springVersion" runtime "cglib:cglib-nodep:$cglibVersion" - // Spring HATEOAS - compile("org.springframework.hateoas:spring-hateoas:$hateoasVersion") { - exclude module: "spring-webmvc" - } - - // Spring Data Commons - providedCompile("org.springframework.data:spring-data-commons:$sdCommonsVersion") { - force = true - exclude module: "slf4j-api" - exclude module: "jcl-over-slf4j" - } - } -} - -project("spring-data-rest-repository") { - apply plugin: "maven" - description = "Spring Data REST Repository integration." - - dependencies { - // Exporter core - compile project(":spring-data-rest-core") - - // JSR-305 - compile "com.google.code.findbugs:jsr305:2.0.1" + // JSR 303 Validation + compile("javax.validation:validation-api:1.0.0.GA", optional) // JODA compile("joda-time:joda-time:$jodaVersion", optional) - // Jackson JSON - compile "com.fasterxml.jackson.core:jackson-databind:$jacksonVersion" - compile("com.fasterxml.jackson.datatype:jackson-datatype-joda:$jacksonVersion", optional) - compile("com.fasterxml.jackson.datatype:jackson-datatype-hibernate4:$jacksonVersion", optional) - - // ROME - //compile "rome:rome:1.0" - - // JPA - compile("org.hibernate.javax.persistence:hibernate-jpa-2.0-api:1.0.1.Final", optional) - - compile("org.springframework:spring-orm:$springVersion", optional) - - // Spring Plugin - compile "org.springframework.plugin:spring-plugin-core:$springPluginVersion" - // Spring Data - compile("org.springframework.data:spring-data-jpa:$sdJpaVersion", optional) - compile("org.springframework.data:spring-data-mongodb:$sdMongoVersion", optional) - - // JSR 303 Validation - compile("javax.validation:validation-api:1.0.0.GA", optional) + testCompile("org.springframework.data:spring-data-jpa:$sdJpaVersion", optional) + testCompile("org.springframework.data:spring-data-mongodb:$sdMongoVersion", optional) // Evo Inflector compile "org.atteo:evo-inflector:${evoVersion}" @@ -199,6 +165,13 @@ project("spring-data-rest-repository") { testCompile "org.hsqldb:hsqldb:$hsqldbVersion" testCompile "org.hibernate:hibernate-entitymanager:$hibernateVersion" testRuntime "org.hibernate:hibernate-validator:$hibernateValidatorVersion" + + // JPA + testRuntime("org.hibernate.javax.persistence:hibernate-jpa-2.0-api:1.0.1.Final", optional) + + testRuntime("org.springframework:spring-orm:$springVersion", optional) + + } } @@ -207,34 +180,39 @@ project("spring-data-rest-webmvc") { description = "Spring Data REST MVC components." dependencies { + // Repository Exporter support - compile project(":spring-data-rest-repository") + compile project(":spring-data-rest-core") // Spring + compile "org.springframework:spring-web:$springVersion" compile "org.springframework:spring-webmvc:$springVersion" + compile("org.hibernate.javax.persistence:hibernate-jpa-2.0-api:1.0.1.Final", optional) + compile("org.springframework:spring-orm:$springVersion", optional) + // APIs compile("javax.servlet:javax.servlet-api:3.0.1", provided) + // Jackson + compile "com.fasterxml.jackson.datatype:jackson-datatype-joda:$jacksonVersion" + compile "com.fasterxml.jackson.datatype:jackson-datatype-hibernate4:$jacksonVersion" + // Testing testCompile "org.eclipse.jetty:jetty-servlet:$jettyVersion" testCompile "org.eclipse.jetty:jetty-webapp:$jettyVersion" testCompile "org.mozilla:rhino:1.7R4" + // Spring Data testCompile "org.springframework:spring-core:$springVersion" testCompile "org.springframework:spring-tx:$springVersion" testCompile "org.springframework.data:spring-data-jpa:$sdJpaVersion" testCompile "org.springframework.data:spring-data-mongodb:$sdMongoVersion" - testCompile("org.springframework.data:spring-data-gemfire:$sdGemfireVersion") { - exclude group: "junit" - exclude group: "org.hamcrest" - exclude module: "spring-test" - } + testCompile "org.springframework.data:spring-data-gemfire:$sdGemfireVersion" + // JODA testCompile "joda-time:joda-time:$jodaVersion" - // Jackson - testCompile "com.fasterxml.jackson.datatype:jackson-datatype-joda:$jacksonVersion" - testCompile "com.fasterxml.jackson.datatype:jackson-datatype-hibernate4:$jacksonVersion" + // Hibernate testRuntime "org.hibernate:hibernate-entitymanager:$hibernateVersion" testRuntime "org.hibernate:hibernate-validator:$hibernateValidatorVersion" @@ -363,7 +341,6 @@ configure(rootProject) { dependencies { // For integration testing testCompile project(":spring-data-rest-core") - testCompile project(":spring-data-rest-repository") testCompile project(":spring-data-rest-webmvc") } diff --git a/settings.gradle b/settings.gradle index a48202765..741ac72ae 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,6 +1,6 @@ rootProject.name = "spring-data-rest" include "spring-data-rest-core", - "spring-data-rest-repository", "spring-data-rest-webmvc", - "spring-data-rest-example" \ No newline at end of file + "spring-data-rest-example", + "spring-data-rest-tck" \ No newline at end of file diff --git a/spring-data-rest-core/src/main/java/org/springframework/data/rest/convert/DelegatingConversionService.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/convert/DelegatingConversionService.java deleted file mode 100644 index 15313730f..000000000 --- a/spring-data-rest-core/src/main/java/org/springframework/data/rest/convert/DelegatingConversionService.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2012-2013 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.rest.convert; - -import java.util.Stack; - -import org.springframework.core.convert.ConversionService; -import org.springframework.core.convert.ConverterNotFoundException; -import org.springframework.core.convert.TypeDescriptor; -import org.springframework.util.Assert; - -/** - * This {@link ConversionService} implementation delegates the actual conversion to the {@literal ConversionService} it - * finds in its internal {@link Stack} that claims to be able to convert a given class. It will roll through the - * {@literal ConversionService}s until it finds one that can convert the given type. - * - * @author Jon Brisbin - * @authot Oliver Gierke - */ -public class DelegatingConversionService implements ConversionService { - - private final Stack conversionServices; - - public DelegatingConversionService(ConversionService... svcs) { - - this.conversionServices = new Stack(); - - for (ConversionService svc : svcs) { - Assert.notNull(svc); - conversionServices.add(svc); - } - } - - /* - * (non-Javadoc) - * @see org.springframework.core.convert.ConversionService#canConvert(java.lang.Class, java.lang.Class) - */ - @Override - public boolean canConvert(Class from, Class to) { - - for (ConversionService svc : conversionServices) { - if (svc.canConvert(from, to)) { - return true; - } - } - - return false; - } - - /* - * (non-Javadoc) - * @see org.springframework.core.convert.ConversionService#canConvert(org.springframework.core.convert.TypeDescriptor, org.springframework.core.convert.TypeDescriptor) - */ - @Override - public boolean canConvert(TypeDescriptor from, TypeDescriptor to) { - - for (ConversionService svc : conversionServices) { - if (svc.canConvert(from, to)) { - return true; - } - } - - return false; - } - - /* - * (non-Javadoc) - * @see org.springframework.core.convert.ConversionService#convert(java.lang.Object, java.lang.Class) - */ - @Override - public T convert(Object o, Class type) { - - for (ConversionService svc : conversionServices) { - if (svc.canConvert(o.getClass(), type)) { - return svc.convert(o, type); - } - } - - throw new ConverterNotFoundException(TypeDescriptor.forObject(o), TypeDescriptor.valueOf(type)); - } - - /* - * (non-Javadoc) - * @see org.springframework.core.convert.ConversionService#convert(java.lang.Object, org.springframework.core.convert.TypeDescriptor, org.springframework.core.convert.TypeDescriptor) - */ - @Override - public Object convert(Object o, TypeDescriptor from, TypeDescriptor to) { - - for (ConversionService svc : conversionServices) { - if (svc.canConvert(from, to)) { - return svc.convert(o, from, to); - } - } - - throw new ConverterNotFoundException(from, to); - } -} diff --git a/spring-data-rest-core/src/main/java/org/springframework/data/rest/convert/ISO8601DateConverter.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/convert/ISO8601DateConverter.java deleted file mode 100644 index 0e17aa8dc..000000000 --- a/spring-data-rest-core/src/main/java/org/springframework/data/rest/convert/ISO8601DateConverter.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2012-2013 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.rest.convert; - -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.HashSet; -import java.util.Set; - -import org.springframework.core.convert.ConversionFailedException; -import org.springframework.core.convert.TypeDescriptor; -import org.springframework.core.convert.converter.ConditionalGenericConverter; -import org.springframework.core.convert.converter.Converter; - -/** - * @author Jon Brisbin - */ -public class ISO8601DateConverter implements ConditionalGenericConverter, Converter { - - public static final ConditionalGenericConverter INSTANCE = new ISO8601DateConverter(); - - private static final Set CONVERTIBLE_PAIRS = new HashSet(); - - static { - CONVERTIBLE_PAIRS.add(new ConvertiblePair(String.class, Date.class)); - CONVERTIBLE_PAIRS.add(new ConvertiblePair(Date.class, String.class)); - } - - /* - * (non-Javadoc) - * @see org.springframework.core.convert.converter.ConditionalConverter#matches(org.springframework.core.convert.TypeDescriptor, org.springframework.core.convert.TypeDescriptor) - */ - @Override - public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { - - if (String.class.isAssignableFrom(sourceType.getType())) { - return Date.class.isAssignableFrom(targetType.getType()); - } - - return Date.class.isAssignableFrom(sourceType.getType()) && String.class.isAssignableFrom(targetType.getType()); - } - - /* - * (non-Javadoc) - * @see org.springframework.core.convert.converter.GenericConverter#getConvertibleTypes() - */ - @Override - public Set getConvertibleTypes() { - return CONVERTIBLE_PAIRS; - } - - /* - * (non-Javadoc) - * @see org.springframework.core.convert.converter.GenericConverter#convert(java.lang.Object, org.springframework.core.convert.TypeDescriptor, org.springframework.core.convert.TypeDescriptor) - */ - @Override - public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { - - DateFormat dateFmt = iso8601DateFormat(); - - if (String.class.isAssignableFrom(sourceType.getType())) { - return dateFmt.format(source); - } - - try { - return dateFmt.parse(source.toString()); - } catch (ParseException e) { - throw new ConversionFailedException(sourceType, targetType, source, e); - } - } - - /* - * (non-Javadoc) - * @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object) - */ - @Override - public Date convert(String[] source) { - - if (source.length == 0) { - return null; - } - - try { - return iso8601DateFormat().parse(source[0]); - } catch (ParseException e) { - throw new ConversionFailedException(TypeDescriptor.valueOf(String[].class), TypeDescriptor.valueOf(Date.class), - source[0], new IllegalArgumentException( - "Source does not conform to ISO8601 date format (YYYY-MM-DDTHH:MM:SS-0000")); - } - } - - private DateFormat iso8601DateFormat() { - return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); - } -} diff --git a/spring-data-rest-core/src/main/java/org/springframework/data/rest/convert/package-info.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/convert/package-info.java deleted file mode 100644 index c79336930..000000000 --- a/spring-data-rest-core/src/main/java/org/springframework/data/rest/convert/package-info.java +++ /dev/null @@ -1,5 +0,0 @@ -/** - * {@link org.springframework.core.convert.ConversionService} and {@link org.springframework.core.convert.converter.Converter} integration for Spring Data REST. - */ -package org.springframework.data.rest.convert; - diff --git a/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/Path.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/Path.java index e88ff8bdb..302a42bfa 100644 --- a/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/Path.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/Path.java @@ -63,6 +63,10 @@ public class Path { return new Path(this.path + cleanUp(path), false); } + public Path slash(Path path) { + return slash(path.toString()); + } + /* * (non-Javadoc) * @see java.lang.Object#hashCode() @@ -79,13 +83,14 @@ public class Path { } String trimmed = path.trim().replaceAll(" ", ""); - trimmed = SLASH + trimmed.substring(getFirstNoneSlashIndex(trimmed)); while (trimmed.endsWith("/")) { trimmed = trimmed.substring(0, trimmed.length() - 1); } - return trimmed; + trimmed = trimmed.substring(getFirstNoneSlashIndex(trimmed)); + + return trimmed.contains("://") ? trimmed : SLASH + trimmed; } /* diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/RepositoryConstraintViolationException.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/RepositoryConstraintViolationException.java similarity index 92% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/RepositoryConstraintViolationException.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/RepositoryConstraintViolationException.java index 864920e2f..0fe69c8db 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/RepositoryConstraintViolationException.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/RepositoryConstraintViolationException.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository; +package org.springframework.data.rest.core; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.validation.Errors; diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/UriDomainClassConverter.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/UriDomainClassConverter.java similarity index 98% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/UriDomainClassConverter.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/UriDomainClassConverter.java index 748e4bfbb..f430b51cb 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/UriDomainClassConverter.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/UriDomainClassConverter.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.repository; +package org.springframework.data.rest.core; import java.net.URI; import java.util.HashSet; diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/ValidationErrors.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/ValidationErrors.java similarity index 97% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/ValidationErrors.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/ValidationErrors.java index 46b311a8e..ce4dc5148 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/ValidationErrors.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/ValidationErrors.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository; +package org.springframework.data.rest.core; import static org.springframework.util.ReflectionUtils.*; diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/Description.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/Description.java similarity index 85% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/Description.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/Description.java index 0409c1270..67687da07 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/Description.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/Description.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.annotation; +package org.springframework.data.rest.core.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/HandleAfterCreate.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/HandleAfterCreate.java similarity index 86% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/HandleAfterCreate.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/HandleAfterCreate.java index e36d8f5a1..18d33d473 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/HandleAfterCreate.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/HandleAfterCreate.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.annotation; +package org.springframework.data.rest.core.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/HandleAfterDelete.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/HandleAfterDelete.java similarity index 88% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/HandleAfterDelete.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/HandleAfterDelete.java index c54d758d9..1731bb5f3 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/HandleAfterDelete.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/HandleAfterDelete.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.annotation; +package org.springframework.data.rest.core.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/HandleAfterLinkDelete.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/HandleAfterLinkDelete.java similarity index 88% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/HandleAfterLinkDelete.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/HandleAfterLinkDelete.java index 70de41b3a..e406a420a 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/HandleAfterLinkDelete.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/HandleAfterLinkDelete.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.annotation; +package org.springframework.data.rest.core.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/HandleAfterLinkSave.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/HandleAfterLinkSave.java similarity index 88% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/HandleAfterLinkSave.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/HandleAfterLinkSave.java index 662ba64a8..2c5019b77 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/HandleAfterLinkSave.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/HandleAfterLinkSave.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.annotation; +package org.springframework.data.rest.core.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/HandleAfterSave.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/HandleAfterSave.java similarity index 88% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/HandleAfterSave.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/HandleAfterSave.java index cdf67c483..3e400bda2 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/HandleAfterSave.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/HandleAfterSave.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.annotation; +package org.springframework.data.rest.core.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/HandleBeforeCreate.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/HandleBeforeCreate.java similarity index 86% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/HandleBeforeCreate.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/HandleBeforeCreate.java index 7c7c7fa1b..1a89bae1d 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/HandleBeforeCreate.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/HandleBeforeCreate.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.annotation; +package org.springframework.data.rest.core.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/HandleBeforeDelete.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/HandleBeforeDelete.java similarity index 88% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/HandleBeforeDelete.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/HandleBeforeDelete.java index 7ea568d94..69aa9a79d 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/HandleBeforeDelete.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/HandleBeforeDelete.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.annotation; +package org.springframework.data.rest.core.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/HandleBeforeLinkDelete.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/HandleBeforeLinkDelete.java similarity index 89% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/HandleBeforeLinkDelete.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/HandleBeforeLinkDelete.java index c9a5da9c4..d32d49820 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/HandleBeforeLinkDelete.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/HandleBeforeLinkDelete.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.annotation; +package org.springframework.data.rest.core.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/HandleBeforeLinkSave.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/HandleBeforeLinkSave.java similarity index 88% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/HandleBeforeLinkSave.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/HandleBeforeLinkSave.java index 00929e3ec..c5f4893bf 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/HandleBeforeLinkSave.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/HandleBeforeLinkSave.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.annotation; +package org.springframework.data.rest.core.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/HandleBeforeSave.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/HandleBeforeSave.java similarity index 88% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/HandleBeforeSave.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/HandleBeforeSave.java index c53b334e4..c3c4e02be 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/HandleBeforeSave.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/HandleBeforeSave.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.annotation; +package org.springframework.data.rest.core.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/RepositoryEventHandler.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/RepositoryEventHandler.java similarity index 90% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/RepositoryEventHandler.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/RepositoryEventHandler.java index 4c66e8eaf..22f5a03e4 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/RepositoryEventHandler.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/RepositoryEventHandler.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.annotation; +package org.springframework.data.rest.core.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/RestResource.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/RestResource.java similarity index 94% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/RestResource.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/RestResource.java index a6585711e..91666d38a 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/RestResource.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/annotation/RestResource.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.annotation; +package org.springframework.data.rest.core.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/config/RepositoryRestConfiguration.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/config/RepositoryRestConfiguration.java similarity index 99% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/config/RepositoryRestConfiguration.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/config/RepositoryRestConfiguration.java index 0d85b3f15..062376642 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/config/RepositoryRestConfiguration.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/config/RepositoryRestConfiguration.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.config; +package org.springframework.data.rest.core.config; import java.net.URI; import java.util.ArrayList; diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/config/ResourceMapping.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/config/ResourceMapping.java similarity index 95% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/config/ResourceMapping.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/config/ResourceMapping.java index 74c0c83d4..e32794865 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/config/ResourceMapping.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/config/ResourceMapping.java @@ -13,9 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.config; +package org.springframework.data.rest.core.config; -import static org.springframework.data.rest.repository.support.ResourceMappingUtils.*; +import static org.springframework.data.rest.core.support.ResourceMappingUtils.*; import java.util.HashMap; import java.util.Map; diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/config/ResourceMappingConfiguration.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/config/ResourceMappingConfiguration.java similarity index 97% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/config/ResourceMappingConfiguration.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/config/ResourceMappingConfiguration.java index 9dd745107..8aaeba115 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/config/ResourceMappingConfiguration.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/config/ResourceMappingConfiguration.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.config; +package org.springframework.data.rest.core.config; import java.util.HashMap; import java.util.Map; diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/AbstractRepositoryEventListener.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/AbstractRepositoryEventListener.java similarity index 98% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/AbstractRepositoryEventListener.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/AbstractRepositoryEventListener.java index fb646f130..cc9560348 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/AbstractRepositoryEventListener.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/AbstractRepositoryEventListener.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.context; +package org.springframework.data.rest.core.event; import static org.springframework.core.GenericTypeResolver.*; diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/AfterCreateEvent.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/AfterCreateEvent.java similarity index 82% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/AfterCreateEvent.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/AfterCreateEvent.java index 3490aa020..467e32a47 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/AfterCreateEvent.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/AfterCreateEvent.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.context; +package org.springframework.data.rest.core.event; /** * Event that is emitted after a new entity is saved. diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/AfterDeleteEvent.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/AfterDeleteEvent.java similarity index 83% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/AfterDeleteEvent.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/AfterDeleteEvent.java index 5f6b44f4c..1e851b801 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/AfterDeleteEvent.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/AfterDeleteEvent.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.context; +package org.springframework.data.rest.core.event; /** * Emitted after the entity is deleted from the repository. diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/AfterLinkDeleteEvent.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/AfterLinkDeleteEvent.java similarity index 84% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/AfterLinkDeleteEvent.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/AfterLinkDeleteEvent.java index fdb264854..f06d2aa99 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/AfterLinkDeleteEvent.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/AfterLinkDeleteEvent.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.context; +package org.springframework.data.rest.core.event; /** * Emitted after a link to a related object is deleted from the parent. diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/AfterLinkSaveEvent.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/AfterLinkSaveEvent.java similarity index 84% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/AfterLinkSaveEvent.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/AfterLinkSaveEvent.java index 58cbc3c48..7997437f8 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/AfterLinkSaveEvent.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/AfterLinkSaveEvent.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.context; +package org.springframework.data.rest.core.event; /** * Emitted after saving a linked object to its parent in the repository. diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/AfterSaveEvent.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/AfterSaveEvent.java similarity index 82% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/AfterSaveEvent.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/AfterSaveEvent.java index 57d606006..edbec74d0 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/AfterSaveEvent.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/AfterSaveEvent.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.context; +package org.springframework.data.rest.core.event; /** * Emitted after a save to the repository. diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/AnnotatedHandlerBeanPostProcessor.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/AnnotatedHandlerBeanPostProcessor.java similarity index 85% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/AnnotatedHandlerBeanPostProcessor.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/AnnotatedHandlerBeanPostProcessor.java index c7e163f07..62e434cb6 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/AnnotatedHandlerBeanPostProcessor.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/AnnotatedHandlerBeanPostProcessor.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.context; +package org.springframework.data.rest.core.event; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationTargetException; @@ -12,17 +12,17 @@ import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.context.ApplicationListener; import org.springframework.core.annotation.AnnotationUtils; -import org.springframework.data.rest.repository.annotation.HandleAfterCreate; -import org.springframework.data.rest.repository.annotation.HandleAfterDelete; -import org.springframework.data.rest.repository.annotation.HandleAfterLinkDelete; -import org.springframework.data.rest.repository.annotation.HandleAfterLinkSave; -import org.springframework.data.rest.repository.annotation.HandleAfterSave; -import org.springframework.data.rest.repository.annotation.HandleBeforeCreate; -import org.springframework.data.rest.repository.annotation.HandleBeforeDelete; -import org.springframework.data.rest.repository.annotation.HandleBeforeLinkDelete; -import org.springframework.data.rest.repository.annotation.HandleBeforeLinkSave; -import org.springframework.data.rest.repository.annotation.HandleBeforeSave; -import org.springframework.data.rest.repository.annotation.RepositoryEventHandler; +import org.springframework.data.rest.core.annotation.HandleAfterCreate; +import org.springframework.data.rest.core.annotation.HandleAfterDelete; +import org.springframework.data.rest.core.annotation.HandleAfterLinkDelete; +import org.springframework.data.rest.core.annotation.HandleAfterLinkSave; +import org.springframework.data.rest.core.annotation.HandleAfterSave; +import org.springframework.data.rest.core.annotation.HandleBeforeCreate; +import org.springframework.data.rest.core.annotation.HandleBeforeDelete; +import org.springframework.data.rest.core.annotation.HandleBeforeLinkDelete; +import org.springframework.data.rest.core.annotation.HandleBeforeLinkSave; +import org.springframework.data.rest.core.annotation.HandleBeforeSave; +import org.springframework.data.rest.core.annotation.RepositoryEventHandler; import org.springframework.util.ClassUtils; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/BeforeCreateEvent.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/BeforeCreateEvent.java similarity index 83% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/BeforeCreateEvent.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/BeforeCreateEvent.java index 2325e99a9..247b18efa 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/BeforeCreateEvent.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/BeforeCreateEvent.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.context; +package org.springframework.data.rest.core.event; /** * Event emitted before an entity is saved for the first time. diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/BeforeDeleteEvent.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/BeforeDeleteEvent.java similarity index 84% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/BeforeDeleteEvent.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/BeforeDeleteEvent.java index edd91c755..297f10303 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/BeforeDeleteEvent.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/BeforeDeleteEvent.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.context; +package org.springframework.data.rest.core.event; /** * Emitted before an entity is deleted from the repository. diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/BeforeLinkDeleteEvent.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/BeforeLinkDeleteEvent.java similarity index 85% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/BeforeLinkDeleteEvent.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/BeforeLinkDeleteEvent.java index e1f9803ad..49f22a01a 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/BeforeLinkDeleteEvent.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/BeforeLinkDeleteEvent.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.context; +package org.springframework.data.rest.core.event; /** * Emitted before a link to a related object is deleted from the parent. diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/BeforeLinkSaveEvent.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/BeforeLinkSaveEvent.java similarity index 85% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/BeforeLinkSaveEvent.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/BeforeLinkSaveEvent.java index b737b0e40..baba520de 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/BeforeLinkSaveEvent.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/BeforeLinkSaveEvent.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.context; +package org.springframework.data.rest.core.event; /** * Emitted before a linked object is saved to the repository. diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/BeforeSaveEvent.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/BeforeSaveEvent.java similarity index 81% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/BeforeSaveEvent.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/BeforeSaveEvent.java index 6033f8744..eb08fb79d 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/BeforeSaveEvent.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/BeforeSaveEvent.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.context; +package org.springframework.data.rest.core.event; /** * Emitted before an entity is saved into the repository. diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/ExceptionEvent.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/ExceptionEvent.java similarity index 89% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/ExceptionEvent.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/ExceptionEvent.java index 49ef48e7f..42d9b5fde 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/ExceptionEvent.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/ExceptionEvent.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.context; +package org.springframework.data.rest.core.event; /** * An event to encapsulate an exception occurring anywhere within the REST exporter. diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/LinkSaveEvent.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/LinkSaveEvent.java similarity index 90% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/LinkSaveEvent.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/LinkSaveEvent.java index b5dc887ab..f33c525ab 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/LinkSaveEvent.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/LinkSaveEvent.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.context; +package org.springframework.data.rest.core.event; /** * Base class for {@link RepositoryEvent}s that deal with saving/updating or deleting a linked object. diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/RepositoryEvent.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/RepositoryEvent.java similarity index 85% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/RepositoryEvent.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/RepositoryEvent.java index ecb19beaa..0ae2531d5 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/RepositoryEvent.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/RepositoryEvent.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.context; +package org.springframework.data.rest.core.event; import org.springframework.context.ApplicationEvent; diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/ValidatingRepositoryEventListener.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/ValidatingRepositoryEventListener.java similarity index 86% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/ValidatingRepositoryEventListener.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/ValidatingRepositoryEventListener.java index ec364794b..299339b06 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/ValidatingRepositoryEventListener.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/ValidatingRepositoryEventListener.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.context; +package org.springframework.data.rest.core.event; import static org.springframework.beans.factory.BeanFactoryUtils.*; import static org.springframework.core.annotation.AnnotationUtils.*; @@ -16,17 +16,17 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.repository.support.Repositories; +import org.springframework.data.rest.core.RepositoryConstraintViolationException; +import org.springframework.data.rest.core.ValidationErrors; +import org.springframework.data.rest.core.annotation.HandleAfterDelete; +import org.springframework.data.rest.core.annotation.HandleAfterLinkDelete; +import org.springframework.data.rest.core.annotation.HandleAfterLinkSave; +import org.springframework.data.rest.core.annotation.HandleAfterSave; +import org.springframework.data.rest.core.annotation.HandleBeforeDelete; +import org.springframework.data.rest.core.annotation.HandleBeforeLinkDelete; +import org.springframework.data.rest.core.annotation.HandleBeforeLinkSave; +import org.springframework.data.rest.core.annotation.HandleBeforeSave; import org.springframework.data.rest.core.util.MapUtils; -import org.springframework.data.rest.repository.RepositoryConstraintViolationException; -import org.springframework.data.rest.repository.ValidationErrors; -import org.springframework.data.rest.repository.annotation.HandleAfterDelete; -import org.springframework.data.rest.repository.annotation.HandleAfterLinkDelete; -import org.springframework.data.rest.repository.annotation.HandleAfterLinkSave; -import org.springframework.data.rest.repository.annotation.HandleAfterSave; -import org.springframework.data.rest.repository.annotation.HandleBeforeDelete; -import org.springframework.data.rest.repository.annotation.HandleBeforeLinkDelete; -import org.springframework.data.rest.repository.annotation.HandleBeforeLinkSave; -import org.springframework.data.rest.repository.annotation.HandleBeforeSave; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.validation.Errors; diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/invoke/CrudMethod.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/invoke/CrudMethod.java similarity index 96% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/invoke/CrudMethod.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/invoke/CrudMethod.java index 4ea224cea..445494f29 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/invoke/CrudMethod.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/invoke/CrudMethod.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.invoke; +package org.springframework.data.rest.core.invoke; import java.lang.reflect.Method; diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/invoke/CrudRepositoryInvoker.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/invoke/CrudRepositoryInvoker.java similarity index 80% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/invoke/CrudRepositoryInvoker.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/invoke/CrudRepositoryInvoker.java index 8026cc664..f850dc7c4 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/invoke/CrudRepositoryInvoker.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/invoke/CrudRepositoryInvoker.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.repository.invoke; +package org.springframework.data.rest.core.invoke; import java.io.Serializable; @@ -59,7 +59,7 @@ class CrudRepositoryInvoker extends ReflectionRepositoryInvoker { /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.invoke.RepositoryInvoker#invokeFindAll(org.springframework.data.domain.Sort) + * @see org.springframework.data.rest.core.invoke.RepositoryInvoker#invokeFindAll(org.springframework.data.domain.Sort) */ @Override public Iterable invokeFindAll(Sort pageable) { @@ -68,7 +68,7 @@ class CrudRepositoryInvoker extends ReflectionRepositoryInvoker { /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.invoke.RepositoryInvoker#invokeFindAll(org.springframework.data.domain.Pageable) + * @see org.springframework.data.rest.core.invoke.RepositoryInvoker#invokeFindAll(org.springframework.data.domain.Pageable) */ @Override public Iterable invokeFindAll(Pageable pageable) { @@ -77,7 +77,7 @@ class CrudRepositoryInvoker extends ReflectionRepositoryInvoker { /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.invoke.RepositoryInvoker#invokeFindOne(java.io.Serializable) + * @see org.springframework.data.rest.core.invoke.RepositoryInvoker#invokeFindOne(java.io.Serializable) */ @Override public Object invokeFindOne(Serializable id) { @@ -86,7 +86,7 @@ class CrudRepositoryInvoker extends ReflectionRepositoryInvoker { /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.invoke.ReflectionRepositoryInvoker#invokeSave(java.lang.Object) + * @see org.springframework.data.rest.core.invoke.ReflectionRepositoryInvoker#invokeSave(java.lang.Object) */ @Override public Object invokeSave(Object entity) { @@ -95,7 +95,7 @@ class CrudRepositoryInvoker extends ReflectionRepositoryInvoker { /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.invoke.RepositoryInvoker#invokeDelete(java.io.Serializable) + * @see org.springframework.data.rest.core.invoke.RepositoryInvoker#invokeDelete(java.io.Serializable) */ @Override public void invokeDelete(Serializable id) { diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/invoke/PagingAndSortingRepositoryInvoker.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/invoke/PagingAndSortingRepositoryInvoker.java similarity index 87% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/invoke/PagingAndSortingRepositoryInvoker.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/invoke/PagingAndSortingRepositoryInvoker.java index acf196d2b..cf5665e72 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/invoke/PagingAndSortingRepositoryInvoker.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/invoke/PagingAndSortingRepositoryInvoker.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.repository.invoke; +package org.springframework.data.rest.core.invoke; import java.io.Serializable; @@ -50,7 +50,7 @@ class PagingAndSortingRepositoryInvoker extends CrudRepositoryInvoker { /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.invoke.CrudRepositoryInvoker#invokeFindAll(org.springframework.data.domain.Sort) + * @see org.springframework.data.rest.core.invoke.CrudRepositoryInvoker#invokeFindAll(org.springframework.data.domain.Sort) */ @Override public Iterable invokeFindAll(Sort sort) { @@ -59,7 +59,7 @@ class PagingAndSortingRepositoryInvoker extends CrudRepositoryInvoker { /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.invoke.CrudRepositoryInvoker#invokeFindAll(org.springframework.data.domain.Pageable) + * @see org.springframework.data.rest.core.invoke.CrudRepositoryInvoker#invokeFindAll(org.springframework.data.domain.Pageable) */ @Override public Iterable invokeFindAll(Pageable pageable) { diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/invoke/ReflectionRepositoryInvoker.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/invoke/ReflectionRepositoryInvoker.java similarity index 66% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/invoke/ReflectionRepositoryInvoker.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/invoke/ReflectionRepositoryInvoker.java index 08237afe1..7aeb94f9c 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/invoke/ReflectionRepositoryInvoker.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/invoke/ReflectionRepositoryInvoker.java @@ -13,25 +13,29 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.repository.invoke; +package org.springframework.data.rest.core.invoke; import java.io.Serializable; import java.lang.reflect.Method; +import java.util.Collections; import java.util.List; import java.util.Map; -import org.springframework.beans.BeanWrapperImpl; -import org.springframework.beans.support.ArgumentConvertingMethodInvoker; import org.springframework.core.MethodParameter; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.core.convert.ConversionService; +import org.springframework.core.convert.TypeDescriptor; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.repository.core.CrudMethods; import org.springframework.data.repository.core.RepositoryInformation; -import org.springframework.data.rest.repository.annotation.RestResource; +import org.springframework.data.repository.query.Param; +import org.springframework.data.rest.core.annotation.RestResource; +import org.springframework.hateoas.core.AnnotationAttribute; import org.springframework.hateoas.core.MethodParameters; import org.springframework.util.Assert; +import org.springframework.util.ReflectionUtils; +import org.springframework.util.StringUtils; /** * Base {@link RepositoryInvoker} using reflection to invoke methods on Spring Data Repositories. @@ -40,6 +44,8 @@ import org.springframework.util.Assert; */ class ReflectionRepositoryInvoker implements RepositoryInvoker { + private static final AnnotationAttribute PARAM_ANNOTATION = new AnnotationAttribute(Param.class); + private final Object repository; private final CrudMethods methods; private final RepositoryInformation information; @@ -68,7 +74,7 @@ class ReflectionRepositoryInvoker implements RepositoryInvoker { /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.invoke.RepositoryInvocationInformation#exposesFindAll() + * @see org.springframework.data.rest.core.invoke.RepositoryInvocationInformation#exposesFindAll() */ @Override public boolean exposesFindAll() { @@ -76,7 +82,7 @@ class ReflectionRepositoryInvoker implements RepositoryInvoker { } /* (non-Javadoc) - * @see org.springframework.data.rest.repository.invoke.RepositoryInvoker#invokeFindAll(org.springframework.data.domain.Sort) + * @see org.springframework.data.rest.core.invoke.RepositoryInvoker#invokeFindAll(org.springframework.data.domain.Sort) */ @Override @SuppressWarnings("unchecked") @@ -86,17 +92,32 @@ class ReflectionRepositoryInvoker implements RepositoryInvoker { /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.invoke.RepositoryInvoker#invokeFindAll(org.springframework.data.domain.Pageable) + * @see org.springframework.data.rest.core.invoke.RepositoryInvoker#invokeFindAll(org.springframework.data.domain.Pageable) */ @Override - @SuppressWarnings("unchecked") public Iterable invokeFindAll(Pageable pageable) { - return (Iterable) invoke(methods.getFindAllMethod(), pageable); + + if (!exposesFindAll()) { + return Collections.emptyList(); + } + + Method method = methods.getFindAllMethod(); + Class[] types = method.getParameterTypes(); + + if (types.length == 0) { + return invoke(method); + } + + if (Sort.class.isAssignableFrom(types[0])) { + return invoke(method, pageable == null ? null : pageable.getSort()); + } + + return invoke(method, pageable); } /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.invoke.RepositoryInvocationInformation#exposesSave() + * @see org.springframework.data.rest.core.invoke.RepositoryInvocationInformation#exposesSave() */ @Override public boolean exposesSave() { @@ -104,7 +125,7 @@ class ReflectionRepositoryInvoker implements RepositoryInvoker { } /* (non-Javadoc) - * @see org.springframework.data.rest.repository.invoke.RepositoryInvoker#invokeSave(java.lang.Object) + * @see org.springframework.data.rest.core.invoke.RepositoryInvoker#invokeSave(java.lang.Object) */ @Override public Object invokeSave(Object object) { @@ -113,7 +134,7 @@ class ReflectionRepositoryInvoker implements RepositoryInvoker { /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.invoke.RepositoryInvocationInformation#exposesFindOne() + * @see org.springframework.data.rest.core.invoke.RepositoryInvocationInformation#exposesFindOne() */ @Override public boolean exposesFindOne() { @@ -122,7 +143,7 @@ class ReflectionRepositoryInvoker implements RepositoryInvoker { /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.invoke.RepositoryInvoker#invokeFindOne(java.io.Serializable) + * @see org.springframework.data.rest.core.invoke.RepositoryInvoker#invokeFindOne(java.io.Serializable) */ @Override public Object invokeFindOne(Serializable id) { @@ -131,7 +152,7 @@ class ReflectionRepositoryInvoker implements RepositoryInvoker { /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.invoke.RepositoryInvocationInformation#exposesDelete() + * @see org.springframework.data.rest.core.invoke.RepositoryInvocationInformation#exposesDelete() */ @Override public boolean exposesDelete() { @@ -140,7 +161,7 @@ class ReflectionRepositoryInvoker implements RepositoryInvoker { /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.invoke.RepositoryInvoker#invokeDelete(java.io.Serializable) + * @see org.springframework.data.rest.core.invoke.RepositoryInvoker#invokeDelete(java.io.Serializable) */ @Override public void invokeDelete(Serializable id) { @@ -162,7 +183,7 @@ class ReflectionRepositoryInvoker implements RepositoryInvoker { /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.invoke.RepositoryInvoker#invokeQueryMethod(java.lang.reflect.Method, java.util.Map, org.springframework.data.domain.Pageable, org.springframework.data.domain.Sort) + * @see org.springframework.data.rest.core.invoke.RepositoryInvoker#invokeQueryMethod(java.lang.reflect.Method, java.util.Map, org.springframework.data.domain.Pageable, org.springframework.data.domain.Sort) */ @Override public Object invokeQueryMethod(Method method, Map parameters, Pageable pageable, Sort sort) { @@ -171,7 +192,7 @@ class ReflectionRepositoryInvoker implements RepositoryInvoker { private Object[] prepareParameters(Method method, Map rawParameters, Pageable pageable, Sort sort) { - List parameters = new MethodParameters(method).getParameters(); + List parameters = new MethodParameters(method, PARAM_ANNOTATION).getParameters(); if (parameters.isEmpty()) { return new Object[0]; @@ -192,43 +213,32 @@ class ReflectionRepositoryInvoker implements RepositoryInvoker { } else { String parameterName = param.getParameterName(); - String[] parameterValue = rawParameters.get(parameterName); - Object value = parameterValue.length == 1 ? parameterValue[0] : parameterValue; - if (value == null) { - if (parameterName.startsWith("arg")) { - throw new IllegalArgumentException("No @Param annotation found on query method " + method.getName() - + " for parameter " + parameterName); - } else { - throw new IllegalArgumentException("No query parameter specified for " + method.getName() + " param '" - + parameterName + "'"); - } + if (!StringUtils.hasText(parameterName)) { + throw new IllegalArgumentException("No @Param annotation found on query method " + method.getName() + + " for parameter " + parameterName); } - result[i] = conversionService.convert(parameterValue, targetType); + String[] parameterValue = rawParameters.get(parameterName); + Object value = parameterValue == null ? null : parameterValue.length == 1 ? parameterValue[0] : parameterValue; + + result[i] = conversionService.convert(value, TypeDescriptor.forObject(value), new TypeDescriptor(param)); } } return result; } - private Object invoke(Method method, Object... arguments) { - - BeanWrapperImpl wrapper = new BeanWrapperImpl(); - wrapper.setConversionService(conversionService); - - ArgumentConvertingMethodInvoker invoker = new ArgumentConvertingMethodInvoker(); - invoker.setTargetObject(repository); - invoker.setTargetMethod(method.getName()); - invoker.setArguments(arguments); - invoker.setTypeConverter(wrapper); - - try { - invoker.prepare(); - return invoker.invoke(); - } catch (Exception e) { - throw new IllegalStateException(e); - } + /** + * Invokes the given method with the given arguments on the backing repository. + * + * @param method + * @param arguments + * @return + */ + @SuppressWarnings("unchecked") + private T invoke(Method method, Object... arguments) { + return (T) ReflectionUtils.invokeMethod(method, repository, arguments); } /** diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/invoke/RepositoryInvocationInformation.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/invoke/RepositoryInvocationInformation.java similarity index 93% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/invoke/RepositoryInvocationInformation.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/invoke/RepositoryInvocationInformation.java index ffbbe7e63..f716ac19a 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/invoke/RepositoryInvocationInformation.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/invoke/RepositoryInvocationInformation.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.repository.invoke; +package org.springframework.data.rest.core.invoke; /** * Meta-information about the methods a repository exposes. diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/invoke/RepositoryInvoker.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/invoke/RepositoryInvoker.java similarity index 95% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/invoke/RepositoryInvoker.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/invoke/RepositoryInvoker.java index eca880651..6b4c733f9 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/invoke/RepositoryInvoker.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/invoke/RepositoryInvoker.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.repository.invoke; +package org.springframework.data.rest.core.invoke; import java.io.Serializable; import java.lang.reflect.Method; diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/invoke/RepositoryInvokerFactory.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/invoke/RepositoryInvokerFactory.java similarity index 97% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/invoke/RepositoryInvokerFactory.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/invoke/RepositoryInvokerFactory.java index cac431ab9..abfd8179a 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/invoke/RepositoryInvokerFactory.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/invoke/RepositoryInvokerFactory.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.repository.invoke; +package org.springframework.data.rest.core.invoke; import java.io.Serializable; import java.util.HashMap; diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/invoke/RepositoryMethod.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/invoke/RepositoryMethod.java similarity index 95% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/invoke/RepositoryMethod.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/invoke/RepositoryMethod.java index 0f3a9581a..006634d47 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/invoke/RepositoryMethod.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/invoke/RepositoryMethod.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.invoke; +package org.springframework.data.rest.core.invoke; import java.lang.annotation.Annotation; import java.lang.reflect.Method; @@ -10,7 +10,7 @@ import org.springframework.core.MethodParameter; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.repository.query.Param; -import org.springframework.data.rest.repository.support.Methods; +import org.springframework.data.rest.core.support.Methods; /** * An abstraction to encapsulate metadata about a repository method. diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/invoke/RepositoryQueryMethod.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/invoke/RepositoryQueryMethod.java similarity index 96% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/invoke/RepositoryQueryMethod.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/invoke/RepositoryQueryMethod.java index 30d373c53..67c4655d5 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/invoke/RepositoryQueryMethod.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/invoke/RepositoryQueryMethod.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.invoke; +package org.springframework.data.rest.core.invoke; import java.lang.annotation.Annotation; import java.lang.reflect.Method; diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/CollectionResourceMapping.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/CollectionResourceMapping.java similarity index 93% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/CollectionResourceMapping.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/CollectionResourceMapping.java index bc534d649..4e719aa78 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/CollectionResourceMapping.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/CollectionResourceMapping.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.repository.mapping; +package org.springframework.data.rest.core.mapping; /** * A custom resource mapping for collection resources. diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/EvoInflectorTypeBasedCollectionResourceMapping.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/EvoInflectorTypeBasedCollectionResourceMapping.java similarity index 88% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/EvoInflectorTypeBasedCollectionResourceMapping.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/EvoInflectorTypeBasedCollectionResourceMapping.java index 9896e9df6..5579d9158 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/EvoInflectorTypeBasedCollectionResourceMapping.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/EvoInflectorTypeBasedCollectionResourceMapping.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.repository.mapping; +package org.springframework.data.rest.core.mapping; import org.atteo.evo.inflector.English; import org.springframework.hateoas.RelProvider; @@ -38,7 +38,7 @@ class EvoInflectorTypeBasedCollectionResourceMapping extends TypeBasedCollection /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.mapping.TypeBasedCollectionResourceMapping#getDefaultPathFor(java.lang.Class) + * @see org.springframework.data.rest.core.mapping.TypeBasedCollectionResourceMapping#getDefaultPathFor(java.lang.Class) */ @Override protected String getDefaultPathFor(Class type) { diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/MethodResourceMapping.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/MethodResourceMapping.java similarity index 94% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/MethodResourceMapping.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/MethodResourceMapping.java index d7aff15f1..fa44f1b21 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/MethodResourceMapping.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/MethodResourceMapping.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.repository.mapping; +package org.springframework.data.rest.core.mapping; import java.lang.reflect.Method; diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/RepositoryAwareResourceInformation.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/RepositoryAwareResourceInformation.java similarity index 75% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/RepositoryAwareResourceInformation.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/RepositoryAwareResourceInformation.java index 70fd54854..8572fdf06 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/RepositoryAwareResourceInformation.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/RepositoryAwareResourceInformation.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.repository.mapping; +package org.springframework.data.rest.core.mapping; import org.springframework.context.annotation.Primary; import org.springframework.core.annotation.AnnotationUtils; @@ -57,7 +57,7 @@ class RepositoryAwareResourceInformation implements ResourceMetadata { /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.mapping.ResourceMetadata#getDomainType() + * @see org.springframework.data.rest.core.mapping.ResourceMetadata#getDomainType() */ @Override public Class getDomainType() { @@ -66,7 +66,7 @@ class RepositoryAwareResourceInformation implements ResourceMetadata { /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.mapping.DelegatingResourceInformation#isManaged(org.springframework.data.mapping.PersistentProperty) + * @see org.springframework.data.rest.core.mapping.DelegatingResourceInformation#isManaged(org.springframework.data.mapping.PersistentProperty) */ @Override public boolean isManagedResource(PersistentProperty property) { @@ -77,7 +77,7 @@ class RepositoryAwareResourceInformation implements ResourceMetadata { /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.mapping.ResourceMetadataProvider#getMappingFor(org.springframework.data.mapping.PersistentProperty) + * @see org.springframework.data.rest.core.mapping.ResourceMetadataProvider#getMappingFor(org.springframework.data.mapping.PersistentProperty) */ @Override public ResourceMapping getMappingFor(PersistentProperty property) { @@ -86,7 +86,7 @@ class RepositoryAwareResourceInformation implements ResourceMetadata { /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.mapping.ResourceMetadataProvider#hasMappingFor(org.springframework.data.mapping.PersistentProperty) + * @see org.springframework.data.rest.core.mapping.ResourceMetadataProvider#hasMappingFor(org.springframework.data.mapping.PersistentProperty) */ @Override public boolean isExported(PersistentProperty property) { @@ -95,7 +95,7 @@ class RepositoryAwareResourceInformation implements ResourceMetadata { /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.mapping.CollectionResourceMapping#isExported() + * @see org.springframework.data.rest.core.mapping.CollectionResourceMapping#isExported() */ @Override public Boolean isExported() { @@ -104,7 +104,7 @@ class RepositoryAwareResourceInformation implements ResourceMetadata { /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.mapping.CollectionResourceMapping#getCollectionRel() + * @see org.springframework.data.rest.core.mapping.CollectionResourceMapping#getCollectionRel() */ @Override public String getRel() { @@ -113,7 +113,7 @@ class RepositoryAwareResourceInformation implements ResourceMetadata { /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.mapping.CollectionResourceMapping#getSingleResourceRel() + * @see org.springframework.data.rest.core.mapping.CollectionResourceMapping#getSingleResourceRel() */ @Override public String getSingleResourceRel() { @@ -122,7 +122,7 @@ class RepositoryAwareResourceInformation implements ResourceMetadata { /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.mapping.CollectionResourceMapping#getPath() + * @see org.springframework.data.rest.core.mapping.CollectionResourceMapping#getPath() */ @Override public Path getPath() { @@ -131,7 +131,7 @@ class RepositoryAwareResourceInformation implements ResourceMetadata { /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.mapping.ResourceMetadata#getSearchResourceMappings() + * @see org.springframework.data.rest.core.mapping.ResourceMetadata#getSearchResourceMappings() */ @Override public SearchResourceMappings getSearchResourceMappings() { diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/RepositoryCollectionResourceMapping.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/RepositoryCollectionResourceMapping.java similarity index 85% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/RepositoryCollectionResourceMapping.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/RepositoryCollectionResourceMapping.java index 46af5e4f9..a03a019e3 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/RepositoryCollectionResourceMapping.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/RepositoryCollectionResourceMapping.java @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.repository.mapping; +package org.springframework.data.rest.core.mapping; import java.lang.reflect.Modifier; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.data.rest.core.Path; -import org.springframework.data.rest.repository.annotation.RestResource; -import org.springframework.data.rest.repository.support.RepositoriesUtils; +import org.springframework.data.rest.core.annotation.RestResource; +import org.springframework.data.rest.core.support.RepositoriesUtils; import org.springframework.hateoas.RelProvider; import org.springframework.hateoas.core.EvoInflectorRelProvider; import org.springframework.util.Assert; @@ -68,7 +68,7 @@ class RepositoryCollectionResourceMapping implements CollectionResourceMapping { /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.mapping.ResourceMapping#getPath() + * @see org.springframework.data.rest.core.mapping.ResourceMapping#getPath() */ @Override public Path getPath() { @@ -79,7 +79,7 @@ class RepositoryCollectionResourceMapping implements CollectionResourceMapping { /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.mapping.ResourceMapping#getRel() + * @see org.springframework.data.rest.core.mapping.ResourceMapping#getRel() */ @Override public String getRel() { @@ -88,7 +88,7 @@ class RepositoryCollectionResourceMapping implements CollectionResourceMapping { /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.mapping.CollectionResourceMapping#getSingleResourceRel() + * @see org.springframework.data.rest.core.mapping.CollectionResourceMapping#getSingleResourceRel() */ @Override public String getSingleResourceRel() { @@ -97,7 +97,7 @@ class RepositoryCollectionResourceMapping implements CollectionResourceMapping { /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.mapping.ResourceMapping#isExported() + * @see org.springframework.data.rest.core.mapping.ResourceMapping#isExported() */ @Override public Boolean isExported() { diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/RepositoryMethodResourceMapping.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/RepositoryMethodResourceMapping.java similarity index 75% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/RepositoryMethodResourceMapping.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/RepositoryMethodResourceMapping.java index 51428d051..c350d4184 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/RepositoryMethodResourceMapping.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/RepositoryMethodResourceMapping.java @@ -13,13 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.repository.mapping; +package org.springframework.data.rest.core.mapping; import java.lang.reflect.Method; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.data.rest.core.Path; -import org.springframework.data.rest.repository.annotation.RestResource; +import org.springframework.data.rest.core.annotation.RestResource; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -50,17 +50,14 @@ class RepositoryMethodResourceMapping implements MethodResourceMapping { this.isExported = annotation != null ? annotation.exported() : true; this.rel = annotation != null ? annotation.rel() : method.getName(); - - Path resourcePath = resourceMapping.getPath(); - String toAppend = annotation == null || !StringUtils.hasText(annotation.path()) ? method.getName() : annotation - .path(); - this.path = resourcePath.slash(toAppend); + this.path = annotation == null || !StringUtils.hasText(annotation.path()) ? new Path(method.getName()) : new Path( + annotation.path()); this.method = method; } /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.mapping.ResourceMapping#isExported() + * @see org.springframework.data.rest.core.mapping.ResourceMapping#isExported() */ @Override public Boolean isExported() { @@ -69,7 +66,7 @@ class RepositoryMethodResourceMapping implements MethodResourceMapping { /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.mapping.ResourceMapping#getRel() + * @see org.springframework.data.rest.core.mapping.ResourceMapping#getRel() */ @Override public String getRel() { @@ -78,7 +75,7 @@ class RepositoryMethodResourceMapping implements MethodResourceMapping { /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.mapping.ResourceMapping#getPath() + * @see org.springframework.data.rest.core.mapping.ResourceMapping#getPath() */ @Override public Path getPath() { @@ -87,7 +84,7 @@ class RepositoryMethodResourceMapping implements MethodResourceMapping { /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.mapping.MethodResourceMapping#getMethod() + * @see org.springframework.data.rest.core.mapping.MethodResourceMapping#getMethod() */ @Override public Method getMethod() { diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/ResourceMapping.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/ResourceMapping.java similarity index 95% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/ResourceMapping.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/ResourceMapping.java index 24af6b058..3d8aed519 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/ResourceMapping.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/ResourceMapping.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.repository.mapping; +package org.springframework.data.rest.core.mapping; import org.springframework.data.rest.core.Path; diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/ResourceMappings.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/ResourceMappings.java similarity index 83% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/ResourceMappings.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/ResourceMappings.java index d3db6bffe..5a7de21e4 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/ResourceMappings.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/ResourceMappings.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.repository.mapping; +package org.springframework.data.rest.core.mapping; import java.lang.reflect.Method; import java.util.ArrayList; @@ -25,8 +25,8 @@ import java.util.Map; import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.repository.core.RepositoryInformation; import org.springframework.data.repository.support.Repositories; -import org.springframework.data.rest.config.RepositoryRestConfiguration; -import org.springframework.data.rest.repository.support.RepositoriesUtils; +import org.springframework.data.rest.core.config.RepositoryRestConfiguration; +import org.springframework.data.rest.core.support.RepositoriesUtils; import org.springframework.hateoas.RelProvider; import org.springframework.hateoas.core.EvoInflectorRelProvider; import org.springframework.util.Assert; @@ -122,17 +122,25 @@ public class ResourceMappings implements Iterable { } Class domainType = RepositoriesUtils.getDomainType(type); - RepositoryInformation repositoryInformation = repositories.getRepositoryInformationFor(domainType); - List mappings = new ArrayList(); - ResourceMetadata repositoryMapping = getMappingFor(repositoryInformation.getRepositoryInterface()); - for (Method queryMethod : repositoryInformation.getQueryMethods()) { - mappings.add(new RepositoryMethodResourceMapping(queryMethod, repositoryMapping)); + if (searchCache.containsKey(domainType)) { + return searchCache.get(domainType); } - SearchResourceMappings searchMappings = new SearchResourceMappings(mappings); - searchCache.put(type, searchMappings); - return searchMappings; + RepositoryInformation repositoryInformation = repositories.getRepositoryInformationFor(domainType); + List mappings = new ArrayList(); + ResourceMetadata resourceMapping = getMappingFor(domainType); + + if (resourceMapping.isExported()) { + for (Method queryMethod : repositoryInformation.getQueryMethods()) { + mappings.add(new RepositoryMethodResourceMapping(queryMethod, resourceMapping)); + } + } + + SearchResourceMappings searchResourceMappings = new SearchResourceMappings(mappings); + searchCache.put(type, searchResourceMappings); + searchCache.put(domainType, searchResourceMappings); + return searchResourceMappings; } /** @@ -176,7 +184,7 @@ public class ResourceMappings implements Iterable { /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.mapping.ResourceMetadataProvider#getMappingFor(org.springframework.data.mapping.PersistentProperty) + * @see org.springframework.data.rest.core.mapping.ResourceMetadataProvider#getMappingFor(org.springframework.data.mapping.PersistentProperty) */ ResourceMapping getMappingFor(PersistentProperty property) { return getMappingFor(property.getActualType()); @@ -184,7 +192,7 @@ public class ResourceMappings implements Iterable { /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.mapping.ResourceMetadataProvider#hasMappingFor(org.springframework.data.mapping.PersistentProperty) + * @see org.springframework.data.rest.core.mapping.ResourceMetadataProvider#hasMappingFor(org.springframework.data.mapping.PersistentProperty) */ public boolean isMapped(PersistentProperty property) { diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/ResourceMetadata.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/ResourceMetadata.java similarity index 97% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/ResourceMetadata.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/ResourceMetadata.java index 67137abc7..125f1c202 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/ResourceMetadata.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/ResourceMetadata.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.repository.mapping; +package org.springframework.data.rest.core.mapping; import org.springframework.data.mapping.PersistentProperty; diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/SearchResourceMappings.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/SearchResourceMappings.java similarity index 64% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/SearchResourceMappings.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/SearchResourceMappings.java index 8b829dbf5..246f927ac 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/SearchResourceMappings.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/SearchResourceMappings.java @@ -13,11 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.repository.mapping; +package org.springframework.data.rest.core.mapping; import java.lang.reflect.Method; +import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; import org.springframework.data.rest.core.Path; import org.springframework.util.Assert; @@ -29,10 +31,13 @@ import org.springframework.util.Assert; */ public class SearchResourceMappings implements Iterable, ResourceMapping { + private static final String AMBIGUOUS_MAPPING = "Ambiguous search mapping detected. Both %s and " + + "%s are mapped to %s! Tweak configuration to get to unambiguous paths!"; + private static final Path PATH = new Path("/search"); private static final String REL = "search"; - private final List mappings; + private final Map mappings; /** * Creates a new {@link SearchResourceMappings} from the given @@ -42,7 +47,20 @@ public class SearchResourceMappings implements Iterable, public SearchResourceMappings(List mappings) { Assert.notNull(mappings, "MethodResourceMappings must not be null!"); - this.mappings = mappings; + + this.mappings = new HashMap(mappings.size()); + + for (MethodResourceMapping mapping : mappings) { + + MethodResourceMapping existing = this.mappings.get(mapping.getPath()); + + if (existing != null) { + throw new IllegalStateException(String.format(AMBIGUOUS_MAPPING, existing.getMethod(), mapping.getMethod(), + existing.getPath())); + } + + this.mappings.put(mapping.getPath(), mapping); + } } /** @@ -55,18 +73,13 @@ public class SearchResourceMappings implements Iterable, Assert.hasText(path, "Path must not be null or empty!"); - for (MethodResourceMapping mapping : mappings) { - if (mapping.getPath().matches(path)) { - return mapping.getMethod(); - } - } - - return null; + MethodResourceMapping mapping = mappings.get(new Path(path)); + return mapping == null ? null : mapping.getMethod(); } /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.mapping.ResourceMapping#getPath() + * @see org.springframework.data.rest.core.mapping.ResourceMapping#getPath() */ @Override public Path getPath() { @@ -75,7 +88,7 @@ public class SearchResourceMappings implements Iterable, /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.mapping.ResourceMapping#getRel() + * @see org.springframework.data.rest.core.mapping.ResourceMapping#getRel() */ @Override public String getRel() { @@ -84,18 +97,19 @@ public class SearchResourceMappings implements Iterable, /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.mapping.ResourceMapping#isExported() + * @see org.springframework.data.rest.core.mapping.ResourceMapping#isExported() */ @Override public Boolean isExported() { return !mappings.isEmpty(); } - /* (non-Javadoc) + /* + * (non-Javadoc) * @see java.lang.Iterable#iterator() */ @Override public Iterator iterator() { - return mappings.iterator(); + return mappings.values().iterator(); } } diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/TypeBasedCollectionResourceMapping.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/TypeBasedCollectionResourceMapping.java similarity index 86% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/TypeBasedCollectionResourceMapping.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/TypeBasedCollectionResourceMapping.java index 36946b29a..42b2a3047 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/TypeBasedCollectionResourceMapping.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/mapping/TypeBasedCollectionResourceMapping.java @@ -13,13 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.repository.mapping; +package org.springframework.data.rest.core.mapping; import java.lang.reflect.Modifier; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.data.rest.core.Path; -import org.springframework.data.rest.repository.annotation.RestResource; +import org.springframework.data.rest.core.annotation.RestResource; import org.springframework.hateoas.RelProvider; import org.springframework.hateoas.core.EvoInflectorRelProvider; import org.springframework.util.Assert; @@ -64,7 +64,7 @@ class TypeBasedCollectionResourceMapping implements CollectionResourceMapping { /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.mapping.ResourceMapping#getPath() + * @see org.springframework.data.rest.core.mapping.ResourceMapping#getPath() */ @Override public Path getPath() { @@ -76,7 +76,7 @@ class TypeBasedCollectionResourceMapping implements CollectionResourceMapping { /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.mapping.ResourceMapping#isExported() + * @see org.springframework.data.rest.core.mapping.ResourceMapping#isExported() */ @Override public Boolean isExported() { @@ -85,7 +85,7 @@ class TypeBasedCollectionResourceMapping implements CollectionResourceMapping { /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.mapping.ResourceMapping#getRel() + * @see org.springframework.data.rest.core.mapping.ResourceMapping#getRel() */ @Override public String getRel() { @@ -99,7 +99,7 @@ class TypeBasedCollectionResourceMapping implements CollectionResourceMapping { /* * (non-Javadoc) - * @see org.springframework.data.rest.repository.mapping.CollectionResourceMapping#getSingleResourceRel() + * @see org.springframework.data.rest.core.mapping.CollectionResourceMapping#getSingleResourceRel() */ @Override public String getSingleResourceRel() { diff --git a/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/package-info.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/package-info.java deleted file mode 100644 index ab46b12e2..000000000 --- a/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/package-info.java +++ /dev/null @@ -1,5 +0,0 @@ -/** - * Core components used across Spring Data REST. - */ -package org.springframework.data.rest.core; - diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/support/DomainObjectMerger.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/support/DomainObjectMerger.java similarity index 97% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/support/DomainObjectMerger.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/support/DomainObjectMerger.java index ecd2346ff..d55a19c32 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/support/DomainObjectMerger.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/support/DomainObjectMerger.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.support; +package org.springframework.data.rest.core.support; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.convert.ConversionService; diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/support/Methods.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/support/Methods.java similarity index 92% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/support/Methods.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/support/Methods.java index 2b9335220..dbf1ad3f4 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/support/Methods.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/support/Methods.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.support; +package org.springframework.data.rest.core.support; import java.lang.reflect.Method; diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/support/RepositoriesUtils.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/support/RepositoriesUtils.java similarity index 77% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/support/RepositoriesUtils.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/support/RepositoriesUtils.java index 65bc655d5..1e74734e8 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/support/RepositoriesUtils.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/support/RepositoriesUtils.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.repository.support; +package org.springframework.data.rest.core.support; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.data.repository.Repository; @@ -27,13 +27,20 @@ import org.springframework.data.repository.core.support.DefaultRepositoryMetadat */ public class RepositoriesUtils { - public static Class getDomainType(Class repositoryType) { + /** + * Resolves the domain type from the given type. Will resolve the repository domain type if the given type is a + * repository or return the type as is if not. + * + * @param type must not be {@literal null}. + * @return + */ + public static Class getDomainType(Class type) { - if (!isRepositoryInterface(repositoryType)) { - return null; + if (!isRepositoryInterface(type)) { + return type; } - return getMetadataFor(repositoryType).getDomainType(); + return getMetadataFor(type).getDomainType(); } public static boolean isRepositoryInterface(Class type) { diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/support/RepositoryRelProvider.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/support/RepositoryRelProvider.java similarity index 92% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/support/RepositoryRelProvider.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/support/RepositoryRelProvider.java index 0117f8174..b80a3650b 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/support/RepositoryRelProvider.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/support/RepositoryRelProvider.java @@ -13,9 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.repository.support; +package org.springframework.data.rest.core.support; -import org.springframework.data.rest.repository.mapping.ResourceMappings; +import org.springframework.data.rest.core.mapping.ResourceMappings; import org.springframework.hateoas.RelProvider; /** diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/support/ResourceMappingUtils.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/support/ResourceMappingUtils.java similarity index 93% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/support/ResourceMappingUtils.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/support/ResourceMappingUtils.java index fea187694..213a7a9da 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/support/ResourceMappingUtils.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/support/ResourceMappingUtils.java @@ -13,9 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.repository.support; +package org.springframework.data.rest.core.support; -import static org.springframework.data.rest.repository.support.ResourceStringUtils.*; +import static org.springframework.data.rest.core.support.ResourceStringUtils.*; import static org.springframework.core.annotation.AnnotationUtils.*; import static org.springframework.util.StringUtils.*; @@ -24,9 +24,9 @@ import java.lang.reflect.Method; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.repository.core.RepositoryInformation; -import org.springframework.data.rest.config.RepositoryRestConfiguration; -import org.springframework.data.rest.config.ResourceMapping; -import org.springframework.data.rest.repository.annotation.RestResource; +import org.springframework.data.rest.core.annotation.RestResource; +import org.springframework.data.rest.core.config.RepositoryRestConfiguration; +import org.springframework.data.rest.core.config.ResourceMapping; /** * Helper methods to get the default rel and path values or to use values supplied by annotations. diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/support/ResourceStringUtils.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/support/ResourceStringUtils.java similarity index 96% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/support/ResourceStringUtils.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/support/ResourceStringUtils.java index a021f832d..6d3040f13 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/support/ResourceStringUtils.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/support/ResourceStringUtils.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.repository.support; +package org.springframework.data.rest.core.support; /** * Helper methods aiming at handling String representations of resources. diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/support/SimpleRelProvider.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/support/SimpleRelProvider.java similarity index 96% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/support/SimpleRelProvider.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/support/SimpleRelProvider.java index a7ffae5c8..71136584f 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/support/SimpleRelProvider.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/support/SimpleRelProvider.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.repository.support; +package org.springframework.data.rest.core.support; import org.springframework.hateoas.RelProvider; import org.springframework.util.StringUtils; diff --git a/spring-data-rest-core/src/main/java/org/springframework/data/rest/convert/UUIDConverter.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/util/UUIDConverter.java similarity index 98% rename from spring-data-rest-core/src/main/java/org/springframework/data/rest/convert/UUIDConverter.java rename to spring-data-rest-core/src/main/java/org/springframework/data/rest/core/util/UUIDConverter.java index e1cf1a071..4aa4e9716 100644 --- a/spring-data-rest-core/src/main/java/org/springframework/data/rest/convert/UUIDConverter.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/util/UUIDConverter.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.convert; +package org.springframework.data.rest.core.util; import java.util.HashSet; import java.util.Set; diff --git a/spring-data-rest-core/src/main/java/org/springframework/data/rest/package-info.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/package-info.java deleted file mode 100644 index 0acebd7b7..000000000 --- a/spring-data-rest-core/src/main/java/org/springframework/data/rest/package-info.java +++ /dev/null @@ -1,5 +0,0 @@ -/** - * Spring Data REST - */ -package org.springframework.data.rest; - diff --git a/spring-data-rest-core/src/test/java/org/springframework/data/rest/convert/DelegatingConversionServiceUnitTests.java b/spring-data-rest-core/src/test/java/org/springframework/data/rest/convert/DelegatingConversionServiceUnitTests.java deleted file mode 100644 index 4d2b38710..000000000 --- a/spring-data-rest-core/src/test/java/org/springframework/data/rest/convert/DelegatingConversionServiceUnitTests.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2012-2013 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.rest.convert; - -import static org.hamcrest.MatcherAssert.*; -import static org.hamcrest.Matchers.*; -import static org.mockito.Matchers.*; -import static org.mockito.Mockito.*; - -import java.util.UUID; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Matchers; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; -import org.springframework.core.convert.ConversionService; -import org.springframework.format.support.DefaultFormattingConversionService; - -/** - * Tests to ensure the {@link DelegatingConversionService} properly delegates conversions to the - * {@link org.springframework.core.convert.ConversionService} that is appropriate for the given source and return types. - * - * @author Jon Brisbin - * @author Oliver Gierke - */ -@RunWith(MockitoJUnitRunner.class) -public class DelegatingConversionServiceUnitTests { - - private static final UUID RANDOM_UUID = UUID.fromString("9deccfd7-f892-4e26-a4d5-c92893392e78"); - - @Mock ConversionService conversionService; - DelegatingConversionService delegatingConversionService; - - @Before - public void setup() { - - DefaultFormattingConversionService cs = new DefaultFormattingConversionService(false); - cs.addConverter(UUIDConverter.INSTANCE); - - delegatingConversionService = new DelegatingConversionService(conversionService, cs); - - when(conversionService.canConvert(String.class, UUID.class)).thenReturn(false); - when(conversionService.canConvert(UUID.class, String.class)).thenReturn(false); - } - - @Test - public void shouldDelegateToProperConversionService() { - - assertThat(delegatingConversionService.canConvert(String.class, UUID.class), is(true)); - assertThat(delegatingConversionService.convert(RANDOM_UUID.toString(), UUID.class), is(RANDOM_UUID)); - - verifyConversionService(); - } - - @Test - public void shouldConvertUUIDToString() { - - assertThat(delegatingConversionService.canConvert(UUID.class, String.class), is(true)); - assertThat(delegatingConversionService.convert(RANDOM_UUID, String.class), is(RANDOM_UUID.toString())); - - verifyConversionService(); - } - - private void verifyConversionService() { - - verify(conversionService, times(0)).convert(Matchers.any(String.class), eq(UUID.class)); - verify(conversionService, times(0)).convert(Matchers.any(UUID.class), eq(String.class)); - } -} diff --git a/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/AbstractIntegrationTests.java b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/AbstractIntegrationTests.java new file mode 100644 index 000000000..4ca37f9cb --- /dev/null +++ b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/AbstractIntegrationTests.java @@ -0,0 +1,44 @@ +/* + * Copyright 2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.rest.core; + +import org.junit.Before; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.rest.core.domain.jpa.Person; +import org.springframework.data.rest.core.domain.jpa.PersonRepository; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.annotation.Transactional; + +/** + * Base class for integration tests loading {@link RepositoryTestsConfig} and populating the {@link PersonRepository} + * with a {@link Person}. + * + * @author Oliver Gierke + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = RepositoryTestsConfig.class) +@Transactional +public abstract class AbstractIntegrationTests { + + @Autowired PersonRepository repository; + + @Before + public void populateDatabase() { + repository.save(new Person("John", "Doe")); + } +} diff --git a/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/PathUnitTests.java b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/PathUnitTests.java index 10b4c9767..f6ca513fc 100644 --- a/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/PathUnitTests.java +++ b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/PathUnitTests.java @@ -62,4 +62,9 @@ public class PathUnitTests { public void doesNotMatchIfDifferent() { assertThat(new Path("/foobar").matches("barfoo"), is(false)); } + + @Test + public void doesNotPrefixAbsoluteUris() { + assertThat(new Path("http://localhost").toString(), is("http://localhost")); + } } diff --git a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/RepositoryRestConfigurationIntegrationTests.java b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/RepositoryRestConfigurationIntegrationTests.java similarity index 55% rename from spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/RepositoryRestConfigurationIntegrationTests.java rename to spring-data-rest-core/src/test/java/org/springframework/data/rest/core/RepositoryRestConfigurationIntegrationTests.java index 4bca09de7..cfb6b8733 100644 --- a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/RepositoryRestConfigurationIntegrationTests.java +++ b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/RepositoryRestConfigurationIntegrationTests.java @@ -1,26 +1,21 @@ -package org.springframework.data.rest.repository; +package org.springframework.data.rest.core; import static org.hamcrest.MatcherAssert.*; import static org.hamcrest.Matchers.*; import org.junit.Test; -import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.rest.config.RepositoryRestConfiguration; -import org.springframework.data.rest.config.ResourceMapping; -import org.springframework.data.rest.repository.domain.jpa.ConfiguredPersonRepository; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.data.rest.core.config.RepositoryRestConfiguration; +import org.springframework.data.rest.core.config.ResourceMapping; +import org.springframework.data.rest.core.domain.jpa.ConfiguredPersonRepository; /** * Tests to check that {@link ResourceMapping}s are handled correctly. * * @author Jon Brisbin */ -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = RepositoryTestsConfig.class) @SuppressWarnings("deprecation") -public class RepositoryRestConfigurationIntegrationTests { +public class RepositoryRestConfigurationIntegrationTests extends AbstractIntegrationTests { @Autowired RepositoryRestConfiguration config; diff --git a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/RepositoryTestsConfig.java b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/RepositoryTestsConfig.java similarity index 79% rename from spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/RepositoryTestsConfig.java rename to spring-data-rest-core/src/test/java/org/springframework/data/rest/core/RepositoryTestsConfig.java index 9742a2cbb..886e89568 100644 --- a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/RepositoryTestsConfig.java +++ b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/RepositoryTestsConfig.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository; +package org.springframework.data.rest.core; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; @@ -7,11 +7,12 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.data.repository.support.DomainClassConverter; import org.springframework.data.repository.support.Repositories; -import org.springframework.data.rest.config.RepositoryRestConfiguration; -import org.springframework.data.rest.repository.domain.jpa.ConfiguredPersonRepository; -import org.springframework.data.rest.repository.domain.jpa.JpaRepositoryConfig; -import org.springframework.data.rest.repository.domain.jpa.Person; -import org.springframework.data.rest.repository.domain.jpa.PersonRepository; +import org.springframework.data.rest.core.UriDomainClassConverter; +import org.springframework.data.rest.core.config.RepositoryRestConfiguration; +import org.springframework.data.rest.core.domain.jpa.ConfiguredPersonRepository; +import org.springframework.data.rest.core.domain.jpa.JpaRepositoryConfig; +import org.springframework.data.rest.core.domain.jpa.Person; +import org.springframework.data.rest.core.domain.jpa.PersonRepository; import org.springframework.format.support.DefaultFormattingConversionService; /** diff --git a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/config/ResourceMappingUnitTests.java b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/config/ResourceMappingUnitTests.java similarity index 81% rename from spring-data-rest-repository/src/test/java/org/springframework/data/rest/config/ResourceMappingUnitTests.java rename to spring-data-rest-core/src/test/java/org/springframework/data/rest/core/config/ResourceMappingUnitTests.java index 459a0422e..26ddf0241 100644 --- a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/config/ResourceMappingUnitTests.java +++ b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/config/ResourceMappingUnitTests.java @@ -13,11 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.config; +package org.springframework.data.rest.core.config; import static org.hamcrest.MatcherAssert.*; import static org.hamcrest.Matchers.*; -import static org.springframework.data.rest.repository.support.ResourceMappingUtils.*; +import static org.springframework.data.rest.core.support.ResourceMappingUtils.*; import java.lang.reflect.Method; @@ -25,9 +25,9 @@ import org.junit.Test; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.repository.query.Param; -import org.springframework.data.rest.repository.annotation.RestResource; -import org.springframework.data.rest.repository.domain.jpa.Person; -import org.springframework.data.rest.repository.mapping.ResourceMapping; +import org.springframework.data.rest.core.annotation.RestResource; +import org.springframework.data.rest.core.domain.jpa.Person; +import org.springframework.data.rest.core.mapping.ResourceMapping; import org.springframework.hateoas.RelProvider; import org.springframework.hateoas.core.EvoInflectorRelProvider; @@ -43,7 +43,7 @@ public class ResourceMappingUnitTests { @Test public void shouldDetectPathAndRemoveLeadingSlashIfAny() { - org.springframework.data.rest.config.ResourceMapping mapping = new org.springframework.data.rest.config.ResourceMapping( + org.springframework.data.rest.core.config.ResourceMapping mapping = new org.springframework.data.rest.core.config.ResourceMapping( findRel(AnnotatedWithLeadingSlashPersonRepository.class), findPath(AnnotatedWithLeadingSlashPersonRepository.class), findExported(AnnotatedWithLeadingSlashPersonRepository.class)); @@ -59,7 +59,7 @@ public class ResourceMappingUnitTests { public void shouldDetectPathAndRemoveLeadingSlashIfAnyOnMethod() throws Exception { Method method = AnnotatedWithLeadingSlashPersonRepository.class.getMethod("findByFirstName", String.class, Pageable.class); - org.springframework.data.rest.config.ResourceMapping mapping = new org.springframework.data.rest.config.ResourceMapping( + org.springframework.data.rest.core.config.ResourceMapping mapping = new org.springframework.data.rest.core.config.ResourceMapping( findRel(method), findPath(method), findExported(method)); // The rel attribute defaults to class name @@ -73,7 +73,7 @@ public class ResourceMappingUnitTests { public void shouldReturnDefaultIfPathContainsOnlySlashTextOnMethod() throws Exception { Method method = AnnotatedWithLeadingSlashPersonRepository.class.getMethod("findByLastName", String.class, Pageable.class); - org.springframework.data.rest.config.ResourceMapping mapping = new org.springframework.data.rest.config.ResourceMapping( + org.springframework.data.rest.core.config.ResourceMapping mapping = new org.springframework.data.rest.core.config.ResourceMapping( findRel(method), findPath(method), findExported(method)); // The rel defaults to method name diff --git a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/context/RepositoryEventIntegrationTests.java b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/context/RepositoryEventIntegrationTests.java similarity index 55% rename from spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/context/RepositoryEventIntegrationTests.java rename to spring-data-rest-core/src/test/java/org/springframework/data/rest/core/context/RepositoryEventIntegrationTests.java index 520ddcbb0..e1ac7aedc 100644 --- a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/context/RepositoryEventIntegrationTests.java +++ b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/context/RepositoryEventIntegrationTests.java @@ -1,14 +1,32 @@ -package org.springframework.data.rest.repository.context; +package org.springframework.data.rest.core.context; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; -import org.springframework.data.rest.repository.domain.jpa.Person; -import org.springframework.data.rest.repository.domain.jpa.PersonRepository; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.data.rest.core.RepositoryTestsConfig; +import org.springframework.data.rest.core.domain.jpa.AnnotatedPersonEventHandler; +import org.springframework.data.rest.core.domain.jpa.Person; +import org.springframework.data.rest.core.domain.jpa.PersonBeforeSaveHandler; +import org.springframework.data.rest.core.domain.jpa.PersonRepository; +import org.springframework.data.rest.core.event.AfterCreateEvent; +import org.springframework.data.rest.core.event.AfterDeleteEvent; +import org.springframework.data.rest.core.event.AfterLinkDeleteEvent; +import org.springframework.data.rest.core.event.AfterLinkSaveEvent; +import org.springframework.data.rest.core.event.AfterSaveEvent; +import org.springframework.data.rest.core.event.AnnotatedHandlerBeanPostProcessor; +import org.springframework.data.rest.core.event.BeforeCreateEvent; +import org.springframework.data.rest.core.event.BeforeDeleteEvent; +import org.springframework.data.rest.core.event.BeforeLinkDeleteEvent; +import org.springframework.data.rest.core.event.BeforeLinkSaveEvent; +import org.springframework.data.rest.core.event.BeforeSaveEvent; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.annotation.Transactional; /** * Tests around the {@link org.springframework.context.ApplicationEvent} handling abstractions. @@ -16,9 +34,30 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; * @author Jon Brisbin */ @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = RepositoryEventTestsConfig.class) +@ContextConfiguration +@Transactional public class RepositoryEventIntegrationTests { + @Configuration + @Import({ RepositoryTestsConfig.class }) + static class RepositoryEventTestsConfig { + + @Bean + public PersonBeforeSaveHandler personBeforeSaveHandler() { + return new PersonBeforeSaveHandler(); + } + + @Bean + public AnnotatedPersonEventHandler beforeSaveHandler() { + return new AnnotatedPersonEventHandler(); + } + + @Bean + public AnnotatedHandlerBeanPostProcessor annotatedHandlerBeanPostProcessor() { + return new AnnotatedHandlerBeanPostProcessor(); + } + } + @Autowired ApplicationContext appCtx; @Autowired PersonRepository people; Person person; diff --git a/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/context/ValidatorIntegrationTests.java b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/context/ValidatorIntegrationTests.java new file mode 100644 index 000000000..2cad9fe2c --- /dev/null +++ b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/context/ValidatorIntegrationTests.java @@ -0,0 +1,46 @@ +package org.springframework.data.rest.core.context; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.data.rest.core.RepositoryConstraintViolationException; +import org.springframework.data.rest.core.RepositoryTestsConfig; +import org.springframework.data.rest.core.domain.jpa.Person; +import org.springframework.data.rest.core.event.BeforeSaveEvent; +import org.springframework.data.rest.core.event.ValidatingRepositoryEventListener; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.annotation.Transactional; + +/** + * Tests to check the {@link org.springframework.validation.Validator} integration. + * + * @author Jon Brisbin + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration +@Transactional +public class ValidatorIntegrationTests { + + @Configuration + @Import({ RepositoryTestsConfig.class }) + static class ValidatorTestsConfig { + + @Bean + public ValidatingRepositoryEventListener validatingListener() { + return new ValidatingRepositoryEventListener(); + } + } + + @Autowired ApplicationContext appCtx; + + @Test(expected = RepositoryConstraintViolationException.class) + public void shouldValidateLastName() throws Exception { + appCtx.publishEvent(new BeforeSaveEvent(new Person())); + } + +} diff --git a/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/AnnotatedPersonEventHandler.java b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/AnnotatedPersonEventHandler.java new file mode 100644 index 000000000..1bba59f9f --- /dev/null +++ b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/AnnotatedPersonEventHandler.java @@ -0,0 +1,45 @@ +package org.springframework.data.rest.core.domain.jpa; + +import org.springframework.data.rest.core.annotation.HandleAfterCreate; +import org.springframework.data.rest.core.annotation.HandleAfterDelete; +import org.springframework.data.rest.core.annotation.HandleAfterLinkDelete; +import org.springframework.data.rest.core.annotation.HandleAfterLinkSave; +import org.springframework.data.rest.core.annotation.HandleAfterSave; +import org.springframework.data.rest.core.annotation.HandleBeforeCreate; +import org.springframework.data.rest.core.annotation.HandleBeforeDelete; +import org.springframework.data.rest.core.annotation.HandleBeforeLinkDelete; +import org.springframework.data.rest.core.annotation.HandleBeforeLinkSave; +import org.springframework.data.rest.core.annotation.HandleBeforeSave; +import org.springframework.data.rest.core.annotation.RepositoryEventHandler; + +/** + * @author Jon Brisbin + */ +@RepositoryEventHandler(Person.class) +public class AnnotatedPersonEventHandler { + @HandleAfterCreate + @HandleAfterDelete + @HandleAfterSave + public void handleAfter(Person p) { + throw new RuntimeException(); + } + + @HandleAfterLinkDelete + @HandleAfterLinkSave + public void handleAfterLink(Person p, Object o) { + throw new RuntimeException(); + } + + @HandleBeforeCreate + @HandleBeforeDelete + @HandleBeforeSave + public void handleBefore(Person p) { + throw new RuntimeException(); + } + + @HandleBeforeLinkDelete + @HandleBeforeLinkSave + public void handleBeforeLink(Person p, Object o) { + throw new RuntimeException(); + } +} diff --git a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/AnnotatedPersonRepository.java b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/AnnotatedPersonRepository.java similarity index 57% rename from spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/AnnotatedPersonRepository.java rename to spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/AnnotatedPersonRepository.java index 32f30d441..0689a9941 100644 --- a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/AnnotatedPersonRepository.java +++ b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/AnnotatedPersonRepository.java @@ -1,11 +1,11 @@ -package org.springframework.data.rest.repository.domain.jpa; +package org.springframework.data.rest.core.domain.jpa; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.NoRepositoryBean; -import org.springframework.data.rest.repository.annotation.RestResource; +import org.springframework.data.rest.core.annotation.RestResource; /** - * A repository to manage {@link org.springframework.data.rest.repository.domain.jpa.Person}s. + * A repository to manage {@link org.springframework.data.rest.core.domain.jpa.Person}s. * * @author Jon Brisbin */ diff --git a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/ConfiguredPersonRepository.java b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/ConfiguredPersonRepository.java similarity index 83% rename from spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/ConfiguredPersonRepository.java rename to spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/ConfiguredPersonRepository.java index d4566fa99..4c9a1fe58 100644 --- a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/ConfiguredPersonRepository.java +++ b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/ConfiguredPersonRepository.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.domain.jpa; +package org.springframework.data.rest.core.domain.jpa; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.NoRepositoryBean; diff --git a/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/CreditCard.java b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/CreditCard.java new file mode 100644 index 000000000..1a7a1e83e --- /dev/null +++ b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/CreditCard.java @@ -0,0 +1,29 @@ +/* + * Copyright 2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.rest.core.domain.jpa; + +import javax.persistence.Entity; +import javax.persistence.Id; + +/** + * @author Oliver Gierke + */ +@Entity +public class CreditCard { + + @Id Long id; + String creditCardNumber; +} diff --git a/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/CreditCardRepository.java b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/CreditCardRepository.java new file mode 100644 index 000000000..540a688f5 --- /dev/null +++ b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/CreditCardRepository.java @@ -0,0 +1,26 @@ +/* + * Copyright 2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.rest.core.domain.jpa; + +import org.springframework.data.repository.CrudRepository; + +/** + * @author Oliver Gierke + */ +interface CreditCardRepository extends CrudRepository { + + CreditCard findByCreditCardNumber(String creditCardNumber); +} diff --git a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/JpaRepositoryConfig.java b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/JpaRepositoryConfig.java similarity index 95% rename from spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/JpaRepositoryConfig.java rename to spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/JpaRepositoryConfig.java index 607742005..a0090d488 100644 --- a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/JpaRepositoryConfig.java +++ b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/JpaRepositoryConfig.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.repository.domain.jpa; +package org.springframework.data.rest.core.domain.jpa; import javax.persistence.EntityManagerFactory; import javax.sql.DataSource; @@ -48,7 +48,7 @@ public class JpaRepositoryConfig { @Bean public MessageSource messageSource() { ResourceBundleMessageSource ms = new ResourceBundleMessageSource(); - ms.setBasename("org.springframework.data.rest.repository.ValidationErrors"); + ms.setBasename("org.springframework.data.rest.core.ValidationErrors"); return ms; } diff --git a/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/Order.java b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/Order.java new file mode 100644 index 000000000..5e96914ea --- /dev/null +++ b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/Order.java @@ -0,0 +1,48 @@ +/* + * Copyright 2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.rest.core.domain.jpa; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + +/** + * @author Oliver Gierke + */ +@Entity +@Table(name = "ORDERS") +public class Order { + + private @Id Long id; + private @ManyToOne Person creator; + + public Order(Person creator) { + this.creator = creator; + } + + protected Order() { + + } + + public Long getId() { + return id; + } + + public Person getCreator() { + return creator; + } +} diff --git a/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/OrderRepository.java b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/OrderRepository.java new file mode 100644 index 000000000..9d58b778c --- /dev/null +++ b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/OrderRepository.java @@ -0,0 +1,25 @@ +/* + * Copyright 2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.rest.core.domain.jpa; + +import org.springframework.data.repository.CrudRepository; + +/** + * @author Oliver Gierke + */ +public interface OrderRepository extends CrudRepository { + +} diff --git a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/Person.java b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/Person.java similarity index 96% rename from spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/Person.java rename to spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/Person.java index 4d2d0c80a..891e41f48 100644 --- a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/Person.java +++ b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/Person.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.domain.jpa; +package org.springframework.data.rest.core.domain.jpa; import java.util.ArrayList; import java.util.Calendar; diff --git a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/PersonBeforeSaveHandler.java b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/PersonBeforeSaveHandler.java similarity index 58% rename from spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/PersonBeforeSaveHandler.java rename to spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/PersonBeforeSaveHandler.java index 16c0ffe50..83d06ce6c 100644 --- a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/PersonBeforeSaveHandler.java +++ b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/PersonBeforeSaveHandler.java @@ -1,6 +1,6 @@ -package org.springframework.data.rest.repository.domain.jpa; +package org.springframework.data.rest.core.domain.jpa; -import org.springframework.data.rest.repository.context.AbstractRepositoryEventListener; +import org.springframework.data.rest.core.event.AbstractRepositoryEventListener; /** * @author Jon Brisbin diff --git a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/PersonNameValidator.java b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/PersonNameValidator.java similarity index 84% rename from spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/PersonNameValidator.java rename to spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/PersonNameValidator.java index 61729a072..21c786f3d 100644 --- a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/PersonNameValidator.java +++ b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/PersonNameValidator.java @@ -1,9 +1,9 @@ -package org.springframework.data.rest.repository.domain.jpa; +package org.springframework.data.rest.core.domain.jpa; import static org.springframework.util.ClassUtils.*; import static org.springframework.util.StringUtils.*; -import org.springframework.data.rest.repository.annotation.HandleBeforeSave; +import org.springframework.data.rest.core.annotation.HandleBeforeSave; import org.springframework.stereotype.Component; import org.springframework.validation.Errors; import org.springframework.validation.Validator; diff --git a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/PersonRepository.java b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/PersonRepository.java similarity index 53% rename from spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/PersonRepository.java rename to spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/PersonRepository.java index 68d9cfeea..be749d0c0 100644 --- a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/PersonRepository.java +++ b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/PersonRepository.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.domain.jpa; +package org.springframework.data.rest.core.domain.jpa; import java.util.Date; @@ -7,9 +7,9 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.query.Param; -import org.springframework.data.rest.convert.ISO8601DateConverter; -import org.springframework.data.rest.repository.annotation.ConvertWith; -import org.springframework.data.rest.repository.annotation.RestResource; +import org.springframework.data.rest.core.annotation.RestResource; +import org.springframework.format.annotation.DateTimeFormat; +import org.springframework.format.annotation.DateTimeFormat.ISO; /** * A repository to manage {@link Person}s. @@ -20,12 +20,11 @@ import org.springframework.data.rest.repository.annotation.RestResource; public interface PersonRepository extends PagingAndSortingRepository { @RestResource(rel = "firstname", path = "firstname") - public Page findByFirstName(@Param("firstName") String firstName, Pageable pageable); + Page findByFirstName(@Param("firstName") String firstName, Pageable pageable); - public Page findByCreatedGreaterThan(@Param("date") Date date, Pageable pageable); + Page findByCreatedGreaterThan(@Param("date") Date date, Pageable pageable); @Query("select p from Person p where p.created > :date") - public Page findByCreatedUsingISO8601Date(@Param("date") @ConvertWith(ISO8601DateConverter.class) Date date, + Page findByCreatedUsingISO8601Date(@Param("date") @DateTimeFormat(iso = ISO.DATE_TIME) Date date, Pageable pageable); - } diff --git a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/PlainPersonRepository.java b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/PlainPersonRepository.java similarity index 82% rename from spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/PlainPersonRepository.java rename to spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/PlainPersonRepository.java index 168eecacd..18e71e3f9 100644 --- a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/PlainPersonRepository.java +++ b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/jpa/PlainPersonRepository.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.domain.jpa; +package org.springframework.data.rest.core.domain.jpa; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.NoRepositoryBean; diff --git a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/mongodb/MongoDbRepositoryConfig.java b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/mongodb/MongoDbRepositoryConfig.java similarity index 93% rename from spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/mongodb/MongoDbRepositoryConfig.java rename to spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/mongodb/MongoDbRepositoryConfig.java index cb7ade123..ec3c3e2a4 100644 --- a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/mongodb/MongoDbRepositoryConfig.java +++ b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/mongodb/MongoDbRepositoryConfig.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.domain.mongodb; +package org.springframework.data.rest.core.domain.mongodb; import java.net.UnknownHostException; diff --git a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/mongodb/Profile.java b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/mongodb/Profile.java similarity index 91% rename from spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/mongodb/Profile.java rename to spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/mongodb/Profile.java index f08fb49af..affcddca2 100644 --- a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/mongodb/Profile.java +++ b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/mongodb/Profile.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.domain.mongodb; +package org.springframework.data.rest.core.domain.mongodb; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document; diff --git a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/mongodb/ProfileLoader.java b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/mongodb/ProfileLoader.java similarity index 87% rename from spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/mongodb/ProfileLoader.java rename to spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/mongodb/ProfileLoader.java index 0ed111568..5bdf856aa 100644 --- a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/mongodb/ProfileLoader.java +++ b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/mongodb/ProfileLoader.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.domain.mongodb; +package org.springframework.data.rest.core.domain.mongodb; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; diff --git a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/mongodb/ProfileRepository.java b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/mongodb/ProfileRepository.java similarity index 80% rename from spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/mongodb/ProfileRepository.java rename to spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/mongodb/ProfileRepository.java index e4253d27e..7147d7143 100644 --- a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/mongodb/ProfileRepository.java +++ b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/domain/mongodb/ProfileRepository.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.domain.mongodb; +package org.springframework.data.rest.core.domain.mongodb; import org.bson.types.ObjectId; import org.springframework.data.repository.CrudRepository; diff --git a/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/invoke/ReflectionRepositoryInvokerIntegrationTests.java b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/invoke/ReflectionRepositoryInvokerIntegrationTests.java new file mode 100644 index 000000000..a49a43803 --- /dev/null +++ b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/invoke/ReflectionRepositoryInvokerIntegrationTests.java @@ -0,0 +1,122 @@ +/* + * Copyright 2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.rest.core.invoke; + +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.*; + +import java.lang.reflect.Method; +import java.util.Date; +import java.util.HashMap; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.convert.ConversionService; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.repository.core.RepositoryInformation; +import org.springframework.data.repository.support.Repositories; +import org.springframework.data.rest.core.AbstractIntegrationTests; +import org.springframework.data.rest.core.domain.jpa.Order; +import org.springframework.data.rest.core.domain.jpa.OrderRepository; +import org.springframework.data.rest.core.domain.jpa.Person; +import org.springframework.data.rest.core.domain.jpa.PersonRepository; + +/** + * Integration tests for {@link ReflectionRepositoryInvoker}. + * + * @author Oliver Gierke + */ +public class ReflectionRepositoryInvokerIntegrationTests extends AbstractIntegrationTests { + + @Autowired Repositories repositories; + @Autowired ConversionService conversionService; + @Autowired PersonRepository repository; + @Autowired OrderRepository orderRepository; + + RepositoryInformation information; + RepositoryInvoker invoker; + + @Before + public void setUp() { + + information = repositories.getRepositoryInformationFor(Person.class); + invoker = new ReflectionRepositoryInvoker(repository, information, conversionService); + } + + @Test + public void invokesFindOneWithStringIdCorrectly() { + + Person person = repository.findAll().iterator().next(); + assertThat(person, is(notNullValue())); + + Object result = invoker.invokeFindOne(person.getId().toString()); + assertThat(result, is(instanceOf(Person.class))); + } + + @Test + public void invokesFindAllWithoutPageableCorrectly() { + + Iterable result = invoker.invokeFindAll((Pageable) null); + assertThat(result, is(instanceOf(Page.class))); + } + + @Test + public void invokesFindAllWithPageableCorrectly() { + + Iterable result = invoker.invokeFindAll(new PageRequest(0, 10)); + assertThat(result, is(instanceOf(Page.class))); + } + + @Test + public void fallsBackToPlainFindAllIfRepositoryIsNotPaging() { + + ReflectionRepositoryInvoker invoker = new ReflectionRepositoryInvoker(orderRepository, + repositories.getRepositoryInformationFor(Order.class), conversionService); + Iterable result = invoker.invokeFindAll(new PageRequest(0, 10)); + + assertThat(result, is(instanceOf(List.class))); + } + + @Test + public void invokesQueryMethod() throws Exception { + + HashMap parameters = new HashMap(); + parameters.put("firstName", new String[] { "John" }); + + Method method = PersonRepository.class.getMethod("findByFirstName", String.class, Pageable.class); + Object result = invoker.invokeQueryMethod(method, parameters, null, null); + + assertThat(result, is(instanceOf(Page.class))); + } + + @Test + public void considersFormattingAnnotationsOnQueryMethodParameters() throws Exception { + + HashMap parameters = new HashMap(); + parameters.put("date", new String[] { "2013-07-18T10:49:00.000+02:00" }); + + Method method = PersonRepository.class.getMethod("findByCreatedUsingISO8601Date", Date.class, Pageable.class); + Object result = invoker.invokeQueryMethod(method, parameters, null, null); + + assertThat(result, is(instanceOf(Page.class))); + Page page = (Page) result; + assertThat(page.getNumberOfElements(), is(1)); + } +} diff --git a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/invoke/RepositoryMethodUnitTests.java b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/invoke/RepositoryMethodUnitTests.java similarity index 89% rename from spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/invoke/RepositoryMethodUnitTests.java rename to spring-data-rest-core/src/test/java/org/springframework/data/rest/core/invoke/RepositoryMethodUnitTests.java index fd133573c..cccda4954 100644 --- a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/invoke/RepositoryMethodUnitTests.java +++ b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/invoke/RepositoryMethodUnitTests.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.invoke; +package org.springframework.data.rest.core.invoke; import static org.hamcrest.MatcherAssert.*; import static org.hamcrest.Matchers.*; @@ -11,8 +11,9 @@ import java.util.Map; import org.junit.Before; import org.junit.Test; import org.springframework.data.domain.Pageable; -import org.springframework.data.rest.repository.domain.jpa.PersonRepository; -import org.springframework.data.rest.repository.support.Methods; +import org.springframework.data.rest.core.domain.jpa.PersonRepository; +import org.springframework.data.rest.core.invoke.RepositoryMethod; +import org.springframework.data.rest.core.support.Methods; import org.springframework.util.ReflectionUtils; /** diff --git a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/mapping/RepositoryCollectionResourceMappingUnitTests.java b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/mapping/RepositoryCollectionResourceMappingUnitTests.java similarity index 87% rename from spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/mapping/RepositoryCollectionResourceMappingUnitTests.java rename to spring-data-rest-core/src/test/java/org/springframework/data/rest/core/mapping/RepositoryCollectionResourceMappingUnitTests.java index a3a94cacf..12fc7d545 100644 --- a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/mapping/RepositoryCollectionResourceMappingUnitTests.java +++ b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/mapping/RepositoryCollectionResourceMappingUnitTests.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.repository.mapping; +package org.springframework.data.rest.core.mapping; import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; @@ -21,7 +21,10 @@ import static org.junit.Assert.*; import org.junit.Test; import org.springframework.data.repository.Repository; import org.springframework.data.rest.core.Path; -import org.springframework.data.rest.repository.annotation.RestResource; +import org.springframework.data.rest.core.annotation.RestResource; +import org.springframework.data.rest.core.mapping.CollectionResourceMapping; +import org.springframework.data.rest.core.mapping.RepositoryCollectionResourceMapping; +import org.springframework.data.rest.core.mapping.ResourceMapping; /** * Unit tests for {@link RepositoryCollectionResourceMapping}. @@ -35,7 +38,7 @@ public class RepositoryCollectionResourceMappingUnitTests { CollectionResourceMapping mapping = new RepositoryCollectionResourceMapping(PersonRepository.class); - assertThat(mapping.getPath(), is(new Path("person"))); + assertThat(mapping.getPath(), is(new Path("persons"))); assertThat(mapping.getRel(), is("persons")); assertThat(mapping.getSingleResourceRel(), is("person")); assertThat(mapping.isExported(), is(true)); diff --git a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/mapping/RepositoryMethodResourceMappingUnitTests.java b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/mapping/RepositoryMethodResourceMappingUnitTests.java similarity index 77% rename from spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/mapping/RepositoryMethodResourceMappingUnitTests.java rename to spring-data-rest-core/src/test/java/org/springframework/data/rest/core/mapping/RepositoryMethodResourceMappingUnitTests.java index 17e655a5f..2e1d25f3a 100644 --- a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/mapping/RepositoryMethodResourceMappingUnitTests.java +++ b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/mapping/RepositoryMethodResourceMappingUnitTests.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.repository.mapping; +package org.springframework.data.rest.core.mapping; import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; @@ -23,32 +23,34 @@ import java.lang.reflect.Method; import org.junit.Test; import org.springframework.data.repository.Repository; import org.springframework.data.rest.core.Path; -import org.springframework.data.rest.repository.annotation.RestResource; +import org.springframework.data.rest.core.annotation.RestResource; +import org.springframework.data.rest.core.mapping.RepositoryCollectionResourceMapping; +import org.springframework.data.rest.core.mapping.RepositoryMethodResourceMapping; +import org.springframework.data.rest.core.mapping.ResourceMapping; /** * @author Oliver Gierke */ public class RepositoryMethodResourceMappingUnitTests { - RepositoryCollectionResourceMapping resourceMapping = new RepositoryCollectionResourceMapping( - PersonRepository.class); - + RepositoryCollectionResourceMapping resourceMapping = new RepositoryCollectionResourceMapping(PersonRepository.class); + @Test public void foo() throws Exception { Method method = PersonRepository.class.getMethod("findByLastname", String.class); ResourceMapping mapping = new RepositoryMethodResourceMapping(method, resourceMapping); - assertThat(mapping.getPath(), is(new Path("person/findByLastname"))); + assertThat(mapping.getPath(), is(new Path("findByLastname"))); } - + @Test public void usesConfiguredNameWithLeadingSlash() throws Exception { Method method = PersonRepository.class.getMethod("findByFirstname", String.class); ResourceMapping mapping = new RepositoryMethodResourceMapping(method, resourceMapping); - assertThat(mapping.getPath(), is(new Path("person/bar"))); + assertThat(mapping.getPath(), is(new Path("bar"))); } static class Person {} @@ -56,10 +58,10 @@ public class RepositoryMethodResourceMappingUnitTests { interface PersonRepository extends Repository { Iterable findByLastname(String lastname); - + @RestResource(path = "/bar") Iterable findByFirstname(String firstname); - + @RestResource(path = "foo") Iterable findByEmailAddress(String email); } diff --git a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/mapping/ResourceMappingsIntegrationTest.java b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/mapping/ResourceMappingsIntegrationTest.java similarity index 59% rename from spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/mapping/ResourceMappingsIntegrationTest.java rename to spring-data-rest-core/src/test/java/org/springframework/data/rest/core/mapping/ResourceMappingsIntegrationTest.java index 79334ed91..e82c557a0 100644 --- a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/mapping/ResourceMappingsIntegrationTest.java +++ b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/mapping/ResourceMappingsIntegrationTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.repository.mapping; +package org.springframework.data.rest.core.mapping; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; @@ -25,11 +25,15 @@ import org.junit.runner.RunWith; import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.repository.support.Repositories; -import org.springframework.data.rest.config.RepositoryRestConfiguration; -import org.springframework.data.rest.repository.domain.jpa.JpaRepositoryConfig; -import org.springframework.data.rest.repository.domain.jpa.Person; +import org.springframework.data.rest.core.config.RepositoryRestConfiguration; +import org.springframework.data.rest.core.domain.jpa.CreditCard; +import org.springframework.data.rest.core.domain.jpa.JpaRepositoryConfig; +import org.springframework.data.rest.core.domain.jpa.Person; +import org.springframework.data.rest.core.mapping.ResourceMappings; +import org.springframework.data.rest.core.mapping.ResourceMetadata; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.annotation.Transactional; /** * Integration tests for {@link ResourceMappings}. @@ -38,6 +42,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = JpaRepositoryConfig.class) +@Transactional public class ResourceMappingsIntegrationTest { @Autowired ListableBeanFactory factory; @@ -52,9 +57,25 @@ public class ResourceMappingsIntegrationTest { } @Test - public void foo() { + public void detectsAllMappings() { + assertThat(mappings, is(Matchers. iterableWithSize(6))); + } - assertThat(mappings, is(Matchers. iterableWithSize(2))); - assertThat(mappings.getMappingFor(Person.class).isExported(), is(true)); + @Test + public void exportsResourceAndSearchesForPersons() { + + ResourceMetadata personMappings = mappings.getMappingFor(Person.class); + + assertThat(personMappings.isExported(), is(true)); + assertThat(personMappings.getSearchResourceMappings().isExported(), is(true)); + } + + @Test + public void doesNotExportAnyMappingsForHiddenRepository() { + + ResourceMetadata creditCardMapping = mappings.getMappingFor(CreditCard.class); + + assertThat(creditCardMapping.isExported(), is(false)); + assertThat(creditCardMapping.getSearchResourceMappings().isExported(), is(false)); } } diff --git a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/mapping/TypeBasedCollectionResourceMappingUnitTest.java b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/mapping/TypeBasedCollectionResourceMappingUnitTest.java similarity index 87% rename from spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/mapping/TypeBasedCollectionResourceMappingUnitTest.java rename to spring-data-rest-core/src/test/java/org/springframework/data/rest/core/mapping/TypeBasedCollectionResourceMappingUnitTest.java index 24d57be68..5077d594a 100644 --- a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/mapping/TypeBasedCollectionResourceMappingUnitTest.java +++ b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/mapping/TypeBasedCollectionResourceMappingUnitTest.java @@ -13,14 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.repository.mapping; +package org.springframework.data.rest.core.mapping; import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; import org.junit.Test; import org.springframework.data.rest.core.Path; -import org.springframework.data.rest.repository.annotation.RestResource; +import org.springframework.data.rest.core.annotation.RestResource; +import org.springframework.data.rest.core.mapping.CollectionResourceMapping; +import org.springframework.data.rest.core.mapping.TypeBasedCollectionResourceMapping; /** * Unit tests for {@link TypeBasedCollectionResourceMapping}. diff --git a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/support/ResourceStringUtilsTest.java b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/support/ResourceStringUtilsTest.java similarity index 94% rename from spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/support/ResourceStringUtilsTest.java rename to spring-data-rest-core/src/test/java/org/springframework/data/rest/core/support/ResourceStringUtilsTest.java index 80077a6e9..e36b49519 100644 --- a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/support/ResourceStringUtilsTest.java +++ b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/support/ResourceStringUtilsTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.repository.support; +package org.springframework.data.rest.core.support; import java.util.Arrays; import java.util.Collection; @@ -21,6 +21,7 @@ import java.util.Collection; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; +import org.springframework.data.rest.core.support.ResourceStringUtils; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; diff --git a/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/util/FunctionTests.java b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/util/FunctionTests.java new file mode 100644 index 000000000..ee80d0116 --- /dev/null +++ b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/util/FunctionTests.java @@ -0,0 +1,45 @@ +/* + * Copyright 2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.rest.core.util; + +import org.junit.Test; + +/** + * @author Oliver Gierke + */ +public class FunctionTests { + + @Test + public void foo() { + + Foo foo = new Foo(); + + foo.apply(new Function() { + + @Override + public Integer apply(String input) { + return null; + } + }); + } + + static class Foo { + + public Integer apply(Function function) { + return null; + } + } +} diff --git a/spring-data-rest-repository/src/test/resources/ValidationErrors.properties b/spring-data-rest-core/src/test/resources/ValidationErrors.properties similarity index 100% rename from spring-data-rest-repository/src/test/resources/ValidationErrors.properties rename to spring-data-rest-core/src/test/resources/ValidationErrors.properties diff --git a/spring-data-rest-core/src/test/resources/logback.xml b/spring-data-rest-core/src/test/resources/logback.xml index 905c91963..ad5cbef50 100644 --- a/spring-data-rest-core/src/test/resources/logback.xml +++ b/spring-data-rest-core/src/test/resources/logback.xml @@ -1,17 +1,16 @@ + - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - + + + %d %5p %40.40c:%4L - %m%n + + - + - - - + + + \ No newline at end of file diff --git a/spring-data-rest-example/src/main/java/org/springframework/data/rest/example/RestExporterExampleRestConfig.java b/spring-data-rest-example/src/main/java/org/springframework/data/rest/example/RestExporterExampleRestConfig.java index 1cd6e749b..84128e177 100644 --- a/spring-data-rest-example/src/main/java/org/springframework/data/rest/example/RestExporterExampleRestConfig.java +++ b/spring-data-rest-example/src/main/java/org/springframework/data/rest/example/RestExporterExampleRestConfig.java @@ -4,7 +4,7 @@ import org.springframework.context.MessageSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.support.ReloadableResourceBundleMessageSource; -import org.springframework.data.rest.config.RepositoryRestConfiguration; +import org.springframework.data.rest.core.config.RepositoryRestConfiguration; import org.springframework.data.rest.example.jpa.Person; import org.springframework.data.rest.example.jpa.PersonValidator; import org.springframework.data.rest.webmvc.RepositoryLinksResource; diff --git a/spring-data-rest-example/src/main/java/org/springframework/data/rest/example/gemfire/core/Customer.java b/spring-data-rest-example/src/main/java/org/springframework/data/rest/example/gemfire/core/Customer.java index 53fc172ea..a315cced2 100644 --- a/spring-data-rest-example/src/main/java/org/springframework/data/rest/example/gemfire/core/Customer.java +++ b/spring-data-rest-example/src/main/java/org/springframework/data/rest/example/gemfire/core/Customer.java @@ -19,8 +19,6 @@ import java.util.Collections; import java.util.HashSet; import java.util.Set; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import org.springframework.data.gemfire.mapping.Region; import org.springframework.util.Assert; diff --git a/spring-data-rest-example/src/main/java/org/springframework/data/rest/example/gemfire/core/EmailAddress.java b/spring-data-rest-example/src/main/java/org/springframework/data/rest/example/gemfire/core/EmailAddress.java index 90ae8333f..e38195ecb 100644 --- a/spring-data-rest-example/src/main/java/org/springframework/data/rest/example/gemfire/core/EmailAddress.java +++ b/spring-data-rest-example/src/main/java/org/springframework/data/rest/example/gemfire/core/EmailAddress.java @@ -17,14 +17,15 @@ package org.springframework.data.rest.example.gemfire.core; import java.util.regex.Pattern; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import org.springframework.core.convert.converter.Converter; import org.springframework.stereotype.Component; import org.springframework.util.Assert; import org.springframework.util.StringUtils; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; + /** * Value object to represent email addresses. * diff --git a/spring-data-rest-example/src/main/java/org/springframework/data/rest/example/gemfire/order/LineItem.java b/spring-data-rest-example/src/main/java/org/springframework/data/rest/example/gemfire/order/LineItem.java index 2259f415a..f0dba2ee6 100644 --- a/spring-data-rest-example/src/main/java/org/springframework/data/rest/example/gemfire/order/LineItem.java +++ b/spring-data-rest-example/src/main/java/org/springframework/data/rest/example/gemfire/order/LineItem.java @@ -17,9 +17,8 @@ package org.springframework.data.rest.example.gemfire.order; import java.math.BigDecimal; -import org.springframework.util.Assert; - import org.springframework.data.rest.example.gemfire.core.Product; +import org.springframework.util.Assert; /** * @author Oliver Gierke diff --git a/spring-data-rest-example/src/main/java/org/springframework/data/rest/example/jpa/Person.java b/spring-data-rest-example/src/main/java/org/springframework/data/rest/example/jpa/Person.java index f78170705..ccc227062 100644 --- a/spring-data-rest-example/src/main/java/org/springframework/data/rest/example/jpa/Person.java +++ b/spring-data-rest-example/src/main/java/org/springframework/data/rest/example/jpa/Person.java @@ -5,6 +5,7 @@ import java.util.Calendar; import java.util.Collections; import java.util.Date; import java.util.List; + import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; @@ -15,39 +16,34 @@ import javax.persistence.ManyToOne; import javax.persistence.PrePersist; import javax.validation.constraints.NotNull; -import org.springframework.data.rest.repository.annotation.Description; -import org.springframework.data.rest.repository.annotation.RestResource; +import org.springframework.data.rest.core.annotation.Description; +import org.springframework.data.rest.core.annotation.RestResource; /** * An entity that represents a person. - * + * * @author Jon Brisbin */ @Entity public class Person { - private Long id; - @Description("A person's first name") - private String firstName; - @Description("A person's last name") - @NotNull - private String lastName; - @Description("A person's siblings") - @RestResource(exported = false) - private List siblings = Collections.emptyList(); + private Long id; + private @Description("A person's first name") String firstName; + private @Description("A person's last name") @NotNull String lastName; + private @Description("Timestamp this person object was created") Date created; + private @Description("A person's siblings") @RestResource(exported = false) List siblings = Collections + .emptyList(); private Person father; - @Description("Timestamp this person object was created") - private Date created; - public Person() { - } + public Person() {} public Person(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } - @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) public Long getId() { return id; } @@ -73,7 +69,7 @@ public class Person { } public Person addSibling(Person p) { - if(siblings == Collections.EMPTY_LIST) { + if (siblings == Collections.EMPTY_LIST) { siblings = new ArrayList(); } siblings.add(p); @@ -89,7 +85,8 @@ public class Person { this.siblings = siblings; } - @ManyToOne public Person getFather() { + @ManyToOne + public Person getFather() { return father; } @@ -101,23 +98,17 @@ public class Person { return created; } - public void setCreated(Date created) { - } + public void setCreated(Date created) {} @PrePersist private void prePersist() { this.created = Calendar.getInstance().getTime(); } - @Override public String toString() { - return "Person{" + - "id=" + id + - ", firstName='" + firstName + '\'' + - ", lastName='" + lastName + '\'' + - ", siblings=[" + siblings.size() + "]" + - ", father=" + father + - ", created=" + created + - '}'; + @Override + public String toString() { + return "Person{" + "id=" + id + ", firstName='" + firstName + '\'' + ", lastName='" + lastName + '\'' + + ", siblings=[" + siblings.size() + "]" + ", father=" + father + ", created=" + created + '}'; } -} \ No newline at end of file +} diff --git a/spring-data-rest-example/src/main/java/org/springframework/data/rest/example/jpa/PersonRepository.java b/spring-data-rest-example/src/main/java/org/springframework/data/rest/example/jpa/PersonRepository.java index 12e844d98..4f5cf2407 100644 --- a/spring-data-rest-example/src/main/java/org/springframework/data/rest/example/jpa/PersonRepository.java +++ b/spring-data-rest-example/src/main/java/org/springframework/data/rest/example/jpa/PersonRepository.java @@ -1,3 +1,18 @@ +/* + * Copyright 2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.data.rest.example.jpa; import java.util.Date; @@ -7,29 +22,26 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.query.Param; -import org.springframework.data.rest.convert.ISO8601DateConverter; -import org.springframework.data.rest.repository.annotation.ConvertWith; -import org.springframework.data.rest.repository.annotation.RestResource; +import org.springframework.data.rest.core.annotation.RestResource; +import org.springframework.format.annotation.DateTimeFormat; +import org.springframework.format.annotation.DateTimeFormat.ISO; /** * A repository to manage {@link Person}s. - * + * * @author Jon Brisbin */ @RestResource(rel = "people", path = "people") public interface PersonRepository extends PagingAndSortingRepository { @RestResource(rel = "firstname", path = "firstname") - public Page findByFirstName(@Param("firstName") String firstName, Pageable pageable); + Page findByFirstName(@Param("firstName") String firstName, Pageable pageable); - public Person findFirstPersonByFirstName(@Param("firstName") String firstName); + Person findFirstPersonByFirstName(@Param("firstName") String firstName); - public Page findByCreatedGreaterThan(@Param("date") Date date, Pageable pageable); + Page findByCreatedGreaterThan(@Param("date") Date date, Pageable pageable); @Query("select p from Person p where p.created > :date") - public Page findByCreatedUsingISO8601Date(@Param("date") - @ConvertWith(ISO8601DateConverter.class) - Date date, - Pageable pageable); - + Page findByCreatedUsingISO8601Date(@Param("date") @DateTimeFormat(iso = ISO.DATE_TIME) Date date, + Pageable pageable); } diff --git a/spring-data-rest-example/src/main/java/org/springframework/data/rest/example/mongodb/ProfileRepository.java b/spring-data-rest-example/src/main/java/org/springframework/data/rest/example/mongodb/ProfileRepository.java index 0930f1595..94aed6e78 100644 --- a/spring-data-rest-example/src/main/java/org/springframework/data/rest/example/mongodb/ProfileRepository.java +++ b/spring-data-rest-example/src/main/java/org/springframework/data/rest/example/mongodb/ProfileRepository.java @@ -1,7 +1,7 @@ package org.springframework.data.rest.example.mongodb; import org.springframework.data.repository.CrudRepository; -import org.springframework.data.rest.repository.annotation.RestResource; +import org.springframework.data.rest.core.annotation.RestResource; /** * @author Jon Brisbin diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/ConvertWith.java b/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/ConvertWith.java deleted file mode 100644 index 479e3a95c..000000000 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/annotation/ConvertWith.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.springframework.data.rest.repository.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.core.convert.converter.Converter; - -/** - * @author Jon Brisbin - */ -@Target({ ElementType.PARAMETER }) -@Retention(RetentionPolicy.RUNTIME) -@Inherited -public @interface ConvertWith { - - Class> value(); - -} diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/invoke/MethodParameterConversionService.java b/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/invoke/MethodParameterConversionService.java deleted file mode 100644 index e6134e8fb..000000000 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/invoke/MethodParameterConversionService.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.springframework.data.rest.repository.invoke; - -import org.springframework.core.MethodParameter; -import org.springframework.core.convert.ConversionFailedException; -import org.springframework.core.convert.ConversionService; -import org.springframework.core.convert.TypeDescriptor; -import org.springframework.core.convert.converter.Converter; -import org.springframework.data.rest.repository.annotation.ConvertWith; -import org.springframework.util.Assert; - -/** - * A special conversion service that can convert {@link MethodParameter}s and their values to a target type, taking into - * account any specific conversion instructions annotated on the parameter with {@link ConvertWith}. - * - * @author Jon Brisbin - */ -public class MethodParameterConversionService { - - private final ConversionService delegateConversionService; - - public MethodParameterConversionService(ConversionService delegateConversionService) { - Assert.notNull(delegateConversionService, "Delegate ConversionService cannot be null."); - this.delegateConversionService = delegateConversionService; - } - - public boolean canConvert(Class sourceType, MethodParameter param) { - return canConvert(TypeDescriptor.valueOf(sourceType), param); - } - - public boolean canConvert(TypeDescriptor sourceType, MethodParameter param) { - return (delegateConversionService.canConvert(sourceType, new TypeDescriptor(param)) || param - .hasParameterAnnotation(ConvertWith.class)); - } - - public T convert(Object source, MethodParameter param) { - return convert(source, TypeDescriptor.forObject(source), param); - } - - @SuppressWarnings({ "unchecked" }) - public T convert(Object source, TypeDescriptor sourceType, MethodParameter param) { - TypeDescriptor targetType = new TypeDescriptor(param); - - try { - if (param.hasParameterAnnotation(ConvertWith.class)) { - Converter converter = (Converter) param.getParameterAnnotation(ConvertWith.class).value() - .newInstance(); - return converter.convert(source); - } else { - return (T) delegateConversionService.convert(source, sourceType, targetType); - } - } catch (Exception e) { - throw new ConversionFailedException(sourceType, targetType, source, e); - } - } - -} diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/invoke/RepositoryMethodResponse.java b/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/invoke/RepositoryMethodResponse.java deleted file mode 100644 index 32fa77998..000000000 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/invoke/RepositoryMethodResponse.java +++ /dev/null @@ -1,104 +0,0 @@ -package org.springframework.data.rest.repository.invoke; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -import com.fasterxml.jackson.annotation.JsonProperty; -import org.springframework.hateoas.Link; - -/** - * JSON-serializable response for returns that have a mix of results and links. Also used in responses that have just - * links (in that case, 'results' will be an empty array). - * - * @author Jon Brisbin - */ -public class RepositoryMethodResponse { - - @JsonProperty("results") private List results = new ArrayList(); - @JsonProperty("links") private List links = new ArrayList(); - private long totalCount = 0; - private int totalPages = 1; - private int currentPage = 1; - - public RepositoryMethodResponse addLink(Link l) { - links.add(l); - return this; - } - - public RepositoryMethodResponse addResult(Object obj) { - results.add(obj); - return this; - } - - public RepositoryMethodResponse addAllResults(Iterator results) { - if (null == results) { - return this; - } - - while (results.hasNext()) { - addResult(results.next()); - } - - return this; - } - - public List getResults() { - return results; - } - - public boolean hasResults() { - return (results.size() > 0); - } - - public RepositoryMethodResponse setResults(List results) { - if (null == results) { - this.results = Collections.emptyList(); - } else { - this.results = results; - } - return this; - } - - public List getLinks() { - return links; - } - - public RepositoryMethodResponse setLinks(List links) { - if (null == links) { - this.links = Collections.emptyList(); - } else { - this.links = links; - } - return this; - } - - public long getTotalCount() { - return totalCount; - } - - public RepositoryMethodResponse setTotalCount(long totalCount) { - this.totalCount = totalCount; - return this; - } - - public int getTotalPages() { - return totalPages; - } - - public RepositoryMethodResponse setTotalPages(int totalPages) { - this.totalPages = totalPages; - return this; - } - - public int getCurrentPage() { - return currentPage; - } - - public RepositoryMethodResponse setCurrentPage(int currentPage) { - this.currentPage = currentPage; - return this; - } - -} diff --git a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/context/RepositoryEventTestsConfig.java b/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/context/RepositoryEventTestsConfig.java deleted file mode 100644 index 61d8e4ba9..000000000 --- a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/context/RepositoryEventTestsConfig.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.springframework.data.rest.repository.context; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.data.rest.repository.RepositoryTestsConfig; -import org.springframework.data.rest.repository.domain.jpa.AnnotatedPersonEventHandler; -import org.springframework.data.rest.repository.domain.jpa.PersonBeforeSaveHandler; - -/** - * @author Jon Brisbin - */ -@Configuration -@Import({ RepositoryTestsConfig.class }) -public class RepositoryEventTestsConfig { - - @Bean - public PersonBeforeSaveHandler personBeforeSaveHandler() { - return new PersonBeforeSaveHandler(); - } - - @Bean - public AnnotatedPersonEventHandler beforeSaveHandler() { - return new AnnotatedPersonEventHandler(); - } - - @Bean - public AnnotatedHandlerBeanPostProcessor annotatedHandlerBeanPostProcessor() { - return new AnnotatedHandlerBeanPostProcessor(); - } - -} diff --git a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/context/ValidatorIntegrationTests.java b/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/context/ValidatorIntegrationTests.java deleted file mode 100644 index 8c0b501f2..000000000 --- a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/context/ValidatorIntegrationTests.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.springframework.data.rest.repository.context; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.data.rest.repository.RepositoryConstraintViolationException; -import org.springframework.data.rest.repository.domain.jpa.Person; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -/** - * Tests to check the {@link org.springframework.validation.Validator} integration. - * - * @author Jon Brisbin - */ -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = ValidatorTestsConfig.class) -public class ValidatorIntegrationTests { - - @Autowired ApplicationContext appCtx; - - @Test(expected = RepositoryConstraintViolationException.class) - public void shouldValidateLastName() throws Exception { - appCtx.publishEvent(new BeforeSaveEvent(new Person())); - } - -} diff --git a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/context/ValidatorTestsConfig.java b/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/context/ValidatorTestsConfig.java deleted file mode 100644 index 4a6080c87..000000000 --- a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/context/ValidatorTestsConfig.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.springframework.data.rest.repository.context; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.data.rest.repository.RepositoryTestsConfig; - -/** - * @author Jon Brisbin - */ -@Configuration -@Import({ RepositoryTestsConfig.class }) -public class ValidatorTestsConfig { - - @Bean - public ValidatingRepositoryEventListener validatingListener() { - return new ValidatingRepositoryEventListener(); - } - -} diff --git a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/AnnotatedPersonEventHandler.java b/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/AnnotatedPersonEventHandler.java deleted file mode 100644 index 5eb0d21a6..000000000 --- a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/AnnotatedPersonEventHandler.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.springframework.data.rest.repository.domain.jpa; - -import org.springframework.data.rest.repository.annotation.HandleAfterCreate; -import org.springframework.data.rest.repository.annotation.HandleAfterDelete; -import org.springframework.data.rest.repository.annotation.HandleAfterLinkDelete; -import org.springframework.data.rest.repository.annotation.HandleAfterLinkSave; -import org.springframework.data.rest.repository.annotation.HandleAfterSave; -import org.springframework.data.rest.repository.annotation.HandleBeforeCreate; -import org.springframework.data.rest.repository.annotation.HandleBeforeDelete; -import org.springframework.data.rest.repository.annotation.HandleBeforeLinkDelete; -import org.springframework.data.rest.repository.annotation.HandleBeforeLinkSave; -import org.springframework.data.rest.repository.annotation.HandleBeforeSave; -import org.springframework.data.rest.repository.annotation.RepositoryEventHandler; - -/** - * @author Jon Brisbin - */ -@RepositoryEventHandler(Person.class) -public class AnnotatedPersonEventHandler { - @HandleAfterCreate - @HandleAfterDelete - @HandleAfterSave - public void handleAfter(Person p) { - throw new RuntimeException(); - } - - @HandleAfterLinkDelete - @HandleAfterLinkSave - public void handleAfterLink(Person p, Object o) { - throw new RuntimeException(); - } - - @HandleBeforeCreate - @HandleBeforeDelete - @HandleBeforeSave - public void handleBefore(Person p) { - throw new RuntimeException(); - } - - @HandleBeforeLinkDelete - @HandleBeforeLinkSave - public void handleBeforeLink(Person p, Object o) { - throw new RuntimeException(); - } -} diff --git a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/PersonLoader.java b/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/PersonLoader.java deleted file mode 100644 index 9c2eb3691..000000000 --- a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/PersonLoader.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.springframework.data.rest.repository.domain.jpa; - -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -/** - * @author Jon Brisbin - */ -@Component -public class PersonLoader implements InitializingBean { - - @Autowired PersonRepository people; - - @Override - public void afterPropertiesSet() throws Exception { - people.save(new Person("John", "Doe")); - } -} diff --git a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/invoke/MethodParameterConversionServiceUnitTests.java b/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/invoke/MethodParameterConversionServiceUnitTests.java deleted file mode 100644 index cba3b18ad..000000000 --- a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/invoke/MethodParameterConversionServiceUnitTests.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.springframework.data.rest.repository.invoke; - -import static org.hamcrest.MatcherAssert.*; -import static org.hamcrest.Matchers.*; - -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; - -import org.junit.Before; -import org.junit.Test; -import org.springframework.core.MethodParameter; -import org.springframework.core.convert.support.ConfigurableConversionService; -import org.springframework.data.domain.Pageable; -import org.springframework.data.rest.convert.ISO8601DateConverter; -import org.springframework.data.rest.repository.domain.jpa.PersonRepository; -import org.springframework.format.support.DefaultFormattingConversionService; - -/** - * @author Jon Brisbin - */ -public class MethodParameterConversionServiceUnitTests { - - static final SimpleDateFormat ISO8601_FMT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); - static final String[] DATE_S = new String[] { "2010-01-01T12:00:00-0600" }; - static final Date DATE_D; - - static { - try { - DATE_D = ISO8601_FMT.parse(DATE_S[0]); - } catch (ParseException e) { - throw new IllegalStateException(e); - } - } - - MethodParameter findByCreatedGreaterThan; - MethodParameter findByCreatedUsingISO8601Date; - - @Before - public void setup() throws NoSuchMethodException { - findByCreatedGreaterThan = new MethodParameter(PersonRepository.class.getMethod("findByCreatedGreaterThan", - Date.class, Pageable.class), 0); - findByCreatedUsingISO8601Date = new MethodParameter(PersonRepository.class.getMethod( - "findByCreatedUsingISO8601Date", Date.class, Pageable.class), 0); - } - - @SuppressWarnings({ "deprecation" }) - @Test - public void shouldConvertDateParameterUsingDefaultConverter() throws Exception { - ConfigurableConversionService cs = new DefaultFormattingConversionService(); - MethodParameterConversionService conversionService = new MethodParameterConversionService(cs); - - String dateStr = "01/01/2010"; - assertThat(conversionService.canConvert(String.class, findByCreatedGreaterThan), is(true)); - assertThat((Date) conversionService.convert(dateStr, findByCreatedGreaterThan), is(new Date(dateStr))); - } - - @Test - public void shouldConvertDateParameterUsingSpecificConverter() throws Exception { - ConfigurableConversionService cs = new DefaultFormattingConversionService(); - cs.addConverter(ISO8601DateConverter.INSTANCE); - MethodParameterConversionService conversionService = new MethodParameterConversionService(cs); - - assertThat(conversionService.canConvert(String.class, findByCreatedUsingISO8601Date), is(true)); - assertThat((Date) conversionService.convert(DATE_S, findByCreatedUsingISO8601Date), is(DATE_D)); - } - -} diff --git a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/invoke/ReflectionRepositoryInvokerIntegrationTests.java b/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/invoke/ReflectionRepositoryInvokerIntegrationTests.java deleted file mode 100644 index 08f3e4950..000000000 --- a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/invoke/ReflectionRepositoryInvokerIntegrationTests.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2013 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.rest.repository.invoke; - -import static org.hamcrest.CoreMatchers.*; -import static org.junit.Assert.*; - -import java.util.List; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.convert.ConversionService; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.repository.core.RepositoryInformation; -import org.springframework.data.repository.support.Repositories; -import org.springframework.data.rest.repository.RepositoryTestsConfig; -import org.springframework.data.rest.repository.domain.jpa.Person; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -/** - * Integration tests for {@link ReflectionRepositoryInvoker}. - * - * @author Oliver Gierke - */ -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = RepositoryTestsConfig.class) -public class ReflectionRepositoryInvokerIntegrationTests { - - @Autowired Repositories repositories; - @Autowired ConversionService conversionService; - - Object repository; - RepositoryInformation information; - RepositoryInvoker invoker; - - @Before - public void setUp() { - - information = repositories.getRepositoryInformationFor(Person.class); - repository = repositories.getRepositoryFor(Person.class); - invoker = new ReflectionRepositoryInvoker(repository, information, conversionService); - } - - @Test - public void invokesFindOneWithStringIdCorrectly() { - - Object result = invoker.invokeFindOne("1"); - assertThat(result, is(instanceOf(Person.class))); - } - - @Test - public void invokesFindAllWithoutPageableCorrectly() { - - Iterable result = invoker.invokeFindAll((Pageable) null); - assertThat(result, is(instanceOf(List.class))); - } - - @Test - public void invokesFindAllWithPageableCorrectly() { - - Iterable result = invoker.invokeFindAll(new PageRequest(0, 10)); - assertThat(result, is(instanceOf(Page.class))); - } -} diff --git a/spring-data-rest-repository/src/test/resources/logback.xml b/spring-data-rest-repository/src/test/resources/logback.xml deleted file mode 100644 index ad5cbef50..000000000 --- a/spring-data-rest-repository/src/test/resources/logback.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - %d %5p %40.40c:%4L - %m%n - - - - - - - - - - \ No newline at end of file diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/AbstractRepositoryRestController.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/AbstractRepositoryRestController.java index e671e292b..4cec36e8f 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/AbstractRepositoryRestController.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/AbstractRepositoryRestController.java @@ -33,8 +33,8 @@ import org.springframework.core.convert.ConversionFailedException; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.dao.OptimisticLockingFailureException; import org.springframework.data.domain.Page; -import org.springframework.data.rest.repository.RepositoryConstraintViolationException; -import org.springframework.data.rest.repository.mapping.ResourceMetadata; +import org.springframework.data.rest.core.RepositoryConstraintViolationException; +import org.springframework.data.rest.core.mapping.ResourceMetadata; import org.springframework.data.rest.webmvc.support.ExceptionMessage; import org.springframework.data.rest.webmvc.support.RepositoryConstraintViolationExceptionMessage; import org.springframework.data.rest.webmvc.support.ValidationExceptionHandler; diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/BaseUriMethodArgumentResolver.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/BaseUriMethodArgumentResolver.java deleted file mode 100644 index 080101b58..000000000 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/BaseUriMethodArgumentResolver.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2012-2013 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.rest.webmvc; - -import java.net.URI; -import javax.servlet.http.HttpServletRequest; - -import org.springframework.core.MethodParameter; -import org.springframework.data.rest.config.RepositoryRestConfiguration; -import org.springframework.data.rest.webmvc.annotation.BaseURI; -import org.springframework.web.bind.support.WebDataBinderFactory; -import org.springframework.web.context.request.NativeWebRequest; -import org.springframework.web.method.support.HandlerMethodArgumentResolver; -import org.springframework.web.method.support.ModelAndViewContainer; -import org.springframework.web.servlet.support.ServletUriComponentsBuilder; - -/** - * @author Jon Brisbin - * @author Oliver Gierke - */ -public class BaseUriMethodArgumentResolver implements HandlerMethodArgumentResolver { - - private final RepositoryRestConfiguration config; - - public BaseUriMethodArgumentResolver(RepositoryRestConfiguration config) { - this.config = config; - } - - @Override - public boolean supportsParameter(MethodParameter parameter) { - return (null != parameter.getParameterAnnotation(BaseURI.class) && parameter.getParameterType() == URI.class); - } - - @Override - public URI resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, - NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { - HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class); - - // Use configured URI if there is one or set the current one as the default if not. - if (null == config.getBaseUri()) { - URI baseUri = ServletUriComponentsBuilder.fromServletMapping(servletRequest).build().toUri(); - config.setBaseUri(baseUri); - } - - return config.getBaseUri(); - } -} diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/ControllerUtils.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/ControllerUtils.java index 23580ffa2..f34ea1f6c 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/ControllerUtils.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/ControllerUtils.java @@ -19,6 +19,7 @@ import java.util.Collections; import org.springframework.core.convert.TypeDescriptor; import org.springframework.hateoas.Resource; +import org.springframework.hateoas.ResourceSupport; import org.springframework.hateoas.Resources; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -35,14 +36,14 @@ public class ControllerUtils { public static final Iterable> EMPTY_RESOURCE_LIST = Collections.emptyList(); public static final TypeDescriptor STRING_TYPE = TypeDescriptor.valueOf(String.class); - public static > ResponseEntity> toResponseEntity(HttpHeaders headers, R resource, - HttpStatus status) { + public static ResponseEntity toResponseEntity(HttpHeaders headers, + R resource, HttpStatus status) { HttpHeaders hdrs = new HttpHeaders(); if (null != headers) { hdrs.putAll(headers); } - return new ResponseEntity>(resource, hdrs, status); + return new ResponseEntity(resource, hdrs, status); } } diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/PersistentEntityResource.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/PersistentEntityResource.java similarity index 97% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/PersistentEntityResource.java rename to spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/PersistentEntityResource.java index 81166b100..a9edff4c7 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/PersistentEntityResource.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/PersistentEntityResource.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.repository; +package org.springframework.data.rest.webmvc; import java.util.Arrays; diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/PersistentEntityResourceAssembler.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/PersistentEntityResourceAssembler.java index a82c833ab..e1e5b4e59 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/PersistentEntityResourceAssembler.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/PersistentEntityResourceAssembler.java @@ -18,7 +18,6 @@ package org.springframework.data.rest.webmvc; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.model.BeanWrapper; import org.springframework.data.repository.support.Repositories; -import org.springframework.data.rest.repository.PersistentEntityResource; import org.springframework.hateoas.EntityLinks; import org.springframework.hateoas.Link; import org.springframework.hateoas.ResourceAssembler; diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/PersistentEntityResourceHandlerMethodArgumentResolver.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/PersistentEntityResourceHandlerMethodArgumentResolver.java index c053142f4..b2589633c 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/PersistentEntityResourceHandlerMethodArgumentResolver.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/PersistentEntityResourceHandlerMethodArgumentResolver.java @@ -1,11 +1,11 @@ package org.springframework.data.rest.webmvc; import java.util.List; + import javax.servlet.http.HttpServletRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.MethodParameter; -import org.springframework.data.rest.repository.PersistentEntityResource; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.server.ServletServerHttpRequest; import org.springframework.web.bind.support.WebDataBinderFactory; diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryController.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryController.java index 33c9cd94d..0c3f4d182 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryController.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryController.java @@ -17,8 +17,8 @@ package org.springframework.data.rest.webmvc; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.repository.support.Repositories; -import org.springframework.data.rest.repository.mapping.ResourceMappings; -import org.springframework.data.rest.repository.mapping.ResourceMetadata; +import org.springframework.data.rest.core.mapping.ResourceMappings; +import org.springframework.data.rest.core.mapping.ResourceMetadata; import org.springframework.data.web.PagedResourcesAssembler; import org.springframework.hateoas.EntityLinks; import org.springframework.web.bind.annotation.RequestMapping; diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryEntityController.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryEntityController.java index 9123fcc15..63ffab98b 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryEntityController.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryEntityController.java @@ -34,23 +34,23 @@ import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mapping.model.BeanWrapper; import org.springframework.data.repository.support.DomainClassConverter; import org.springframework.data.repository.support.Repositories; -import org.springframework.data.rest.config.RepositoryRestConfiguration; -import org.springframework.data.rest.repository.PersistentEntityResource; -import org.springframework.data.rest.repository.context.AfterCreateEvent; -import org.springframework.data.rest.repository.context.AfterDeleteEvent; -import org.springframework.data.rest.repository.context.AfterSaveEvent; -import org.springframework.data.rest.repository.context.BeforeCreateEvent; -import org.springframework.data.rest.repository.context.BeforeDeleteEvent; -import org.springframework.data.rest.repository.context.BeforeSaveEvent; -import org.springframework.data.rest.repository.invoke.RepositoryInvoker; -import org.springframework.data.rest.repository.mapping.ResourceMetadata; -import org.springframework.data.rest.repository.mapping.SearchResourceMappings; -import org.springframework.data.rest.repository.support.DomainObjectMerger; +import org.springframework.data.rest.core.config.RepositoryRestConfiguration; +import org.springframework.data.rest.core.event.AfterCreateEvent; +import org.springframework.data.rest.core.event.AfterDeleteEvent; +import org.springframework.data.rest.core.event.AfterSaveEvent; +import org.springframework.data.rest.core.event.BeforeCreateEvent; +import org.springframework.data.rest.core.event.BeforeDeleteEvent; +import org.springframework.data.rest.core.event.BeforeSaveEvent; +import org.springframework.data.rest.core.invoke.RepositoryInvoker; +import org.springframework.data.rest.core.mapping.ResourceMetadata; +import org.springframework.data.rest.core.mapping.SearchResourceMappings; +import org.springframework.data.rest.core.support.DomainObjectMerger; import org.springframework.data.web.PagedResourcesAssembler; import org.springframework.hateoas.EntityLinks; import org.springframework.hateoas.Link; import org.springframework.hateoas.PagedResources; import org.springframework.hateoas.Resource; +import org.springframework.hateoas.ResourceSupport; import org.springframework.hateoas.Resources; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -160,7 +160,7 @@ class RepositoryEntityController extends AbstractRepositoryRestController implem @ResponseBody @RequestMapping(value = BASE_MAPPING, method = RequestMethod.POST, consumes = { "application/json" }, produces = { "application/json", "text/uri-list" }) - public ResponseEntity> createNewEntity(RepositoryRestRequest repoRequest, + public ResponseEntity createNewEntity(RepositoryRestRequest repoRequest, PersistentEntityResource incoming) { RepositoryInvoker invoker = repoRequest.getRepositoryInvoker(); @@ -222,7 +222,7 @@ class RepositoryEntityController extends AbstractRepositoryRestController implem @ResponseBody @RequestMapping(value = BASE_MAPPING + "/{id}", method = RequestMethod.PUT, consumes = { "application/json" }, produces = { "application/json", "text/uri-list" }) - public ResponseEntity> updateEntity(RepositoryRestRequest request, + public ResponseEntity updateEntity(RepositoryRestRequest request, PersistentEntityResource incoming, @PathVariable String id) { RepositoryInvoker invoker = request.getRepositoryInvoker(); diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryInvokerHandlerMethodArgumentResolver.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryInvokerHandlerMethodArgumentResolver.java index 67de5ceee..15fee0f0b 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryInvokerHandlerMethodArgumentResolver.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryInvokerHandlerMethodArgumentResolver.java @@ -16,8 +16,8 @@ package org.springframework.data.rest.webmvc; import org.springframework.core.MethodParameter; -import org.springframework.data.rest.repository.invoke.RepositoryInvoker; -import org.springframework.data.rest.repository.invoke.RepositoryInvokerFactory; +import org.springframework.data.rest.core.invoke.RepositoryInvoker; +import org.springframework.data.rest.core.invoke.RepositoryInvokerFactory; import org.springframework.web.bind.support.WebDataBinderFactory; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.method.support.HandlerMethodArgumentResolver; diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryLinksResource.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryLinksResource.java index 8c1101e6e..a9f0e40db 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryLinksResource.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryLinksResource.java @@ -1,9 +1,9 @@ package org.springframework.data.rest.webmvc; -import org.springframework.hateoas.Resources; - import java.util.Collections; +import org.springframework.hateoas.Resources; + /** * @author Jon Brisbin */ diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryPropertyReferenceController.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryPropertyReferenceController.java index 333a965cb..124d6f1d5 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryPropertyReferenceController.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryPropertyReferenceController.java @@ -15,16 +15,15 @@ */ package org.springframework.data.rest.webmvc; -import static org.springframework.data.rest.core.util.UriUtils.*; -import static org.springframework.data.rest.repository.support.ResourceMappingUtils.*; import static org.springframework.data.rest.webmvc.ControllerUtils.*; +import static org.springframework.hateoas.mvc.ControllerLinkBuilder.*; -import java.net.URI; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationEventPublisher; @@ -35,19 +34,20 @@ import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mapping.model.BeanWrapper; import org.springframework.data.repository.support.DomainClassConverter; import org.springframework.data.repository.support.Repositories; -import org.springframework.data.rest.config.RepositoryRestConfiguration; -import org.springframework.data.rest.config.ResourceMapping; +import org.springframework.data.rest.core.event.AfterLinkDeleteEvent; +import org.springframework.data.rest.core.event.AfterLinkSaveEvent; +import org.springframework.data.rest.core.event.BeforeLinkDeleteEvent; +import org.springframework.data.rest.core.event.BeforeLinkSaveEvent; +import org.springframework.data.rest.core.invoke.RepositoryInvoker; +import org.springframework.data.rest.core.mapping.ResourceMapping; +import org.springframework.data.rest.core.mapping.ResourceMetadata; import org.springframework.data.rest.core.util.Function; -import org.springframework.data.rest.repository.PersistentEntityResource; -import org.springframework.data.rest.repository.context.AfterLinkDeleteEvent; -import org.springframework.data.rest.repository.context.AfterLinkSaveEvent; -import org.springframework.data.rest.repository.context.BeforeLinkDeleteEvent; -import org.springframework.data.rest.repository.context.BeforeLinkSaveEvent; -import org.springframework.data.rest.repository.invoke.RepositoryInvoker; -import org.springframework.data.rest.repository.mapping.ResourceMetadata; import org.springframework.data.web.PagedResourcesAssembler; import org.springframework.hateoas.Link; import org.springframework.hateoas.Resource; +import org.springframework.hateoas.ResourceSupport; +import org.springframework.hateoas.Resources; +import org.springframework.hateoas.mvc.ControllerLinkBuilder; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; @@ -64,29 +64,26 @@ import org.springframework.web.bind.annotation.ResponseBody; * @author Oliver Gierke */ @RestController -@SuppressWarnings({ "unchecked", "deprecation" }) +@SuppressWarnings({ "unchecked" }) public class RepositoryPropertyReferenceController extends AbstractRepositoryRestController implements ApplicationEventPublisherAware { private static final String BASE_MAPPING = "/{repository}/{id}/{property}"; private final Repositories repositories; - private final RepositoryRestConfiguration config; private final PersistentEntityResourceAssembler perAssembler; private final DomainClassConverter converter; private ApplicationEventPublisher publisher; @Autowired - public RepositoryPropertyReferenceController(Repositories repositories, RepositoryRestConfiguration config, - DomainClassConverter domainClassConverter, PagedResourcesAssembler assembler, - PersistentEntityResourceAssembler perAssembler) { + public RepositoryPropertyReferenceController(Repositories repositories, DomainClassConverter domainClassConverter, + PagedResourcesAssembler assembler, PersistentEntityResourceAssembler perAssembler) { super(assembler, perAssembler); this.repositories = repositories; this.perAssembler = perAssembler; - this.config = config; this.converter = domainClassConverter; } @@ -102,12 +99,15 @@ public class RepositoryPropertyReferenceController extends AbstractRepositoryRes @RequestMapping(value = BASE_MAPPING, method = RequestMethod.GET, produces = { "application/json", "application/x-spring-data-verbose+json" }) @ResponseBody - public ResponseEntity> followPropertyReference(final RepositoryRestRequest repoRequest, + public ResponseEntity followPropertyReference(final RepositoryRestRequest repoRequest, @PathVariable String id, @PathVariable String property) throws ResourceNotFoundException, NoSuchMethodException { + final HttpHeaders headers = new HttpHeaders(); - Function> handler = new Function>() { + + Function handler = new Function() { + @Override - public Resource apply(ReferencedProperty prop) { + public ResourceSupport apply(ReferencedProperty prop) { if (null == prop.propertyValue) { throw new ResourceNotFoundException(); @@ -121,7 +121,7 @@ public class RepositoryPropertyReferenceController extends AbstractRepositoryRes resources.add(perAssembler.toResource(obj)); } - return new Resource(resources); + return new Resources>(resources); } else if (prop.property.isMap()) { @@ -141,13 +141,14 @@ public class RepositoryPropertyReferenceController extends AbstractRepositoryRes } } }; - Resource responseResource = doWithReferencedProperty(repoRequest, id, property, handler); + + ResourceSupport responseResource = doWithReferencedProperty(repoRequest, id, property, handler); return ControllerUtils.toResponseEntity(headers, responseResource, HttpStatus.OK); } @RequestMapping(value = BASE_MAPPING, method = RequestMethod.DELETE) @ResponseBody - public ResponseEntity> deletePropertyReference(final RepositoryRestRequest repoRequest, + public ResponseEntity deletePropertyReference(final RepositoryRestRequest repoRequest, @PathVariable String id, @PathVariable String property) throws ResourceNotFoundException, NoSuchMethodException, HttpRequestMethodNotSupportedException { @@ -157,12 +158,15 @@ public class RepositoryPropertyReferenceController extends AbstractRepositoryRes return new ResponseEntity>(HttpStatus.METHOD_NOT_ALLOWED); } - Function> handler = new Function>() { + Function handler = new Function() { + @Override public Resource apply(ReferencedProperty prop) { + if (null == prop.propertyValue) { return null; } + if (prop.property.isCollectionLike()) { throw new IllegalArgumentException(new HttpRequestMethodNotSupportedException("DELETE")); } else if (prop.property.isMap()) { @@ -174,6 +178,7 @@ public class RepositoryPropertyReferenceController extends AbstractRepositoryRes publisher.publishEvent(new BeforeLinkDeleteEvent(prop.wrapper.getBean(), prop.propertyValue)); Object result = repoMethodInvoker.invokeSave(prop.wrapper.getBean()); publisher.publishEvent(new AfterLinkDeleteEvent(result, prop.propertyValue)); + return null; } }; @@ -188,16 +193,19 @@ public class RepositoryPropertyReferenceController extends AbstractRepositoryRes return ControllerUtils.toResponseEntity(null, EMPTY_RESOURCE, HttpStatus.NO_CONTENT); } + @ResponseBody @RequestMapping(value = BASE_MAPPING + "/{propertyId}", method = RequestMethod.GET, produces = { "application/json", "application/x-spring-data-verbose+json", "application/x-spring-data-compact+json", "text/uri-list" }) - @ResponseBody - public ResponseEntity> followPropertyReference(final RepositoryRestRequest repoRequest, + public ResponseEntity followPropertyReference(final RepositoryRestRequest repoRequest, @PathVariable String id, @PathVariable String property, final @PathVariable String propertyId) throws ResourceNotFoundException, NoSuchMethodException { + final HttpHeaders headers = new HttpHeaders(); - Function> handler = new Function>() { + Function handler = new Function() { + @Override - public Resource apply(ReferencedProperty prop) { + public ResourceSupport apply(ReferencedProperty prop) { + if (null == prop.propertyValue) { throw new ResourceNotFoundException(); } @@ -234,46 +242,54 @@ public class RepositoryPropertyReferenceController extends AbstractRepositoryRes } }; - Resource responseResource = doWithReferencedProperty(repoRequest, id, property, handler); + ResourceSupport responseResource = doWithReferencedProperty(repoRequest, id, property, handler); return ControllerUtils.toResponseEntity(headers, responseResource, HttpStatus.OK); } + @ResponseBody @RequestMapping(value = BASE_MAPPING, method = RequestMethod.GET, produces = { "application/x-spring-data-compact+json", "text/uri-list" }) - @ResponseBody - public ResponseEntity> followPropertyReferenceCompact(RepositoryRestRequest repoRequest, + public ResponseEntity followPropertyReferenceCompact(RepositoryRestRequest repoRequest, @PathVariable String id, @PathVariable String property) throws ResourceNotFoundException, NoSuchMethodException { - ResponseEntity> response = followPropertyReference(repoRequest, id, property); + + ResponseEntity response = followPropertyReference(repoRequest, id, property); + if (response.getStatusCode() != HttpStatus.OK) { return response; } ResourceMetadata repoMapping = repoRequest.getResourceMetadata(); PersistentProperty persistentProp = repoRequest.getPersistentEntity().getPersistentProperty(property); + ResourceMapping propertyMapping = repoMapping.getMappingFor(persistentProp); - Class propType = persistentProp.isCollectionLike() || persistentProp.isMap() ? persistentProp.getComponentType() - : persistentProp.getType(); - ResourceMapping propRepoMapping = getResourceMapping(config, repositories.getRepositoryInformationFor(propType)); - String propRel = String.format("%s.%s.%s", repoMapping.getSingleResourceRel(), property, propRepoMapping.getRel()); - - Resource resource = response.getBody(); + ResourceSupport resource = response.getBody(); List links = new ArrayList(); - URI entityBaseUri = buildUri(repoRequest.getBaseUri(), repoMapping.getPath().toString(), id, property); + ControllerLinkBuilder linkBuilder = linkTo(methodOn(RepositoryPropertyReferenceController.class) + .followPropertyReference(repoRequest, id, property)); - if (resource.getContent() instanceof Iterable) { - for (Resource res : (Iterable>) resource.getContent()) { - Link propLink = propertyReferenceLink(res, entityBaseUri, propRel); - links.add(propLink); - } - } else if (resource.getContent() instanceof Map) { - for (Map.Entry> entry : ((Map>) resource.getContent()).entrySet()) { - Link l = new Link(entry.getValue().getLink("self").getHref(), entry.getKey().toString()); - links.add(l); + if (resource instanceof Resource) { + + Object content = ((Resource) resource).getContent(); + if (content instanceof Iterable) { + + for (Resource res : (Iterable>) content) { + links.add(linkBuilder.withRel(propertyMapping.getRel())); + } + + } else if (content instanceof Map) { + + Map> map = (Map>) content; + + for (Entry> entry : map.entrySet()) { + Link l = new Link(entry.getValue().getLink("self").getHref(), entry.getKey().toString()); + links.add(l); + } } + } else { - links.add(new Link(entityBaseUri.toString(), propRel)); + links.add(linkBuilder.withRel(propertyMapping.getRel())); } return ControllerUtils.toResponseEntity(null, new Resource(EMPTY_RESOURCE_LIST, links), HttpStatus.OK); @@ -282,7 +298,7 @@ public class RepositoryPropertyReferenceController extends AbstractRepositoryRes @RequestMapping(value = BASE_MAPPING, method = { RequestMethod.POST, RequestMethod.PUT }, consumes = { "application/json", "application/x-spring-data-compact+json", "text/uri-list" }) @ResponseBody - public ResponseEntity> createPropertyReference(final RepositoryRestRequest repoRequest, + public ResponseEntity createPropertyReference(final RepositoryRestRequest repoRequest, final @RequestBody Resource incoming, @PathVariable String id, @PathVariable String property) throws NoSuchMethodException { @@ -291,38 +307,53 @@ public class RepositoryPropertyReferenceController extends AbstractRepositoryRes if (!invoker.exposesSave()) { return new ResponseEntity>(HttpStatus.METHOD_NOT_ALLOWED); } - Function> handler = new Function>() { + Function handler = new Function() { + @Override - public Resource apply(ReferencedProperty prop) { + public ResourceSupport apply(ReferencedProperty prop) { + if (prop.property.isCollectionLike()) { + Collection coll = new ArrayList(); + if (HttpMethod.POST.equals(repoRequest.getRequestMethod())) { coll.addAll((Collection) prop.propertyValue); } + for (Link l : incoming.getLinks()) { Object propVal = loadPropertyValue(prop.propertyType, l.getHref()); coll.add(propVal); } + prop.wrapper.setProperty(prop.property, coll); + } else if (prop.property.isMap()) { + Map m = new HashMap(); + if (HttpMethod.POST.equals(repoRequest.getRequestMethod())) { m.putAll((Map) prop.propertyValue); } + for (Link l : incoming.getLinks()) { Object propVal = loadPropertyValue(prop.propertyType, l.getHref()); m.put(l.getRel(), propVal); } + prop.wrapper.setProperty(prop.property, m); + } else { + if (HttpMethod.POST.equals(repoRequest.getRequestMethod())) { throw new IllegalStateException( "Cannot POST a reference to this singular property since the property type is not a List or a Map."); } + if (incoming.getLinks().size() != 1) { throw new IllegalArgumentException( "Must send only 1 link to update a property reference that isn't a List or a Map."); } + Object propVal = loadPropertyValue(prop.propertyType, incoming.getLinks().get(0).getHref()); prop.wrapper.setProperty(prop.property, propVal); } @@ -330,6 +361,7 @@ public class RepositoryPropertyReferenceController extends AbstractRepositoryRes publisher.publishEvent(new BeforeLinkSaveEvent(prop.wrapper.getBean(), prop.propertyValue)); Object result = invoker.invokeSave(prop.wrapper.getBean()); publisher.publishEvent(new AfterLinkSaveEvent(result, prop.propertyValue)); + return null; } }; @@ -341,7 +373,7 @@ public class RepositoryPropertyReferenceController extends AbstractRepositoryRes @RequestMapping(value = BASE_MAPPING + "/{propertyId}", method = RequestMethod.DELETE) @ResponseBody - public ResponseEntity> deletePropertyReferenceId(final RepositoryRestRequest repoRequest, + public ResponseEntity deletePropertyReferenceId(final RepositoryRestRequest repoRequest, @PathVariable String id, @PathVariable String property, final @PathVariable String propertyId) throws NoSuchMethodException { @@ -351,12 +383,15 @@ public class RepositoryPropertyReferenceController extends AbstractRepositoryRes throw new NoSuchMethodError(); } - Function> handler = new Function>() { + Function handler = new Function() { + @Override - public Resource apply(ReferencedProperty prop) { + public ResourceSupport apply(ReferencedProperty prop) { + if (null == prop.propertyValue) { return null; } + if (prop.property.isCollectionLike()) { Collection coll = new ArrayList(); for (Object obj : (Collection) prop.propertyValue) { @@ -384,6 +419,7 @@ public class RepositoryPropertyReferenceController extends AbstractRepositoryRes publisher.publishEvent(new BeforeLinkDeleteEvent(prop.wrapper.getBean(), prop.propertyValue)); Object result = invoker.invokeSave(prop.wrapper.getBean()); publisher.publishEvent(new AfterLinkDeleteEvent(result, prop.propertyValue)); + return null; } }; @@ -393,28 +429,21 @@ public class RepositoryPropertyReferenceController extends AbstractRepositoryRes return ControllerUtils.toResponseEntity(null, EMPTY_RESOURCE, HttpStatus.NO_CONTENT); } - private Link propertyReferenceLink(Resource resource, URI baseUri, String rel) { - Link selfLink = resource.getLink("self"); - String objId = selfLink.getHref().substring(selfLink.getHref().lastIndexOf('/') + 1); - return new Link(buildUri(baseUri, objId).toString(), rel); - } - private Object loadPropertyValue(Class type, String href) { String id = href.substring(href.lastIndexOf('/') + 1); return converter.convert(id, STRING_TYPE, TypeDescriptor.valueOf(type)); } - private Resource doWithReferencedProperty(RepositoryRestRequest repoRequest, String id, String propertyPath, - Function> handler) throws NoSuchMethodException { + private ResourceSupport doWithReferencedProperty(RepositoryRestRequest repoRequest, String id, String propertyPath, + Function handler) throws NoSuchMethodException { - RepositoryInvoker repoMethodInvoker = repoRequest.getRepositoryInvoker(); + RepositoryInvoker invoker = repoRequest.getRepositoryInvoker(); - if (!repoMethodInvoker.exposesFindOne()) { + if (!invoker.exposesFindOne()) { throw new NoSuchMethodException(); } - Object domainObj = converter.convert(id, STRING_TYPE, - TypeDescriptor.valueOf(repoRequest.getPersistentEntity().getType())); + Object domainObj = invoker.invokeFindOne(id); if (null == domainObj) { throw new ResourceNotFoundException(); @@ -444,13 +473,7 @@ public class RepositoryPropertyReferenceController extends AbstractRepositoryRes this.property = property; this.propertyValue = propertyValue; this.wrapper = wrapper; - if (property.isCollectionLike()) { - this.propertyType = property.getComponentType(); - } else if (property.isMap()) { - this.propertyType = property.getMapValueType(); - } else { - this.propertyType = property.getType(); - } + this.propertyType = property.getActualType(); this.entity = repositories.getPersistentEntity(propertyType); } } diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryRestHandlerMapping.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryRestHandlerMapping.java index 75f33a246..0564d92bd 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryRestHandlerMapping.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryRestHandlerMapping.java @@ -12,8 +12,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.Ordered; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.data.repository.support.Repositories; -import org.springframework.data.rest.config.RepositoryRestConfiguration; -import org.springframework.data.rest.repository.mapping.ResourceMappings; +import org.springframework.data.rest.core.config.RepositoryRestConfiguration; +import org.springframework.data.rest.core.mapping.ResourceMappings; import org.springframework.data.rest.webmvc.support.JpaHelper; import org.springframework.http.MediaType; import org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor; diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryRestRequest.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryRestRequest.java index 2e796b2fb..044f637bf 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryRestRequest.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryRestRequest.java @@ -15,13 +15,12 @@ */ package org.springframework.data.rest.webmvc; -import java.net.URI; - import javax.servlet.http.HttpServletRequest; import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.rest.repository.invoke.RepositoryInvoker; -import org.springframework.data.rest.repository.mapping.ResourceMetadata; +import org.springframework.data.rest.core.invoke.RepositoryInvoker; +import org.springframework.data.rest.core.mapping.ResourceMetadata; +import org.springframework.data.rest.core.mapping.SearchResourceMappings; import org.springframework.http.HttpMethod; import org.springframework.web.context.request.NativeWebRequest; @@ -32,16 +31,14 @@ import org.springframework.web.context.request.NativeWebRequest; class RepositoryRestRequest { private final NativeWebRequest request; - private final URI baseUri; private final ResourceMetadata resourceMetadata; private final RepositoryInvoker repoInvoker; private final PersistentEntity persistentEntity; - public RepositoryRestRequest(PersistentEntity entity, NativeWebRequest request, URI baseUri, - ResourceMetadata repoInfo, RepositoryInvoker invoker) { + public RepositoryRestRequest(PersistentEntity entity, NativeWebRequest request, ResourceMetadata repoInfo, + RepositoryInvoker invoker) { this.request = request; - this.baseUri = baseUri; this.resourceMetadata = repoInfo; if (resourceMetadata == null || !resourceMetadata.isExported()) { @@ -62,14 +59,18 @@ class RepositoryRestRequest { return HttpMethod.valueOf(request.getNativeRequest(HttpServletRequest.class).getMethod()); } - URI getBaseUri() { - return baseUri; + Class getDomainType() { + return resourceMetadata.getDomainType(); } ResourceMetadata getResourceMetadata() { return resourceMetadata; } + SearchResourceMappings getSearchMappings() { + return resourceMetadata.getSearchResourceMappings(); + } + RepositoryInvoker getRepositoryInvoker() { return repoInvoker; } diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryRestRequestHandlerMethodArgumentResolver.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryRestRequestHandlerMethodArgumentResolver.java index eb77f7ca7..341e9979c 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryRestRequestHandlerMethodArgumentResolver.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryRestRequestHandlerMethodArgumentResolver.java @@ -15,15 +15,13 @@ */ package org.springframework.data.rest.webmvc; -import java.net.URI; - import org.springframework.core.MethodParameter; import org.springframework.core.convert.ConversionService; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.repository.support.Repositories; -import org.springframework.data.rest.repository.invoke.RepositoryInvoker; -import org.springframework.data.rest.repository.invoke.RepositoryInvokerFactory; -import org.springframework.data.rest.repository.mapping.ResourceMetadata; +import org.springframework.data.rest.core.invoke.RepositoryInvoker; +import org.springframework.data.rest.core.invoke.RepositoryInvokerFactory; +import org.springframework.data.rest.core.mapping.ResourceMetadata; import org.springframework.util.Assert; import org.springframework.web.bind.support.WebDataBinderFactory; import org.springframework.web.context.request.NativeWebRequest; @@ -39,7 +37,6 @@ public class RepositoryRestRequestHandlerMethodArgumentResolver implements Handl private final Repositories repositories; private final RepositoryInvokerFactory invokerFactory; private final ResourceMetadataHandlerMethodArgumentResolver resourceMetadataResolver; - private final BaseUriMethodArgumentResolver baseUriResolver; /** * Creates a new {@link RepositoryRestRequestHandlerMethodArgumentResolver} using the given {@link Repositories} and @@ -49,8 +46,7 @@ public class RepositoryRestRequestHandlerMethodArgumentResolver implements Handl * @param conversionService must not be {@literal null}. */ public RepositoryRestRequestHandlerMethodArgumentResolver(Repositories repositories, - ConversionService conversionService, ResourceMetadataHandlerMethodArgumentResolver resourceMetadataResolver, - BaseUriMethodArgumentResolver baseUriResolver) { + ConversionService conversionService, ResourceMetadataHandlerMethodArgumentResolver resourceMetadataResolver) { Assert.notNull(repositories, "Repositories must not be null!"); Assert.notNull(conversionService, "ConversionService must not be null!"); @@ -58,7 +54,6 @@ public class RepositoryRestRequestHandlerMethodArgumentResolver implements Handl this.repositories = repositories; this.invokerFactory = new RepositoryInvokerFactory(repositories, conversionService); this.resourceMetadataResolver = resourceMetadataResolver; - this.baseUriResolver = baseUriResolver; } /* @@ -78,7 +73,6 @@ public class RepositoryRestRequestHandlerMethodArgumentResolver implements Handl public RepositoryRestRequest resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { - URI baseUri = baseUriResolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory); ResourceMetadata repoInfo = resourceMetadataResolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory); @@ -87,6 +81,6 @@ public class RepositoryRestRequestHandlerMethodArgumentResolver implements Handl // TODO reject if ResourceMetadata cannot be resolved - return new RepositoryRestRequest(persistentEntity, webRequest, baseUri, repoInfo, repositoryInvoker); + return new RepositoryRestRequest(persistentEntity, webRequest, repoInfo, repositoryInvoker); } } diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositorySearchController.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositorySearchController.java index 4a1c1304d..a2008d84e 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositorySearchController.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositorySearchController.java @@ -18,7 +18,6 @@ package org.springframework.data.rest.webmvc; import static org.springframework.data.rest.webmvc.ControllerUtils.*; import java.lang.reflect.Method; -import java.net.URI; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -26,63 +25,201 @@ import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Pageable; -import org.springframework.data.rest.repository.invoke.RepositoryInvoker; -import org.springframework.data.rest.repository.mapping.ResourceMapping; -import org.springframework.data.rest.repository.mapping.ResourceMappings; -import org.springframework.data.rest.repository.mapping.ResourceMetadata; -import org.springframework.data.rest.repository.mapping.SearchResourceMappings; +import org.springframework.data.rest.core.invoke.RepositoryInvoker; +import org.springframework.data.rest.core.mapping.ResourceMapping; +import org.springframework.data.rest.core.mapping.ResourceMappings; +import org.springframework.data.rest.core.mapping.ResourceMetadata; +import org.springframework.data.rest.core.mapping.SearchResourceMappings; import org.springframework.data.web.PagedResourcesAssembler; import org.springframework.hateoas.EntityLinks; import org.springframework.hateoas.Link; import org.springframework.hateoas.LinkBuilder; +import org.springframework.hateoas.Links; import org.springframework.hateoas.Resource; import org.springframework.hateoas.ResourceSupport; import org.springframework.hateoas.Resources; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.util.Assert; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; /** + * Controller to lookup and execute searches on a given repository. + * * @author Jon Brisbin * @author Oliver Gierke */ @RestController class RepositorySearchController extends AbstractRepositoryRestController { - private static final String BASE_MAPPING = "/{repository}/search"; + private static final String SEARCH = "/search"; + private static final String BASE_MAPPING = "/{repository}" + SEARCH; private final EntityLinks entityLinks; private final ResourceMappings mappings; + /** + * Creates a new {@link RepositorySearchController} using the given {@link PagedResourcesAssembler}, + * {@link PersistentEntityResourceAssembler}, {@link EntityLinks} and {@link ResourceMappings}. + * + * @param assembler must not be {@literal null}. + * @param perAssembler must not be {@literal null}. + * @param entityLinks must not be {@literal null}. + * @param mappings must not be {@literal null}. + */ @Autowired public RepositorySearchController(PagedResourcesAssembler assembler, PersistentEntityResourceAssembler perAssembler, EntityLinks entityLinks, ResourceMappings mappings) { super(assembler, perAssembler); + Assert.notNull(entityLinks, "EntityLinks must not be null!"); + Assert.notNull(mappings, "ResourceMappings must not be null!"); + this.entityLinks = entityLinks; this.mappings = mappings; } - @RequestMapping(value = BASE_MAPPING, method = RequestMethod.GET, produces = { "application/json", - "application/x-spring-data-compact+json" }) + /** + * Exposes links to the individual search resources exposed by the backing repository. + * + * @param request + * @return + */ @ResponseBody - public Resource list(RepositoryRestRequest repoRequest) throws ResourceNotFoundException { - List links = new ArrayList(); - links.addAll(queryMethodLinks(repoRequest.getBaseUri(), repoRequest.getPersistentEntity().getType())); - if (links.isEmpty()) { + @RequestMapping(value = BASE_MAPPING, method = RequestMethod.GET, // + produces = { "application/json", "application/x-spring-data-compact+json" }) + public Resource listSearches(RepositoryRestRequest request) { + + SearchResourceMappings resourceMappings = request.getSearchMappings(); + + if (!resourceMappings.isExported()) { throw new ResourceNotFoundException(); } - return new Resource(Collections.emptyList(), links); + + Links queryMethodLinks = getSearchLinks(request.getDomainType()); + + if (queryMethodLinks.isEmpty()) { + throw new ResourceNotFoundException(); + } + + return new Resource(Collections.emptyList(), queryMethodLinks); } - protected List queryMethodLinks(URI baseUri, Class domainType) { + /** + * Executes the search with the given name. + * + * @param request + * @param repository + * @param search + * @param pageable + * @return + * @throws ResourceNotFoundException + */ + @ResponseBody + @RequestMapping(value = BASE_MAPPING + "/{search}", method = RequestMethod.GET, // + produces = { "application/json", "application/x-spring-data-verbose+json" }) + public ResponseEntity> executeSearch(RepositoryRestRequest request, @PathVariable String search, + Pageable pageable) { + + Method method = checkExecutability(request, search); + Resources resources = executeQueryMethod(request, method, pageable); + + return new ResponseEntity>(resources, HttpStatus.OK); + } + + /** + * Executes a query method and exposes the results in compact form. + * + * @param repoRequest + * @param repository + * @param method + * @param pageable + * @return + */ + @ResponseBody + @RequestMapping(value = BASE_MAPPING + "/{method}", method = RequestMethod.GET, // + produces = { "application/x-spring-data-compact+json" }) + public ResourceSupport executeSearchCompact(RepositoryRestRequest repoRequest, @PathVariable String repository, + @PathVariable String search, Pageable pageable) { + + Method method = checkExecutability(repoRequest, search); + ResourceSupport resource = executeQueryMethod(repoRequest, method, pageable); List links = new ArrayList(); - LinkBuilder builder = entityLinks.linkFor(domainType).slash("search"); + + if (resource instanceof Resources && ((Resources) resource).getContent() != null) { + + for (Object obj : ((Resources) resource).getContent()) { + if (null != obj && obj instanceof Resource) { + Resource res = (Resource) obj; + links.add(resourceLink(repoRequest, res)); + } + } + + } else if (resource instanceof Resource) { + + Resource res = (Resource) resource; + links.add(resourceLink(repoRequest, res)); + } + + return new Resource(EMPTY_RESOURCE_LIST, links); + } + + /** + * Checks that the given request is actually executable. Will reject execution if we don't find a search with the + * given name. + * + * @param request + * @param searchName + * @return + */ + private Method checkExecutability(RepositoryRestRequest request, String searchName) { + + ResourceMetadata metadata = request.getResourceMetadata(); + SearchResourceMappings searchMapping = metadata.getSearchResourceMappings(); + + if (!searchMapping.isExported()) { + throw new ResourceNotFoundException(); + } + + Method method = searchMapping.getMappedMethod(searchName); + + if (method == null) { + throw new ResourceNotFoundException(); + } + + return method; + } + + /** + * @param repoRequest + * @param method + * @param pageable + * @return + */ + private Resources executeQueryMethod(final RepositoryRestRequest repoRequest, Method method, Pageable pageable) { + + RepositoryInvoker repoMethodInvoker = repoRequest.getRepositoryInvoker(); + Map parameters = repoRequest.getRequest().getParameterMap(); + Object result = repoMethodInvoker.invokeQueryMethod(method, parameters, pageable, null); + + return resultToResources(result); + } + + /** + * Returns {@link Links} to the individual searches exposed. + * + * @param domainType the domain type we want to obtain the search links for. + * @return + */ + private Links getSearchLinks(Class domainType) { + + List links = new ArrayList(); + LinkBuilder builder = entityLinks.linkFor(domainType).slash(SEARCH); for (ResourceMapping mapping : mappings.getSearchResourceMappings(domainType)) { @@ -90,62 +227,9 @@ class RepositorySearchController extends AbstractRepositoryRestController { continue; } - links.add(builder.slash(mapping.getPath().toString()).withRel(mapping.getRel())); + links.add(builder.slash(mapping.getPath()).withRel(mapping.getRel())); } - return links; - } - - @RequestMapping(value = BASE_MAPPING + "/{method}", method = RequestMethod.GET, produces = { "application/json", - "application/x-spring-data-verbose+json" }) - @ResponseBody - public ResponseEntity query(final RepositoryRestRequest repoRequest, - @PathVariable String repository, @PathVariable String method, Pageable pageable) throws ResourceNotFoundException { - - ResourceMetadata metadata = repoRequest.getResourceMetadata(); - SearchResourceMappings searchMapping = metadata.getSearchResourceMappings(); - - if (searchMapping.isExported()) { - return new ResponseEntity(HttpStatus.NOT_FOUND); - } - - RepositoryInvoker repoMethodInvoker = repoRequest.getRepositoryInvoker(); - - Method mappedMethod = searchMapping.getMappedMethod(method); - - if (mappedMethod == null) { - return new ResponseEntity(HttpStatus.NOT_FOUND); - } - - Map parameters = repoRequest.getRequest().getParameterMap(); - Object result = repoMethodInvoker.invokeQueryMethod(mappedMethod, parameters, pageable, null); - - return new ResponseEntity(resultToResources(result), HttpStatus.OK); - } - - @ResponseBody - @RequestMapping(value = BASE_MAPPING + "/{method}", method = RequestMethod.GET, - produces = { "application/x-spring-data-compact+json" }) - public ResourceSupport queryCompact(RepositoryRestRequest repoRequest, @PathVariable String repository, - @PathVariable String method, Pageable pageable) { - List links = new ArrayList(); - - ResponseEntity entity = query(repoRequest, repository, method, pageable); - ResourceSupport resource = entity.getBody(); - links.addAll(resource.getLinks()); - - if (resource instanceof Resources && ((Resources) resource).getContent() != null) { - for (Object obj : ((Resources) resource).getContent()) { - if (null != obj && obj instanceof Resource) { - Resource res = (Resource) obj; - links.add(resourceLink(repoRequest, res)); - } - } - } else if (resource instanceof Resource) { - Resource res = (Resource) resource; - links.add(resourceLink(repoRequest, res)); - } - - return new Resource(EMPTY_RESOURCE_LIST, links); + return new Links(links); } } diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/ResourceMetadataHandlerMethodArgumentResolver.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/ResourceMetadataHandlerMethodArgumentResolver.java index c9bec0947..cbcd2ca64 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/ResourceMetadataHandlerMethodArgumentResolver.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/ResourceMetadataHandlerMethodArgumentResolver.java @@ -23,8 +23,8 @@ import javax.servlet.http.HttpServletRequest; import org.springframework.core.MethodParameter; import org.springframework.data.repository.core.RepositoryInformation; import org.springframework.data.repository.support.Repositories; -import org.springframework.data.rest.repository.mapping.ResourceMappings; -import org.springframework.data.rest.repository.mapping.ResourceMetadata; +import org.springframework.data.rest.core.mapping.ResourceMappings; +import org.springframework.data.rest.core.mapping.ResourceMetadata; import org.springframework.util.Assert; import org.springframework.web.bind.support.WebDataBinderFactory; import org.springframework.web.context.request.NativeWebRequest; diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/ResourceNotFoundException.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/ResourceNotFoundException.java index 5333d07c8..fbc4f2c98 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/ResourceNotFoundException.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/ResourceNotFoundException.java @@ -1,16 +1,20 @@ package org.springframework.data.rest.webmvc; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + /** * Indicates a resource was not found. * * @author Jon Brisbin */ +@ResponseStatus(HttpStatus.NOT_FOUND) public class ResourceNotFoundException extends RuntimeException { private static final long serialVersionUID = 7992904489502842099L; public ResourceNotFoundException() { - super("Resource not found"); + super("Resource not found!"); } public ResourceNotFoundException(String message) { diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/ResourceProcessorHandlerMethodReturnValueHandler.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/ResourceProcessorHandlerMethodReturnValueHandler.java index 413d13a61..a4ca4b697 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/ResourceProcessorHandlerMethodReturnValueHandler.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/ResourceProcessorHandlerMethodReturnValueHandler.java @@ -15,6 +15,14 @@ */ package org.springframework.data.rest.webmvc; +import static org.springframework.data.util.ClassTypeInformation.*; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + import org.springframework.core.MethodParameter; import org.springframework.core.Ordered; import org.springframework.core.annotation.AnnotationAwareOrderComparator; @@ -33,14 +41,6 @@ import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.method.support.HandlerMethodReturnValueHandler; import org.springframework.web.method.support.ModelAndViewContainer; -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -import static org.springframework.data.util.ClassTypeInformation.from; - /** * {@link HandlerMethodReturnValueHandler} to post-process the objects returned from controller methods using the * configured {@link ResourceProcessor}s. diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/annotation/BaseURI.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/annotation/BaseURI.java deleted file mode 100644 index c2d280f71..000000000 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/annotation/BaseURI.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.springframework.data.rest.webmvc.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Marker annotation to denote which {@link java.net.URI} parameter should be resolved to the request base URI. - * - * @author Jon Brisbin - */ -@Target({ ElementType.PARAMETER }) -@Retention(RetentionPolicy.RUNTIME) -public @interface BaseURI { -} diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.java index 34640b6c5..bcacc08b5 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.java @@ -32,15 +32,14 @@ import org.springframework.context.annotation.Lazy; import org.springframework.core.convert.support.ConfigurableConversionService; import org.springframework.data.repository.support.DomainClassConverter; import org.springframework.data.repository.support.Repositories; -import org.springframework.data.rest.config.RepositoryRestConfiguration; -import org.springframework.data.rest.convert.ISO8601DateConverter; -import org.springframework.data.rest.convert.UUIDConverter; -import org.springframework.data.rest.repository.UriDomainClassConverter; -import org.springframework.data.rest.repository.context.AnnotatedHandlerBeanPostProcessor; -import org.springframework.data.rest.repository.context.ValidatingRepositoryEventListener; -import org.springframework.data.rest.repository.mapping.ResourceMappings; -import org.springframework.data.rest.repository.support.DomainObjectMerger; -import org.springframework.data.rest.webmvc.BaseUriMethodArgumentResolver; +import org.springframework.data.rest.core.UriDomainClassConverter; +import org.springframework.data.rest.core.config.RepositoryRestConfiguration; +import org.springframework.data.rest.core.event.AnnotatedHandlerBeanPostProcessor; +import org.springframework.data.rest.core.event.ValidatingRepositoryEventListener; +import org.springframework.data.rest.core.invoke.RepositoryInvokerFactory; +import org.springframework.data.rest.core.mapping.ResourceMappings; +import org.springframework.data.rest.core.support.DomainObjectMerger; +import org.springframework.data.rest.core.util.UUIDConverter; import org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler; import org.springframework.data.rest.webmvc.PersistentEntityResourceHandlerMethodArgumentResolver; import org.springframework.data.rest.webmvc.RepositoryRestHandlerAdapter; @@ -107,7 +106,6 @@ public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebCon DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService(); conversionService.addConverter(UUIDConverter.INSTANCE); - conversionService.addConverter(ISO8601DateConverter.INSTANCE); configureConversionService(conversionService); return conversionService; } @@ -185,16 +183,6 @@ public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebCon return new DomainObjectMerger(repositories(), defaultConversionService()); } - /** - * Resolves the base {@link java.net.URI} under which this application is configured. - * - * @return - */ - @Bean - public BaseUriMethodArgumentResolver baseUriMethodArgumentResolver() { - return new BaseUriMethodArgumentResolver(config()); - } - /** * Turns an {@link javax.servlet.http.HttpServletRequest} into a * {@link org.springframework.http.server.ServerHttpRequest}. @@ -214,7 +202,7 @@ public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebCon @Bean public RepositoryRestRequestHandlerMethodArgumentResolver repoRequestArgumentResolver() { return new RepositoryRestRequestHandlerMethodArgumentResolver(repositories(), defaultConversionService(), - resourceMetadataHandlerMethodArgumentResolver(), baseUriMethodArgumentResolver()); + resourceMetadataHandlerMethodArgumentResolver()); } @Bean @@ -378,6 +366,11 @@ public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebCon return er; } + @Bean + public RepositoryInvokerFactory repositoryInvokerFactory() { + return new RepositoryInvokerFactory(repositories(), defaultConversionService()); + } + private List> defaultMessageConverters() { List> messageConverters = new ArrayList>(); messageConverters.add(jacksonHttpMessageConverter()); @@ -386,8 +379,8 @@ public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebCon } private List defaultMethodArgumentResolvers() { - return Arrays.asList(baseUriMethodArgumentResolver(), pageableResolver(), sortResolver(), - serverHttpRequestMethodArgumentResolver(), repoRequestArgumentResolver(), persistentEntityArgumentResolver(), + return Arrays.asList(pageableResolver(), sortResolver(), serverHttpRequestMethodArgumentResolver(), + repoRequestArgumentResolver(), persistentEntityArgumentResolver(), resourceMetadataHandlerMethodArgumentResolver()); } diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/PersistentEntityJackson2Module.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/PersistentEntityJackson2Module.java index 3252cf800..c49db8d72 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/PersistentEntityJackson2Module.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/PersistentEntityJackson2Module.java @@ -25,11 +25,11 @@ import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mapping.PropertyHandler; import org.springframework.data.mapping.model.BeanWrapper; import org.springframework.data.repository.support.Repositories; -import org.springframework.data.rest.config.RepositoryRestConfiguration; -import org.springframework.data.rest.repository.PersistentEntityResource; -import org.springframework.data.rest.repository.UriDomainClassConverter; -import org.springframework.data.rest.repository.mapping.ResourceMappings; -import org.springframework.data.rest.repository.mapping.ResourceMetadata; +import org.springframework.data.rest.core.UriDomainClassConverter; +import org.springframework.data.rest.core.config.RepositoryRestConfiguration; +import org.springframework.data.rest.core.mapping.ResourceMappings; +import org.springframework.data.rest.core.mapping.ResourceMetadata; +import org.springframework.data.rest.webmvc.PersistentEntityResource; import org.springframework.data.rest.webmvc.support.RepositoryLinkBuilder; import org.springframework.hateoas.Link; import org.springframework.http.converter.HttpMessageNotReadableException; diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/PersistentEntityToJsonSchemaConverter.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/PersistentEntityToJsonSchemaConverter.java index c9b9ad621..f6e33ac08 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/PersistentEntityToJsonSchemaConverter.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/PersistentEntityToJsonSchemaConverter.java @@ -9,7 +9,6 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import javax.annotation.Nonnull; import javax.validation.constraints.NotNull; import org.springframework.core.convert.TypeDescriptor; @@ -20,9 +19,9 @@ import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mapping.PropertyHandler; import org.springframework.data.repository.support.Repositories; -import org.springframework.data.rest.repository.annotation.Description; -import org.springframework.data.rest.repository.mapping.ResourceMappings; -import org.springframework.data.rest.repository.mapping.ResourceMetadata; +import org.springframework.data.rest.core.annotation.Description; +import org.springframework.data.rest.core.mapping.ResourceMappings; +import org.springframework.data.rest.core.mapping.ResourceMetadata; import org.springframework.data.rest.webmvc.support.RepositoryLinkBuilder; import org.springframework.hateoas.Link; @@ -90,9 +89,7 @@ public class PersistentEntityToJsonSchemaConverter implements ConditionalGeneric public void doWithPersistentProperty(PersistentProperty persistentProperty) { Class propertyType = persistentProperty.getType(); String type = uncapitalize(propertyType.getSimpleName()); - boolean notNull = persistentProperty.getField().isAnnotationPresent(Nonnull.class) - || persistentProperty.getGetter().isAnnotationPresent(Nonnull.class) - || persistentProperty.getField().isAnnotationPresent(NotNull.class) + boolean notNull = persistentProperty.getField().isAnnotationPresent(NotNull.class) || persistentProperty.getGetter().isAnnotationPresent(NotNull.class); String desc = persistentProperty.getField().isAnnotationPresent(Description.class) ? persistentProperty .getField().getAnnotation(Description.class).value() : persistentProperty.getGetter().isAnnotationPresent( diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/PersistentEntityResourceProcessor.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/PersistentEntityResourceProcessor.java similarity index 93% rename from spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/PersistentEntityResourceProcessor.java rename to spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/PersistentEntityResourceProcessor.java index 63035b020..0096108ce 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/context/PersistentEntityResourceProcessor.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/PersistentEntityResourceProcessor.java @@ -1,4 +1,4 @@ -package org.springframework.data.rest.repository.context; +package org.springframework.data.rest.webmvc.support; import static org.springframework.util.ClassUtils.*; @@ -7,7 +7,7 @@ import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.repository.support.Repositories; -import org.springframework.data.rest.repository.PersistentEntityResource; +import org.springframework.data.rest.webmvc.PersistentEntityResource; import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation; import org.springframework.hateoas.Resource; diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/RepositoryConstraintViolationExceptionMessage.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/RepositoryConstraintViolationExceptionMessage.java index c15129754..98bc4f799 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/RepositoryConstraintViolationExceptionMessage.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/RepositoryConstraintViolationExceptionMessage.java @@ -4,11 +4,12 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; -import com.fasterxml.jackson.annotation.JsonProperty; import org.springframework.context.MessageSource; -import org.springframework.data.rest.repository.RepositoryConstraintViolationException; +import org.springframework.data.rest.core.RepositoryConstraintViolationException; import org.springframework.validation.FieldError; +import com.fasterxml.jackson.annotation.JsonProperty; + /** * @author Jon Brisbin */ diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/RepositoryEntityLinks.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/RepositoryEntityLinks.java index cd7d98c5d..f1829cb31 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/RepositoryEntityLinks.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/RepositoryEntityLinks.java @@ -2,9 +2,9 @@ package org.springframework.data.rest.webmvc.support; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.repository.support.Repositories; -import org.springframework.data.rest.config.RepositoryRestConfiguration; -import org.springframework.data.rest.repository.mapping.ResourceMappings; -import org.springframework.data.rest.repository.mapping.ResourceMetadata; +import org.springframework.data.rest.core.config.RepositoryRestConfiguration; +import org.springframework.data.rest.core.mapping.ResourceMappings; +import org.springframework.data.rest.core.mapping.ResourceMetadata; import org.springframework.hateoas.Link; import org.springframework.hateoas.LinkBuilder; import org.springframework.hateoas.core.AbstractEntityLinks; diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/RepositoryLinkBuilder.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/RepositoryLinkBuilder.java index b792d1cab..61ef5d733 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/RepositoryLinkBuilder.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/RepositoryLinkBuilder.java @@ -18,7 +18,7 @@ package org.springframework.data.rest.webmvc.support; import java.net.URI; import org.springframework.data.mapping.PersistentProperty; -import org.springframework.data.rest.repository.mapping.ResourceMetadata; +import org.springframework.data.rest.core.mapping.ResourceMetadata; import org.springframework.data.rest.webmvc.RepositoryController; import org.springframework.hateoas.Link; import org.springframework.hateoas.core.LinkBuilderSupport; diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/AbstractControllerIntegrationTests.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/AbstractControllerIntegrationTests.java new file mode 100644 index 000000000..21fcb4ad8 --- /dev/null +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/AbstractControllerIntegrationTests.java @@ -0,0 +1,80 @@ +/* + * Copyright 2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.rest.webmvc; + +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mapping.PersistentEntity; +import org.springframework.data.repository.support.Repositories; +import org.springframework.data.rest.core.Path; +import org.springframework.data.rest.core.invoke.RepositoryInvokerFactory; +import org.springframework.data.rest.core.mapping.ResourceMappings; +import org.springframework.data.rest.core.mapping.ResourceMetadata; +import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration; +import org.springframework.data.rest.webmvc.jpa.JpaRepositoryConfig; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.util.Assert; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import org.springframework.web.context.request.ServletWebRequest; + +/** + * Base class to write integration tests for controllers. + * + * @author Oliver Gierke + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { RepositoryRestMvcConfiguration.class, JpaRepositoryConfig.class }) +public class AbstractControllerIntegrationTests { + + public static final Path BASE = new Path("http://localhost"); + + @Autowired Repositories repositories; + @Autowired RepositoryInvokerFactory invokerFactory; + @Autowired ResourceMappings mappings; + + /** + * Returns a {@link RepositoryRestRequest} for the given domain type. + * + * @param domainType must not be {@literal null}. + * @return + */ + protected RepositoryRestRequest getRequest(Class domainType) { + return getRequest(domainType, RequestParameters.NONE); + } + + protected RepositoryRestRequest getRequest(Class domainType, RequestParameters parameters) { + + Assert.notNull(domainType, "Domain type must not be null!"); + + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setParameters(parameters.asMap()); + + ServletRequestAttributes requestAttributes = new ServletRequestAttributes(request); + RequestContextHolder.setRequestAttributes(requestAttributes); + + PersistentEntity entity = repositories.getPersistentEntity(domainType); + + return new RepositoryRestRequest(entity, new ServletWebRequest(request), mappings.getMappingFor(domainType), + invokerFactory.getInvokerFor(domainType)); + } + + protected ResourceMetadata getMetadata(Class domainType) { + return mappings.getMappingFor(domainType); + } +} diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/CustomMethodArgumentResolverTests.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/CustomMethodArgumentResolverTests.java deleted file mode 100644 index e732c93be..000000000 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/CustomMethodArgumentResolverTests.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2012-2013 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.rest.webmvc; - -import static org.hamcrest.MatcherAssert.*; -import static org.hamcrest.Matchers.*; - -import java.net.URI; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; -import org.springframework.core.MethodParameter; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.rest.config.RepositoryRestConfiguration; -import org.springframework.data.rest.webmvc.annotation.BaseURI; -import org.springframework.data.web.PageableHandlerMethodArgumentResolver; -import org.springframework.web.bind.support.WebDataBinderFactory; -import org.springframework.web.context.request.ServletWebRequest; -import org.springframework.web.method.support.ModelAndViewContainer; - -/** - * @author Jon Brisbin - * @author Oliver Gierke - */ -@RunWith(MockitoJUnitRunner.class) -public class CustomMethodArgumentResolverTests { - - static final MethodParameter BASE_URI; - static final MethodParameter PAGE_SORT; - - static { - try { - BASE_URI = MethodParameter.forMethodOrConstructor(Methods.class.getDeclaredMethod("baseUri", URI.class), 0); - PAGE_SORT = MethodParameter.forMethodOrConstructor( - Methods.class.getDeclaredMethod("pagingAndSorting", Pageable.class), 0); - } catch (NoSuchMethodException e) { - throw new IllegalStateException(e); - } - } - - private final RepositoryRestConfiguration config = new RepositoryRestConfiguration().setBaseUri(URI - .create("http://localhost:8080")); - private final BaseUriMethodArgumentResolver baseUriResolver = new BaseUriMethodArgumentResolver(config); - private final PageableHandlerMethodArgumentResolver pageSortResolver = new PageableHandlerMethodArgumentResolver(); - private ModelAndViewContainer mavContainer; - @Mock WebDataBinderFactory webDataBinderFactory; - - @Before - public void setup() { - mavContainer = new ModelAndViewContainer(); - - pageSortResolver.setOneIndexedParameters(true); - pageSortResolver.setFallbackPageable(new PageRequest(1, 5)); - } - - @Test - public void baseUriMethodArgumentResolver() throws Exception { - assertThat("Finds @BaseURI-annotated java.net.URI parameter", baseUriResolver.supportsParameter(BASE_URI), is(true)); - - // Resolve the base URI - URI baseUri = (URI) baseUriResolver.resolveArgument(BASE_URI, mavContainer, new ServletWebRequest( - Requests.ROOT_REQUEST), webDataBinderFactory); - - assertThat("Base URI should be 'http://localhost:8080'", baseUri.toString(), is("http://localhost:8080")); - } - - @Test - public void pagingAndSortingMethodArgumentResolver() throws Exception { - assertThat("Finds PagingAndSorting parameter", pageSortResolver.supportsParameter(PAGE_SORT), is(true)); - - // Resolve Page and Sort information - Pageable pageSort = pageSortResolver.resolveArgument(PAGE_SORT, mavContainer, new ServletWebRequest( - Requests.PAGE_REQUEST), webDataBinderFactory); - - assertThat("Finds page parameter value", pageSort.getPageNumber(), is(1)); - assertThat("Finds limit parameter value", pageSort.getPageSize(), is(10)); - } - - static class Methods { - void baseUri(@BaseURI URI baseUri) {} - - void pagingAndSorting(Pageable pageSort) {} - } -} diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/RepositorySearchControllerIntegrationTests.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/RepositorySearchControllerIntegrationTests.java new file mode 100644 index 000000000..d2784929f --- /dev/null +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/RepositorySearchControllerIntegrationTests.java @@ -0,0 +1,86 @@ +/* + * Copyright 2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.rest.webmvc; + +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.*; + +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.rest.core.mapping.ResourceMetadata; +import org.springframework.data.rest.webmvc.ResourceTester.HasSelfLink; +import org.springframework.data.rest.webmvc.jpa.CreditCard; +import org.springframework.data.rest.webmvc.jpa.Order; +import org.springframework.data.rest.webmvc.jpa.Person; +import org.springframework.hateoas.PagedResources; +import org.springframework.hateoas.Resource; +import org.springframework.hateoas.Resources; +import org.springframework.http.ResponseEntity; + +/** + * Integration tests for the {@link RepositorySearchController}. + * + * @author Oliver Gierke + */ +public class RepositorySearchControllerIntegrationTests extends AbstractControllerIntegrationTests { + + @Autowired RepositorySearchController controller; + + @Test + public void rendersCorrectSearchLinksForPersons() { + + RepositoryRestRequest request = getRequest(Person.class); + Resource resource = controller.listSearches(request); + + ResourceTester tester = ResourceTester.of(resource); + tester.assertNumberOfLinks(4); + tester.assertHasLink("findFirstPersonByFirstName", "http://localhost/people/search/findFirstPersonByFirstName"); + tester.assertHasLink("firstname", "http://localhost/people/search/firstname"); + tester.assertHasLink("findByCreatedUsingISO8601Date", + "http://localhost/people/search/findByCreatedUsingISO8601Date"); + tester.assertHasLink("findByCreatedGreaterThan", "http://localhost/people/search/findByCreatedGreaterThan"); + } + + @Test(expected = ResourceNotFoundException.class) + public void returns404ForUnexportedRepository() { + + RepositoryRestRequest request = getRequest(CreditCard.class); + controller.listSearches(request); + } + + @Test(expected = ResourceNotFoundException.class) + public void returns404ForRepositoryWithoutSearches() { + + RepositoryRestRequest request = getRequest(Order.class); + controller.listSearches(request); + } + + @Test + public void executesSearchAgainstRepository() { + + RequestParameters parameters = new RequestParameters("firstName", "John"); + RepositoryRestRequest request = getRequest(Person.class, parameters); + + ResponseEntity> response = controller.executeSearch(request, "firstname", null); + + ResourceTester tester = ResourceTester.of(response.getBody()); + PagedResources pagedResources = tester.assertIsPage(); + assertThat(pagedResources.getContent().size(), is(1)); + + ResourceMetadata metadata = getMetadata(Person.class); + tester.withContentResource(new HasSelfLink(BASE.slash(metadata.getPath()).slash("{id}"))); + } +} diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/RequestParameters.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/RequestParameters.java new file mode 100644 index 000000000..4c9505f81 --- /dev/null +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/RequestParameters.java @@ -0,0 +1,57 @@ +/* + * Copyright 2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.rest.webmvc; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.springframework.util.Assert; + +/** + * @author Oliver Gierke + */ +public class RequestParameters { + + public static RequestParameters NONE = new RequestParameters(); + + private final Map parameters; + + public RequestParameters(String key, String... values) { + this(new HashMap(), key, values); + } + + private RequestParameters(Map parameters, String key, String... values) { + + Assert.notNull(parameters, "Parameters must not be null!"); + Assert.hasText(key, "Key must not be null or empty!"); + + this.parameters = new HashMap(parameters); + this.parameters.put(key, values); + } + + private RequestParameters() { + this.parameters = new HashMap(); + } + + public RequestParameters and(String key, String... values) { + return new RequestParameters(parameters, key, values); + } + + public Map asMap() { + return Collections.unmodifiableMap(parameters); + } +} diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/ResourceProcessorHandlerMethodReturnValueHandlerUnitTests.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/ResourceProcessorHandlerMethodReturnValueHandlerUnitTests.java index 840154e76..012a4122e 100644 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/ResourceProcessorHandlerMethodReturnValueHandlerUnitTests.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/ResourceProcessorHandlerMethodReturnValueHandlerUnitTests.java @@ -17,6 +17,7 @@ package org.springframework.data.rest.webmvc; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; +import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; import static org.springframework.data.rest.webmvc.HttpEntityMatcher.*; import static org.springframework.util.ReflectionUtils.*; @@ -44,6 +45,7 @@ import org.springframework.hateoas.mvc.HeaderLinksResponseEntity; import org.springframework.http.HttpEntity; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.util.ReflectionUtils.MethodCallback; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.method.support.HandlerMethodReturnValueHandler; import org.springframework.web.method.support.ModelAndViewContainer; diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/ResourceTester.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/ResourceTester.java new file mode 100644 index 000000000..0fc7ed6d9 --- /dev/null +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/ResourceTester.java @@ -0,0 +1,135 @@ +/* + * Copyright 2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.rest.webmvc; + +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.*; + +import org.springframework.data.rest.core.Path; +import org.springframework.hateoas.Link; +import org.springframework.hateoas.PagedResources; +import org.springframework.hateoas.Resource; +import org.springframework.hateoas.ResourceSupport; +import org.springframework.hateoas.Resources; +import org.springframework.util.Assert; +import org.springframework.web.util.UriTemplate; + +/** + * Simple wrapper for {@link Resource}s to allow easy assertions on it. + * + * @author Oliver Gierke + */ +public class ResourceTester { + + private final ResourceSupport resource; + + public static ResourceTester of(Object object) { + assertThat(object, is(instanceOf(ResourceSupport.class))); + return new ResourceTester((ResourceSupport) object); + } + + /** + * Creates a new {@link ResourceTester} for the given {@link ResourceSupport}. + * + * @param resource must not be {@literal null}. + */ + private ResourceTester(ResourceSupport resource) { + Assert.notNull(resource, "Resource must not be null!"); + this.resource = resource; + } + + /** + * Asserts that the {@link Resource} contains the given number of {@link Link}s. + * + * @param number + */ + public void assertNumberOfLinks(int number) { + assertThat(resource.getLinks().size(), is(number)); + } + + /** + * Asserts that the {@link Resource} has a linke with the given rel and href. + * + * @param rel must not be {@literal null}. + * @param href can be {@literal null}, if so, only the presence of a {@link Link} with the given rel is checked. + */ + public Link assertHasLink(String rel, String href) { + + Link link = resource.getLink(rel); + assertThat("Expected link with rel '" + rel + "' but didn't find it in " + resource.getLinks(), link, + is(notNullValue())); + + if (href != null) { + assertThat(link.getHref(), is(href)); + } + + return link; + } + + @SuppressWarnings("unchecked") + public PagedResources assertIsPage() { + + assertThat(resource, is(instanceOf(PagedResources.class))); + return (PagedResources) resource; + } + + public ResourceTester getContentResource() { + + assertThat(resource, is(instanceOf(Resources.class))); + Object next = ((Resources) resource).getContent().iterator().next(); + + assertThat(next, is(instanceOf(ResourceSupport.class))); + return new ResourceTester((ResourceSupport) next); + } + + public void withContentResource(ContentResourceHandler handler) { + + assertThat(resource, is(instanceOf(Resources.class))); + + for (Object element : ((Resources) resource).getContent()) { + assertThat(element, is(instanceOf(ResourceSupport.class))); + handler.doWith(of(element)); + } + } + + public interface ContentResourceHandler { + + void doWith(ResourceTester content); + } + + public static class HasSelfLink implements ContentResourceHandler { + + private final Path template; + + public HasSelfLink(Path template) { + this.template = template; + } + + /* + * (non-Javadoc) + * @see org.springframework.data.rest.webmvc.ResourceTester.ContentResourceHandler#doWith(org.springframework.data.rest.webmvc.ResourceTester) + */ + @Override + public void doWith(ResourceTester content) { + + String href = content.assertHasLink("self", null).getHref(); + + UriTemplate uriTemplate = new UriTemplate(template.toString()); + assertThat(String.format("Expected %s to match %s!", href, uriTemplate.toString()), uriTemplate.matches(href), + is(true)); + } + } +} diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/gemfire/EmailAddress.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/gemfire/EmailAddress.java index 0b81621bc..7424f9aed 100644 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/gemfire/EmailAddress.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/gemfire/EmailAddress.java @@ -17,14 +17,15 @@ package org.springframework.data.rest.webmvc.gemfire; import java.util.regex.Pattern; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import org.springframework.core.convert.converter.Converter; import org.springframework.stereotype.Component; import org.springframework.util.Assert; import org.springframework.util.StringUtils; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; + /** * Value object to represent email addresses. * diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/JpaWebTests.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/JpaWebTests.java index 363854f86..d653d268f 100644 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/JpaWebTests.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/JpaWebTests.java @@ -22,7 +22,7 @@ import java.util.Arrays; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.rest.repository.mapping.ResourceMappings; +import org.springframework.data.rest.core.mapping.ResourceMappings; import org.springframework.data.rest.webmvc.AbstractWebIntegrationTests; import org.springframework.hateoas.Link; import org.springframework.mock.web.MockHttpServletResponse; diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/Order.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/Order.java new file mode 100644 index 000000000..3eab44513 --- /dev/null +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/Order.java @@ -0,0 +1,46 @@ +/* + * Copyright 2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.rest.webmvc.jpa; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.ManyToOne; + +/** + * @author Oliver Gierke + */ +@Entity +public class Order { + + @Id private Long id; + @ManyToOne private Person creator; + + public Order(Person creator) { + this.creator = creator; + } + + protected Order() { + + } + + public Long getId() { + return id; + } + + public Person getCreator() { + return creator; + } +} diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/OrderRepository.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/OrderRepository.java new file mode 100644 index 000000000..0d2fab326 --- /dev/null +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/OrderRepository.java @@ -0,0 +1,25 @@ +/* + * Copyright 2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.rest.webmvc.jpa; + +import org.springframework.data.repository.CrudRepository; + +/** + * @author Oliver Gierke + */ +public interface OrderRepository extends CrudRepository { + +} diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/Person.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/Person.java index a99768d0d..1936d50dd 100644 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/Person.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/Person.java @@ -5,6 +5,7 @@ import java.util.Calendar; import java.util.Collections; import java.util.Date; import java.util.List; + import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; @@ -13,7 +14,7 @@ import javax.persistence.ManyToOne; import javax.persistence.PrePersist; import javax.validation.constraints.NotNull; -import org.springframework.data.rest.repository.annotation.Description; +import org.springframework.data.rest.core.annotation.Description; /** * An entity that represents a person. diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/PersonRepository.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/PersonRepository.java index 48f1f2997..28cbeea06 100644 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/PersonRepository.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/PersonRepository.java @@ -1,3 +1,18 @@ +/* + * Copyright 2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.data.rest.webmvc.jpa; import java.util.Date; @@ -7,9 +22,9 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.query.Param; -import org.springframework.data.rest.convert.ISO8601DateConverter; -import org.springframework.data.rest.repository.annotation.ConvertWith; -import org.springframework.data.rest.repository.annotation.RestResource; +import org.springframework.data.rest.core.annotation.RestResource; +import org.springframework.format.annotation.DateTimeFormat; +import org.springframework.format.annotation.DateTimeFormat.ISO; /** * A repository to manage {@link Person}s. @@ -20,14 +35,13 @@ import org.springframework.data.rest.repository.annotation.RestResource; public interface PersonRepository extends PagingAndSortingRepository { @RestResource(rel = "firstname", path = "firstname") - public Page findByFirstName(@Param("firstName") String firstName, Pageable pageable); + Page findByFirstName(@Param("firstName") String firstName, Pageable pageable); - public Person findFirstPersonByFirstName(@Param("firstName") String firstName); + Person findFirstPersonByFirstName(@Param("firstName") String firstName); - public Page findByCreatedGreaterThan(@Param("date") Date date, Pageable pageable); + Page findByCreatedGreaterThan(@Param("date") Date date, Pageable pageable); @Query("select p from Person p where p.created > :date") - public Page findByCreatedUsingISO8601Date(@Param("date") @ConvertWith(ISO8601DateConverter.class) Date date, + Page findByCreatedUsingISO8601Date(@Param("date") @DateTimeFormat(iso = ISO.DATE_TIME) Date date, Pageable pageable); - } diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/PersistentEntitySerializationTests.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/PersistentEntitySerializationTests.java index f81f93518..92b75817e 100644 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/PersistentEntitySerializationTests.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/PersistentEntitySerializationTests.java @@ -13,7 +13,7 @@ import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.repository.support.Repositories; -import org.springframework.data.rest.repository.PersistentEntityResource; +import org.springframework.data.rest.webmvc.PersistentEntityResource; import org.springframework.data.rest.webmvc.jpa.Person; import org.springframework.data.rest.webmvc.jpa.PersonRepository; import org.springframework.hateoas.Link; diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/RepositoryTestsConfig.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/RepositoryTestsConfig.java index 96d074590..d4225f670 100644 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/RepositoryTestsConfig.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/RepositoryTestsConfig.java @@ -9,9 +9,9 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.data.repository.support.DomainClassConverter; import org.springframework.data.repository.support.Repositories; -import org.springframework.data.rest.config.RepositoryRestConfiguration; -import org.springframework.data.rest.repository.UriDomainClassConverter; -import org.springframework.data.rest.repository.mapping.ResourceMappings; +import org.springframework.data.rest.core.UriDomainClassConverter; +import org.springframework.data.rest.core.config.RepositoryRestConfiguration; +import org.springframework.data.rest.core.mapping.ResourceMappings; import org.springframework.data.rest.webmvc.jpa.JpaRepositoryConfig; import org.springframework.data.rest.webmvc.jpa.Person; import org.springframework.data.rest.webmvc.jpa.PersonRepository; diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/mongodb/MongoDbRepositoryConfig.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/mongodb/MongoDbRepositoryConfig.java index 4f2da5313..7edc669f0 100644 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/mongodb/MongoDbRepositoryConfig.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/mongodb/MongoDbRepositoryConfig.java @@ -17,7 +17,6 @@ package org.springframework.data.rest.webmvc.mongodb; import java.net.UnknownHostException; -import com.mongodb.Mongo; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @@ -26,6 +25,8 @@ import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.SimpleMongoDbFactory; import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; +import com.mongodb.Mongo; + /** * @author Jon Brisbin */