Author: gk
Date: Fri Sep 30 11:15:54 2016
New Revision: 1762882
URL: http://svn.apache.org/viewvc?rev=1762882&view=rev
Log:
Add optional support for jayway/JsonPath, update versions fro gson, jackson,
fix gson collection
Added:
turbine/fulcrum/trunk/json/gson/src/java/org/apache/fulcrum/json/gson/DateTypeAdapter.java
(with props)
turbine/fulcrum/trunk/json/gson/src/test/org/apache/fulcrum/json/gson/JsonPathGSONServiceTest.java
(with props)
turbine/fulcrum/trunk/json/jackson2/src/test/org/apache/fulcrum/json/jackson/JsonPathJacksonTest.java
(with props)
Modified:
turbine/fulcrum/trunk/json/gson/pom.xml
turbine/fulcrum/trunk/json/gson/src/java/org/apache/fulcrum/json/gson/GSONBuilderService.java
turbine/fulcrum/trunk/json/gson/src/test/TestComponentConfig.xml
turbine/fulcrum/trunk/json/gson/src/test/org/apache/fulcrum/json/gson/DefaultServiceTest.java
turbine/fulcrum/trunk/json/gson/src/test/org/apache/fulcrum/json/gson/TypeAdapterForCollection.java
turbine/fulcrum/trunk/json/jackson2/pom.xml
turbine/fulcrum/trunk/json/jackson2/src/java/org/apache/fulcrum/json/jackson/Jackson2MapperService.java
turbine/fulcrum/trunk/json/jackson2/src/test/TestComponentConfig.xml
turbine/fulcrum/trunk/json/jackson2/src/test/org/apache/fulcrum/json/jackson/DefaultServiceTest.java
turbine/fulcrum/trunk/json/jackson2/src/test/org/apache/fulcrum/json/jackson/JacksonMapperTest.java
turbine/fulcrum/trunk/json/src/changes/changes.xml
Modified: turbine/fulcrum/trunk/json/gson/pom.xml
URL:
http://svn.apache.org/viewvc/turbine/fulcrum/trunk/json/gson/pom.xml?rev=1762882&r1=1762881&r2=1762882&view=diff
==============================================================================
--- turbine/fulcrum/trunk/json/gson/pom.xml (original)
+++ turbine/fulcrum/trunk/json/gson/pom.xml Fri Sep 30 11:15:54 2016
@@ -86,8 +86,28 @@
<artifactId>gson</artifactId>
<version>${gson.version}</version>
</dependency>
+ <dependency>
+ <groupId>com.jayway.jsonpath</groupId>
+ <artifactId>json-path</artifactId>
+ <version>2.2.0</version>
+ <optional>true</optional>
+ <!-- as we are using gson -->
+ <exclusions>
+ <exclusion>
+ <groupId>net.minidev</groupId>
+ <artifactId>json-smart</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-nop</artifactId>
+ <version>1.7.21</version>
+ <optional>true</optional>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<properties>
- <gson.version>2.3.1</gson.version>
+ <gson.version>2.6.1</gson.version>
</properties>
</project>
Added:
turbine/fulcrum/trunk/json/gson/src/java/org/apache/fulcrum/json/gson/DateTypeAdapter.java
URL:
http://svn.apache.org/viewvc/turbine/fulcrum/trunk/json/gson/src/java/org/apache/fulcrum/json/gson/DateTypeAdapter.java?rev=1762882&view=auto
==============================================================================
---
turbine/fulcrum/trunk/json/gson/src/java/org/apache/fulcrum/json/gson/DateTypeAdapter.java
(added)
+++
turbine/fulcrum/trunk/json/gson/src/java/org/apache/fulcrum/json/gson/DateTypeAdapter.java
Fri Sep 30 11:15:54 2016
@@ -0,0 +1,89 @@
+package org.apache.fulcrum.json.gson;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import java.io.IOException;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.util.Date;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonSyntaxException;
+import com.google.gson.TypeAdapter;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
+import com.google.gson.stream.JsonWriter;
+
+/**
+ * Adapter for Date. Although this class appears stateless, it is not.
+ * DateFormat captures its time zone and locale when it is created, which gives
+ * this class state. DateFormat isn't thread safe either, so this class has
+ * to synchronize its read and write methods.
+ */
+public final class DateTypeAdapter extends TypeAdapter<Date> {
+ public static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() {
+ @Override
+ @SuppressWarnings("unchecked") // we use a runtime check to make sure the
'T's equal
+ public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
+ return typeToken.getRawType() == Date.class ? (TypeAdapter<T>) new
DateTypeAdapter() : null;
+ }
+ };
+
+ // default
+ private DateFormat customDateFormat =
DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT);;
+
+ public void setCustomDateFormat(DateFormat df) {
+ this.customDateFormat = df;
+ }
+
+ public DateFormat getCustomDateFormat() {
+ return customDateFormat;
+ }
+
+
+ @Override public Date read(JsonReader in) throws IOException {
+ if (in.peek() == JsonToken.NULL) {
+ in.nextNull();
+ return null;
+ }
+ return deserializeToDate(in.nextString());
+ }
+
+ private synchronized Date deserializeToDate(String json) {
+ try {
+ return customDateFormat.parse(json);
+ } catch (ParseException e) {
+ throw new JsonSyntaxException(json, e);
+ }
+ }
+
+ @Override public synchronized void write(JsonWriter out, Date value) throws
IOException {
+ if (value == null) {
+ out.nullValue();
+ return;
+ }
+ String dateFormatAsString = customDateFormat.format(value);
+ out.value(dateFormatAsString);
+ }
+
+}
+
Propchange:
turbine/fulcrum/trunk/json/gson/src/java/org/apache/fulcrum/json/gson/DateTypeAdapter.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
turbine/fulcrum/trunk/json/gson/src/java/org/apache/fulcrum/json/gson/GSONBuilderService.java
URL:
http://svn.apache.org/viewvc/turbine/fulcrum/trunk/json/gson/src/java/org/apache/fulcrum/json/gson/GSONBuilderService.java?rev=1762882&r1=1762881&r2=1762882&view=diff
==============================================================================
---
turbine/fulcrum/trunk/json/gson/src/java/org/apache/fulcrum/json/gson/GSONBuilderService.java
(original)
+++
turbine/fulcrum/trunk/json/gson/src/java/org/apache/fulcrum/json/gson/GSONBuilderService.java
Fri Sep 30 11:15:54 2016
@@ -1,4 +1,4 @@
-package org.apache.fulcrum.json.gson;
+ package org.apache.fulcrum.json.gson;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -25,10 +25,12 @@ import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
+import java.util.EnumSet;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Hashtable;
-import java.util.Iterator;
+import java.util.Set;
+import java.util.concurrent.Callable;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.configuration.Configurable;
@@ -41,11 +43,12 @@ import com.google.gson.ExclusionStrategy
import com.google.gson.FieldAttributes;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonPrimitive;
-import com.google.gson.JsonSerializationContext;
-import com.google.gson.JsonSerializer;
import com.google.gson.reflect.TypeToken;
+import com.jayway.jsonpath.Option;
+import com.jayway.jsonpath.spi.json.GsonJsonProvider;
+import com.jayway.jsonpath.spi.json.JsonProvider;
+import com.jayway.jsonpath.spi.mapper.GsonMappingProvider;
+import com.jayway.jsonpath.spi.mapper.MappingProvider;
/**
*
@@ -63,6 +66,8 @@ public class GSONBuilderService extends
private static final String GLOBAL_ADAPTERS = "globalAdapters";
private static final String DATE_FORMAT = "dateFormat";
+
+ private static final String USEJSONPATH = "useJsonPath";
private String dateFormat;
@@ -70,6 +75,8 @@ public class GSONBuilderService extends
private Hashtable<String, String> adapters = null;
+ private boolean useJsonPath = false;
+
GsonBuilder gson;
@Override
@@ -198,21 +205,27 @@ public class GSONBuilderService extends
throw new Exception("Not implemented!");
}
- public JsonService registerTypeAdapter(JsonSerializer serdeser, Type type)
{
+ public JsonService registerTypeAdapter(Object serdeser, Type type) {
gson.registerTypeAdapter(type, serdeser);
return this;
}
+
+ /**
+ * Alternative method to calling {@link #gson#registerTypeAdapter(Object,
Type)}.
+ * Note: Always use either this direct format call or the other adapter
register call,
+ * otherwise inconsistencies may occur!
+ *
+ * @param dformat
+ */
+ public void setDateFormat(final String dfStr) {
+ gson.setDateFormat(dfStr);
+ }
@Override
public void setDateFormat(final DateFormat df) {
- JsonSerializer<Date> ser = new JsonSerializer<Date>() {
- @Override
- public JsonElement serialize(Date src, Type typeOfSrc,
- JsonSerializationContext context) {
- return src == null ? null : new JsonPrimitive(df.format(src));
- }
- };
- registerTypeAdapter(ser, Date.class);
+ DateTypeAdapter dateTypeAdapter = new DateTypeAdapter();
+ dateTypeAdapter.setCustomDateFormat(df);
+ gson.registerTypeAdapter(Date.class,dateTypeAdapter);
}
public void getJsonService() throws InstantiationException {
@@ -227,8 +240,10 @@ public class GSONBuilderService extends
getLogger().debug("conf.getName()" + conf.getName());
final Configuration configuredDateFormat = conf.getChild(DATE_FORMAT,
- true);
- this.dateFormat = configuredDateFormat.getValue(DEFAULTDATEFORMAT);
+ false);
+ if (configuredDateFormat != null) {
+ this.dateFormat = configuredDateFormat.getValue();//
DEFAULTDATEFORMAT);
+ }
final Configuration configuredAdapters = conf.getChild(GLOBAL_ADAPTERS,
true);
if (configuredAdapters != null) {
@@ -244,14 +259,22 @@ public class GSONBuilderService extends
}
}
// TODO provide configurable Type Adapters
+ final Configuration configuredjsonPath = conf.getChild(
+ USEJSONPATH, false);
+ if (configuredjsonPath != null) {
+ this.useJsonPath = configuredjsonPath.getValueAsBoolean();
+ }
}
@Override
public void initialize() throws Exception {
gson = new GsonBuilder();
getLogger().debug("initialized: gson:" + gson);
- getLogger().info("setting date format to:" + dateFormat);
- setDateFormat(new SimpleDateFormat(dateFormat));
+ if (dateFormat != null) {
+ getLogger().info("setting date format to: " + dateFormat);
+ setDateFormat(new SimpleDateFormat(dateFormat));
+ //setDateFormat(dateFormat);
+ }
if (adapters != null) {
Enumeration<String> enumKey = adapters.keys();
@@ -276,6 +299,37 @@ public class GSONBuilderService extends
}
}
}
+
+ if (useJsonPath) {
+ // set it before runtime
+ com.jayway.jsonpath.Configuration.setDefaults(new
com.jayway.jsonpath.Configuration.Defaults() {
+
+ private Callable<Gson> gsonFuture = new Callable<Gson>() {
+ @Override
+ public Gson call() {
+ return GSONBuilderService.this.gson.create();
+ }
+ };
+
+ private final JsonProvider jsonProvider = new
GsonJsonProvider(GSONBuilderService.this.gson.create());
+ private final MappingProvider mappingProvider = new
GsonMappingProvider(gsonFuture);
+
+ @Override
+ public JsonProvider jsonProvider() {
+ return jsonProvider;
+ }
+
+ @Override
+ public MappingProvider mappingProvider() {
+ return mappingProvider;
+ }
+
+ @Override
+ public Set<Option> options() {
+ return EnumSet.noneOf(Option.class);
+ }
+ });
+ }
}
/**
Modified: turbine/fulcrum/trunk/json/gson/src/test/TestComponentConfig.xml
URL:
http://svn.apache.org/viewvc/turbine/fulcrum/trunk/json/gson/src/test/TestComponentConfig.xml?rev=1762882&r1=1762881&r2=1762882&view=diff
==============================================================================
--- turbine/fulcrum/trunk/json/gson/src/test/TestComponentConfig.xml (original)
+++ turbine/fulcrum/trunk/json/gson/src/test/TestComponentConfig.xml Fri Sep 30
11:15:54 2016
@@ -24,5 +24,6 @@
<!-- adapter
forClass="java.util.ArrayList">org.apache.fulcrum.json.gson.TypeAdapterForCollection</adapter>
<adapter
forClass="org.apache.fulcrum.json.TestClass">org.apache.fulcrum.json.gson.TestJsonSerializer</adapter-->
</globalAdapters>
+ <useJsonPath>true</useJsonPath>
</json>
</componentConfig>
Modified:
turbine/fulcrum/trunk/json/gson/src/test/org/apache/fulcrum/json/gson/DefaultServiceTest.java
URL:
http://svn.apache.org/viewvc/turbine/fulcrum/trunk/json/gson/src/test/org/apache/fulcrum/json/gson/DefaultServiceTest.java?rev=1762882&r1=1762881&r2=1762882&view=diff
==============================================================================
---
turbine/fulcrum/trunk/json/gson/src/test/org/apache/fulcrum/json/gson/DefaultServiceTest.java
(original)
+++
turbine/fulcrum/trunk/json/gson/src/test/org/apache/fulcrum/json/gson/DefaultServiceTest.java
Fri Sep 30 11:15:54 2016
@@ -98,6 +98,16 @@ public class DefaultServiceTest extends
serJson);
}
@Test
+ public void testSerializeDefaultDate() throws Exception {
+ //MM:dd:yyyy
+ Map<String, Object> map = new HashMap<String, Object>();
+ map.put("date", Calendar.getInstance().getTime());
+ String serJson = sc.ser(map);
+ System.out.println("serJson:" + serJson);
+ assertTrue("Serialize with Adapater failed ",
+ serJson.matches("\\{\"date\":\"\\d\\d:\\d\\d:\\d{4}\"\\}"));
+ }
+ @Test
public void testSerializeDate() throws Exception {
final SimpleDateFormat MMddyyyy = new SimpleDateFormat("MM/dd/yyyy");
Map<String, Object> map = new HashMap<String, Object>();
@@ -148,7 +158,7 @@ public class DefaultServiceTest extends
String adapterSer = sc.ser(rectList);
assertEquals(
"collect ser",
-
"{'rect0':0,'rect1':1,'rect2':4,'rect3':9,'rect4':16,'rect5':25,'rect6':36,'rect7':49,'rect8':64,'rect9':81}",
+
"[{'rect0':0,'rect1':1,'rect2':4,'rect3':9,'rect4':16,'rect5':25,'rect6':36,'rect7':49,'rect8':64,'rect9':81}]",
adapterSer.replace('"', '\''));
}
@Test
Added:
turbine/fulcrum/trunk/json/gson/src/test/org/apache/fulcrum/json/gson/JsonPathGSONServiceTest.java
URL:
http://svn.apache.org/viewvc/turbine/fulcrum/trunk/json/gson/src/test/org/apache/fulcrum/json/gson/JsonPathGSONServiceTest.java?rev=1762882&view=auto
==============================================================================
---
turbine/fulcrum/trunk/json/gson/src/test/org/apache/fulcrum/json/gson/JsonPathGSONServiceTest.java
(added)
+++
turbine/fulcrum/trunk/json/gson/src/test/org/apache/fulcrum/json/gson/JsonPathGSONServiceTest.java
Fri Sep 30 11:15:54 2016
@@ -0,0 +1,149 @@
+package org.apache.fulcrum.json.gson;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.fulcrum.json.JsonService;
+import org.apache.fulcrum.json.Rectangle;
+import org.apache.fulcrum.json.TestClass;
+import org.apache.fulcrum.testcontainer.BaseUnit4Test;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.gson.JsonPrimitive;
+import com.jayway.jsonpath.JsonPath;
+import com.jayway.jsonpath.TypeRef;
+
+/**
+ * GSON JSON Test
+ *
+ * @author gk
+ * @version $Id$
+ */
+public class JsonPathGSONServiceTest extends BaseUnit4Test
+{
+ private JsonService sc = null;
+ private final String preDefinedOutput =
+
"{\"container\":{\"cf\":\"Config.xml\"},\"configurationName\":\"Config.xml\",\"name\":\"mytest\"}";
+
+ @Before
+ public void setUp() throws Exception
+ {
+ sc = (JsonService) this.lookup( JsonService.ROLE );
+ }
+ @Test
+ public void testSerialize() throws Exception
+ {
+ String serJson = sc.ser( new TestClass("mytest") );
+ String cf = ((JsonPrimitive)
JsonPath.parse(serJson).read("$.container.cf")).getAsString();// .using(conf)
+ assertEquals("Serialization failed ", "Config.xml", cf);
+ }
+
+ @Test
+ public void testDefaultGsonSerializeDate() throws Exception
+ {
+ // default calls with default DateTypeAdapter
+ Map<String,Object> map = new HashMap<String,Object>();
+ Calendar refDate = Calendar.getInstance();
+ map.put( "date", refDate.getTime() );
+
+ //sc.setDateFormat( MMddyyyy );
+ String serJson = sc.ser( map );
+ System.out.println("serJson:"+ serJson);
+ assertTrue("Serialize with Adapater failed ", serJson.matches(
"\\{\"date\":\"\\d\\d:\\d\\d:\\d{4}\"\\}" ));
+
+ Date date = JsonPath.parse(serJson).read("$.date", Date.class);//
.using(conf)
+ Calendar parsedDate = Calendar.getInstance();
+ parsedDate.setTime(date);
+ assertEquals("Serialization failed ", refDate.get(Calendar.DATE),
parsedDate.get(Calendar.DATE));
+ }
+
+ @Test
+ public void testGsonSerializeDate() throws Exception
+ {
+ final SimpleDateFormat MMddyyyy = new SimpleDateFormat( "MM/dd/yyyy");
+ Map<String,Object> map = new HashMap<String,Object>();
+ Calendar refDate = Calendar.getInstance();
+ map.put( "date", refDate.getTime() );
+ //((GSONBuilderService)sc).setDateFormat( "MM/dd/yyyy" );
+ sc.setDateFormat( MMddyyyy );
+ String serJson = sc.ser( map );
+ System.out.println("serJson:"+ serJson);
+ assertTrue("Serialize with Adapter failed ", serJson.matches(
"\\{\"date\":\"\\d\\d/\\d\\d/\\d{4}\"\\}" ));
+ Date date = JsonPath.parse(serJson).read("$.date", Date.class);//
.using(conf)
+ Calendar parsedDate = Calendar.getInstance();
+ parsedDate.setTime(date);
+ assertEquals("Serialization failed ", refDate.get(Calendar.DATE),
parsedDate.get(Calendar.DATE));
+ }
+
+ @Test
+ public void testCollection() throws Exception
+ {
+ List<Rectangle> rectList = new ArrayList<Rectangle>();
+ for ( int i = 0; i < 10; i++ )
+ {
+ Rectangle filteredRect = new Rectangle(i,i,"rect"+i);
+ rectList.add( filteredRect );
+ }
+ String result = sc.ser( rectList );
+ assertEquals("collect
ser","[{'w':0,'h':0,'name':'rect0'},{'w':1,'h':1,'name':'rect1'},{'w':2,'h':2,'name':'rect2'},{'w':3,'h':3,'name':'rect3'},{'w':4,'h':4,'name':'rect4'},{'w':5,'h':5,'name':'rect5'},{'w':6,'h':6,'name':'rect6'},{'w':7,'h':7,'name':'rect7'},{'w':8,'h':8,'name':'rect8'},{'w':9,'h':9,'name':'rect9'}]",
+ result.replace( '"', '\'' ) );
+ List<Map<String, Object>> beanList2 =
JsonPath.parse(result).read("$[-2:]", List.class);
+ assertEquals("Expect 2 Elements failed ", 2, beanList2.size());
+ }
+ @Test
+ public void testSerializeTypeAdapterForCollection() throws Exception
+ {
+ sc.addAdapter( "Collection Adapter", ArrayList.class ,
TypeAdapterForCollection.class );
+ List<Rectangle> rectList = new ArrayList<Rectangle>();
+ for ( int i = 0; i < 10; i++ )
+ {
+ Rectangle filteredRect = new Rectangle(i,i,"rect"+i);
+ rectList.add( filteredRect );
+ }
+ String serColl = sc.ser( rectList );
+ assertEquals("collect
ser","[{'rect0':0,'rect1':1,'rect2':4,'rect3':9,'rect4':16,'rect5':25,'rect6':36,'rect7':49,'rect8':64,'rect9':81}]",
+ serColl.replace( '"', '\'' ) );
+
+ System.out.println("serColl: "+ serColl);
+ TypeRef<List<Rectangle>> typeRef = new TypeRef<List<Rectangle>>() { };
+ List<Rectangle> result = JsonPath.parse(serColl).read("$",typeRef);
+ System.out.println("result: "+ result);
+ int idx = 0;
+ for (Rectangle rect : result) {
+ assertEquals("deser reread size failed", (idx * idx),
rect.getSize());
+ idx++;
+ }
+ }
+
+
+
+}
Propchange:
turbine/fulcrum/trunk/json/gson/src/test/org/apache/fulcrum/json/gson/JsonPathGSONServiceTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
turbine/fulcrum/trunk/json/gson/src/test/org/apache/fulcrum/json/gson/TypeAdapterForCollection.java
URL:
http://svn.apache.org/viewvc/turbine/fulcrum/trunk/json/gson/src/test/org/apache/fulcrum/json/gson/TypeAdapterForCollection.java?rev=1762882&r1=1762881&r2=1762882&view=diff
==============================================================================
---
turbine/fulcrum/trunk/json/gson/src/test/org/apache/fulcrum/json/gson/TypeAdapterForCollection.java
(original)
+++
turbine/fulcrum/trunk/json/gson/src/test/org/apache/fulcrum/json/gson/TypeAdapterForCollection.java
Fri Sep 30 11:15:54 2016
@@ -32,17 +32,20 @@ import com.google.gson.stream.JsonWriter
public class TypeAdapterForCollection extends TypeAdapter<List<Rectangle>> {
@Override
public void write(JsonWriter out, List<Rectangle> data) throws IOException
{
+ out.beginArray();
out.beginObject();
for (int i = 0; i < data.size(); i++) {
out.name(data.get(i).getName());
out.value(data.get(i).getSize());
}
out.endObject();
+ out.endArray();
}
@Override
public List<Rectangle> read(JsonReader in) throws IOException {
ArrayList<Rectangle> list = new ArrayList<Rectangle>();
+ in.beginArray();
in.beginObject();
while (in.hasNext()) {
String name = in.nextName();
@@ -52,6 +55,7 @@ public class TypeAdapterForCollection ex
list.add(new Rectangle(value, value, name));
}
in.endObject();
+ in.endArray();
return list;
}
Modified: turbine/fulcrum/trunk/json/jackson2/pom.xml
URL:
http://svn.apache.org/viewvc/turbine/fulcrum/trunk/json/jackson2/pom.xml?rev=1762882&r1=1762881&r2=1762882&view=diff
==============================================================================
--- turbine/fulcrum/trunk/json/jackson2/pom.xml (original)
+++ turbine/fulcrum/trunk/json/jackson2/pom.xml Fri Sep 30 11:15:54 2016
@@ -105,9 +105,29 @@
<version>2.6.6</version>
<optional>true</optional>
</dependency>
+ <dependency>
+ <groupId>com.jayway.jsonpath</groupId>
+ <artifactId>json-path</artifactId>
+ <version>2.2.0</version>
+ <optional>true</optional>
+ <!-- as we are using jackson -->
+ <exclusions>
+ <exclusion>
+ <groupId>net.minidev</groupId>
+ <artifactId>json-smart</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-nop</artifactId>
+ <version>1.7.21</version>
+ <optional>true</optional>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<properties>
<!-- 2.7.x hase Java 7 baseline, but copmiled with Java 6 support,
cft. https://github.com/FasterXML/jackson/wiki/Jackson-Release-2.7 -->
- <jackson2.version>2.7.3</jackson2.version>
+ <jackson2.version>2.7.7</jackson2.version>
</properties>
</project>
Modified:
turbine/fulcrum/trunk/json/jackson2/src/java/org/apache/fulcrum/json/jackson/Jackson2MapperService.java
URL:
http://svn.apache.org/viewvc/turbine/fulcrum/trunk/json/jackson2/src/java/org/apache/fulcrum/json/jackson/Jackson2MapperService.java?rev=1762882&r1=1762881&r2=1762882&view=diff
==============================================================================
---
turbine/fulcrum/trunk/json/jackson2/src/java/org/apache/fulcrum/json/jackson/Jackson2MapperService.java
(original)
+++
turbine/fulcrum/trunk/json/jackson2/src/java/org/apache/fulcrum/json/jackson/Jackson2MapperService.java
Fri Sep 30 11:15:54 2016
@@ -23,10 +23,12 @@ import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Collection;
+import java.util.EnumSet;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.configuration.Configurable;
@@ -63,6 +65,11 @@ import com.fasterxml.jackson.databind.se
import com.fasterxml.jackson.databind.ser.PropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
+import com.jayway.jsonpath.Option;
+import com.jayway.jsonpath.spi.json.JacksonJsonProvider;
+import com.jayway.jsonpath.spi.json.JsonProvider;
+import com.jayway.jsonpath.spi.mapper.JacksonMappingProvider;
+import com.jayway.jsonpath.spi.mapper.MappingProvider;
/**
*
@@ -89,6 +96,7 @@ public class Jackson2MapperService exten
private static final String DATE_FORMAT = "dateFormat";
private static final String ESCAPE_CHARS = "escapeCharsGlobal";
private static final String ESCAPE_CHAR_CLASS = "escapeCharsClass";
+ private static final String USEJSONPATH = "useJsonPath";
ObjectMapper mapper;
AnnotationIntrospector primary; // support default
AnnotationIntrospector secondary;
@@ -112,6 +120,7 @@ public class Jackson2MapperService exten
String[] defaultTypeDefs = null;
private CacheService cacheService;
private boolean escapeCharsGlobal = false; // to be backward compatible,
but should be true, then escaping to avoid XSS payload by default
+ private boolean useJsonPath = false;
private String escapeCharsClass = null;
@Override
@@ -502,6 +511,7 @@ public class Jackson2MapperService exten
final Configuration configuredAnnotationInspectors = conf.getChild(
ANNOTATIONINSPECTOR, false);
+
if (configuredAnnotationInspectors != null) {
Configuration[] nameVal = configuredAnnotationInspectors
.getChildren();
@@ -559,6 +569,11 @@ public class Jackson2MapperService exten
configuredDefaultType.getAttribute("type"),
configuredDefaultType.getAttribute("key") };
}
+ final Configuration configuredjsonPath = conf.getChild(
+ USEJSONPATH, false);
+ if (configuredjsonPath != null) {
+ this.useJsonPath = configuredjsonPath.getValueAsBoolean();
+ }
}
@Override
@@ -770,6 +785,30 @@ public class Jackson2MapperService exten
"setting cacheService logger: "
+ cacheService.getClass().getSimpleName());
}
+
+ if (useJsonPath) {
+ // set it before runtime
+ com.jayway.jsonpath.Configuration.setDefaults(new
com.jayway.jsonpath.Configuration.Defaults() {
+
+ private final JsonProvider jsonProvider = new
JacksonJsonProvider(Jackson2MapperService.this.mapper);
+ private final MappingProvider mappingProvider = new
JacksonMappingProvider(Jackson2MapperService.this.mapper);
+
+ @Override
+ public JsonProvider jsonProvider() {
+ return jsonProvider;
+ }
+
+ @Override
+ public MappingProvider mappingProvider() {
+ return mappingProvider;
+ }
+
+ @Override
+ public Set<Option> options() {
+ return EnumSet.noneOf(Option.class);
+ }
+ });
+ }
}
public ObjectMapper getMapper() {
Modified: turbine/fulcrum/trunk/json/jackson2/src/test/TestComponentConfig.xml
URL:
http://svn.apache.org/viewvc/turbine/fulcrum/trunk/json/jackson2/src/test/TestComponentConfig.xml?rev=1762882&r1=1762881&r2=1762882&view=diff
==============================================================================
--- turbine/fulcrum/trunk/json/jackson2/src/test/TestComponentConfig.xml
(original)
+++ turbine/fulcrum/trunk/json/jackson2/src/test/TestComponentConfig.xml Fri
Sep 30 11:15:54 2016
@@ -20,7 +20,7 @@
<componentConfig>
<json>
- <annotationInspectors>
+ <annotationInspectors>
<primary>org.apache.fulcrum.json.jackson.SimpleNameIntrospector</primary>
<secondary>com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector</secondary>
<features>
@@ -30,14 +30,14 @@
<feature value="false"
type="com.fasterxml.jackson.databind.DeserializationFeature">FAIL_ON_UNKNOWN_PROPERTIES</feature>
<feature value="false"
type="com.fasterxml.jackson.databind.MapperFeature">ALLOW_FINAL_FIELDS_AS_MUTATORS</feature>
<feature value="true"
type="com.fasterxml.jackson.core.JsonParser">ALLOW_UNQUOTED_FIELD_NAMES</feature>
-
<!-- feature
value="true">com.fasterxml.jackson.databind.SerializationFeature.INDENT_OUTPUT</feature-->
</features>
- </annotationInspectors>
- <dateFormat>MM/dd/yyyy</dateFormat>
- <escapeCharsGlobal>true</escapeCharsGlobal>
- <!-- defaultTyping type="NON_FINAL" key="type"/--><!-- or
OBJECT_AND_NON_CONCRETE -->
- <!-- cacheFilters>false</cacheFilters-->
- <!-- escapeCharsClass>net.example.EscapeCharClass</escapeCharsClass -->
+ </annotationInspectors>
+ <dateFormat>MM/dd/yyyy</dateFormat>
+ <escapeCharsGlobal>true</escapeCharsGlobal>
+ <!-- defaultTyping type="NON_FINAL" key="type"/--><!-- or
OBJECT_AND_NON_CONCRETE -->
+ <!-- cacheFilters>false</cacheFilters-->
+ <!-- escapeCharsClass>net.example.EscapeCharClass</escapeCharsClass
-->
+ <useJsonPath>true</useJsonPath>
</json>
</componentConfig>
Modified:
turbine/fulcrum/trunk/json/jackson2/src/test/org/apache/fulcrum/json/jackson/DefaultServiceTest.java
URL:
http://svn.apache.org/viewvc/turbine/fulcrum/trunk/json/jackson2/src/test/org/apache/fulcrum/json/jackson/DefaultServiceTest.java?rev=1762882&r1=1762881&r2=1762882&view=diff
==============================================================================
---
turbine/fulcrum/trunk/json/jackson2/src/test/org/apache/fulcrum/json/jackson/DefaultServiceTest.java
(original)
+++
turbine/fulcrum/trunk/json/jackson2/src/test/org/apache/fulcrum/json/jackson/DefaultServiceTest.java
Fri Sep 30 11:15:54 2016
@@ -552,6 +552,14 @@ public class DefaultServiceTest extends
//((Jackson2MapperService)sc).getMapper().getFactory().setCharacterEscapes(esc
) );
}
+ /**
+ * checks if string serJson is deserializable to class target with adapter
mixin and returns result.
+ * @param serJson JSON String to be tested
+ * @param target class to be expected
+ * @param mixin adapter set
+ * @return the resulting instance
+ * @throws Exception
+ */
private <T> T checkDeserialization(String serJson, Class<T> target, Class
mixin) throws Exception {
sc.addAdapter("Mixin Adapter", target, mixin);
T result = sc.deSer(serJson,target);
Modified:
turbine/fulcrum/trunk/json/jackson2/src/test/org/apache/fulcrum/json/jackson/JacksonMapperTest.java
URL:
http://svn.apache.org/viewvc/turbine/fulcrum/trunk/json/jackson2/src/test/org/apache/fulcrum/json/jackson/JacksonMapperTest.java?rev=1762882&r1=1762881&r2=1762882&view=diff
==============================================================================
---
turbine/fulcrum/trunk/json/jackson2/src/test/org/apache/fulcrum/json/jackson/JacksonMapperTest.java
(original)
+++
turbine/fulcrum/trunk/json/jackson2/src/test/org/apache/fulcrum/json/jackson/JacksonMapperTest.java
Fri Sep 30 11:15:54 2016
@@ -45,7 +45,6 @@ import org.junit.Test;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsonorg.JsonOrgModule;
/**
@@ -360,31 +359,6 @@ public class JacksonMapperTest extends B
}
}
- // @JsonFilter("myFilter")
- static class Bean {
- private String name;
- private int age;
- public String profession;
-
- public Bean() {
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public int getAge() {
- return age;
- }
-
- public void setAge(int age) {
- this.age = age;
- }
- }
public static abstract class Mixin2 {
void MixIn2(int w, int h) {
Added:
turbine/fulcrum/trunk/json/jackson2/src/test/org/apache/fulcrum/json/jackson/JsonPathJacksonTest.java
URL:
http://svn.apache.org/viewvc/turbine/fulcrum/trunk/json/jackson2/src/test/org/apache/fulcrum/json/jackson/JsonPathJacksonTest.java?rev=1762882&view=auto
==============================================================================
---
turbine/fulcrum/trunk/json/jackson2/src/test/org/apache/fulcrum/json/jackson/JsonPathJacksonTest.java
(added)
+++
turbine/fulcrum/trunk/json/jackson2/src/test/org/apache/fulcrum/json/jackson/JsonPathJacksonTest.java
Fri Sep 30 11:15:54 2016
@@ -0,0 +1,193 @@
+package org.apache.fulcrum.json.jackson;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import static org.junit.Assert.*;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.avalon.framework.logger.ConsoleLogger;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.fulcrum.json.JsonService;
+import org.apache.fulcrum.json.Rectangle;
+import org.apache.fulcrum.json.TestClass;
+import org.apache.fulcrum.testcontainer.BaseUnit4Test;
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.fasterxml.jackson.datatype.jsonorg.JsonOrgModule;
+import com.jayway.jsonpath.Configuration;
+import com.jayway.jsonpath.JsonPath;
+import com.jayway.jsonpath.TypeRef;
+import com.jayway.jsonpath.spi.json.JacksonJsonProvider;
+
+/**
+ * Jackson2 JSON Test
+ *
+ * Test without type setting
+ *
+ * @author gk
+ * @version $Id: JacksonMapperTest.java 1738815 2016-04-12 15:22:39Z gk $
+ */
+public class JsonPathJacksonTest extends BaseUnit4Test {
+
+ private JsonService sc = null;
+ Logger logger;
+
+ @Before
+ public void setUp() throws Exception {
+ sc = (JsonService) this.lookup(JsonService.ROLE);
+ logger = new ConsoleLogger(ConsoleLogger.LEVEL_DEBUG);
+ try {
+ Configuration conf = Configuration.defaultConfiguration();
+ System.out.println("jayway jsonpath conf:"+ conf.jsonProvider());
+ assertEquals("Jackson JsonPath JsonProvider match failed ",
JacksonJsonProvider.class.getName(), conf.jsonProvider().getClass().getName());
+ System.out.println("Jackson2MapperService.mapper:"+
((Jackson2MapperService)sc).getMapper() + " confjsonProvider:" +
conf.jsonProvider());
+ assertTrue("JsonProvider is not a JacksonJsonProvider ",
conf.jsonProvider() instanceof JacksonJsonProvider);
+ assertEquals("JacksonJsonProvider mapper is not configured
mapper", ((Jackson2MapperService)sc).getMapper(),
((JacksonJsonProvider)conf.jsonProvider()).getObjectMapper());
+ } catch (Throwable e) {
+ if (e.getCause() != null && e.getCause() instanceof
ClassNotFoundException) {
+ System.out.println(e.getCause());
+ fail("Check correct initialization with useJsonPath = true):");
+ } else {
+ fail(e.getMessage());
+ }
+ }
+
+ }
+
+ @Test
+ public void testSerialize() throws Exception {
+ String serJson = sc.ser(new TestClass("mytest"));
+ System.out.println("serJson:"+ serJson);
+ String cf = JsonPath.parse(serJson).read("$.container.cf");//
.using(conf)
+ assertEquals("Serialization failed ", "Config.xml", cf);
+ }
+
+ @Test
+ public void testSerializeDateWithDefaultDateFormat() throws Exception {
+ Map<String, Date> map = new HashMap<String, Date>();
+ Calendar refDate = Calendar.getInstance();
+ map.put("date", refDate.getTime());
+ String serJson = sc.ser(map);
+ //System.out.println("serJson date: "+ serJson);
+ Date date = JsonPath.parse(serJson).read("$.date", Date.class);//
.using(conf)
+ Calendar parsedDate = Calendar.getInstance();
+ parsedDate.setTime(date);
+ assertEquals("Serialization failed ", refDate.get(Calendar.DATE),
parsedDate.get(Calendar.DATE));
+ }
+
+ @Test
+ public void testDeserializationCollectionWithFilter() throws Exception {
+
+ List<Bean> beanList = new ArrayList<Bean>();
+ for (int i = 0; i < 10; i++) {
+ Bean filteredBean = new Bean();
+ filteredBean.setName("joe" + i);
+ filteredBean.setAge(i);
+ beanList.add(filteredBean);
+ }
+ String result = sc.serializeOnlyFilter(beanList, Bean.class, "name",
"age");
+ //System.out.println("bean list: "+ result);
+
+ Bean joe2 = JsonPath.parse(result).read("$[2]", Bean.class);
+ assertEquals("DeSer failed ", "joe2", joe2.getName());
+ // could not map to typed list
+ List<Map<String, Object>> beanList2 =
JsonPath.parse(result).read("$[-2:]", List.class);
+ assertEquals("Expect 2 Elements failed ", 2, beanList2.size());
+ //System.out.println("bean list result: "+ beanList2);
+ assertEquals("DeSer failed ", "joe9", beanList2.get(1).get("name"));
+ }
+
+ @Test
+ public void testSerializeExcludeField() throws Exception {
+ // could not use as TestClass constructor generates configurationName
again
+ //String serJson = sc.serializeAllExceptFilter(new
TestClass("mytest"), "configurationName");
+ String serJson = sc.serializeAllExceptFilter(new TestClass("mytest"),
"name");
+ System.out.println("serJson: "+ serJson);
+ TypeRef<TestClass> typeRef = new TypeRef<TestClass>() { };
+ // could not use as TestClass constructor generates configurationName
again
+ TestClass result = JsonPath.parse(serJson).read("$",typeRef); //
TestClass.class
+ assertTrue(result.getName() == null);// !
+ }
+
+
+ @Test
+ public void testDeserializationCollection() throws Exception {
+ List<Rectangle> rectList = new ArrayList<Rectangle>();
+ for (int i = 0; i < 10; i++) {
+ Rectangle filteredRect = new Rectangle(i, i, "rect" + i);
+ rectList.add(filteredRect);
+ }
+ String serColl = sc.ser(rectList);
+ System.out.println("serColl: "+ serColl);
+ TypeRef<List<Rectangle>> typeRef = new TypeRef<List<Rectangle>>() { };
+ List<Rectangle> result = JsonPath.parse(serColl).read("$",typeRef);
+ //System.out.println("result: "+ result);
+ int idx = 0;
+ for (Rectangle rect : result) {
+ assertEquals("deser reread size failed", (idx * idx),
rect.getSize());
+ idx++;
+ }
+ }
+
+ @Test
+ public void testDeSerToORGJSONCollectionObject() throws Exception {
+ // test array
+ List<Bean> beanResults = new ArrayList<Bean> ( );
+ Bean tu = new Bean();
+ tu.setName("jim jar");
+ beanResults.add(tu);
+ Bean tu2 = new Bean();
+ tu2.setName("jim2 jar2");
+ tu2.setAge(45);
+ beanResults.add(tu2);
+
+ String[] filterAttr = {"age","name" };
+ String filteredSerList = sc.serializeOnlyFilter(beanResults,
Bean.class, filterAttr);
+ logger.debug("serList: "+ filteredSerList);
+
+ sc.addAdapter(null, null,new JsonOrgModule());
+
+ TypeRef<JSONArray> typeRef = new TypeRef<JSONArray>() { };
+ JSONArray jsonOrgResult =
JsonPath.parse(filteredSerList).read("$",typeRef);
+
+ logger.debug("jsonOrgResult: "+ jsonOrgResult.toString(2));
+ assertEquals("DeSer failed ", "jim jar",
((JSONObject)(jsonOrgResult.get(0))).get("name") );
+ assertEquals("DeSer failed ", 45,
((JSONObject)(jsonOrgResult.get(1))).get("age") );
+ }
+
+ @Test
+ public void testDeSerUnQuotedObject() throws Exception {
+ String jsonString = "{name:\"joe\"}";
+ TypeRef<Bean> typeRef = new TypeRef<Bean>() { };
+ Bean result = JsonPath.parse(jsonString).read("$",typeRef);
+ assertTrue("expected bean object!", result instanceof Bean);
+ }
+
+}
Propchange:
turbine/fulcrum/trunk/json/jackson2/src/test/org/apache/fulcrum/json/jackson/JsonPathJacksonTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: turbine/fulcrum/trunk/json/src/changes/changes.xml
URL:
http://svn.apache.org/viewvc/turbine/fulcrum/trunk/json/src/changes/changes.xml?rev=1762882&r1=1762881&r2=1762882&view=diff
==============================================================================
--- turbine/fulcrum/trunk/json/src/changes/changes.xml (original)
+++ turbine/fulcrum/trunk/json/src/changes/changes.xml Fri Sep 30 11:15:54 2016
@@ -25,6 +25,12 @@
<body>
<release version="1.1.1" date="in SVN">
+ <action type="update" dev="gk">
+ Gson: Update to version 2.6.1, add support for JsonPath, Bugfix in
date formatting and array serial/deserial test
+ </action>
+ <action type="update" dev="gk">
+ Jackson 2: Update to version 2.7.7, add support for JsonPath
+ </action>
</release>
<release version="1.1.0" date="2015-06-22">
<action type="update" dev="gk">