From 29c838253772a7f03ca3832139bab0388c20df03 Mon Sep 17 00:00:00 2001 From: rfeng Date: Mon, 17 Sep 2012 18:10:11 +0000 Subject: Enhance the include/exclude filter processing and fix a NPE git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1386756 13f79535-47bb-0310-9956-ffa450edef68 --- .../rest/provider/DataBindingJAXRSWriter.java | 8 ++++ .../wireformat/json/CatalogServiceTestCase.java | 36 ++++++++++++++- .../databinding/json/jackson/JacksonHelper.java | 54 +++++++++++++++------- .../json/jackson/Object2JSONTestCase.java | 10 +++- 4 files changed, 88 insertions(+), 20 deletions(-) diff --git a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/DataBindingJAXRSWriter.java b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/DataBindingJAXRSWriter.java index 4ee1ff8c92..6064d23b1e 100644 --- a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/DataBindingJAXRSWriter.java +++ b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/DataBindingJAXRSWriter.java @@ -120,8 +120,16 @@ public class DataBindingJAXRSWriter extends DataBindingJAXRSProvider implemen Set fieldSet = tokenize(fields); for (String f : fieldSet) { if (f.startsWith("-")) { + if (excludedFields == null) { + excludedFields = new HashSet(); + metadata.put(EXCLUDED_FIELDS, excludedFields); + } excludedFields.add(f.substring(1)); } else { + if (includedFields == null) { + includedFields = new HashSet(); + metadata.put(INCLUDED_FIELDS, includedFields); + } includedFields.add(f); } } diff --git a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/java/org/apache/tuscany/sca/binding/rest/wireformat/json/CatalogServiceTestCase.java b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/java/org/apache/tuscany/sca/binding/rest/wireformat/json/CatalogServiceTestCase.java index c09871241c..7a07c9b5c8 100644 --- a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/java/org/apache/tuscany/sca/binding/rest/wireformat/json/CatalogServiceTestCase.java +++ b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/java/org/apache/tuscany/sca/binding/rest/wireformat/json/CatalogServiceTestCase.java @@ -91,15 +91,47 @@ public class CatalogServiceTestCase { } @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/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 9430a326b2..50a4b0fff8 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,8 +24,10 @@ import java.io.InputStream; 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 @@ public class JacksonHelper { } private static class TuscanyBeanPropertyFilter extends SimpleBeanPropertyFilter { - private Set includedFields; - private Set excludedFields; + private List includedFields; + private List excludedFields; private Stack path = new Stack(); public TuscanyBeanPropertyFilter(Set includedFields, Set excludedFields) { if (includedFields == null) { - includedFields = Collections.emptySet(); + includedFields = new HashSet(); + includedFields.add(""); // Allows any fields } if (excludedFields == null) { excludedFields = Collections.emptySet(); } - this.includedFields = includedFields; - this.excludedFields = excludedFields; + this.includedFields = new ArrayList(includedFields); + Collections.sort(this.includedFields, Collections.reverseOrder()); + this.excludedFields = new ArrayList(excludedFields); + Collections.sort(this.excludedFields, Collections.reverseOrder()); } @Override @@ -294,11 +299,11 @@ public class JacksonHelper { 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 @@ public class JacksonHelper { * @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 @@ public class JacksonHelper { * @param included * @return */ - private boolean matches(Stack path, Set patterns, boolean included) { + private boolean isAllowed(String fullName, List included, List 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 path) { StringBuilder builder = new StringBuilder(); for (int i = 0; i < path.size(); i++) { builder.append(path.get(i)); @@ -339,12 +366,7 @@ public class JacksonHelper { } } 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/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 745937b87e..d46f7ecf8e 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 @@ -271,10 +271,15 @@ public class Object2JSONTestCase { Object2JSON t1 = new Object2JSON(); TransformationContext context = new TransformationContextImpl(); Set included = new HashSet(); + Set excluded = new HashSet(); 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 @@ public class Object2JSONTestCase { Assert.assertTrue(json.has("you")); Assert.assertTrue(json.getJSONObject("you").has("name")); Assert.assertFalse(json.getJSONObject("you").has("id")); + context = new TransformationContextImpl(); - Set excluded = new HashSet(); + excluded = new HashSet(); excluded.add("you.name"); excluded.add("age"); context.getMetadata().put("excludedFields", excluded); -- cgit v1.2.3