Author: gk
Date: Wed Nov  6 16:02:41 2013
New Revision: 1539377

URL: http://svn.apache.org/r1539377
Log:
added basic documentation. 
updated interface, added reload parameter to serialize* methods.
renamed CustomIntrospector.java to SimpleNameIntrospector.java.
added primitive collection test.

Added:
    turbine/fulcrum/trunk/json/gson/xdocs/
    turbine/fulcrum/trunk/json/gson/xdocs/index.xml   (with props)
    
turbine/fulcrum/trunk/json/jackson2/src/java/org/apache/fulcrum/json/jackson/SimpleNameIntrospector.java
   (with props)
    turbine/fulcrum/trunk/json/jackson2/xdocs/
    turbine/fulcrum/trunk/json/jackson2/xdocs/index.xml   (with props)
Removed:
    
turbine/fulcrum/trunk/json/jackson2/src/java/org/apache/fulcrum/json/jackson/CustomIntrospector.java
Modified:
    
turbine/fulcrum/trunk/json/api/src/java/org/apache/fulcrum/json/JsonService.java
    
turbine/fulcrum/trunk/json/gson/src/java/org/apache/fulcrum/json/gson/GSONBuilderService.java
    
turbine/fulcrum/trunk/json/gson/src/test/org/apache/fulcrum/json/gson/DefaultServiceTest.java
    
turbine/fulcrum/trunk/json/jackson/src/java/org/apache/fulcrum/json/jackson/JacksonMapperService.java
    
turbine/fulcrum/trunk/json/jackson2/src/java/org/apache/fulcrum/json/jackson/Jackson2MapperService.java
    turbine/fulcrum/trunk/json/jackson2/src/test/TestComponentConfig.xml
    
turbine/fulcrum/trunk/json/jackson2/src/test/org/apache/fulcrum/json/jackson/DefaultServiceTest.java

Modified: 
turbine/fulcrum/trunk/json/api/src/java/org/apache/fulcrum/json/JsonService.java
URL: 
http://svn.apache.org/viewvc/turbine/fulcrum/trunk/json/api/src/java/org/apache/fulcrum/json/JsonService.java?rev=1539377&r1=1539376&r2=1539377&view=diff
==============================================================================
--- 
turbine/fulcrum/trunk/json/api/src/java/org/apache/fulcrum/json/JsonService.java
 (original)
+++ 
turbine/fulcrum/trunk/json/api/src/java/org/apache/fulcrum/json/JsonService.java
 Wed Nov  6 16:02:41 2013
@@ -83,12 +83,24 @@ public interface JsonService {
     <T> T deSer(String src, Class<T> type) throws Exception;
 
     /**
+     * @see #serializeOnlyFilter(Object, Class, boolean, String...).
+     * 
+     * <code>refreshFilter</code> is <code>false</code>.
+     */
+    public <T> String serializeOnlyFilter(Object src, Class<T> filterClass,
+            String... filterAttr) throws Exception;
+    
+    /**
      * Serialize only object properties where filters attributes are provided
      * 
      * @param src
      *            The Java object to serialize
      * @param filterClass
      *            The class to which the filtering should be applied
+     *            
+     * @param refreshFilter
+     *             refresh Filter (clean cache for this filerClass)
+     *  
      * @param filterAttr
      *            The class bean attributes which should be serialized
      * 
@@ -97,7 +109,7 @@ public interface JsonService {
      * @throws Exception
      *             if JSON serialization or filter registration fails
      */
-    public <T> String serializeOnlyFilter(Object src, Class<T> filterClass,
+    public <T> String serializeOnlyFilter(Object src, Class<T> filterClass, 
boolean refreshFilter,
             String... filterAttr) throws Exception;
 
     /**
@@ -109,6 +121,8 @@ public interface JsonService {
      *            The class to which the filtering should be applied. If its 
the
      *            same class, just the filterAttributes get applied. If not the
      *            class is filtered out, if found as a property type.
+     * @param refreshFilter
+     *            refresh Filter (clean cache for this filerClass)      
      * 
      * @param filterAttr
      *            The bean attributes which should not be serialized
@@ -119,6 +133,14 @@ public interface JsonService {
      *             if JSON serialization or filter registration fails
      */
     public <T> String serializeAllExceptFilter(Object src,
+            Class<T> filterClass, boolean refreshFilter, String... filterAttr) 
throws Exception;
+    
+    /** 
+     * @see #serializeAllExceptFilter(Object, Class, boolean, String...)
+     * 
+     * <code>refreshFilter</code> is <code>false</code>.
+     */
+    public <T> String serializeAllExceptFilter(Object src,
             Class<T> filterClass, String... filterAttr) throws Exception;
 
     /**

Modified: 
turbine/fulcrum/trunk/json/gson/src/java/org/apache/fulcrum/json/gson/GSONBuilderService.java
URL: 
http://svn.apache.org/viewvc/turbine/fulcrum/trunk/json/gson/src/java/org/apache/fulcrum/json/gson/GSONBuilderService.java?rev=1539377&r1=1539376&r2=1539377&view=diff
==============================================================================
--- 
turbine/fulcrum/trunk/json/gson/src/java/org/apache/fulcrum/json/gson/GSONBuilderService.java
 (original)
+++ 
turbine/fulcrum/trunk/json/gson/src/java/org/apache/fulcrum/json/gson/GSONBuilderService.java
 Wed Nov  6 16:02:41 2013
@@ -96,6 +96,12 @@ public class GSONBuilderService extends 
             String... filterAttr) throws Exception {
         throw new Exception("Not yet implemented!");
     }
+    
+    @Override
+    public <T> String serializeOnlyFilter(Object arg0, Class<T> arg1,
+            boolean arg2, String... arg3) throws Exception {
+        throw new Exception("Not yet implemented!");
+    }
 
     @Override
     public JsonService addAdapter(String name, Class target, Object adapter)
@@ -114,6 +120,12 @@ public class GSONBuilderService extends 
     @Override
     public <T> String serializeAllExceptFilter(Object src,
             Class<T> filterClass, String... filterAttr) throws Exception {
+        return serializeAllExceptFilter(src, filterClass, false, filterAttr);
+    }
+    
+    @Override
+    public <T> String serializeAllExceptFilter(Object src, Class<T> 
filterClass,
+            boolean arg2, String... filterAttr) throws Exception {
         return gson
                 .addSerializationExclusionStrategy(
                         exclude(filterClass, filterAttr)).create().toJson(src);

Modified: 
turbine/fulcrum/trunk/json/gson/src/test/org/apache/fulcrum/json/gson/DefaultServiceTest.java
URL: 
http://svn.apache.org/viewvc/turbine/fulcrum/trunk/json/gson/src/test/org/apache/fulcrum/json/gson/DefaultServiceTest.java?rev=1539377&r1=1539376&r2=1539377&view=diff
==============================================================================
--- 
turbine/fulcrum/trunk/json/gson/src/test/org/apache/fulcrum/json/gson/DefaultServiceTest.java
 (original)
+++ 
turbine/fulcrum/trunk/json/gson/src/test/org/apache/fulcrum/json/gson/DefaultServiceTest.java
 Wed Nov  6 16:02:41 2013
@@ -128,6 +128,20 @@ public class DefaultServiceTest extends 
                 
"[{'w':0,'h':0,'name':'rect0'},{'w':1,'h':1,'name':'rect1'},{'w':2,'h':2,'name':'rect2'},{'w':3,'h':3,'name':'rect3'},{'w':4,'h':4,'name':'rect4'},{'w':5,'h':5,'name':'rect5'},{'w':6,'h':6,'name':'rect6'},{'w':7,'h':7,'name':'rect7'},{'w':8,'h':8,'name':'rect8'},{'w':9,'h':9,'name':'rect9'}]",
                 adapterSer.replace('"', '\''));
     }
+    
+    public void testSerializationCollectioPrimitiveWrapper() throws Exception {
+
+        List<Integer> intList = new ArrayList<Integer>();
+        for (int i = 0; i < 10; i++) {
+            Integer integer = new Integer(i*i);
+            intList.add(integer);
+        }
+        String result = sc.ser(intList);
+        assertEquals(
+                "Serialization of beans failed ",
+                "[0,1,4,9,16,25,36,49,64,81]",
+                result);
+    }
 
     public void testSerializeTypeAdapterForCollection() throws Exception {
         sc.addAdapter("Collection Adapter", ArrayList.class,

Added: turbine/fulcrum/trunk/json/gson/xdocs/index.xml
URL: 
http://svn.apache.org/viewvc/turbine/fulcrum/trunk/json/gson/xdocs/index.xml?rev=1539377&view=auto
==============================================================================
--- turbine/fulcrum/trunk/json/gson/xdocs/index.xml (added)
+++ turbine/fulcrum/trunk/json/gson/xdocs/index.xml Wed Nov  6 16:02:41 2013
@@ -0,0 +1,109 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+  <properties>
+    <title>JSON Component</title>
+    <author email="[email protected]">Georg Kallidis</author>
+  </properties>
+
+  <body>
+
+  <section name="Overview">
+    <p>
+      This Service serves as a JSON serializer or deserializer using <a 
href="http://code.google.com/p/google-gson/";>GSON</a>.
+    </p>
+
+    <p>
+      It is written
+      for use in Turbine but it can be used in any container compatible
+      with Avalon's ECM container.
+    </p>
+    
+  </section>
+
+<section name="Configuration">
+    <subsection name="Role Configuration">
+      <source><![CDATA[
+   <role
+        name="org.apache.fulcrum.json.JsonService"
+        shorthand="json"
+        default-class="org.apache.fulcrum.json.gson.GSONBuilderService"/>
+]]></source>
+    </subsection>
+    
+    <subsection name="Component Configuration">
+      <table>
+        <tr>
+          <th>Item</th>
+          <th>Datatype</th>
+          <th>Cardinality</th>
+          <th>Description</th>
+        </tr>
+        <tr>
+          <td>globalAdapters</td>
+          <td>Complex</td>
+          <td>[0|1]</td>
+          <td>
+            If not set no adapter is set. Otherwise provide for each sub 
element <code>adapter</code> the class name of the adapter and set the 
attribute <code>forClass</code> to the class name the adapter should be 
applied. See the configuration example below. 
+          </td>
+        </tr>
+        <tr>
+          <td>dateFormat</td>
+          <td>String</td>
+          <td>[0|*]</td>
+          <td>
+            If set changes the date format. Provided string should be in a 
Format acceptable to the class 
<code>java.text.SimpleDateFormat.SimpleDateFormat(String)</code>. The default 
value is
+            <code>MM/dd/yyyy</code>. 
+          </td>
+        </tr>
+      </table>
+    </subsection>
+
+    <subsection name="Component Configuration Example">
+      <source><![CDATA[
+  <json>
+    <dateFormat>MM/dd/yyyy</dateFormat>
+    <globalAdapters>>
+      <adapter forClass="x.y.z.Class">a.b.c.d.AdapterForClassXYZ</adapter-->
+    </globalAdapters>
+  </json>
+]]></source>
+    </subsection>
+  </section>
+
+  <section name="Usage">
+    <p>
+    You get a JSON service from the service like this:
+    </p>
+
+    <source><![CDATA[
+JsonService jsonService = (JsonService)TurbineServices
+        .getInstance().getService(JsonService.ROLE);
+]]></source>
+
+    <p>
+    </p>
+
+  </section>
+
+</body>
+</document>

Propchange: turbine/fulcrum/trunk/json/gson/xdocs/index.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
turbine/fulcrum/trunk/json/jackson/src/java/org/apache/fulcrum/json/jackson/JacksonMapperService.java
URL: 
http://svn.apache.org/viewvc/turbine/fulcrum/trunk/json/jackson/src/java/org/apache/fulcrum/json/jackson/JacksonMapperService.java?rev=1539377&r1=1539376&r2=1539377&view=diff
==============================================================================
--- 
turbine/fulcrum/trunk/json/jackson/src/java/org/apache/fulcrum/json/jackson/JacksonMapperService.java
 (original)
+++ 
turbine/fulcrum/trunk/json/jackson/src/java/org/apache/fulcrum/json/jackson/JacksonMapperService.java
 Wed Nov  6 16:02:41 2013
@@ -138,6 +138,13 @@ public class JacksonMapperService extend
     @Override
     public synchronized <T> String serializeAllExceptFilter(Object src,
             Class<T> filterClass, String... filterAttr) throws Exception {
+        return serializeAllExceptFilter(src, filterClass, false, filterAttr);
+    }
+    
+    @Override
+    public <T> String serializeAllExceptFilter(Object src,
+            Class<T> filterClass, boolean refreshFilter, String... filterAttr)
+            throws Exception {
         setCustomIntrospectorWithExternalFilterId(filterClass);
         FilterProvider filter;
         if (!this.filters.containsKey(filterClass.getName())) {
@@ -155,9 +162,14 @@ public class JacksonMapperService extend
     }
 
     @Override
-    @SuppressWarnings("unchecked")
     public synchronized <T> String serializeOnlyFilter(Object src,
             Class<T> filterClass, String... filterAttr) throws Exception {
+        return serializeOnlyFilter(src, filterClass, false, filterAttr);
+    }
+    
+    @Override
+    public <T> String serializeOnlyFilter(Object src, Class<T> filterClass,
+            boolean refreshFilter, String... filterAttr) throws Exception {
         setCustomIntrospectorWithExternalFilterId(filterClass);
         FilterProvider filter;
         if (!this.filters.containsKey(filterClass.getName())) {
@@ -170,7 +182,7 @@ public class JacksonMapperService extend
         }
         String serialized = ser(src, filter);
         getLogger().debug("serialized " + serialized);
-        if (!cacheFilters)
+        if (!cacheFilters || refreshFilter)
             removeFilterClass(filterClass);
         return serialized;
     }
@@ -417,4 +429,5 @@ public class JacksonMapperService extend
             context.setMixInAnnotations(this.clazz, this.mixin);
         }
     }
+
 }

Modified: 
turbine/fulcrum/trunk/json/jackson2/src/java/org/apache/fulcrum/json/jackson/Jackson2MapperService.java
URL: 
http://svn.apache.org/viewvc/turbine/fulcrum/trunk/json/jackson2/src/java/org/apache/fulcrum/json/jackson/Jackson2MapperService.java?rev=1539377&r1=1539376&r2=1539377&view=diff
==============================================================================
--- 
turbine/fulcrum/trunk/json/jackson2/src/java/org/apache/fulcrum/json/jackson/Jackson2MapperService.java
 (original)
+++ 
turbine/fulcrum/trunk/json/jackson2/src/java/org/apache/fulcrum/json/jackson/Jackson2MapperService.java
 Wed Nov  6 16:02:41 2013
@@ -71,8 +71,9 @@ import com.fasterxml.jackson.databind.se
  * not support (e.g filter + mixin or default + filter for the same bean /
  * object).
  * 
- * Note: If using {@link CustomIntrospector} unregister filters by setting
- * {@link #cacheFilters} to <code>false</code>.
+ * Note: If using {@link SimpleNameIntrospector}, filters are set by class id, 
which are cached by default. 
+ * By setting {@link #cacheFilters} to <code>false</code> each filter will be 
unregistered and the cache cleaned.
+ * On the other hand, by setting the refresh parameterin method calls using 
{@link #filter(Object, Class, FilterContext, boolean, String...)} class 
filtering is done only on class level.
  * 
  * @author gk
  * @version $Id$
@@ -120,7 +121,12 @@ public class Jackson2MapperService exten
 
     @Override
     public <T> String ser(Object src, Class<T> type) throws Exception {
-        getLogger().debug("ser::" + src + " with type" + type);
+        if (src == null) {
+            getLogger().info("no serializable object:" + src + " for type "+ 
type);
+            return null;
+        } else {
+            getLogger().debug("ser class::" + src.getClass() + " with type" + 
type);
+        }
         if (filters.containsKey(src.getClass().getName())) {
             getLogger()
                     .warn("Found registered filter - could not use custom view 
and custom filter for class:"
@@ -133,11 +139,16 @@ public class Jackson2MapperService exten
     }
 
     public <T> String ser(Object src, FilterProvider filters) throws Exception 
{
-        String serResult;
+        String serResult= null;
+        if (src == null) {
+            getLogger().info("no serializable object:" + src);
+            return serResult;
+        } 
         if (filters != null) {
-            getLogger().debug("ser::" + src + " with filters " + filters);
+            getLogger().debug("ser class::" + src.getClass() + " with filters 
" + filters);
             serResult = mapper.writer(filters).writeValueAsString(src);
         } else {
+            getLogger().debug("ser class::" + src.getClass() + " without 
filters" +filters); 
             serResult = ser(src);
         }
         return serResult;
@@ -208,31 +219,48 @@ public class Jackson2MapperService exten
         getLogger().debug("registering module " + mx + "  for: " + mixin);
         return mapper.registerModule(mx).writer().writeValueAsString(src);
     }
-
+    
     @Override
     public synchronized <T> String serializeAllExceptFilter(Object src,
             Class<T> filterClass, String... filterAttr) throws Exception {
+        return serializeAllExceptFilter(src, filterClass, false, filterAttr);
+    }
+
+    public synchronized <T> String serializeAllExceptFilter(Object src,
+            Class<T> filterClass, boolean refresh, String... filterAttr) 
throws Exception {
         FilterContext fc = new FilterContext();
         if (filterAttr != null)
             fc.setFilter(SimpleBeanPropertyFilter
                     .serializeAllExcept(filterAttr));
-        return filter(src, filterClass, fc, filterAttr);
+        return filter(src, filterClass, fc, refresh, filterAttr);
+    }
+    
+    @Override
+    public synchronized <T> String serializeOnlyFilter(Object src,
+            Class<T> filterClass,  String... filterAttr) throws Exception {
+        return serializeOnlyFilter(src, filterClass, false, filterAttr);
     }
 
     @Override
     public synchronized <T> String serializeOnlyFilter(Object src,
-            Class<T> filterClass, String... filterAttr) throws Exception {
+            Class<T> filterClass, boolean refresh, String... filterAttr) 
throws Exception {
         FilterContext fc = new FilterContext();
-        fc.setFilter(SimpleBeanPropertyFilter.filterOutAllExcept(filterAttr));
-        return filter(src, filterClass, fc, filterAttr);
+        if (filterAttr != null && filterAttr.length > 0)
+            
fc.setFilter(SimpleBeanPropertyFilter.filterOutAllExcept(filterAttr));
+        return filter(src, filterClass, fc, refresh, filterAttr);
     }
 
     private <T> String filter(Object src, Class<T> filterClass,
-            FilterContext fc, String... filterAttr) throws Exception {
+            FilterContext fc,  boolean refresh, String... filterAttr) throws 
Exception {
+        if (src == null) {
+            getLogger().info("no serializable object:" + src + " for 
filterClass "+ filterClass);
+            return null;
+        }
         FilterProvider filter = checkFilter(fc, src.getClass(), filterClass,
                 filterAttr);
+        getLogger().info("filtering with filter "+ filter);
         String serialized = ser(src, filter);
-        if (!cacheFilters) {
+        if (!cacheFilters || refresh) {
             removeFilter(filterClass);
             removeFilter(src.getClass());
         }
@@ -242,23 +270,20 @@ public class Jackson2MapperService exten
     @SuppressWarnings("unchecked")
     private <T> FilterProvider checkFilter(FilterContext fc,
             Class rootFilterClass, Class<T> filterClass, String... filterAttr) 
{
-        SimpleFilterProvider filter = null;
-        // if (filterAttr == null) return filter;
-        filter = new SimpleFilterProvider();
-        if (filterAttr != null
+        SimpleFilterProvider filter = new SimpleFilterProvider();
+        if (filterAttr != null && filterAttr.length > 0
                 && (filterClass == null || 
!rootFilterClass.equals(filterClass))) {
             // filter attributes in root class
-            retrieveFilter(fc, rootFilterClass, filter, filterAttr);
+            filter = retrieveFilter(filter, fc, rootFilterClass, filterAttr);
         }
         if (filterClass != null) {
-            retrieveFilter(fc, filterClass, filter, filterAttr);
+            filter = retrieveFilter(filter, fc, filterClass, filterAttr);
         }
         return filter;
     }
 
-    private <T> SimpleFilterProvider retrieveFilter(FilterContext fc,
-            Class<T> filterClass, SimpleFilterProvider filter,
-            String... filterAttr) {
+    private <T> SimpleFilterProvider retrieveFilter(SimpleFilterProvider 
filter, FilterContext fc,
+            Class<T> filterClass, String... filterAttr) {
         if (!this.filters.containsKey(filterClass.getName())) {
             getLogger().debug("add filter for class" + filterClass.getName());
             if (fc.getFilter() != null) {
@@ -302,9 +327,9 @@ public class Jackson2MapperService exten
 
     private <T> void setCustomIntrospectorWithExternalFilterId(
             Class<T> externalFilterId) {
-        if (primary instanceof CustomIntrospector) {
+        if (primary instanceof SimpleNameIntrospector) {
             if (externalFilterId != null) {
-                ((CustomIntrospector) primary)
+                ((SimpleNameIntrospector) primary)
                         .setExternalFilterClasses(externalFilterId);
                 getLogger()
                         .debug("added class for filters "
@@ -315,9 +340,9 @@ public class Jackson2MapperService exten
 
     private <T> void removeCustomIntrospectorWithExternalFilterId(
             Class<T> externalFilterId) {
-        if (primary instanceof CustomIntrospector) {
+        if (primary instanceof SimpleNameIntrospector) {
             if (externalFilterId != null) {
-                ((CustomIntrospector) primary)
+                ((SimpleNameIntrospector) primary)
                         .removeExternalFilterClass(externalFilterId);
                 getLogger().debug(
                         "removed from introspector filter id  "
@@ -438,10 +463,12 @@ public class Jackson2MapperService exten
                     "using default introspector:"
                             + primary.getClass().getName());
             mapper.setAnnotationIntrospector(primary);
-        } else {
+        } else if (primary != null && secondary != null){
             AnnotationIntrospector pair = new AnnotationIntrospectorPair(
                     primary, secondary);
             mapper.setAnnotationIntrospector(pair);
+        } else {
+            mapper.setAnnotationIntrospector(primary);
         }
 
         if (features != null) {

Added: 
turbine/fulcrum/trunk/json/jackson2/src/java/org/apache/fulcrum/json/jackson/SimpleNameIntrospector.java
URL: 
http://svn.apache.org/viewvc/turbine/fulcrum/trunk/json/jackson2/src/java/org/apache/fulcrum/json/jackson/SimpleNameIntrospector.java?rev=1539377&view=auto
==============================================================================
--- 
turbine/fulcrum/trunk/json/jackson2/src/java/org/apache/fulcrum/json/jackson/SimpleNameIntrospector.java
 (added)
+++ 
turbine/fulcrum/trunk/json/jackson2/src/java/org/apache/fulcrum/json/jackson/SimpleNameIntrospector.java
 Wed Nov  6 16:02:41 2013
@@ -0,0 +1,106 @@
+package org.apache.fulcrum.json.jackson;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import com.fasterxml.jackson.databind.introspect.AnnotatedClass;
+import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
+import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
+
+/**
+ * The intent of this custom introspector is to provide filtering capabilities
+ * by using String parameters (properties and class types), which could be
+ * adjusted e.g. from a scriptable context (velocity template).
+ * 
+ * 
+ * @author gk
+ * @version $Id$
+ * 
+ */
+public class SimpleNameIntrospector extends JacksonAnnotationIntrospector {
+    public List<String> externalFilterClasses = Collections
+            .synchronizedList(new ArrayList());
+
+    /**
+     * Filtering on method types
+     * 
+     */
+    @Override
+    public Boolean isIgnorableType(AnnotatedClass ac) {
+        Boolean isIgnorable = super.isIgnorableType(ac);
+        if (isIgnorable == null || !isIgnorable) {
+            if (!externalFilterClasses.isEmpty()
+                    && externalFilterClasses.contains(ac.getName())) {
+                isIgnorable = true;
+            }
+        }
+        return isIgnorable;
+    }
+
+    /**
+     * @return Object Filtering on properties returns an object, if
+     *         {@link #externalFilterClasses} contains the class provided. The
+     *         filter itself currently is {@link SimpleFilterProvider}.
+     */
+    @Override
+    public Object findFilterId(AnnotatedClass ac) {
+        // Let's default to current behavior if annotation is found:
+        Object id = super.findFilterId(ac);
+        // but use simple class name if not
+        if (id == null) {
+            String name = ac.getName();
+            if (!externalFilterClasses.isEmpty()
+                    && externalFilterClasses.contains(name)) {
+                id = name;
+            }
+        }
+        return id;
+    }
+
+    public List<String> getExternalFilterClasses() {
+        return externalFilterClasses;
+    }
+
+    public void setExternalFilterClass(Class externalFilterClass) {
+        if (!externalFilterClasses.contains(externalFilterClass.getName())) {
+            externalFilterClasses.add(externalFilterClass.getName());
+        }
+    }
+
+    public void setExternalFilterClasses(Class... classes) {
+
+        for (int i = 0; i < classes.length; i++) {
+            if (!externalFilterClasses.contains(classes[i].getName())) {
+
+                externalFilterClasses.add(classes[i].getName());
+            }
+        }
+    }
+
+    public void removeExternalFilterClass(Class externalFilterClass) {
+        if (externalFilterClasses.contains(externalFilterClass.getName())) {
+            externalFilterClasses.remove(externalFilterClass.getName());
+        }
+    }
+
+}
\ No newline at end of file

Propchange: 
turbine/fulcrum/trunk/json/jackson2/src/java/org/apache/fulcrum/json/jackson/SimpleNameIntrospector.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: turbine/fulcrum/trunk/json/jackson2/src/test/TestComponentConfig.xml
URL: 
http://svn.apache.org/viewvc/turbine/fulcrum/trunk/json/jackson2/src/test/TestComponentConfig.xml?rev=1539377&r1=1539376&r2=1539377&view=diff
==============================================================================
--- turbine/fulcrum/trunk/json/jackson2/src/test/TestComponentConfig.xml 
(original)
+++ turbine/fulcrum/trunk/json/jackson2/src/test/TestComponentConfig.xml Wed 
Nov  6 16:02:41 2013
@@ -21,7 +21,7 @@
 <componentConfig>
   <json>
   <annotationInspectors>
-       <primary>org.apache.fulcrum.json.jackson.CustomIntrospector</primary>
+       
<primary>org.apache.fulcrum.json.jackson.SimpleNameIntrospector</primary>
         
<secondary>com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector</secondary>
         <features>
           <feature value="false" 
type="com.fasterxml.jackson.databind.SerializationFeature">FAIL_ON_EMPTY_BEANS</feature>

Modified: 
turbine/fulcrum/trunk/json/jackson2/src/test/org/apache/fulcrum/json/jackson/DefaultServiceTest.java
URL: 
http://svn.apache.org/viewvc/turbine/fulcrum/trunk/json/jackson2/src/test/org/apache/fulcrum/json/jackson/DefaultServiceTest.java?rev=1539377&r1=1539376&r2=1539377&view=diff
==============================================================================
--- 
turbine/fulcrum/trunk/json/jackson2/src/test/org/apache/fulcrum/json/jackson/DefaultServiceTest.java
 (original)
+++ 
turbine/fulcrum/trunk/json/jackson2/src/test/org/apache/fulcrum/json/jackson/DefaultServiceTest.java
 Wed Nov  6 16:02:41 2013
@@ -29,6 +29,7 @@ import java.util.Map;
 import org.apache.fulcrum.json.JsonService;
 import org.apache.fulcrum.json.Rectangle;
 import org.apache.fulcrum.json.TestClass;
+import org.apache.fulcrum.json.jackson.JacksonMapperTest.Bean;
 import org.apache.fulcrum.json.jackson.filters.CustomModuleWrapper;
 import org.apache.fulcrum.testcontainer.BaseUnitTest;
 
@@ -132,6 +133,20 @@ public class DefaultServiceTest extends 
                 
"[{'w':0,'h':0,'name':'rect0','size':0},{'w':1,'h':1,'name':'rect1','size':1},{'w':2,'h':2,'name':'rect2','size':4},{'w':3,'h':3,'name':'rect3','size':9},{'w':4,'h':4,'name':'rect4','size':16},{'w':5,'h':5,'name':'rect5','size':25},{'w':6,'h':6,'name':'rect6','size':36},{'w':7,'h':7,'name':'rect7','size':49},{'w':8,'h':8,'name':'rect8','size':64},{'w':9,'h':9,'name':'rect9','size':81}]",
                 adapterSer.replace('"', '\''));
     }
+    
+    public void testSerializationCollectioPrimitiveWrapper() throws Exception {
+
+        List<Integer> intList = new ArrayList<Integer>();
+        for (int i = 0; i < 10; i++) {
+            Integer integer = new Integer(i*i);
+            intList.add(integer);
+        }
+        String result = sc.serializeOnlyFilter(intList, Integer.class, null);
+        assertEquals(
+                "Serialization of beans failed ",
+                "[0,1,4,9,16,25,36,49,64,81]",
+                result);
+    }
 
     public void testSerializeTypeAdapterForCollection() throws Exception {
         TestSerializer tser = new TestSerializer();

Added: turbine/fulcrum/trunk/json/jackson2/xdocs/index.xml
URL: 
http://svn.apache.org/viewvc/turbine/fulcrum/trunk/json/jackson2/xdocs/index.xml?rev=1539377&view=auto
==============================================================================
--- turbine/fulcrum/trunk/json/jackson2/xdocs/index.xml (added)
+++ turbine/fulcrum/trunk/json/jackson2/xdocs/index.xml Wed Nov  6 16:02:41 2013
@@ -0,0 +1,176 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+  <properties>
+    <title>JSON Component</title>
+    <author email="[email protected]">Georg Kallidis</author>
+  </properties>
+
+  <body>
+
+  <section name="Overview">
+    <p>
+      This Service serves as a JSON serializer or deserializer using <a 
href="http://jackson.codehaus.org/";>Jackson</a>.
+    </p>
+
+    <p>
+      It is written
+      for use in Turbine but it can be used in any container compatible
+      with Avalon's ECM container.
+    </p>
+    
+  </section>
+
+<section name="Configuration">
+    <subsection name="Role Configuration">
+      <source><![CDATA[
+  <role
+        name="org.apache.fulcrum.json.JsonService"
+        shorthand="json"
+        default-class="org.apache.fulcrum.json.jackson.Jackson2MapperService"/>
+]]></source>
+    </subsection>
+    
+    <subsection name="Component Configuration">
+      <table>
+        <tr>
+          <th>Item</th>
+          <th>Datatype</th>
+          <th>Cardinality</th>
+          <th>Description</th>
+        </tr>
+        <tr>
+          <td>annotationInspectors</td>
+          <td>Complex</td>
+          <td>[0|1]</td>
+          <td>
+            If not set only one 
<code>com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector</code>
 is set as annotation introspector. Otherwise you could provide a primary and 
optionally an secondary inspector. Setting the inspector
+            
<code>org.apache.fulcrum.json.jackson.SimpleNameIntrospector</code> yields 
property and class name based filtering. See the configuration example below 
and in <a href="#velocity">section</a>. Features could be set to 
<code>false</code> or <code>true</code> by setting the attribute <b>value</b> 
of the sub element feature. The feature attribute <b>type</b> should be the 
class name of any sub interface of 
<code>com.fasterxml.jackson.databind.cfg.ConfigFeature</code>. The element 
content itself defines any feature (enum value) for this feature. Cft. the 
configuration example below.
+          </td>
+        </tr>
+        <tr>
+          <td>dateFormat</td>
+          <td>String</td>
+          <td>[0|*]</td>
+          <td>
+            If set changes the date format. The provided string should be in a 
format acceptable to the class 
<code>java.text.SimpleDateFormat.SimpleDateFormat(String)</code>. The default 
value is
+            <code>MM/dd/yyyy</code>. 
+          </td>
+        </tr>
+        <tr>
+          <td>defaultTyping</td>
+          <td>String</td>
+          <td>[0|*]</td>
+          <td>
+            The default is no defaultTyping. Otherwise set it to a Jackson 2 
enum value in class 
<code>com.fasterxml.jackson.databind.ObjectMapper.DefaultTyping</code>.
+          </td>
+        </tr>
+        <tr>
+          <td>cacheFilters</td>
+          <td>boolean</td>
+          <td>[0|*]</td>
+          <td>
+            If set to <code>true</code>, caching is not enabled. Each filter 
applied remains valid and is not removed.
+            This implicits, that you cannot retrieve for the same class/Bean 
other properties in another call.
+            You could then invalidate (refresh) the cache per class. Cft. the 
<code>filter*(t)</code> methods with <code>refreshfilter</code> property. The 
default value is <code>true</code>. 
+          </td>
+        </tr>
+      </table>
+    </subsection>
+
+    <subsection name="Component Configuration Example">
+      <source><![CDATA[
+<json>
+  <annotationInspectors>
+       <primary>org.apache.fulcrum.json.jackson.CustomIntrospector</primary>
+        
<secondary>com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector</secondary>
+        <features>
+          <feature value="false" 
type="com.fasterxml.jackson.databind.SerializationFeature">FAIL_ON_EMPTY_BEANS</feature>
+          <feature value="false" 
type="com.fasterxml.jackson.databind.DeserializationFeature">EAGER_DESERIALIZER_FETCH</feature>
+          <feature value="false" 
type="com.fasterxml.jackson.databind.MapperFeature">ALLOW_FINAL_FIELDS_AS_MUTATORS</feature>
+
+          <!-- feature 
value="true">com.fasterxml.jackson.databind.SerializationFeature.INDENT_OUTPUT</feature-->
+        </features>
+  </annotationInspectors>
+   <dateFormat>MM/dd/yyyy</dateFormat>
+   <defaultTyping type="NON_FINAL" key="type"/><!-- or e.g.  
OBJECT_AND_NON_CONCRETE -->
+   <!-- cacheFilters>false</cacheFilters>
+  </json>
+]]></source>
+    </subsection>
+  </section>
+
+  <section name="Usage">
+    <p>
+    You get a JSON service from the service like this:
+    </p>
+
+    <source><![CDATA[
+JsonService jsonService = (JsonService)TurbineServices
+        .getInstance().getService(JsonService.ROLE);
+]]></source>
+
+    <p>
+    </p>
+
+  </section>
+  
+  <section name="Velocity" id="velocity">
+
+    <subsection name="Usage in Velocity Template">
+    <p>
+     Some methods are explicitely provided to be used in a velocity context. 
You could provide it via the Turbine Pull service: 
+    </p>   
+    <source><![CDATA[
+    public Object getJson(Object src, String className, boolean refresh, 
String... props ) {
+        String result= null;
+        jsonService = 
(JsonService)TurbineServices.getInstance().getService(JsonService.ROLE);
+        try
+        {
+            Class clazz = Class.forName(className);
+            result = jsonService.serializeOnlyFilter( src, clazz, refresh, 
props );
+        }
+        catch ( Exception e )
+        {
+            log.error(e.getMessage(),e );
+        }
+        return result;        
+    }
+]]></source>
+     You could then call the json method from this tool in a velocity template 
like this:
+     
+     <source><![CDATA[
+    #set ($json =   $!pullTool.getJson($items, "x.y.z.Item", true, "prop1", 
"prop2", "prop3" ) )
+    
+    ## parse json in javascript ....
+]]></source>
+    
+    </subsection>
+    <subsection name="Configuration Requirements">
+    <p>
+    Add <code>org.apache.fulcrum.json.jackson.SimpleNameIntrospector</code> to 
the annotation inspectors as primary or secondary inspector. Of course 
annotations are still valid, as the Introspector extends 
JacksonAnnotationIntrospector and additionally calls the super class methods in 
its overwritten methods.
+    </p>
+    <p>
+<source>
+
+</body>
+</document>

Propchange: turbine/fulcrum/trunk/json/jackson2/xdocs/index.xml
------------------------------------------------------------------------------
    svn:eol-style = native


Reply via email to