From e4660cb019a85229d47a043581be126f03dfd0f1 Mon Sep 17 00:00:00 2001 From: rfeng Date: Mon, 10 Sep 2012 18:11:53 +0000 Subject: Start to add the ability to allow partial json serialization git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1383017 13f79535-47bb-0310-9956-ffa450edef68 --- .../modules/databinding-json/META-INF/MANIFEST.MF | 1 + .../json/jackson/JSON2OutputStream.java | 17 +++++++++-- .../databinding/json/jackson/JacksonHelper.java | 35 ++++++++++++++++++++-- .../sca/databinding/json/jackson/Object2JSON.java | 9 +++++- .../json/jackson/Object2JSONTestCase.java | 29 ++++++++++++++++++ 5 files changed, 85 insertions(+), 6 deletions(-) diff --git a/sca-java-2.x/trunk/modules/databinding-json/META-INF/MANIFEST.MF b/sca-java-2.x/trunk/modules/databinding-json/META-INF/MANIFEST.MF index 806252650a..e55bc5ccfe 100644 --- a/sca-java-2.x/trunk/modules/databinding-json/META-INF/MANIFEST.MF +++ b/sca-java-2.x/trunk/modules/databinding-json/META-INF/MANIFEST.MF @@ -27,6 +27,7 @@ Import-Package: javax.xml.namespace, org.codehaus.jackson.map.introspect, org.codehaus.jackson.map.module, org.codehaus.jackson.map.ser, + org.codehaus.jackson.map.ser.impl, org.codehaus.jackson.map.type, org.codehaus.jackson.map.util, org.codehaus.jackson.type, diff --git a/sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/JSON2OutputStream.java b/sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/JSON2OutputStream.java index 1151d59570..baa514ae4d 100644 --- a/sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/JSON2OutputStream.java +++ b/sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/JSON2OutputStream.java @@ -22,6 +22,8 @@ package org.apache.tuscany.sca.databinding.json.jackson; import java.io.InputStream; import java.io.IOException; import java.io.OutputStream; +import java.util.List; +import java.util.Set; import org.apache.tuscany.sca.databinding.PushTransformer; import org.apache.tuscany.sca.databinding.TransformationContext; @@ -30,6 +32,9 @@ import org.apache.tuscany.sca.databinding.json.JSONDataBinding; import org.codehaus.jackson.JsonNode; import org.codehaus.jackson.JsonParser; import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.map.ser.FilterProvider; +import org.codehaus.jackson.map.ser.impl.SimpleBeanPropertyFilter; +import org.codehaus.jackson.map.ser.impl.SimpleFilterProvider; import org.json.JSONArray; import org.json.JSONObject; @@ -50,16 +55,17 @@ public class JSON2OutputStream implements PushTransformer if (source == null) { return; } + if (source instanceof InputStream) { try { - InputStream input = (InputStream) source; + InputStream input = (InputStream)source; byte[] buffer = new byte[4096]; int n = 0; while (-1 != (n = input.read(buffer))) { sink.write(buffer, 0, n); } input.close(); - } catch(IOException e) { + } catch (IOException e) { throw new TransformationException(e); } } else if (source instanceof JsonNode) { @@ -79,7 +85,12 @@ public class JSON2OutputStream implements PushTransformer } else { ObjectMapper mapper = JacksonHelper.createObjectMapper(source.getClass()); try { - mapper.writeValue(sink, source); + FilterProvider filterProvider = JacksonHelper.configureFilterProvider(context); + if (filterProvider != null) { + mapper.writer(filterProvider).writeValue(sink, source); + } else { + mapper.writeValue(sink, source); + } } catch (Throwable e) { throw new TransformationException(e); } diff --git a/sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/JacksonHelper.java b/sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/JacksonHelper.java index 049907786c..6d198f71e5 100644 --- a/sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/JacksonHelper.java +++ b/sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/JacksonHelper.java @@ -24,11 +24,13 @@ import java.io.InputStream; import java.io.OutputStream; import java.io.Reader; import java.io.StringWriter; +import java.util.Set; import javax.xml.bind.annotation.adapters.XmlAdapter; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters; +import org.apache.tuscany.sca.databinding.TransformationContext; import org.codehaus.jackson.JsonEncoding; import org.codehaus.jackson.JsonFactory; import org.codehaus.jackson.JsonGenerator; @@ -41,9 +43,13 @@ import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.map.annotate.JsonSerialize; import org.codehaus.jackson.map.deser.BeanDeserializerFactory; import org.codehaus.jackson.map.deser.StdDeserializerProvider; +import org.codehaus.jackson.map.introspect.AnnotatedClass; import org.codehaus.jackson.map.introspect.JacksonAnnotationIntrospector; import org.codehaus.jackson.map.module.SimpleDeserializers; import org.codehaus.jackson.map.ser.CustomSerializerFactory; +import org.codehaus.jackson.map.ser.FilterProvider; +import org.codehaus.jackson.map.ser.impl.SimpleBeanPropertyFilter; +import org.codehaus.jackson.map.ser.impl.SimpleFilterProvider; import org.codehaus.jackson.map.util.StdDateFormat; import org.codehaus.jackson.xc.JaxbAnnotationIntrospector; import org.codehaus.jackson.xc.XmlAdapterJsonDeserializer; @@ -100,7 +106,7 @@ public class JacksonHelper { } } } - if ( cls != null && mapper == null ) { + if (cls != null && mapper == null) { return MAPPER; } if (mapper == null) { @@ -108,7 +114,15 @@ public class JacksonHelper { mapper.registerModule(new JsonOrgModule()); } // Let's honor the Jackson annotations first - AnnotationIntrospector primary = new JacksonAnnotationIntrospector(); + AnnotationIntrospector primary = new JacksonAnnotationIntrospector() { + + @Override + public Object findFilterId(AnnotatedClass annotatedClass) { + Object filterId = super.findFilterId(annotatedClass); + return filterId == null ? "tuscanyFilter" : filterId; + } + + }; AnnotationIntrospector secondary = new JaxbAnnotationIntrospector(); AnnotationIntrospector pair = new AnnotationIntrospector.Pair(primary, secondary); mapper.setDeserializationConfig(mapper.getDeserializationConfig().withAnnotationIntrospector(pair) @@ -117,6 +131,7 @@ public class JacksonHelper { mapper.setSerializationConfig(mapper.getSerializationConfig().withAnnotationIntrospector(pair) .withSerializationInclusion(JsonSerialize.Inclusion.NON_NULL) .withDateFormat(StdDateFormat.getBlueprintISO8601Format())); + return mapper; } @@ -230,4 +245,20 @@ public class JacksonHelper { } } + private final static SimpleBeanPropertyFilter DEFAULT_FILTER = SimpleBeanPropertyFilter.serializeAllExcept(); + + public static FilterProvider configureFilterProvider(TransformationContext context) { + SimpleBeanPropertyFilter filter = DEFAULT_FILTER; + if (context != null) { + Set included = (Set)context.getMetadata().get("includedFields"); + Set excluded = (Set)context.getMetadata().get("excludedFields"); + if (included != null && !included.isEmpty()) { + filter = SimpleBeanPropertyFilter.filterOutAllExcept(included); + } else if (excluded != null && !excluded.isEmpty()) { + filter = SimpleBeanPropertyFilter.serializeAllExcept(excluded); + } + } + FilterProvider filters = new SimpleFilterProvider().addFilter("tuscanyFilter", filter); + return filters; + } } diff --git a/sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/Object2JSON.java b/sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/Object2JSON.java index 2b77054934..fc0753e3d3 100644 --- a/sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/Object2JSON.java +++ b/sca-java-2.x/trunk/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/Object2JSON.java @@ -30,6 +30,7 @@ import org.apache.tuscany.sca.databinding.json.JSONHelper; import org.codehaus.jackson.JsonNode; import org.codehaus.jackson.JsonParser; import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.map.ser.FilterProvider; /** * @version $Rev$ $Date$ @@ -57,7 +58,13 @@ public class Object2JSON implements PullTransformer { return source; } ObjectMapper mapper = JacksonHelper.createObjectMapper(targetType); - String value = mapper.writeValueAsString(source); + String value = null; + FilterProvider filterProvider = JacksonHelper.configureFilterProvider(context); + if (filterProvider != null) { + value = mapper.writer(filterProvider).writeValueAsString(source); + } else { + value = mapper.writeValueAsString(source); + } if (JsonNode.class.isAssignableFrom(targetType)) { return JacksonHelper.createJsonParser(value).readValueAsTree(); } else if (targetType == String.class || targetType == Object.class || targetType.isPrimitive()) { diff --git a/sca-java-2.x/trunk/modules/databinding-json/src/test/java/org/apache/tuscany/sca/databinding/json/jackson/Object2JSONTestCase.java b/sca-java-2.x/trunk/modules/databinding-json/src/test/java/org/apache/tuscany/sca/databinding/json/jackson/Object2JSONTestCase.java index 4476f4cf53..6e1312d40a 100644 --- a/sca-java-2.x/trunk/modules/databinding-json/src/test/java/org/apache/tuscany/sca/databinding/json/jackson/Object2JSONTestCase.java +++ b/sca-java-2.x/trunk/modules/databinding-json/src/test/java/org/apache/tuscany/sca/databinding/json/jackson/Object2JSONTestCase.java @@ -21,6 +21,7 @@ package org.apache.tuscany.sca.databinding.json.jackson; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.Date; import java.util.List; @@ -251,6 +252,34 @@ public class Object2JSONTestCase { Assert.assertEquals(v, me); } + @Test + public void testBean2JSONWithFilter() throws Exception { + MyBean me = new MyBean(); + me.setAge(30); + me.setBooks(new ArrayList()); + me.setFriends(new String[] {"John", "Mike"}); + me.setVip(true); + me.setName("Me"); + me.setDate(new Date()); + YourBean you = new YourBean(); + you.setId(123); + you.setName(null); + me.setYou(you); + Object2JSON t1 = new Object2JSON(); + TransformationContext context = new TransformationContextImpl(); + context.getMetadata().put("includedFields", Collections.singleton("name")); + Object result = t1.transform(me, context); + System.out.println(result); + Assert.assertTrue(result.toString().contains("name")); + Assert.assertFalse(result.toString().contains("age")); + context = new TransformationContextImpl(); + context.getMetadata().put("excludedFields", Collections.singleton("name")); + result = t1.transform(me, context); + System.out.println(result); + Assert.assertFalse(result.toString().contains("name")); + Assert.assertTrue(result.toString().contains("age")); + } + @Test public void testString2JSON() throws Exception { Object2JSON t1 = new Object2JSON(); -- cgit v1.2.3