Enhance the partial read support so that we can use the full property names in the object tree
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1384975 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
2b5427b858
commit
e8455342e0
3 changed files with 114 additions and 32 deletions
|
@ -49,6 +49,10 @@ import org.apache.tuscany.sca.interfacedef.impl.DataTypeImpl;
|
|||
@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 class DataBindingJAXRSWriter<T> extends DataBindingJAXRSProvider implemen
|
|||
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.OutputStream;
|
|||
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 org.json.JSONObject;
|
|||
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 class JacksonHelper {
|
|||
@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 class JacksonHelper {
|
|||
.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 class JacksonHelper {
|
|||
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,7 +286,6 @@ public class JacksonHelper {
|
|||
}
|
||||
this.includedFields = includedFields;
|
||||
this.excludedFields = excludedFields;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -284,18 +293,58 @@ public class JacksonHelper {
|
|||
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.ArrayList;
|
|||
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 class Object2JSONTestCase {
|
|||
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
|
||||
|
|
Loading…
Add table
Reference in a new issue