Enhance the include/exclude filter processing and fix a NPE
git-svn-id: https://svn.apache.org/repos/asf/tuscany/sca-java-2.x/trunk@1386756 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/DataBindingJAXRSWriter.java b/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/DataBindingJAXRSWriter.java
index 4ee1ff8..6064d23 100644
--- a/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/DataBindingJAXRSWriter.java
+++ b/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/DataBindingJAXRSWriter.java
@@ -120,8 +120,16 @@
Set<String> fieldSet = tokenize(fields);
for (String f : fieldSet) {
if (f.startsWith("-")) {
+ if (excludedFields == null) {
+ excludedFields = new HashSet<String>();
+ metadata.put(EXCLUDED_FIELDS, excludedFields);
+ }
excludedFields.add(f.substring(1));
} else {
+ if (includedFields == null) {
+ includedFields = new HashSet<String>();
+ metadata.put(INCLUDED_FIELDS, includedFields);
+ }
includedFields.add(f);
}
}
diff --git a/modules/binding-rest-runtime/src/test/java/org/apache/tuscany/sca/binding/rest/wireformat/json/CatalogServiceTestCase.java b/modules/binding-rest-runtime/src/test/java/org/apache/tuscany/sca/binding/rest/wireformat/json/CatalogServiceTestCase.java
index c098712..7a07c9b 100644
--- a/modules/binding-rest-runtime/src/test/java/org/apache/tuscany/sca/binding/rest/wireformat/json/CatalogServiceTestCase.java
+++ b/modules/binding-rest-runtime/src/test/java/org/apache/tuscany/sca/binding/rest/wireformat/json/CatalogServiceTestCase.java
@@ -91,15 +91,47 @@
}
@Test
- public void testGetInvocationWithFilter() throws Exception {
+ public void testGetInvocationWithFilter1() throws Exception {
WebConversation wc = new WebConversation();
- WebRequest request = new GetMethodWebRequest(SERVICE_URL + "?excludedFields=price");
+ WebRequest request = new GetMethodWebRequest(SERVICE_URL + "?excludedFields=items.price");
request.setHeaderField("Content-Type", "application/json");
WebResponse response = wc.getResource(request);
Assert.assertEquals(200, response.getResponseCode());
String json = response.getText();
+ System.out.println(json);
Assert.assertNotNull(json);
+ Assert.assertTrue(json.contains("name"));
+ Assert.assertFalse(json.contains("price"));
+ }
+
+ @Test
+ public void testGetInvocationWithFilter2() throws Exception {
+ WebConversation wc = new WebConversation();
+ WebRequest request = new GetMethodWebRequest(SERVICE_URL + "?fields=items,-items.price");
+ request.setHeaderField("Content-Type", "application/json");
+ WebResponse response = wc.getResource(request);
+
+ Assert.assertEquals(200, response.getResponseCode());
+ String json = response.getText();
+ System.out.println(json);
+ Assert.assertNotNull(json);
+ Assert.assertTrue(json.contains("name"));
+ Assert.assertFalse(json.contains("price"));
+ }
+
+ @Test
+ public void testGetInvocationWithFilter3() throws Exception {
+ WebConversation wc = new WebConversation();
+ WebRequest request = new GetMethodWebRequest(SERVICE_URL + "?includedFields=items.name&excludedFields=items");
+ request.setHeaderField("Content-Type", "application/json");
+ WebResponse response = wc.getResource(request);
+
+ Assert.assertEquals(200, response.getResponseCode());
+ String json = response.getText();
+ System.out.println(json);
+ Assert.assertNotNull(json);
+ Assert.assertTrue(json.contains("name"));
Assert.assertFalse(json.contains("price"));
}
diff --git a/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/JacksonHelper.java b/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/JacksonHelper.java
index 9430a32..50a4b0f 100644
--- a/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/JacksonHelper.java
+++ b/modules/databinding-json/src/main/java/org/apache/tuscany/sca/databinding/json/jackson/JacksonHelper.java
@@ -24,8 +24,10 @@
import java.io.OutputStream;
import java.io.Reader;
import java.io.StringWriter;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
import java.util.Stack;
@@ -272,20 +274,23 @@
}
private static class TuscanyBeanPropertyFilter extends SimpleBeanPropertyFilter {
- private Set<String> includedFields;
- private Set<String> excludedFields;
+ private List<String> includedFields;
+ private List<String> excludedFields;
private Stack<String> path = new Stack<String>();
public TuscanyBeanPropertyFilter(Set<String> includedFields, Set<String> excludedFields) {
if (includedFields == null) {
- includedFields = Collections.emptySet();
+ includedFields = new HashSet<String>();
+ includedFields.add(""); // Allows any fields
}
if (excludedFields == null) {
excludedFields = Collections.emptySet();
}
- this.includedFields = includedFields;
- this.excludedFields = excludedFields;
+ this.includedFields = new ArrayList<String>(includedFields);
+ Collections.sort(this.includedFields, Collections.reverseOrder());
+ this.excludedFields = new ArrayList<String>(excludedFields);
+ Collections.sort(this.excludedFields, Collections.reverseOrder());
}
@Override
@@ -294,11 +299,11 @@
SerializerProvider provider,
BeanPropertyWriter writer) throws Exception {
path.push(writer.getName());
+ String fname = getFullName(path);
try {
// System.out.println(path);
- if (matches(path, includedFields, true)) {
- writer.serializeAsField(bean, jgen, provider);
- } else if (includedFields.isEmpty() && !matches(path, excludedFields, false)) {
+ if (isAllowed(fname, includedFields, excludedFields)) {
+ // Matching includes, write
writer.serializeAsField(bean, jgen, provider);
}
} finally {
@@ -312,7 +317,7 @@
* @param target
* @return
*/
- private boolean isPrefix(String source, String target) {
+ private boolean matches(String source, String target) {
int index = source.indexOf(target);
if (index == -1) {
return false;
@@ -330,7 +335,29 @@
* @param included
* @return
*/
- private boolean matches(Stack<String> path, Set<String> patterns, boolean included) {
+ private boolean isAllowed(String fullName, List<String> included, List<String> excluded) {
+ String ex = null;
+ for (String p : excluded) {
+ if (matches(fullName, p)) {
+ ex = p;
+ break;
+ }
+ }
+ for (String p : included) {
+ if (matches(fullName, p) // If the parent element is included
+ || matches(p, fullName) // If one of the child elements is included
+ ) {
+ if (ex != null && ex.length() > p.length()) {
+ // We already have an exclusion pattern that's more matching
+ return false;
+ }
+ return true;
+ }
+ }
+ return ex == null && included.contains("");
+ }
+
+ private String getFullName(Stack<String> path) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < path.size(); i++) {
builder.append(path.get(i));
@@ -339,12 +366,7 @@
}
}
String qname = builder.toString();
- for (String p : patterns) {
- if ((included && isPrefix(p, qname)) || ((!included) && isPrefix(qname, p))) {
- return true;
- }
- }
- return false;
+ return qname;
}
}
diff --git a/modules/databinding-json/src/test/java/org/apache/tuscany/sca/databinding/json/jackson/Object2JSONTestCase.java b/modules/databinding-json/src/test/java/org/apache/tuscany/sca/databinding/json/jackson/Object2JSONTestCase.java
index 745937b..d46f7ec 100644
--- a/modules/databinding-json/src/test/java/org/apache/tuscany/sca/databinding/json/jackson/Object2JSONTestCase.java
+++ b/modules/databinding-json/src/test/java/org/apache/tuscany/sca/databinding/json/jackson/Object2JSONTestCase.java
@@ -271,10 +271,15 @@
Object2JSON t1 = new Object2JSON();
TransformationContext context = new TransformationContextImpl();
Set<String> included = new HashSet<String>();
+ Set<String> excluded = new HashSet<String>();
included.add("name");
- included.add("you.name");
+ included.add("you");
+ excluded.add("you.id");
+
// included.add("you.id");
context.getMetadata().put("includedFields", included);
+ context.getMetadata().put("excludedFields", excluded);
+
Object result = t1.transform(me, context);
System.out.println(result);
JSONObject json = new JSONObject(result.toString());
@@ -282,8 +287,9 @@
Assert.assertTrue(json.has("you"));
Assert.assertTrue(json.getJSONObject("you").has("name"));
Assert.assertFalse(json.getJSONObject("you").has("id"));
+
context = new TransformationContextImpl();
- Set<String> excluded = new HashSet<String>();
+ excluded = new HashSet<String>();
excluded.add("you.name");
excluded.add("age");
context.getMetadata().put("excludedFields", excluded);