You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2011/08/01 02:10:39 UTC

svn commit: r1152665 - in /tapestry/tapestry5/trunk: tapestry-core/src/main/java/org/apache/tapestry5/internal/services/json/ tapestry-core/src/main/java/org/apache/tapestry5/services/ tapestry-core/src/test/groovy/org/apache/tapestry5/root/ tapestry-i...

Author: hlship
Date: Mon Aug  1 00:10:38 2011
New Revision: 1152665

URL: http://svn.apache.org/viewvc?rev=1152665&view=rev
Log:
TAP5-1591: tapestry-ioc should not depend on tapestry-json

Added:
    tapestry/tapestry5/trunk/tapestry-json/src/main/java/org/apache/tapestry5/internal/
    tapestry/tapestry5/trunk/tapestry-json/src/main/java/org/apache/tapestry5/internal/json/
    tapestry/tapestry5/trunk/tapestry-json/src/main/java/org/apache/tapestry5/internal/json/StringToJSONArray.java
      - copied, changed from r1152388, tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/json/StringToJSONArray.java
    tapestry/tapestry5/trunk/tapestry-json/src/main/java/org/apache/tapestry5/internal/json/StringToJSONObject.java
      - copied, changed from r1152388, tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/json/StringToJSONObject.java
    tapestry/tapestry5/trunk/tapestry-json/src/main/java/org/apache/tapestry5/json/services/
    tapestry/tapestry5/trunk/tapestry-json/src/main/java/org/apache/tapestry5/json/services/JSONModule.java
Removed:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/json/StringToJSONArray.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/json/StringToJSONObject.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/groovy/org/apache/tapestry5/root/StringToJSONTests.groovy
Modified:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
    tapestry/tapestry5/trunk/tapestry-ioc/build.gradle
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/TapestryIOCModule.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/TypeCoercerImplTest.java
    tapestry/tapestry5/trunk/tapestry-json/build.gradle

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java?rev=1152665&r1=1152664&r2=1152665&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java Mon Aug  1 00:10:38 2011
@@ -48,8 +48,6 @@ import org.apache.tapestry5.internal.ser
 import org.apache.tapestry5.internal.services.javascript.DateFieldStack;
 import org.apache.tapestry5.internal.services.javascript.JavaScriptStackPathConstructor;
 import org.apache.tapestry5.internal.services.javascript.JavaScriptStackSourceImpl;
-import org.apache.tapestry5.internal.services.json.StringToJSONArray;
-import org.apache.tapestry5.internal.services.json.StringToJSONObject;
 import org.apache.tapestry5.internal.services.linktransform.LinkTransformerImpl;
 import org.apache.tapestry5.internal.services.linktransform.LinkTransformerInterceptor;
 import org.apache.tapestry5.internal.services.messages.PropertiesFileParserImpl;
@@ -971,8 +969,6 @@ public final class TapestryModule
      * <li>{@link InjectionProvider} to {@link InjectionProvider2}</li>
      * <li>{@link Resource} to {@link DynamicTemplate}</li>
      * <li>{@link Asset} to {@link Resource}</li>
-     * <li>String to {@link JSONObject}</li>
-     * <li>String to {@link JSONArray}</li>
      * <li>{@link ValueEncoder} to {@link ValueEncoderFactory}</li>
      * </ul>
      */
@@ -1150,10 +1146,6 @@ public final class TapestryModule
 
         configuration.add(CCTWToCCTW2Coercion.TUPLE);
 
-        configuration.add(CoercionTuple.create(String.class, JSONObject.class, new StringToJSONObject()));
-
-        configuration.add(CoercionTuple.create(String.class, JSONArray.class, new StringToJSONArray()));
-
         configuration.add(CoercionTuple.create(ValueEncoder.class, ValueEncoderFactory.class, new Coercion<ValueEncoder, ValueEncoderFactory>()
         {
             public ValueEncoderFactory coerce(ValueEncoder input)

Modified: tapestry/tapestry5/trunk/tapestry-ioc/build.gradle
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/build.gradle?rev=1152665&r1=1152664&r2=1152665&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/build.gradle (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/build.gradle Mon Aug  1 00:10:38 2011
@@ -3,7 +3,6 @@ description = "A code-centric, high-perf
 dependencies {
   compile project(':tapestry-func')
   compile project(':tapestry5-annotations')
-  compile project(':tapestry-json')
   compile project(":plastic")
 
   provided project(':tapestry-test')

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/TapestryIOCModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/TapestryIOCModule.java?rev=1152665&r1=1152664&r2=1152665&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/TapestryIOCModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/TapestryIOCModule.java Mon Aug  1 00:10:38 2011
@@ -23,8 +23,6 @@ import org.apache.tapestry5.ioc.internal
 import org.apache.tapestry5.ioc.internal.util.InternalUtils;
 import org.apache.tapestry5.ioc.services.cron.PeriodicExecutor;
 import org.apache.tapestry5.ioc.util.TimeInterval;
-import org.apache.tapestry5.json.JSONArray;
-import org.apache.tapestry5.json.JSONObject;
 import org.apache.tapestry5.services.UpdateListenerHub;
 
 import java.io.File;
@@ -179,8 +177,6 @@ public final class TapestryIOCModule
      * <li>Collection to Object[] (via the toArray() method)
      * <li>{@link Flow} to List</li>
      * <li>{@link Flow} to Boolean (false if empty)</li>
-     * <li>{@link String} to {@link JSONObject}</li>
-     * <li>{@link String} to {@link JSONArray}</li>
      * </ul>
      */
     @Contribute(TypeCoercer.class)
@@ -428,21 +424,6 @@ public final class TapestryIOCModule
             }
         });
 
-        add(configuration, String.class, JSONArray.class, new Coercion<String, JSONArray>()
-        {
-            public JSONArray coerce(String input)
-            {
-                return new JSONArray(input);
-            }
-        });
-
-        add(configuration, String.class, JSONObject.class, new Coercion<String, JSONObject>()
-        {
-            public JSONObject coerce(String input)
-            {
-                return new JSONObject(input);
-            }
-        });
     }
 
     private static <S, T> void add(Configuration<CoercionTuple> configuration, Class<S> sourceType,

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/TypeCoercerImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/TypeCoercerImplTest.java?rev=1152665&r1=1152664&r2=1152665&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/TypeCoercerImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/TypeCoercerImplTest.java Mon Aug  1 00:10:38 2011
@@ -21,8 +21,6 @@ import org.apache.tapestry5.ioc.internal
 import org.apache.tapestry5.ioc.services.Coercion;
 import org.apache.tapestry5.ioc.services.TypeCoercer;
 import org.apache.tapestry5.ioc.util.TimeInterval;
-import org.apache.tapestry5.json.JSONArray;
-import org.apache.tapestry5.json.JSONObject;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.DataProvider;
@@ -87,14 +85,18 @@ public class TypeCoercerImplTest extends
         assertEquals(coercer.explain(Integer.class, Integer.class), "");
     }
 
-    /** TAP5-917 */
+    /**
+     * TAP5-917
+     */
     @Test
     public void explain_primitive_to_wrapper_type()
     {
         assertEquals(coercer.explain(int.class, Integer.class), "");
     }
 
-    /** TAP5-917 */
+    /**
+     * TAP5-917
+     */
     @Test
     public void explain_wrapper_to_primitive_type()
     {
@@ -122,8 +124,7 @@ public class TypeCoercerImplTest extends
         {
             coercer.coerce("", Map.class);
             unreachable();
-        }
-        catch (RuntimeException ex)
+        } catch (RuntimeException ex)
         {
             assertTrue(ex.getMessage().contains(
                     "Could not find a coercion from type java.lang.String to type java.util.Map"));
@@ -137,8 +138,7 @@ public class TypeCoercerImplTest extends
         {
             coercer.coerce(Collections.EMPTY_MAP, Float.class);
             unreachable();
-        }
-        catch (RuntimeException ex)
+        } catch (RuntimeException ex)
         {
             assertTrue(ex
                     .getMessage()
@@ -176,124 +176,120 @@ public class TypeCoercerImplTest extends
         byte byte1 = 12, byte2 = 56;
         short short1 = 34, short2 = 98;
         return new Object[][]
-        {
-                // There's a lot of these!
+                {
+                        // There's a lot of these!
 
-                { this, String.class, toString() },
+                        {this, String.class, toString()},
 
-                { 55l, Integer.class, 55 },
+                        {55l, Integer.class, 55},
 
-                { "", Boolean.class, false },
+                        {"", Boolean.class, false},
 
-                { "  ", Boolean.class, false },
+                        {"  ", Boolean.class, false},
 
-                { "x", Boolean.class, true },
+                        {"x", Boolean.class, true},
 
-                { " z ", Boolean.class, true },
+                        {" z ", Boolean.class, true},
 
-                { "false", Boolean.class, false },
+                        {"false", Boolean.class, false},
 
-                { "  False ", Boolean.class, false },
+                        {"  False ", Boolean.class, false},
 
-                { null, Boolean.class, false },
+                        {null, Boolean.class, false},
 
-                { new Double(256), Integer.class, new Integer(256) },
+                        {new Double(256), Integer.class, new Integer(256)},
 
-                { new Double(22.7), Integer.class, new Integer(22) },
+                        {new Double(22.7), Integer.class, new Integer(22)},
 
-                { new Integer(0), Boolean.class, false },
+                        {new Integer(0), Boolean.class, false},
 
-                { new Long(32838), Boolean.class, true },
+                        {new Long(32838), Boolean.class, true},
 
-                { new Integer(127), Byte.class, new Byte("127") },
+                        {new Integer(127), Byte.class, new Byte("127")},
 
-                { new Double(58), Short.class, new Short("58") },
+                        {new Double(58), Short.class, new Short("58")},
 
-                { new Integer(33), Long.class, new Long(33) },
+                        {new Integer(33), Long.class, new Long(33)},
 
-                { new Integer(22), Float.class, new Float(22) },
+                        {new Integer(22), Float.class, new Float(22)},
 
-                { new Integer(1234), Double.class, new Double(1234) },
+                        {new Integer(1234), Double.class, new Double(1234)},
 
-                { floatValue, Double.class, floatValue.doubleValue() },
+                        {floatValue, Double.class, floatValue.doubleValue()},
 
-                { Collections.EMPTY_LIST, Boolean.class, false },
+                        {Collections.EMPTY_LIST, Boolean.class, false},
 
-                { Collections.singleton(this), Boolean.class, true },
+                        {Collections.singleton(this), Boolean.class, true},
 
-                { bigDecimalValue, BigDecimal.class, new BigDecimal(bigDecimalValue) },
+                        {bigDecimalValue, BigDecimal.class, new BigDecimal(bigDecimalValue)},
 
-                { new BigDecimal(bigDecimalValue), Double.class, 1.2345656748352436E49 },
+                        {new BigDecimal(bigDecimalValue), Double.class, 1.2345656748352436E49},
 
-                { bigIntegerValue, BigInteger.class, new BigInteger(bigIntegerValue) },
+                        {bigIntegerValue, BigInteger.class, new BigInteger(bigIntegerValue)},
 
-                { new BigInteger("12345678"), Long.class, 12345678l },
+                        {new BigInteger("12345678"), Long.class, 12345678l},
 
-                { -12345678l, BigInteger.class, new BigInteger("-12345678") },
+                        {-12345678l, BigInteger.class, new BigInteger("-12345678")},
 
-                { object, List.class, Collections.singletonList(object) },
+                        {object, List.class, Collections.singletonList(object)},
 
-                { null, Iterable.class, null },
+                        {null, Iterable.class, null},
 
-                { null, List.class, null },
+                        {null, List.class, null},
 
-                { null, Collection.class, null },
+                        {null, Collection.class, null},
 
-                { null, String.class, null },
+                        {null, String.class, null},
 
-                { new Object[]
-                { "a", 123 }, List.class, Arrays.asList("a", 123) },
+                        {new Object[]
+                                {"a", 123}, List.class, Arrays.asList("a", 123)},
 
-                { new String[]
-                { "a", "b" }, List.class, Arrays.asList("a", "b") },
+                        {new String[]
+                                {"a", "b"}, List.class, Arrays.asList("a", "b")},
 
-                { new byte[]
-                { byte1, byte2 }, List.class, Arrays.asList(byte1, byte2) },
+                        {new byte[]
+                                {byte1, byte2}, List.class, Arrays.asList(byte1, byte2)},
 
-                { new short[]
-                { short1, short2 }, List.class, Arrays.asList(short1, short2) },
+                        {new short[]
+                                {short1, short2}, List.class, Arrays.asList(short1, short2)},
 
-                { new int[]
-                { 1, 2 }, List.class, Arrays.asList(1, 2) },
+                        {new int[]
+                                {1, 2}, List.class, Arrays.asList(1, 2)},
 
-                { new long[]
-                { 123L, 321L }, List.class, Arrays.asList(123L, 321L) },
+                        {new long[]
+                                {123L, 321L}, List.class, Arrays.asList(123L, 321L)},
 
-                { new float[]
-                { 3.4f, 7.777f }, List.class, Arrays.asList(3.4f, 7.777f) },
+                        {new float[]
+                                {3.4f, 7.777f}, List.class, Arrays.asList(3.4f, 7.777f)},
 
-                { new double[]
-                { 3.4, 7.777 }, List.class, Arrays.asList(3.4, 7.777) },
+                        {new double[]
+                                {3.4, 7.777}, List.class, Arrays.asList(3.4, 7.777)},
 
-                { new char[]
-                { 'a', 'b' }, List.class, Arrays.asList('a', 'b') },
+                        {new char[]
+                                {'a', 'b'}, List.class, Arrays.asList('a', 'b')},
 
-                { new boolean[]
-                { true, false }, List.class, Arrays.asList(true, false) },
+                        {new boolean[]
+                                {true, false}, List.class, Arrays.asList(true, false)},
 
-                { "foo/bar/baz.txt", File.class, new File("foo/bar/baz.txt") },
+                        {"foo/bar/baz.txt", File.class, new File("foo/bar/baz.txt")},
 
-                { new TimeInterval("2 h"), Long.class, 2 * 60 * 60 * 1000l },
+                        {new TimeInterval("2 h"), Long.class, 2 * 60 * 60 * 1000l},
 
-                { "2 h", TimeInterval.class, new TimeInterval("120 m") },
+                        {"2 h", TimeInterval.class, new TimeInterval("120 m")},
 
-                { F.flow(), Boolean.class, false },
+                        {F.flow(), Boolean.class, false},
 
-                { F.flow(1, 2, 3), Boolean.class, true },
+                        {F.flow(1, 2, 3), Boolean.class, true},
 
-                { F.flow(1, 2, 3), List.class, Arrays.asList(1, 2, 3) },
+                        {F.flow(1, 2, 3), List.class, Arrays.asList(1, 2, 3)},
 
-                { "[1, true]", JSONArray.class, new JSONArray(1, true) },
+                        // TAP5-98:
 
-                { "{ 'fred': 1, 'barney': 2}", JSONObject.class, new JSONObject().put("fred", 1).put("barney", 2) },
+                        {"mixin", AnnotationUseContext.class, AnnotationUseContext.MIXIN},
 
-                // TAP5-98:
+                        // null to arbitrary object is still null
 
-                { "mixin", AnnotationUseContext.class, AnnotationUseContext.MIXIN },
-
-                // null to arbitrary object is still null
-
-                { null, XMLReader.class, null } };
+                        {null, XMLReader.class, null}};
     }
 
     @Test(dataProvider = "explain_inputs")
@@ -306,14 +302,14 @@ public class TypeCoercerImplTest extends
     public Object[][] explain_inputs()
     {
         return new Object[][]
-        {
-        { StringBuffer.class, Integer.class, "Object --> String, String --> Long, Long --> Integer" },
-        { void.class, Map.class, "null --> null" },
-        { void.class, Boolean.class, "null --> Boolean" },
-        { Object[].class, Boolean.class, "Object[] --> java.util.List, java.util.Collection --> Boolean" },
-        { String[].class, List.class, "Object[] --> java.util.List" },
-        { Float.class, Double.class, "Float --> Double" },
-        { Double.class, BigDecimal.class, "Object --> String, String --> java.math.BigDecimal" }, };
+                {
+                        {StringBuffer.class, Integer.class, "Object --> String, String --> Long, Long --> Integer"},
+                        {void.class, Map.class, "null --> null"},
+                        {void.class, Boolean.class, "null --> Boolean"},
+                        {Object[].class, Boolean.class, "Object[] --> java.util.List, java.util.Collection --> Boolean"},
+                        {String[].class, List.class, "Object[] --> java.util.List"},
+                        {Float.class, Double.class, "Float --> Double"},
+                        {Double.class, BigDecimal.class, "Object --> String, String --> java.math.BigDecimal"},};
     }
 
     @Test
@@ -324,7 +320,7 @@ public class TypeCoercerImplTest extends
         Object[] result = coercer.coerce(input, Object[].class);
 
         assertArraysEqual(result, new Object[]
-        { input });
+                {input});
     }
 
     @Test
@@ -337,7 +333,9 @@ public class TypeCoercerImplTest extends
         assertArraysEqual(result, input.toArray());
     }
 
-    /** TAP5-1141 */
+    /**
+     * TAP5-1141
+     */
     @Test
     public void object_whose_toString_returns_null_to_boolean()
     {

Modified: tapestry/tapestry5/trunk/tapestry-json/build.gradle
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-json/build.gradle?rev=1152665&r1=1152664&r2=1152665&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-json/build.gradle (original)
+++ tapestry/tapestry5/trunk/tapestry-json/build.gradle Mon Aug  1 00:10:38 2011
@@ -2,6 +2,13 @@ description = "Repackaged, improved (and
 
 dependencies {
 
-  testCompile project(':tapestry-test')
+    provided project(':tapestry-ioc')
+    testCompile project(':tapestry-test')
 
+}
+
+jar {
+    manifest {
+        attributes 'Tapestry-Module-Classes': 'org.apache.tapestry5.json.services.JSONModule'
+    }
 }
\ No newline at end of file

Copied: tapestry/tapestry5/trunk/tapestry-json/src/main/java/org/apache/tapestry5/internal/json/StringToJSONArray.java (from r1152388, tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/json/StringToJSONArray.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-json/src/main/java/org/apache/tapestry5/internal/json/StringToJSONArray.java?p2=tapestry/tapestry5/trunk/tapestry-json/src/main/java/org/apache/tapestry5/internal/json/StringToJSONArray.java&p1=tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/json/StringToJSONArray.java&r1=1152388&r2=1152665&rev=1152665&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/json/StringToJSONArray.java (original)
+++ tapestry/tapestry5/trunk/tapestry-json/src/main/java/org/apache/tapestry5/internal/json/StringToJSONArray.java Mon Aug  1 00:10:38 2011
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package org.apache.tapestry5.internal.services.json;
+package org.apache.tapestry5.internal.json;
 
 import org.apache.tapestry5.ioc.services.Coercion;
 import org.apache.tapestry5.json.JSONArray;

Copied: tapestry/tapestry5/trunk/tapestry-json/src/main/java/org/apache/tapestry5/internal/json/StringToJSONObject.java (from r1152388, tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/json/StringToJSONObject.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-json/src/main/java/org/apache/tapestry5/internal/json/StringToJSONObject.java?p2=tapestry/tapestry5/trunk/tapestry-json/src/main/java/org/apache/tapestry5/internal/json/StringToJSONObject.java&p1=tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/json/StringToJSONObject.java&r1=1152388&r2=1152665&rev=1152665&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/json/StringToJSONObject.java (original)
+++ tapestry/tapestry5/trunk/tapestry-json/src/main/java/org/apache/tapestry5/internal/json/StringToJSONObject.java Mon Aug  1 00:10:38 2011
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package org.apache.tapestry5.internal.services.json;
+package org.apache.tapestry5.internal.json;
 
 import org.apache.tapestry5.ioc.services.Coercion;
 import org.apache.tapestry5.json.JSONObject;

Added: tapestry/tapestry5/trunk/tapestry-json/src/main/java/org/apache/tapestry5/json/services/JSONModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-json/src/main/java/org/apache/tapestry5/json/services/JSONModule.java?rev=1152665&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-json/src/main/java/org/apache/tapestry5/json/services/JSONModule.java (added)
+++ tapestry/tapestry5/trunk/tapestry-json/src/main/java/org/apache/tapestry5/json/services/JSONModule.java Mon Aug  1 00:10:38 2011
@@ -0,0 +1,48 @@
+// Copyright 2011 The Apache Software Foundation
+//
+// Licensed 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.
+
+package org.apache.tapestry5.json.services;
+
+import org.apache.tapestry5.internal.json.StringToJSONArray;
+import org.apache.tapestry5.internal.json.StringToJSONObject;
+import org.apache.tapestry5.ioc.Configuration;
+import org.apache.tapestry5.ioc.annotations.Contribute;
+import org.apache.tapestry5.ioc.services.CoercionTuple;
+import org.apache.tapestry5.ioc.services.TypeCoercer;
+import org.apache.tapestry5.json.JSONArray;
+import org.apache.tapestry5.json.JSONObject;
+
+/**
+ * A module that integrates JSON into Tapestry in terms of type coercions.  tapestry-json can still
+ * be used independently of the rest of Tapestry (since its a 'provided' dependency),
+ * but when used with tapestry-ioc on the classpath, the coercions described by this module become available.
+ *
+ * @since 5.3
+ */
+public class JSONModule
+{
+    /**
+     * <ul>
+     * <li>{@link String} to {@link org.apache.tapestry5.json.JSONObject}</li>
+     * <li>{@link String} to {@link org.apache.tapestry5.json.JSONArray}</li>
+     * </ul>
+     */
+    @Contribute(TypeCoercer.class)
+    public static void provideCoercions(Configuration<CoercionTuple> configuration)
+    {
+        configuration.add(CoercionTuple.create(String.class, JSONObject.class, new StringToJSONObject()));
+
+        configuration.add(CoercionTuple.create(String.class, JSONArray.class, new StringToJSONArray()));
+    }
+}