Permalink
Browse files

Enhance the partial read support so that we can use the full property…

… names in the object tree

git-svn-id: https://svn.apache.org/repos/asf/tuscany/sca-java-2.x/trunk@1384975 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information...
1 parent bfa7cb3 commit 889290c54cfae0888be49a71def31476c591d897 @raymondfeng raymondfeng committed Sep 14, 2012
@@ -49,6 +49,10 @@
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML, MediaType.WILDCARD})
public class DataBindingJAXRSWriter<T> extends DataBindingJAXRSProvider implements MessageBodyWriter<T> {
+ public static final String FIELDS = "fields";
+ public static final String EXCLUDED_FIELDS = "excludedFields";
+ public static final String INCLUDED_FIELDS = "includedFields";
+
public DataBindingJAXRSWriter(ExtensionPointRegistry registry) {
super(registry);
}
@@ -99,15 +103,28 @@ public void writeTo(T t,
HTTPContext context = ThreadHTTPContext.getHTTPContext();
if (context != null) {
metadata = new HashMap<String, Object>();
- String included = context.getHttpRequest().getParameter("includedFields");
- String excluded = context.getHttpRequest().getParameter("excludedFields");
+ String included = context.getHttpRequest().getParameter(INCLUDED_FIELDS);
+ String excluded = context.getHttpRequest().getParameter(EXCLUDED_FIELDS);
Set<String> includedFields = tokenize(included);
if (includedFields != null) {
- metadata.put("includedFields", includedFields);
+ metadata.put(INCLUDED_FIELDS, includedFields);
}
Set<String> excludedFields = tokenize(excluded);
if (excludedFields != null) {
- metadata.put("excludedFields", excludedFields);
+ metadata.put(EXCLUDED_FIELDS, excludedFields);
+ }
+
+ // The syntax is fields=f1,f2,-f3
+ String fields = (String)context.getHttpRequest().getParameter(FIELDS);
+ if (fields != null) {
+ Set<String> fieldSet = tokenize(fields);
+ for (String f : fieldSet) {
+ if (f.startsWith("-")) {
+ excludedFields.add(f.substring(1));
+ } else {
+ includedFields.add(f);
+ }
+ }
}
}
@@ -25,7 +25,9 @@
import java.io.Reader;
import java.io.StringWriter;
import java.util.Collections;
+import java.util.HashSet;
import java.util.Set;
+import java.util.Stack;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@@ -62,10 +64,17 @@
import com.fasterxml.jackson.module.jsonorg.JsonOrgModule;
/**
- *
+ * Helper class for Jackson
*/
public class JacksonHelper {
+ public static final String TUSCANY_FILTER = "tuscanyFilter";
+ public static final String EXCLUDED_FIELDS = "excludedFields";
+ public static final String INCLUDED_FIELDS = "includedFields";
private final static SimpleBeanPropertyFilter DEFAULT_FILTER = SimpleBeanPropertyFilter.serializeAllExcept();
+
+ /**
+ * The default instance of Jackson ObjectMapper
+ */
public final static ObjectMapper MAPPER = createMapper();
private final static JsonFactory FACTORY = new MappingJsonFactory(createMapper());
@@ -123,7 +132,7 @@ public static ObjectMapper createObjectMapper(Class<?> cls) {
@Override
public Object findFilterId(AnnotatedClass annotatedClass) {
Object filterId = super.findFilterId(annotatedClass);
- return filterId == null ? "tuscanyFilter" : filterId;
+ return filterId == null ? TUSCANY_FILTER : filterId;
}
};
@@ -136,7 +145,7 @@ public Object findFilterId(AnnotatedClass annotatedClass) {
.withSerializationInclusion(JsonSerialize.Inclusion.NON_NULL)
.withDateFormat(StdDateFormat.getBlueprintISO8601Format()));
- mapper.setFilters(new SimpleFilterProvider().addFilter("tuscanyFilter", DEFAULT_FILTER));
+ mapper.setFilters(new SimpleFilterProvider().addFilter(TUSCANY_FILTER, DEFAULT_FILTER));
return mapper;
}
@@ -253,21 +262,22 @@ public static String write(JSONObject json) throws IOException {
public static FilterProvider configureFilterProvider(TransformationContext context) {
SimpleBeanPropertyFilter filter = DEFAULT_FILTER;
if (context != null) {
- Set<String> included = (Set<String>)context.getMetadata().get("includedFields");
- Set<String> excluded = (Set<String>)context.getMetadata().get("excludedFields");
- Class<?> type = context.getSourceDataType() == null ? null : context.getSourceDataType().getPhysical();
- filter = new TuscanyBeanPropertyFilter(type, included, excluded);
+ Set<String> included = (Set<String>)context.getMetadata().get(INCLUDED_FIELDS);
+ Set<String> excluded = (Set<String>)context.getMetadata().get(EXCLUDED_FIELDS);
+ // Class<?> type = context.getSourceDataType() == null ? null : context.getSourceDataType().getPhysical();
+ filter = new TuscanyBeanPropertyFilter(included, excluded);
}
- FilterProvider filters = new SimpleFilterProvider().addFilter("tuscanyFilter", filter);
+ FilterProvider filters = new SimpleFilterProvider().addFilter(TUSCANY_FILTER, filter);
return filters;
}
private static class TuscanyBeanPropertyFilter extends SimpleBeanPropertyFilter {
- private Class<?> type;
private Set<String> includedFields;
private Set<String> excludedFields;
- public TuscanyBeanPropertyFilter(Class<?> type, Set<String> includedFields, Set<String> excludedFields) {
+ private Stack<String> path = new Stack<String>();
+
+ public TuscanyBeanPropertyFilter(Set<String> includedFields, Set<String> excludedFields) {
if (includedFields == null) {
includedFields = Collections.emptySet();
}
@@ -276,26 +286,65 @@ public TuscanyBeanPropertyFilter(Class<?> type, Set<String> includedFields, Set<
}
this.includedFields = includedFields;
this.excludedFields = excludedFields;
- this.type = type;
}
@Override
public void serializeAsField(Object bean,
JsonGenerator jgen,
SerializerProvider provider,
BeanPropertyWriter writer) throws Exception {
- /*
- // First check if the type matches and skip the filtering if the type is different
- if (type != null && writer.getMember().getDeclaringClass() != type) {
- writer.serializeAsField(bean, jgen, provider);
- return;
+ path.push(writer.getName());
+ try {
+ // System.out.println(path);
+ if (matches(path, includedFields, true)) {
+ writer.serializeAsField(bean, jgen, provider);
+ } else if (includedFields.isEmpty() && !matches(path, excludedFields, false)) {
+ writer.serializeAsField(bean, jgen, provider);
+ }
+ } finally {
+ path.pop();
}
- */
- if (includedFields.contains(writer.getName())) {
- writer.serializeAsField(bean, jgen, provider);
- } else if (includedFields.isEmpty() && !excludedFields.contains(writer.getName())) {
- writer.serializeAsField(bean, jgen, provider);
+ }
+
+ /**
+ * Check the target string is a prefix of the source separated by .
+ * @param source
+ * @param target
+ * @return
+ */
+ private boolean isPrefix(String source, String target) {
+ int index = source.indexOf(target);
+ if (index == -1) {
+ return false;
+ }
+ if (target.length() == source.length() || source.charAt(target.length()) == '.') {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Check if the path matches the one of the patterns
+ * @param path
+ * @param patterns
+ * @param included
+ * @return
+ */
+ private boolean matches(Stack<String> path, Set<String> patterns, boolean included) {
+ StringBuilder builder = new StringBuilder();
+ for (int i = 0; i < path.size(); i++) {
+ builder.append(path.get(i));
+ if (i != path.size() - 1) {
+ builder.append(".");
+ }
+ }
+ String qname = builder.toString();
+ for (String p : patterns) {
+ if ((included && isPrefix(p, qname)) || ((!included) && isPrefix(qname, p))) {
+ return true;
+ }
}
+ return false;
}
}
@@ -23,13 +23,16 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import junit.framework.Assert;
import org.apache.tuscany.sca.databinding.TransformationContext;
import org.apache.tuscany.sca.databinding.impl.TransformationContextImpl;
import org.apache.tuscany.sca.interfacedef.impl.DataTypeImpl;
+import org.json.JSONObject;
import org.junit.Test;
/**
@@ -263,21 +266,34 @@ public void testBean2JSONWithFilter() throws Exception {
me.setDate(new Date());
YourBean you = new YourBean();
you.setId(123);
- you.setName(null);
+ you.setName("You");
me.setYou(you);
Object2JSON t1 = new Object2JSON();
TransformationContext context = new TransformationContextImpl();
- context.getMetadata().put("includedFields", Collections.singleton("name"));
+ Set<String> included = new HashSet<String>();
+ included.add("name");
+ included.add("you.name");
+ // included.add("you.id");
+ context.getMetadata().put("includedFields", included);
Object result = t1.transform(me, context);
System.out.println(result);
- Assert.assertTrue(result.toString().contains("name"));
- Assert.assertFalse(result.toString().contains("age"));
+ JSONObject json = new JSONObject(result.toString());
+ Assert.assertTrue(json.has("name"));
+ Assert.assertTrue(json.has("you"));
+ Assert.assertTrue(json.getJSONObject("you").has("name"));
+ Assert.assertFalse(json.getJSONObject("you").has("id"));
context = new TransformationContextImpl();
- context.getMetadata().put("excludedFields", Collections.singleton("name"));
+ Set<String> excluded = new HashSet<String>();
+ excluded.add("you.name");
+ excluded.add("age");
+ context.getMetadata().put("excludedFields", excluded);
result = t1.transform(me, context);
System.out.println(result);
- Assert.assertFalse(result.toString().contains("name"));
- Assert.assertTrue(result.toString().contains("age"));
+ json = new JSONObject(result.toString());
+ Assert.assertTrue(json.has("name"));
+ Assert.assertTrue(json.has("you"));
+ Assert.assertTrue(json.getJSONObject("you").has("id"));
+ Assert.assertFalse(json.getJSONObject("you").has("name"));
}
@Test

0 comments on commit 889290c

Please sign in to comment.