Repository: incubator-streams Updated Branches: refs/heads/master 6c4cf0f1c -> c0bdfeb48
resolves STREAMS-241 Project: http://git-wip-us.apache.org/repos/asf/incubator-streams/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-streams/commit/c44ebff7 Tree: http://git-wip-us.apache.org/repos/asf/incubator-streams/tree/c44ebff7 Diff: http://git-wip-us.apache.org/repos/asf/incubator-streams/diff/c44ebff7 Branch: refs/heads/master Commit: c44ebff78c58581d541738892e096a284ae381fa Parents: e9adcac Author: sblackmon <sblack...@w2odigital.com> Authored: Mon Dec 1 15:00:31 2014 -0600 Committer: sblackmon <sblack...@w2odigital.com> Committed: Mon Dec 1 15:00:31 2014 -0600 ---------------------------------------------------------------------- pom.xml | 22 ++++++- streams-pojo/pom.xml | 19 +++++++ .../apache/streams/data/util/ActivityUtil.java | 7 +++ .../jackson/StreamsDateTimeDeserializer.java | 10 +++- .../streams/jackson/StreamsDateTimeFormat.java | 12 ++++ .../jackson/StreamsDateTimeSerializer.java | 5 +- .../streams/jackson/StreamsJacksonMapper.java | 20 ++++++- .../streams/jackson/StreamsJacksonModule.java | 32 ++++++++++- .../data/data/util/CustomDateTimeFormat.java | 14 +++++ .../data/util/CustomDateTimeFormatTest.java | 60 ++++++++++++++++++++ 10 files changed, 191 insertions(+), 10 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-streams/blob/c44ebff7/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index 351ec68..0969d38 100644 --- a/pom.xml +++ b/pom.xml @@ -69,7 +69,7 @@ <joda-time.version>2.2</joda-time.version> <rave.version>0.22</rave.version> <datastax.version>1.0.3</datastax.version> - <jsonschema2pojo.version>0.4.5</jsonschema2pojo.version> + <jsonschema2pojo.version>0.4.6</jsonschema2pojo.version> <jaxb2.version>0.8.3</jaxb2.version> <jaxb2-basics.version>0.8.4</jaxb2-basics.version> <jaxbutil.version>1.2.6</jaxbutil.version> @@ -81,6 +81,7 @@ <commons-io.version>2.4</commons-io.version> <commons-lang3.version>3.1</commons-lang3.version> <typesafe.config.version>1.2.0</typesafe.config.version> + <reflections.version>0.9.9</reflections.version> <orgjson.version>20140107</orgjson.version> <guava.version>17.0</guava.version> <scala.version>2.8.0</scala.version> @@ -220,6 +221,19 @@ </excludes> </configuration> </plugin> + <plugin> + <groupId>org.reflections</groupId> + <artifactId>reflections-maven</artifactId> + <version>${reflections.version}-RC2</version> + <executions> + <execution> + <goals> + <goal>reflections</goal> + </goals> + <phase>process-classes</phase> + </execution> + </executions> + </plugin> </plugins> </pluginManagement> </build> @@ -260,7 +274,11 @@ <artifactId>config</artifactId> <version>${typesafe.config.version}</version> </dependency> - + <dependency> + <groupId>org.reflections</groupId> + <artifactId>reflections</artifactId> + <version>${reflections.version}</version> + </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> http://git-wip-us.apache.org/repos/asf/incubator-streams/blob/c44ebff7/streams-pojo/pom.xml ---------------------------------------------------------------------- diff --git a/streams-pojo/pom.xml b/streams-pojo/pom.xml index 2fc9a69..4cfff43 100644 --- a/streams-pojo/pom.xml +++ b/streams-pojo/pom.xml @@ -91,6 +91,13 @@ <artifactId>guava</artifactId> </dependency> + <dependency> + <groupId>org.reflections</groupId> + <artifactId>reflections</artifactId> + <version>${reflections.version}</version> + </dependency> + + </dependencies> <build> @@ -138,6 +145,18 @@ </executions> </plugin> <plugin> + <groupId>org.reflections</groupId> + <artifactId>reflections-maven</artifactId> + <executions> + <execution> + <goals> + <goal>reflections</goal> + </goals> + <phase>process-classes</phase> + </execution> + </executions> + </plugin> + <plugin> <groupId>org.jsonschema2pojo</groupId> <artifactId>jsonschema2pojo-maven-plugin</artifactId> <configuration> http://git-wip-us.apache.org/repos/asf/incubator-streams/blob/c44ebff7/streams-pojo/src/main/java/org/apache/streams/data/util/ActivityUtil.java ---------------------------------------------------------------------- diff --git a/streams-pojo/src/main/java/org/apache/streams/data/util/ActivityUtil.java b/streams-pojo/src/main/java/org/apache/streams/data/util/ActivityUtil.java index 9d1e7b2..8c6774a 100644 --- a/streams-pojo/src/main/java/org/apache/streams/data/util/ActivityUtil.java +++ b/streams-pojo/src/main/java/org/apache/streams/data/util/ActivityUtil.java @@ -123,4 +123,11 @@ public class ActivityUtil { return String.format("id:%s:activities:%s", providerName, activityId); } + public static boolean isValid(Activity activity) { + return activity != null + && activity.getId() != null + && activity.getVerb() != null + && activity.getProvider() != null + && activity.getProvider().getId() != null; + } } http://git-wip-us.apache.org/repos/asf/incubator-streams/blob/c44ebff7/streams-pojo/src/main/java/org/apache/streams/jackson/StreamsDateTimeDeserializer.java ---------------------------------------------------------------------- diff --git a/streams-pojo/src/main/java/org/apache/streams/jackson/StreamsDateTimeDeserializer.java b/streams-pojo/src/main/java/org/apache/streams/jackson/StreamsDateTimeDeserializer.java index 8f53954..639c5ad 100644 --- a/streams-pojo/src/main/java/org/apache/streams/jackson/StreamsDateTimeDeserializer.java +++ b/streams-pojo/src/main/java/org/apache/streams/jackson/StreamsDateTimeDeserializer.java @@ -29,12 +29,15 @@ import org.joda.time.format.DateTimeFormatter; import java.io.IOException; import java.io.Serializable; -import java.util.ArrayList; import java.util.Iterator; import java.util.List; /** - * Created by sblackmon on 3/27/14. + * StreamsDateTimeDeserializer is a supporting class for + * @see {@link org.apache.streams.jackson.StreamsJacksonMapper} + * + * Converting date-time strings other than RFC3339 to joda DateTime objects requires + * additional formats to be provided when instantiating StreamsJacksonMapper. */ public class StreamsDateTimeDeserializer extends StdDeserializer<DateTime> implements Serializable { @@ -50,6 +53,9 @@ public class StreamsDateTimeDeserializer extends StdDeserializer<DateTime> imple formatters.add(DateTimeFormat.forPattern(format)); } + /** + * Applies each additional format in turn, until it can provide a non-null DateTime + */ @Override public DateTime deserialize(JsonParser jpar, DeserializationContext context) throws IOException { http://git-wip-us.apache.org/repos/asf/incubator-streams/blob/c44ebff7/streams-pojo/src/main/java/org/apache/streams/jackson/StreamsDateTimeFormat.java ---------------------------------------------------------------------- diff --git a/streams-pojo/src/main/java/org/apache/streams/jackson/StreamsDateTimeFormat.java b/streams-pojo/src/main/java/org/apache/streams/jackson/StreamsDateTimeFormat.java new file mode 100644 index 0000000..0c3fff6 --- /dev/null +++ b/streams-pojo/src/main/java/org/apache/streams/jackson/StreamsDateTimeFormat.java @@ -0,0 +1,12 @@ +package org.apache.streams.jackson; + +/** + * Supplies a custom date-time format to StreamsJacksonModule + * + * Implementations must have a no-argument constructor + */ +public interface StreamsDateTimeFormat { + + public String getFormat(); + +} http://git-wip-us.apache.org/repos/asf/incubator-streams/blob/c44ebff7/streams-pojo/src/main/java/org/apache/streams/jackson/StreamsDateTimeSerializer.java ---------------------------------------------------------------------- diff --git a/streams-pojo/src/main/java/org/apache/streams/jackson/StreamsDateTimeSerializer.java b/streams-pojo/src/main/java/org/apache/streams/jackson/StreamsDateTimeSerializer.java index 1e9c895..fff314d 100644 --- a/streams-pojo/src/main/java/org/apache/streams/jackson/StreamsDateTimeSerializer.java +++ b/streams-pojo/src/main/java/org/apache/streams/jackson/StreamsDateTimeSerializer.java @@ -28,12 +28,11 @@ import java.io.IOException; import java.io.Serializable; /** - * Created by sblackmon on 3/27/14. + * StreamsDateTimeSerializer is a supporting class for + * @see {@link org.apache.streams.jackson.StreamsJacksonMapper} */ public class StreamsDateTimeSerializer extends StdSerializer<DateTime> implements Serializable { - - protected StreamsDateTimeSerializer(Class<DateTime> dateTimeClass) { super(dateTimeClass); } http://git-wip-us.apache.org/repos/asf/incubator-streams/blob/c44ebff7/streams-pojo/src/main/java/org/apache/streams/jackson/StreamsJacksonMapper.java ---------------------------------------------------------------------- diff --git a/streams-pojo/src/main/java/org/apache/streams/jackson/StreamsJacksonMapper.java b/streams-pojo/src/main/java/org/apache/streams/jackson/StreamsJacksonMapper.java index 8a74caa..f5eace1 100644 --- a/streams-pojo/src/main/java/org/apache/streams/jackson/StreamsJacksonMapper.java +++ b/streams-pojo/src/main/java/org/apache/streams/jackson/StreamsJacksonMapper.java @@ -24,11 +24,16 @@ import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; +import com.google.common.collect.Lists; import java.util.List; /** - * Created by sblackmon on 3/27/14. + * StreamsJacksonMapper is the recommended interface to jackson for any streams component. + * + * Date-time formats that must be supported can be specified with constructor arguments. + * + * If no Date-time formats are specified, streams will use reflection to find formats. */ public class StreamsJacksonMapper extends ObjectMapper { @@ -38,6 +43,13 @@ public class StreamsJacksonMapper extends ObjectMapper { return INSTANCE; } + public static StreamsJacksonMapper getInstance(String format){ + + StreamsJacksonMapper instance = new StreamsJacksonMapper(Lists.newArrayList(format)); + + return instance; + + } public static StreamsJacksonMapper getInstance(List<String> formats){ StreamsJacksonMapper instance = new StreamsJacksonMapper(formats); @@ -52,6 +64,12 @@ public class StreamsJacksonMapper extends ObjectMapper { configure(); } + public StreamsJacksonMapper(String format) { + super(); + registerModule(new StreamsJacksonModule(Lists.newArrayList(format))); + configure(); + } + public StreamsJacksonMapper(List<String> formats) { super(); registerModule(new StreamsJacksonModule(formats)); http://git-wip-us.apache.org/repos/asf/incubator-streams/blob/c44ebff7/streams-pojo/src/main/java/org/apache/streams/jackson/StreamsJacksonModule.java ---------------------------------------------------------------------- diff --git a/streams-pojo/src/main/java/org/apache/streams/jackson/StreamsJacksonModule.java b/streams-pojo/src/main/java/org/apache/streams/jackson/StreamsJacksonModule.java index 8b44b0f..654a063 100644 --- a/streams-pojo/src/main/java/org/apache/streams/jackson/StreamsJacksonModule.java +++ b/streams-pojo/src/main/java/org/apache/streams/jackson/StreamsJacksonModule.java @@ -22,17 +22,44 @@ import com.fasterxml.jackson.databind.module.SimpleModule; import org.joda.time.DateTime; import org.joda.time.Period; +import org.reflections.Reflections; +import org.reflections.util.ClasspathHelper; +import org.reflections.util.ConfigurationBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; import java.util.List; +import java.util.Set; /** - * Created by sblackmon on 3/27/14. + * StreamsJacksonModule is a supporting class for + * @see {@link org.apache.streams.jackson.StreamsJacksonMapper} + * + * RFC3339 dates are supported by default. */ public class StreamsJacksonModule extends SimpleModule { + private final static Logger LOGGER = LoggerFactory.getLogger(StreamsJacksonModule.class); + public StreamsJacksonModule() { super(); + + Reflections reflections = new Reflections(new ConfigurationBuilder().setUrls(ClasspathHelper.forManifest())); + + Set<Class<? extends StreamsDateTimeFormat>> dateTimeFormatClasses = reflections.getSubTypesOf(StreamsDateTimeFormat.class); + + List<String> dateTimeFormats = new ArrayList<>(); + for (Class dateTimeFormatClass : dateTimeFormatClasses) { + try { + dateTimeFormats.add(((StreamsDateTimeFormat) (dateTimeFormatClass.newInstance())).getFormat()); + } catch (Exception e) { + LOGGER.warn("Exception getting format from " + dateTimeFormatClass); + } + } + addSerializer(DateTime.class, new StreamsDateTimeSerializer(DateTime.class)); - addDeserializer(DateTime.class, new StreamsDateTimeDeserializer(DateTime.class)); + addDeserializer(DateTime.class, new StreamsDateTimeDeserializer(DateTime.class, dateTimeFormats)); addSerializer(Period.class, new StreamsPeriodSerializer(Period.class)); addDeserializer(Period.class, new StreamsPeriodDeserializer(Period.class)); @@ -40,6 +67,7 @@ public class StreamsJacksonModule extends SimpleModule { public StreamsJacksonModule(List<String> formats) { super(); + addSerializer(DateTime.class, new StreamsDateTimeSerializer(DateTime.class)); addDeserializer(DateTime.class, new StreamsDateTimeDeserializer(DateTime.class, formats)); http://git-wip-us.apache.org/repos/asf/incubator-streams/blob/c44ebff7/streams-pojo/src/test/java/org/apache/streams/data/data/util/CustomDateTimeFormat.java ---------------------------------------------------------------------- diff --git a/streams-pojo/src/test/java/org/apache/streams/data/data/util/CustomDateTimeFormat.java b/streams-pojo/src/test/java/org/apache/streams/data/data/util/CustomDateTimeFormat.java new file mode 100644 index 0000000..a599248 --- /dev/null +++ b/streams-pojo/src/test/java/org/apache/streams/data/data/util/CustomDateTimeFormat.java @@ -0,0 +1,14 @@ +package org.apache.streams.data.data.util; + +import org.apache.streams.jackson.StreamsDateTimeFormat; + +/** + * Created by sblackmon on 12/1/14. + */ +public class CustomDateTimeFormat implements StreamsDateTimeFormat { + + @Override + public String getFormat() { + return "EEE MMM dd HH:mm:ss Z yyyy"; + } +} http://git-wip-us.apache.org/repos/asf/incubator-streams/blob/c44ebff7/streams-pojo/src/test/java/org/apache/streams/data/data/util/CustomDateTimeFormatTest.java ---------------------------------------------------------------------- diff --git a/streams-pojo/src/test/java/org/apache/streams/data/data/util/CustomDateTimeFormatTest.java b/streams-pojo/src/test/java/org/apache/streams/data/data/util/CustomDateTimeFormatTest.java new file mode 100644 index 0000000..922b28b --- /dev/null +++ b/streams-pojo/src/test/java/org/apache/streams/data/data/util/CustomDateTimeFormatTest.java @@ -0,0 +1,60 @@ +package org.apache.streams.data.data.util; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.apache.streams.jackson.StreamsJacksonMapper; +import org.apache.streams.pojo.json.Activity; +import org.joda.time.DateTime; +import org.junit.Assert; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * Created by sblackmon on 12/1/14. + */ +public class CustomDateTimeFormatTest { + + @Test + public void testCustomDateTimeFormatExplicit() { + String format = "EEE MMM dd HH:mm:ss Z yyyy"; + String input = "Tue Jan 17 21:21:46 Z 2012"; + Long outputMillis = 1326835306000L; + ObjectMapper mapper = StreamsJacksonMapper.getInstance(format); + DateTime time; + try { + String json = "{\"published\":\"" + input + "\"}"; + Activity activity = mapper.readValue(json, Activity.class); + + //Writes out value as a String including quotes + Long result = activity.getPublished().getMillis(); + + assertEquals(result, outputMillis); + } catch (Exception e) { + e.printStackTrace(); + Assert.fail(); + } + } + + @Test + public void testCustomDateTimeFormatReflection() { + String input = "Tue Jan 17 21:21:46 Z 2012"; + Long outputMillis = 1326835306000L; + ObjectMapper mapper = StreamsJacksonMapper.getInstance(); + DateTime time; + try { + String json = "{\"published\":\"" + input + "\"}"; + Activity activity = mapper.readValue(json, Activity.class); + + //Writes out value as a String including quotes + Long result = activity.getPublished().getMillis(); + + assertEquals(result, outputMillis); + } catch (Exception e) { + e.printStackTrace(); + Assert.fail(); + } + } + + +}