DATAREST-93 - More cleanups.
Merged core and repository modules into core. Renamed some packages for consistency in naming and in preparation to break up some package cycles. Removed @BaseUri and the according resolver. Refactored controllers a bit to have more reusable chunks of code.
This commit is contained in:
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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"));
|
||||
}
|
||||
}
|
||||
@@ -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"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package org.springframework.data.rest.core;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.*;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
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
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class RepositoryRestConfigurationIntegrationTests extends AbstractIntegrationTests {
|
||||
|
||||
@Autowired RepositoryRestConfiguration config;
|
||||
|
||||
@Test
|
||||
public void shouldProvideResourceMappingForConfiguredRepository() throws Exception {
|
||||
ResourceMapping mapping = config.getResourceMappingForRepository(ConfiguredPersonRepository.class);
|
||||
|
||||
assertThat(mapping, notNullValue());
|
||||
assertThat(mapping.getRel(), is("people"));
|
||||
assertThat(mapping.getPath(), is("people"));
|
||||
assertThat(mapping.isExported(), is(false));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package org.springframework.data.rest.core;
|
||||
|
||||
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.repository.support.DomainClassConverter;
|
||||
import org.springframework.data.repository.support.Repositories;
|
||||
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;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin
|
||||
*/
|
||||
@Configuration
|
||||
@Import({ JpaRepositoryConfig.class })
|
||||
public class RepositoryTestsConfig {
|
||||
|
||||
@Autowired private ApplicationContext appCtx;
|
||||
|
||||
@Bean
|
||||
public Repositories repositories() {
|
||||
return new Repositories(appCtx);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Bean
|
||||
public RepositoryRestConfiguration config() {
|
||||
RepositoryRestConfiguration config = new RepositoryRestConfiguration();
|
||||
|
||||
config.setResourceMappingForDomainType(Person.class).setRel("person");
|
||||
|
||||
config.setResourceMappingForRepository(ConfiguredPersonRepository.class).setRel("people").setPath("people")
|
||||
.setExported(false);
|
||||
|
||||
config.setResourceMappingForRepository(PersonRepository.class).setRel("people").setPath("people")
|
||||
.addResourceMappingFor("findByFirstName").setRel("firstname").setPath("firstname");
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DefaultFormattingConversionService defaultConversionService() {
|
||||
return new DefaultFormattingConversionService();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DomainClassConverter<?> domainClassConverter() {
|
||||
return new DomainClassConverter<DefaultFormattingConversionService>(defaultConversionService());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public UriDomainClassConverter uriDomainClassConverter() {
|
||||
return new UriDomainClassConverter(repositories(), domainClassConverter());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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.core.config;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.*;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.springframework.data.rest.core.support.ResourceMappingUtils.*;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
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.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;
|
||||
|
||||
/**
|
||||
* Ensure the {@link ResourceMapping} components convey the correct information.
|
||||
*
|
||||
* @author Jon Brisbin
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class ResourceMappingUnitTests {
|
||||
|
||||
RelProvider relProvider = new EvoInflectorRelProvider();
|
||||
|
||||
@Test
|
||||
public void shouldDetectPathAndRemoveLeadingSlashIfAny() {
|
||||
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));
|
||||
|
||||
// The rel attribute defaults to class name
|
||||
assertThat(mapping.getRel(), is("annotatedWithLeadingSlashPerson"));
|
||||
assertThat(mapping.getPath(), is("people"));
|
||||
// The exported defaults to true
|
||||
assertThat(mapping.isExported(), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDetectPathAndRemoveLeadingSlashIfAnyOnMethod() throws Exception {
|
||||
Method method = AnnotatedWithLeadingSlashPersonRepository.class.getMethod("findByFirstName", String.class,
|
||||
Pageable.class);
|
||||
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
|
||||
assertThat(mapping.getRel(), is("findByFirstName"));
|
||||
assertThat(mapping.getPath(), is("firstname"));
|
||||
// The exported defaults to true
|
||||
assertThat(mapping.isExported(), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnDefaultIfPathContainsOnlySlashTextOnMethod() throws Exception {
|
||||
Method method = AnnotatedWithLeadingSlashPersonRepository.class.getMethod("findByLastName", String.class,
|
||||
Pageable.class);
|
||||
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
|
||||
assertThat(mapping.getRel(), is("findByLastName"));
|
||||
// The path contains only a leading slash therefore defaults to method name
|
||||
assertThat(mapping.getPath(), is("findByLastName"));
|
||||
// The exported defaults to true
|
||||
assertThat(mapping.isExported(), is(true));
|
||||
}
|
||||
|
||||
@RestResource(path = "/people")
|
||||
interface AnnotatedWithLeadingSlashPersonRepository {
|
||||
|
||||
@RestResource(path = "/firstname")
|
||||
Page<Person> findByFirstName(@Param("firstName") String firstName, Pageable pageable);
|
||||
|
||||
@RestResource(path = " / ")
|
||||
Page<Person> findByLastName(@Param("lastName") String firstName, Pageable pageable);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
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.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.
|
||||
*
|
||||
* @author Jon Brisbin
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.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;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
person = people.save(new Person("Jane", "Doe"));
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void shouldDispatchBeforeCreate() throws Exception {
|
||||
appCtx.publishEvent(new BeforeCreateEvent(person));
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void shouldDispatchAfterCreate() throws Exception {
|
||||
appCtx.publishEvent(new AfterCreateEvent(person));
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void shouldDispatchBeforeSave() throws Exception {
|
||||
appCtx.publishEvent(new BeforeSaveEvent(person));
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void shouldDispatchAfterSave() throws Exception {
|
||||
appCtx.publishEvent(new AfterSaveEvent(person));
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void shouldDispatchBeforeDelete() throws Exception {
|
||||
appCtx.publishEvent(new BeforeDeleteEvent(person));
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void shouldDispatchAfterDelete() throws Exception {
|
||||
appCtx.publishEvent(new AfterDeleteEvent(person));
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void shouldDispatchBeforeLinkSave() throws Exception {
|
||||
appCtx.publishEvent(new BeforeLinkSaveEvent(person, new Object()));
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void shouldDispatchAfterLinkSave() throws Exception {
|
||||
appCtx.publishEvent(new AfterLinkSaveEvent(person, new Object()));
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void shouldDispatchBeforeLinkDelete() throws Exception {
|
||||
appCtx.publishEvent(new BeforeLinkDeleteEvent(person, new Object()));
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void shouldDispatchAfterLinkDelete() throws Exception {
|
||||
appCtx.publishEvent(new AfterLinkDeleteEvent(person, new Object()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
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.core.annotation.RestResource;
|
||||
|
||||
/**
|
||||
* A repository to manage {@link org.springframework.data.rest.core.domain.jpa.Person}s.
|
||||
*
|
||||
* @author Jon Brisbin
|
||||
*/
|
||||
@RestResource(rel = "people", exported = false)
|
||||
@NoRepositoryBean
|
||||
public interface AnnotatedPersonRepository extends CrudRepository<Person, Long> {}
|
||||
@@ -0,0 +1,12 @@
|
||||
package org.springframework.data.rest.core.domain.jpa;
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.data.repository.NoRepositoryBean;
|
||||
|
||||
/**
|
||||
* A repository to manage {@link Person}s.
|
||||
*
|
||||
* @author Jon Brisbin
|
||||
*/
|
||||
@NoRepositoryBean
|
||||
public interface ConfiguredPersonRepository extends CrudRepository<Person, Long> {}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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, Long> {
|
||||
|
||||
CreditCard findByCreditCardNumber(String creditCardNumber);
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* 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.core.domain.jpa;
|
||||
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.support.ResourceBundleMessageSource;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||
import org.springframework.orm.jpa.JpaDialect;
|
||||
import org.springframework.orm.jpa.JpaTransactionManager;
|
||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||
import org.springframework.orm.jpa.vendor.Database;
|
||||
import org.springframework.orm.jpa.vendor.HibernateJpaDialect;
|
||||
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Configuration
|
||||
@ComponentScan
|
||||
@EnableJpaRepositories
|
||||
@EnableTransactionManagement
|
||||
public class JpaRepositoryConfig {
|
||||
|
||||
@Bean
|
||||
public MessageSource messageSource() {
|
||||
ResourceBundleMessageSource ms = new ResourceBundleMessageSource();
|
||||
ms.setBasename("org.springframework.data.rest.core.ValidationErrors");
|
||||
return ms;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DataSource dataSource() {
|
||||
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
|
||||
return builder.setType(EmbeddedDatabaseType.HSQL).build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public EntityManagerFactory entityManagerFactory() {
|
||||
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
|
||||
vendorAdapter.setDatabase(Database.HSQL);
|
||||
vendorAdapter.setGenerateDdl(true);
|
||||
|
||||
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
|
||||
factory.setJpaVendorAdapter(vendorAdapter);
|
||||
factory.setPackagesToScan(getClass().getPackage().getName());
|
||||
factory.setDataSource(dataSource());
|
||||
|
||||
factory.afterPropertiesSet();
|
||||
|
||||
return factory.getObject();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JpaDialect jpaDialect() {
|
||||
return new HibernateJpaDialect();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PlatformTransactionManager transactionManager() {
|
||||
JpaTransactionManager txManager = new JpaTransactionManager();
|
||||
txManager.setEntityManagerFactory(entityManagerFactory());
|
||||
return txManager;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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<Order, Long> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package org.springframework.data.rest.core.domain.jpa;
|
||||
|
||||
import java.util.ArrayList;
|
||||
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;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.PrePersist;
|
||||
|
||||
/**
|
||||
* An entity that represents a person.
|
||||
*
|
||||
* @author Jon Brisbin
|
||||
*/
|
||||
@Entity
|
||||
public class Person {
|
||||
|
||||
@Id @GeneratedValue private Long id;
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
@OneToMany private List<Person> siblings = Collections.emptyList();
|
||||
private Date created;
|
||||
|
||||
public Person() {}
|
||||
|
||||
public Person(String firstName, String lastName) {
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public Person addSibling(Person p) {
|
||||
if (siblings == Collections.EMPTY_LIST) {
|
||||
siblings = new ArrayList<Person>();
|
||||
}
|
||||
siblings.add(p);
|
||||
return this;
|
||||
}
|
||||
|
||||
public List<Person> getSiblings() {
|
||||
return siblings;
|
||||
}
|
||||
|
||||
public void setSiblings(List<Person> siblings) {
|
||||
this.siblings = siblings;
|
||||
}
|
||||
|
||||
public Date getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
||||
@PrePersist
|
||||
private void prePersist() {
|
||||
this.created = Calendar.getInstance().getTime();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package org.springframework.data.rest.core.domain.jpa;
|
||||
|
||||
import org.springframework.data.rest.core.event.AbstractRepositoryEventListener;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin
|
||||
*/
|
||||
public class PersonBeforeSaveHandler extends AbstractRepositoryEventListener<Person> {
|
||||
@Override
|
||||
protected void onBeforeSave(Person person) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
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.core.annotation.HandleBeforeSave;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.validation.Errors;
|
||||
import org.springframework.validation.Validator;
|
||||
|
||||
/**
|
||||
* A test {@link Validator} that checks for non-blank names.
|
||||
*
|
||||
* @author Jon Brisbin
|
||||
*/
|
||||
@Component
|
||||
@HandleBeforeSave
|
||||
public class PersonNameValidator implements Validator {
|
||||
|
||||
@Override
|
||||
public boolean supports(Class<?> clazz) {
|
||||
return isAssignable(clazz, Person.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate(Object target, Errors errors) {
|
||||
Person p = (Person) target;
|
||||
if (!hasText(p.getLastName())) {
|
||||
errors.rejectValue("lastName", "blank", "Last name cannot be blank");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package org.springframework.data.rest.core.domain.jpa;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
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.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<Person, Long> {
|
||||
|
||||
@RestResource(rel = "firstname", path = "firstname")
|
||||
Page<Person> findByFirstName(@Param("firstName") String firstName, Pageable pageable);
|
||||
|
||||
Page<Person> findByCreatedGreaterThan(@Param("date") Date date, Pageable pageable);
|
||||
|
||||
@Query("select p from Person p where p.created > :date")
|
||||
Page<Person> findByCreatedUsingISO8601Date(@Param("date") @DateTimeFormat(iso = ISO.DATE_TIME) Date date,
|
||||
Pageable pageable);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package org.springframework.data.rest.core.domain.jpa;
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.data.repository.NoRepositoryBean;
|
||||
|
||||
/**
|
||||
* A repository to manage {@link Person}s.
|
||||
*
|
||||
* @author Jon Brisbin
|
||||
*/
|
||||
@NoRepositoryBean
|
||||
public interface PlainPersonRepository extends CrudRepository<Person, Long> {}
|
||||
@@ -0,0 +1,32 @@
|
||||
package org.springframework.data.rest.core.domain.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;
|
||||
import org.springframework.data.mongodb.MongoDbFactory;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
|
||||
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin
|
||||
*/
|
||||
@Configuration
|
||||
@ComponentScan(basePackageClasses = { MongoDbRepositoryConfig.class })
|
||||
@EnableMongoRepositories
|
||||
public class MongoDbRepositoryConfig {
|
||||
|
||||
@Bean
|
||||
public MongoDbFactory mongoDbFactory() throws UnknownHostException {
|
||||
return new SimpleMongoDbFactory(new Mongo("localhost"), "spring-data-rest");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MongoTemplate mongoTemplate() throws UnknownHostException {
|
||||
return new MongoTemplate(mongoDbFactory());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package org.springframework.data.rest.core.domain.mongodb;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin
|
||||
*/
|
||||
@Document
|
||||
public class Profile {
|
||||
|
||||
@Id private String id;
|
||||
private String name;
|
||||
private String type;
|
||||
|
||||
public Profile() {}
|
||||
|
||||
public Profile(String id, String name, String type) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Profile setName(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public Profile setType(String type) {
|
||||
this.type = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package org.springframework.data.rest.core.domain.mongodb;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin
|
||||
*/
|
||||
@Component
|
||||
public class ProfileLoader implements InitializingBean {
|
||||
|
||||
@Autowired private ProfileRepository profiles;
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
profiles.save(new Profile("jdoe", "jdoe", "account"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.springframework.data.rest.core.domain.mongodb;
|
||||
|
||||
import org.bson.types.ObjectId;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
/**
|
||||
* Repository for managing {@link Profile}s in MongoDB.
|
||||
*
|
||||
* @author Jon Brisbin
|
||||
*/
|
||||
public interface ProfileRepository extends CrudRepository<Profile, ObjectId> {}
|
||||
@@ -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<Object> result = invoker.invokeFindAll((Pageable) null);
|
||||
assertThat(result, is(instanceOf(Page.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokesFindAllWithPageableCorrectly() {
|
||||
|
||||
Iterable<Object> 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<Object> result = invoker.invokeFindAll(new PageRequest(0, 10));
|
||||
|
||||
assertThat(result, is(instanceOf(List.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokesQueryMethod() throws Exception {
|
||||
|
||||
HashMap<String, String[]> parameters = new HashMap<String, String[]>();
|
||||
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<String, String[]> parameters = new HashMap<String, String[]>();
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package org.springframework.data.rest.core.invoke;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.*;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.springframework.util.ReflectionUtils.*;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Tests to verify the integrity of the {@link RepositoryMethod} abstraction.
|
||||
*
|
||||
* @author Jon Brisbin
|
||||
*/
|
||||
public class RepositoryMethodUnitTests {
|
||||
|
||||
Map<String, RepositoryMethod> methods = new HashMap<String, RepositoryMethod>();
|
||||
RepositoryMethod method;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
doWithMethods(PersonRepository.class, new ReflectionUtils.MethodCallback() {
|
||||
@Override
|
||||
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
|
||||
String name = method.getName();
|
||||
RepositoryMethod repoMethod = new RepositoryMethod(method);
|
||||
methods.put(name, repoMethod);
|
||||
}
|
||||
}, Methods.USER_METHODS);
|
||||
method = methods.get("findByFirstName");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFindSimpleQueryMethods() throws Exception {
|
||||
assertThat(method, notNullValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFindPageableInformationOnMethod() throws Exception {
|
||||
assertThat(method, notNullValue());
|
||||
assertThat(method.isPageable(), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotFindSortInformationOnMethod() throws Exception {
|
||||
assertThat(method, notNullValue());
|
||||
assertThat(method.isSortable(), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldProvideParameterClassTypes() throws Exception {
|
||||
assertThat(method, notNullValue());
|
||||
assertThat(method.getParameters().get(0).getParameterType(), is(typeCompatibleWith(String.class)));
|
||||
assertThat(method.getParameters().get(1).getParameterType(), is(typeCompatibleWith(Pageable.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldProvideParameterNames() throws Exception {
|
||||
assertThat(method, notNullValue());
|
||||
assertThat(method.getParameterNames(), contains("firstName", "arg1"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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.mapping;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
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.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}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class RepositoryCollectionResourceMappingUnitTests {
|
||||
|
||||
@Test
|
||||
public void buildsDefaultMappingForRepository() {
|
||||
|
||||
CollectionResourceMapping mapping = new RepositoryCollectionResourceMapping(PersonRepository.class);
|
||||
|
||||
assertThat(mapping.getPath(), is(new Path("persons")));
|
||||
assertThat(mapping.getRel(), is("persons"));
|
||||
assertThat(mapping.getSingleResourceRel(), is("person"));
|
||||
assertThat(mapping.isExported(), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void honorsAnnotatedsMapping() {
|
||||
|
||||
CollectionResourceMapping mapping = new RepositoryCollectionResourceMapping(AnnotatedPersonRepository.class);
|
||||
|
||||
assertThat(mapping.getPath(), is(new Path("bar")));
|
||||
assertThat(mapping.getRel(), is("foo"));
|
||||
assertThat(mapping.getSingleResourceRel(), is("annotatedPerson"));
|
||||
assertThat(mapping.isExported(), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void repositoryAnnotationTrumpsDomainTypeMapping() {
|
||||
|
||||
CollectionResourceMapping mapping = new RepositoryCollectionResourceMapping(
|
||||
AnnotatedAnnotatedPersonRepository.class);
|
||||
|
||||
assertThat(mapping.getPath(), is(new Path("/trumpsAll")));
|
||||
assertThat(mapping.getRel(), is("foo"));
|
||||
assertThat(mapping.getSingleResourceRel(), is("annotatedPerson"));
|
||||
assertThat(mapping.isExported(), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doesNotExposeRepositoryForPublicDomainTypeIfRepoIsPackageProtected() {
|
||||
|
||||
ResourceMapping mapping = new RepositoryCollectionResourceMapping(PackageProtectedRepository.class);
|
||||
assertThat(mapping.isExported(), is(false));
|
||||
}
|
||||
|
||||
public static class Person {}
|
||||
|
||||
@RestResource(path = "bar", rel = "foo", exported = false)
|
||||
static class AnnotatedPerson {}
|
||||
|
||||
public interface PersonRepository extends Repository<Person, Long> {}
|
||||
|
||||
interface AnnotatedPersonRepository extends Repository<AnnotatedPerson, Long> {}
|
||||
|
||||
@RestResource(path = "trumpsAll")
|
||||
interface AnnotatedAnnotatedPersonRepository extends Repository<AnnotatedPerson, Long> {}
|
||||
|
||||
public static class PublicClass {}
|
||||
|
||||
static interface PackageProtectedRepository extends Repository<PublicClass, Long> {}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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.mapping;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
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.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);
|
||||
|
||||
@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("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("bar")));
|
||||
}
|
||||
|
||||
static class Person {}
|
||||
|
||||
interface PersonRepository extends Repository<Person, Long> {
|
||||
|
||||
Iterable<Person> findByLastname(String lastname);
|
||||
|
||||
@RestResource(path = "/bar")
|
||||
Iterable<Person> findByFirstname(String firstname);
|
||||
|
||||
@RestResource(path = "foo")
|
||||
Iterable<Person> findByEmailAddress(String email);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* 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.mapping;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
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.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}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = JpaRepositoryConfig.class)
|
||||
@Transactional
|
||||
public class ResourceMappingsIntegrationTest {
|
||||
|
||||
@Autowired ListableBeanFactory factory;
|
||||
|
||||
ResourceMappings mappings;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
Repositories repositories = new Repositories(factory);
|
||||
this.mappings = new ResourceMappings(new RepositoryRestConfiguration(), repositories);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void detectsAllMappings() {
|
||||
assertThat(mappings, is(Matchers.<ResourceMetadata> iterableWithSize(6)));
|
||||
}
|
||||
|
||||
@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));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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.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.core.annotation.RestResource;
|
||||
import org.springframework.data.rest.core.mapping.CollectionResourceMapping;
|
||||
import org.springframework.data.rest.core.mapping.TypeBasedCollectionResourceMapping;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link TypeBasedCollectionResourceMapping}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class TypeBasedCollectionResourceMappingUnitTest {
|
||||
|
||||
@Test
|
||||
public void defaultsMappingsByType() {
|
||||
|
||||
CollectionResourceMapping mapping = new TypeBasedCollectionResourceMapping(Sample.class);
|
||||
|
||||
assertThat(mapping.getPath(), is(new Path("sample")));
|
||||
assertThat(mapping.getRel(), is("samples"));
|
||||
assertThat(mapping.getSingleResourceRel(), is("sample"));
|
||||
assertThat(mapping.isExported(), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void usesCustomizedRel() {
|
||||
|
||||
CollectionResourceMapping mapping = new TypeBasedCollectionResourceMapping(CustomizedSample.class);
|
||||
|
||||
assertThat(mapping.getPath(), is(new Path("customizedSample")));
|
||||
assertThat(mapping.getRel(), is("myRel"));
|
||||
assertThat(mapping.getSingleResourceRel(), is("customizedSample"));
|
||||
assertThat(mapping.isExported(), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAREST-99
|
||||
*/
|
||||
@Test
|
||||
public void doesNotExportNonPublicTypesByDefault() {
|
||||
|
||||
CollectionResourceMapping mapping = new TypeBasedCollectionResourceMapping(HiddenSample.class);
|
||||
|
||||
assertThat(mapping.isExported(), is(false));
|
||||
}
|
||||
|
||||
public interface Sample {}
|
||||
|
||||
interface HiddenSample {}
|
||||
|
||||
@RestResource(rel = "myRel")
|
||||
interface CustomizedSample {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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.support;
|
||||
|
||||
import java.util.Arrays;
|
||||
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;
|
||||
import static org.junit.runners.Parameterized.Parameters;
|
||||
|
||||
/**
|
||||
* Ensures proper detection and removal of leading slash in strings.
|
||||
*
|
||||
* @author Florent Biville
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
public class ResourceStringUtilsTest {
|
||||
|
||||
final String actual;
|
||||
final String expected;
|
||||
final boolean hasText;
|
||||
|
||||
public ResourceStringUtilsTest(String testDescription, String actual, String expected, boolean hasText) {
|
||||
|
||||
this.actual = actual;
|
||||
this.expected = expected;
|
||||
this.hasText = hasText;
|
||||
}
|
||||
|
||||
@Parameters(name = "{0}")
|
||||
public static Collection<?> parameters() {
|
||||
return Arrays.asList(new Object[][] {
|
||||
{ "empty string has no text and should remain empty", "", "", false },
|
||||
{ "blank string has no text and should remain as is", " ", " ", false },
|
||||
{ "string made of only a leading slash has no text and should be returned empty", "/", "", false },
|
||||
{ "blank string with only slashes has no text and should be returned as is", " / ", " / ", false },
|
||||
{ "normal string has text and should be returned as such", "hello", "hello", true },
|
||||
{ "normal string with leading slash has text and should be returned without leading slash", "/hello", "hello",
|
||||
true }, });
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDetectTextPresence() {
|
||||
assertThat(ResourceStringUtils.hasTextExceptSlash(actual), is(hasText));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRemoveLeadingSlashIfAny() {
|
||||
assertThat(ResourceStringUtils.removeLeadingSlash(actual), is(expected));
|
||||
}
|
||||
}
|
||||
@@ -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<String, Integer>() {
|
||||
|
||||
@Override
|
||||
public Integer apply(String input) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static class Foo {
|
||||
|
||||
public Integer apply(Function<String, Integer> function) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
field.name.required = Field {0}.{1} is required.
|
||||
no.userid = {0}s must be assigned initial userids.
|
||||
@@ -1,17 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
|
||||
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>
|
||||
%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d %5p %40.40c:%4L - %m%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="org.springframework.data.rest" level="DEBUG"/>
|
||||
<logger name="org.springframework.data" level="error" />
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="stdout"/>
|
||||
</root>
|
||||
<root level="error">
|
||||
<appender-ref ref="console" />
|
||||
</root>
|
||||
|
||||
</configuration>
|
||||
Reference in New Issue
Block a user