diff --git a/rest/pom.xml b/rest/pom.xml
index 62507429..ac7c856f 100644
--- a/rest/pom.xml
+++ b/rest/pom.xml
@@ -21,10 +21,6 @@
security
-
- 8.0.15
-
-
org.springframework.boot
diff --git a/rest/projections/src/main/java/example/orders/LineItem.java b/rest/projections/src/main/java/example/orders/LineItem.java
index 9efbf9b2..771002ec 100644
--- a/rest/projections/src/main/java/example/orders/LineItem.java
+++ b/rest/projections/src/main/java/example/orders/LineItem.java
@@ -21,14 +21,18 @@ import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
-import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
import lombok.RequiredArgsConstructor;
+import lombok.ToString;
/**
* @author Oliver Gierke
*/
@Entity
-@Data
+@Getter
+@EqualsAndHashCode(of = "id")
+@ToString
@RequiredArgsConstructor
public class LineItem {
diff --git a/rest/projections/src/test/java/example/orders/SimpleProjectionTests.java b/rest/projections/src/test/java/example/orders/SimpleProjectionTests.java
new file mode 100644
index 00000000..5dd642c9
--- /dev/null
+++ b/rest/projections/src/test/java/example/orders/SimpleProjectionTests.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package example.orders;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.projection.ProjectionFactory;
+import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
+
+/**
+ * Test cases showing the programatic use of a {@link ProjectionFactory}.
+ *
+ * @author Oliver Gierke
+ */
+public class SimpleProjectionTests {
+
+ ProjectionFactory factory = new SpelAwareProxyProjectionFactory();
+
+ @Test
+ public void createMapBackedProjection() {
+
+ Customer customer = factory.createProjection(Customer.class);
+ customer.setFirstname("Dave");
+ customer.setLastname("Matthews");
+
+ // Verify accessors work
+ assertThat(customer.getFirstname(), is("Dave"));
+ assertThat(customer.getLastname(), is("Matthews"));
+
+ // Verify evaluating a SpEL expression
+ assertThat(customer.getFullName(), is("Dave Matthews"));
+ }
+
+ @Test
+ public void createsProxyForSourceMap() {
+
+ Map backingMap = new HashMap<>();
+ backingMap.put("firstname", "Dave");
+ backingMap.put("lastname", "Matthews");
+
+ Customer customer = factory.createProjection(Customer.class, backingMap);
+
+ // Verify accessors work
+ assertThat(customer.getFirstname(), is("Dave"));
+ assertThat(customer.getLastname(), is("Matthews"));
+ }
+
+ interface Customer {
+
+ String getFirstname();
+
+ void setFirstname(String firstname);
+
+ String getLastname();
+
+ void setLastname(String lastname);
+
+ @Value("#{target.firstname + ' ' + target.lastname}")
+ String getFullName();
+ }
+}
diff --git a/rest/starbucks/src/main/java/example/stores/StoreInitializer.java b/rest/starbucks/src/main/java/example/stores/StoreInitializer.java
index 4bc1770b..91ff4e5c 100644
--- a/rest/starbucks/src/main/java/example/stores/StoreInitializer.java
+++ b/rest/starbucks/src/main/java/example/stores/StoreInitializer.java
@@ -24,16 +24,13 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.mapping.DefaultLineMapper;
-import org.springframework.batch.item.file.mapping.FieldSetMapper;
import org.springframework.batch.item.file.separator.DefaultRecordSeparatorPolicy;
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
-import org.springframework.batch.item.file.transform.FieldSet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.geo.Point;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.stereotype.Component;
-import org.springframework.validation.BindException;
/**
* Component initializing a hand full of Starbucks stores and persisting them through a {@link StoreRepository}.
@@ -80,8 +77,16 @@ public class StoreInitializer {
tokenizer.setStrict(false);
DefaultLineMapper lineMapper = new DefaultLineMapper();
+ lineMapper.setFieldSetMapper(fields -> {
+
+ Point location = new Point(fields.readDouble("Longitude"), fields.readDouble("Latitude"));
+ Address address = new Address(fields.readString("Street Address"), fields.readString("City"), fields
+ .readString("Zip"), location);
+
+ return new Store(fields.readString("Name"), address);
+ });
+
lineMapper.setLineTokenizer(tokenizer);
- lineMapper.setFieldSetMapper(StoreFieldSetMapper.INSTANCE);
itemReader.setLineMapper(lineMapper);
itemReader.setRecordSeparatorPolicy(new DefaultRecordSeparatorPolicy());
itemReader.setLinesToSkip(1);
@@ -102,23 +107,4 @@ public class StoreInitializer {
return stores;
}
-
- private static enum StoreFieldSetMapper implements FieldSetMapper {
-
- INSTANCE;
-
- /*
- * (non-Javadoc)
- * @see org.springframework.batch.item.file.mapping.FieldSetMapper#mapFieldSet(org.springframework.batch.item.file.transform.FieldSet)
- */
- @Override
- public Store mapFieldSet(FieldSet fields) throws BindException {
-
- Point location = new Point(fields.readDouble("Longitude"), fields.readDouble("Latitude"));
- Address address = new Address(fields.readString("Street Address"), fields.readString("City"),
- fields.readString("Zip"), location);
-
- return new Store(fields.readString("Name"), address);
- }
- }
}
diff --git a/rest/starbucks/src/main/java/example/stores/StarbucksClient.java b/rest/starbucks/src/test/java/example/stores/StarbucksClient.java
similarity index 64%
rename from rest/starbucks/src/main/java/example/stores/StarbucksClient.java
rename to rest/starbucks/src/test/java/example/stores/StarbucksClient.java
index cc20c15a..022c4e2d 100644
--- a/rest/starbucks/src/main/java/example/stores/StarbucksClient.java
+++ b/rest/starbucks/src/test/java/example/stores/StarbucksClient.java
@@ -20,39 +20,65 @@ import java.util.HashMap;
import java.util.Map;
import java.util.stream.StreamSupport;
+import lombok.extern.slf4j.Slf4j;
+
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.SpringApplicationConfiguration;
+import org.springframework.context.annotation.Configuration;
import org.springframework.hateoas.MediaTypes;
import org.springframework.hateoas.PagedResources;
import org.springframework.hateoas.PagedResources.PageMetadata;
import org.springframework.hateoas.Resource;
import org.springframework.hateoas.client.Traverson;
+import org.springframework.hateoas.client.Traverson.TraversalBuilder;
import org.springframework.hateoas.mvc.TypeReferences.PagedResourcesType;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
+ * A test case to discover the search resource and execute a predefined search with it.
+ *
* @author Oliver Gierke
*/
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringApplicationConfiguration
+@Slf4j
public class StarbucksClient {
- public static void main(String[] args) {
+ @Configuration
+ static class Config {}
+
+ @Test
+ @Ignore
+ public void discoverStoreSearch() {
Traverson traverson = new Traverson(URI.create("http://localhost:8080"), MediaTypes.HAL_JSON);
+ // Set up path traversal
+ TraversalBuilder builder = traverson. //
+ follow("stores", "search", "by-location");
+
+ // Log discovered
+ log.info("");
+ log.info("Discovered link: {}", builder.asTemplatedLink());
+ log.info("");
+
Map parameters = new HashMap<>();
parameters.put("location", "40.740337,-73.995146");
parameters.put("distance", "0.5miles");
- PagedResources> resources = traverson. //
- follow("stores", "search", "by-location").//
+ PagedResources> resources = builder.//
withTemplateParameters(parameters).//
toObject(new PagedResourcesType>() {});
PageMetadata metadata = resources.getMetadata();
- System.out.println(String.format("Got %s of %s stores: ", resources.getContent().size(),
- metadata.getTotalElements()));
+ log.info("Got {} of {} stores: ", resources.getContent().size(), metadata.getTotalElements());
StreamSupport.stream(resources.spliterator(), false).//
map(Resource::getContent).//
- forEach(store -> String.format("- %s - %s", store.name, store.address));
+ forEach(store -> log.info("{} - {}", store.name, store.address));
}
static class Store {