svn commit: r944571 - in /tapestry/tapestry5/trunk/tapestry-core/src: main/java/org/apache/tapestry5/ main/java/org/apache/tapestry5/internal/services/ajax/ main/java/org/apache/tapestry5/json/ main/java/org/apache/tapestry5/services/ test/java/org/apa...

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

svn commit: r944571 - in /tapestry/tapestry5/trunk/tapestry-core/src: main/java/org/apache/tapestry5/ main/java/org/apache/tapestry5/internal/services/ajax/ main/java/org/apache/tapestry5/json/ main/java/org/apache/tapestry5/services/ test/java/org/apa...

hlship
Author: hlship
Date: Sat May 15 05:22:52 2010
New Revision: 944571

URL: http://svn.apache.org/viewvc?rev=944571&view=rev
Log:
TAP5-1153: When in development mode, Tapestry should pretty-print JSON content

Added:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/CompactSession.java   (with props)
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONPrintSession.java   (with props)
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/PrettyPrintSession.java   (with props)
Modified:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ajax/JavascriptSupportImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONArray.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONLiteral.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONObject.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONString.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/JSONArrayEventResultProcessorTest.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/PartialMarkupDocumentLinkerTest.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ajax/JavascriptSupportImplTest.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/json/JSONObjectTest.java

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java?rev=944571&r1=944570&r2=944571&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java Sat May 15 05:22:52 2010
@@ -293,4 +293,12 @@ public class SymbolConstants
      */
     public static final String DEFAULT_JAVASCRIPT = "tapestry.default-javascript";
 
+    /**
+     * If "true", then JSON page initialization content is compressed; if false
+     * then extra white space is added (pretty printing). Defaults to "true" in production mode.
+     *
+     * @since 5.2.0
+     */
+    public static final String COMPACT_JSON = "tapestry.compact-json";
+
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ajax/JavascriptSupportImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ajax/JavascriptSupportImpl.java?rev=944571&r1=944570&r2=944571&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ajax/JavascriptSupportImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ajax/JavascriptSupportImpl.java Sat May 15 05:22:52 2010
@@ -57,6 +57,8 @@ public class JavascriptSupportImpl imple
 
     private final boolean partialMode;
 
+    private final boolean compactMode;
+
     // Using a Map as a case-insensitive set of stack names.
 
     private final Map<String, Boolean> addedStacks = CollectionFactory.newCaseInsensitiveMap();
@@ -88,18 +90,20 @@ public class JavascriptSupportImpl imple
     };
 
     public JavascriptSupportImpl(DocumentLinker linker, JavascriptStackSource javascriptStackSource,
-            JavascriptStackPathConstructor stackPathConstructor)
+            JavascriptStackPathConstructor stackPathConstructor, boolean compactMode)
     {
-        this(linker, javascriptStackSource, stackPathConstructor, new IdAllocator(), false);
+        this(linker, javascriptStackSource, stackPathConstructor, new IdAllocator(), false, compactMode);
     }
 
     public JavascriptSupportImpl(DocumentLinker linker, JavascriptStackSource javascriptStackSource,
-            JavascriptStackPathConstructor stackPathConstructor, IdAllocator idAllocator, boolean partialMode)
+            JavascriptStackPathConstructor stackPathConstructor, IdAllocator idAllocator, boolean partialMode,
+            boolean compactMode)
     {
         this.linker = linker;
         this.idAllocator = idAllocator;
         this.javascriptStackSource = javascriptStackSource;
         this.partialMode = partialMode;
+        this.compactMode = compactMode | partialMode;
         this.stackPathConstructor = stackPathConstructor;
 
         // In partial mode, assume that the infrastructure stack is already present
@@ -183,7 +187,11 @@ public class JavascriptSupportImpl imple
             JSONObject init = inits.get(p);
 
             if (init != null)
-                addScript(p, "Tapestry.init(%s);", init);
+            {
+                String printed = compactMode ? init.toCompactString() : init.toString();
+
+                addScript(p, "Tapestry.init(%s);", printed);
+            }
         }
     }
 

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/CompactSession.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/CompactSession.java?rev=944571&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/CompactSession.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/CompactSession.java Sat May 15 05:22:52 2010
@@ -0,0 +1,67 @@
+// Copyright 2010 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;
+
+import java.io.PrintWriter;
+
+/**
+ * Prints the JSON content compactly, with no indentation or extra whitespace.
+ *
+ * @since 5.2.0
+ */
+class CompactSession implements JSONPrintSession
+{
+    private final PrintWriter writer;
+
+    public CompactSession(PrintWriter writer)
+    {
+        this.writer = writer;
+    }
+
+    public JSONPrintSession indent()
+    {
+        return this;
+    }
+
+    public JSONPrintSession newline()
+    {
+        return this;
+    }
+
+    public JSONPrintSession outdent()
+    {
+        return this;
+    }
+
+    public JSONPrintSession print(String value)
+    {
+        writer.print(value);
+
+        return this;
+    }
+
+    public JSONPrintSession printQuoted(String value)
+    {
+        return print(JSONObject.quote(value));
+    }
+
+    public JSONPrintSession printSymbol(char symbol)
+    {
+        writer.print(symbol);
+
+        return this;
+    }
+
+}

Propchange: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/CompactSession.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONArray.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONArray.java?rev=944571&r1=944570&r2=944571&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONArray.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONArray.java Sat May 15 05:22:52 2010
@@ -4,7 +4,7 @@
 // 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
+// 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,
@@ -15,33 +15,30 @@
 package org.apache.tapestry5.json;
 
 /*
- Copyright (c) 2002 JSON.org
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- The Software shall be used for Good, not Evil.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
+ * Copyright (c) 2002 JSON.org
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * The Software shall be used for Good, not Evil.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
  */
 
-import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
-
+import java.io.PrintWriter;
 import java.util.List;
 
+import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
+
 /**
  * A JSONArray is an ordered sequence of values. Its external text form is a string wrapped in square brackets with
  * commas separating the values. The internal form is an object having <code>get</code> and <code>opt</code> methods for
@@ -59,17 +56,21 @@ import java.util.List;
  * There are also typed <code>get</code> and <code>opt</code> methods that do type checking and type coersion for you.
  * <p/>
  * The texts produced by the <code>toString</code> methods strictly conform to JSON syntax rules. The constructors are
- * more forgiving in the texts they will accept: <ul> <li>An extra <code>,</code>&nbsp;<small>(comma)</small> may appear
- * just before the closing bracket.</li> <li>The <code>null</code> value will be inserted when there is
- * <code>,</code>&nbsp;<small>(comma)</small> elision.</li> <li>Strings may be quoted with
- * <code>'</code>&nbsp;<small>(single quote)</small>.</li> <li>Strings do not need to be quoted at all if they do not
- * begin with a quote or single quote, and if they do not contain leading or trailing spaces, and if they do not contain
- * any of these characters: <code>{ } [ ] / \ : , = ; #</code> and if they do not look like numbers and if they are not
- * the reserved words <code>true</code>, <code>false</code>, or <code>null</code>.</li> <li>Values can be separated by
- * <code>;</code> <small>(semicolon)</small> as well as by <code>,</code> <small>(comma)</small>.</li> <li>Numbers may
- * have the <code>0-</code> <small>(octal)</small> or <code>0x-</code> <small>(hex)</small> prefix.</li> <li>Comments
- * written in the slashshlash, slashstar, and hash conventions will be ignored.</li> </ul>
- *
+ * more forgiving in the texts they will accept:
+ * <ul>
+ * <li>An extra <code>,</code>&nbsp;<small>(comma)</small> may appear just before the closing bracket.</li>
+ * <li>The <code>null</code> value will be inserted when there is <code>,</code>&nbsp;<small>(comma)</small> elision.</li>
+ * <li>Strings may be quoted with <code>'</code>&nbsp;<small>(single quote)</small>.</li>
+ * <li>Strings do not need to be quoted at all if they do not begin with a quote or single quote, and if they do not
+ * contain leading or trailing spaces, and if they do not contain any of these characters:
+ * <code>{ } [ ] / \ : , = ; #</code> and if they do not look like numbers and if they are not the reserved words
+ * <code>true</code>, <code>false</code>, or <code>null</code>.</li>
+ * <li>Values can be separated by <code>;</code> <small>(semicolon)</small> as well as by <code>,</code>
+ * <small>(comma)</small>.</li>
+ * <li>Numbers may have the <code>0-</code> <small>(octal)</small> or <code>0x-</code> <small>(hex)</small> prefix.</li>
+ * <li>Comments written in the slashshlash, slashstar, and hash conventions will be ignored.</li>
+ * </ul>
+ *
  * @author JSON.org
  * @version 2
  */
@@ -97,14 +98,17 @@ public final class JSONArray
 
     public JSONArray(Object... values)
     {
-        for (Object value : values) put(value);
+        for (Object value : values)
+            put(value);
     }
 
     /**
      * Construct a JSONArray from a JSONTokener.
-     *
-     * @param tokenizer A JSONTokener
-     * @throws RuntimeException If there is a syntax error.
+     *
+     * @param tokenizer
+     *            A JSONTokener
+     * @throws RuntimeException
+     *             If there is a syntax error.
      */
     JSONArray(JSONTokener tokenizer)
     {
@@ -115,16 +119,9 @@ public final class JSONArray
 
     private void parse(JSONTokener tokenizer)
     {
-        if (tokenizer.nextClean() != '[')
-        {
-            throw tokenizer
-                    .syntaxError("A JSONArray text must start with '['");
-        }
+        if (tokenizer.nextClean() != '[') { throw tokenizer.syntaxError("A JSONArray text must start with '['"); }
 
-        if (tokenizer.nextClean() == ']')
-        {
-            return;
-        }
+        if (tokenizer.nextClean() == ']') { return; }
 
         tokenizer.back();
 
@@ -145,10 +142,7 @@ public final class JSONArray
             {
                 case ';':
                 case ',':
-                    if (tokenizer.nextClean() == ']')
-                    {
-                        return;
-                    }
+                    if (tokenizer.nextClean() == ']') { return; }
                     tokenizer.back();
                     break;
 
@@ -163,10 +157,12 @@ public final class JSONArray
 
     /**
      * Get the object value associated with an index.
-     *
-     * @param index The index must be between 0 and length() - 1.
+     *
+     * @param index
+     *            The index must be between 0 and length() - 1.
      * @return An object value.
-     * @throws RuntimeException If there is no value for the index.
+     * @throws RuntimeException
+     *             If there is no value for the index.
      */
     public Object get(int index)
     {
@@ -175,27 +171,28 @@ public final class JSONArray
 
     /**
      * Get the boolean value associated with an index. The string values "true" and "false" are converted to boolean.
-     *
-     * @param index The index must be between 0 and length() - 1.
+     *
+     * @param index
+     *            The index must be between 0 and length() - 1.
      * @return The truth.
-     * @throws RuntimeException If there is no value for the index or if the value is not convertable to boolean.
+     * @throws RuntimeException
+     *             If there is no value for the index or if the value is not convertable to boolean.
      */
     public boolean getBoolean(int index)
     {
         Object value = get(index);
 
-        if (value instanceof Boolean)
-        {
-            return (Boolean) value;
-        }
+        if (value instanceof Boolean) { return (Boolean) value; }
 
         if (value instanceof String)
         {
             String asString = (String) value;
 
-            if (asString.equalsIgnoreCase("false")) return false;
+            if (asString.equalsIgnoreCase("false"))
+                return false;
 
-            if (asString.equalsIgnoreCase("true")) return true;
+            if (asString.equalsIgnoreCase("true"))
+                return true;
         }
 
         throw new RuntimeException("JSONArray[" + index + "] is not a Boolean.");
@@ -203,10 +200,12 @@ public final class JSONArray
 
     /**
      * Get the double value associated with an index.
-     *
-     * @param index The index must be between 0 and length() - 1.
+     *
+     * @param index
+     *            The index must be between 0 and length() - 1.
      * @return The value.
-     * @throws IllegalArgumentException If the key is not found or if the value cannot be converted to a number.
+     * @throws IllegalArgumentException
+     *             If the key is not found or if the value cannot be converted to a number.
      */
     public double getDouble(int index)
     {
@@ -214,7 +213,8 @@ public final class JSONArray
 
         try
         {
-            if (value instanceof Number) return ((Number) value).doubleValue();
+            if (value instanceof Number)
+                return ((Number) value).doubleValue();
 
             return Double.valueOf((String) value);
         }
@@ -226,11 +226,13 @@ public final class JSONArray
 
     /**
      * Get the int value associated with an index.
-     *
-     * @param index The index must be between 0 and length() - 1.
+     *
+     * @param index
+     *            The index must be between 0 and length() - 1.
      * @return The value.
-     * @throws IllegalArgumentException If the key is not found or if the value cannot be converted to a number. if the
-     *                                  value cannot be converted to a number.
+     * @throws IllegalArgumentException
+     *             If the key is not found or if the value cannot be converted to a number. if the
+     *             value cannot be converted to a number.
      */
     public int getInt(int index)
     {
@@ -240,46 +242,46 @@ public final class JSONArray
 
     /**
      * Get the JSONArray associated with an index.
-     *
-     * @param index The index must be between 0 and length() - 1.
+     *
+     * @param index
+     *            The index must be between 0 and length() - 1.
      * @return A JSONArray value.
-     * @throws RuntimeException If there is no value for the index. or if the value is not a JSONArray
+     * @throws RuntimeException
+     *             If there is no value for the index. or if the value is not a JSONArray
      */
     public JSONArray getJSONArray(int index)
     {
         Object o = get(index);
-        if (o instanceof JSONArray)
-        {
-            return (JSONArray) o;
-        }
+        if (o instanceof JSONArray) { return (JSONArray) o; }
 
         throw new RuntimeException("JSONArray[" + index + "] is not a JSONArray.");
     }
 
     /**
      * Get the JSONObject associated with an index.
-     *
-     * @param index subscript
+     *
+     * @param index
+     *            subscript
      * @return A JSONObject value.
-     * @throws RuntimeException If there is no value for the index or if the value is not a JSONObject
+     * @throws RuntimeException
+     *             If there is no value for the index or if the value is not a JSONObject
      */
     public JSONObject getJSONObject(int index)
     {
         Object o = get(index);
-        if (o instanceof JSONObject)
-        {
-            return (JSONObject) o;
-        }
+        if (o instanceof JSONObject) { return (JSONObject) o; }
 
         throw new RuntimeException("JSONArray[" + index + "] is not a JSONObject.");
     }
 
     /**
      * Get the long value associated with an index.
-     *
-     * @param index The index must be between 0 and length() - 1.
+     *
+     * @param index
+     *            The index must be between 0 and length() - 1.
      * @return The value.
-     * @throws IllegalArgumentException If the key is not found or if the value cannot be converted to a number.
+     * @throws IllegalArgumentException
+     *             If the key is not found or if the value cannot be converted to a number.
      */
     public long getLong(int index)
     {
@@ -289,10 +291,12 @@ public final class JSONArray
 
     /**
      * Get the string associated with an index.
-     *
-     * @param index The index must be between 0 and length() - 1.
+     *
+     * @param index
+     *            The index must be between 0 and length() - 1.
      * @return A string value.
-     * @throws RuntimeException If there is no value for the index.
+     * @throws RuntimeException
+     *             If there is no value for the index.
      */
     public String getString(int index)
     {
@@ -301,8 +305,9 @@ public final class JSONArray
 
     /**
      * Determine if the value is null.
-     *
-     * @param index The index must be between 0 and length() - 1.
+     *
+     * @param index
+     *            The index must be between 0 and length() - 1.
      * @return true if the value at the index is null, or if there is no value.
      */
     public boolean isNull(int index)
@@ -311,31 +316,8 @@ public final class JSONArray
     }
 
     /**
-     * Make a string from the contents of this JSONArray. The <code>separator</code> string is inserted between each
-     * element. Warning: This method assumes that the data structure is acyclical.
-     *
-     * @param separator A string that will be inserted between the elements.
-     * @return a string.
-     * @throws RuntimeException If the array contains an invalid number.
-     */
-    public String join(String separator)
-    {
-        int len = length();
-        StringBuilder buffer = new StringBuilder();
-
-        for (int i = 0; i < len; i += 1)
-        {
-            if (i > 0) buffer.append(separator);
-
-            buffer.append(JSONObject.valueToString(list.get(i)));
-        }
-
-        return buffer.toString();
-    }
-
-    /**
      * Get the number of elements in the JSONArray, included nulls.
-     *
+     *
      * @return The length (or size).
      */
     public int length()
@@ -345,9 +327,10 @@ public final class JSONArray
 
     /**
      * Append an object value. This increases the array's length by one.
-     *
-     * @param value An object value. The value should be a Boolean, Double, Integer, JSONArray, JSONObject, JSONLiteral,
-     *              Long, or String, or the JSONObject.NULL singleton.
+     *
+     * @param value
+     *            An object value. The value should be a Boolean, Double, Integer, JSONArray, JSONObject, JSONLiteral,
+     *            Long, or String, or the JSONObject.NULL singleton.
      * @return
      */
     public JSONArray put(Object value)
@@ -364,21 +347,21 @@ public final class JSONArray
     /**
      * Put or replace an object value in the JSONArray. If the index is greater than the length of the JSONArray, then
      * null elements will be added as necessary to pad it out.
-     *
-     * @param index The subscript.
-     * @param value The value to put into the array. The value should be a Boolean, Double, Integer, JSONArray,
-     *              JSONObject, JSONString, Long, or String, or the JSONObject.NULL singeton.
+     *
+     * @param index
+     *            The subscript.
+     * @param value
+     *            The value to put into the array. The value should be a Boolean, Double, Integer, JSONArray,
+     *            JSONObject, JSONString, Long, or String, or the JSONObject.NULL singeton.
      * @return
-     * @throws RuntimeException If the index is negative or if the the value is an invalid number.
+     * @throws RuntimeException
+     *             If the index is negative or if the the value is an invalid number.
      */
     public JSONArray put(int index, Object value)
     {
         assert value != null;
 
-        if (index < 0)
-        {
-            throw new RuntimeException("JSONArray[" + index + "] not found.");
-        }
+        if (index < 0) { throw new RuntimeException("JSONArray[" + index + "] not found."); }
 
         JSONObject.testValidity(value);
 
@@ -388,7 +371,8 @@ public final class JSONArray
         }
         else
         {
-            while (index != length()) list.add(JSONObject.NULL);
+            while (index != length())
+                list.add(JSONObject.NULL);
 
             list.add(value);
         }
@@ -397,27 +381,21 @@ public final class JSONArray
     }
 
     /**
-     * Make a JSON text of this JSONArray. For compactness, no unnecessary whitespace is added. If it is not possible to
-     * produce a syntactically correct JSON text then null will be returned instead. This could occur if the array
-     * contains an invalid number.
+     * Make a JSON text of this JSONArray.
      * <p/>
      * Warning: This method assumes that the data structure is acyclical.
-     *
+     * <p>
+     * Starting in release 5.2, the result will be pretty printed for readability.
+     *
      * @return a printable, displayable, transmittable representation of the array.
      */
     @Override
     public String toString()
     {
-        try
-        {
-            return '[' + join(",") + ']';
-        }
-        catch (Exception e)
-        {
-            return null;
-        }
+        return JSONObject.toString(this);
     }
 
+    /** Used for testing. */
     Object[] toArray()
     {
         return list.toArray();
@@ -426,12 +404,66 @@ public final class JSONArray
     @Override
     public boolean equals(Object obj)
     {
-        if (obj == null) return false;
+        if (obj == null)
+            return false;
 
-        if (!(obj instanceof JSONArray)) return false;
+        if (!(obj instanceof JSONArray))
+            return false;
 
         JSONArray other = (JSONArray) obj;
 
         return list.equals(other.list);
     }
+
+    void print(JSONPrintSession session)
+    {
+        session.printSymbol('[');
+
+        session.indent();
+
+        boolean comma = false;
+
+        for (Object value : list)
+        {
+            if (comma)
+                session.printSymbol(',');
+
+            session.newline();
+
+            JSONObject.printValue(session, value);
+
+            comma = true;
+        }
+
+        session.outdent();
+
+        if (comma)
+            session.newline();
+
+        session.printSymbol(']');
+    }
+
+    /**
+     * Prints the JSONArray to the writer compactly (with no extra whitespace).
+     *
+     * @since 5.2.0
+     */
+    public JSONArray print(PrintWriter writer)
+    {
+        print(new CompactSession(writer));
+
+        return this;
+    }
+
+    /**
+     * Prints the JSONArray to the writer using indentation (two spaces per indentation level).
+     *
+     * @since 5.2.0
+     */
+    public JSONArray prettyPrint(PrintWriter writer)
+    {
+        print(new PrettyPrintSession(writer));
+
+        return this;
+    }
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONLiteral.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONLiteral.java?rev=944571&r1=944570&r2=944571&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONLiteral.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONLiteral.java Sat May 15 05:22:52 2010
@@ -4,7 +4,7 @@
 // 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
+// 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,
@@ -18,10 +18,10 @@ package org.apache.tapestry5.json;
  * A way of including some text (often, text that violates the normal JSON specification) as part of a JSON object or
  * array. This is used in a few places where data is nominally JSON but actually includes some non-conformant elements,
  * such as an inline function definition.
- *
+ *
  * @since 5.1.0.2
  */
-public class JSONLiteral
+public class JSONLiteral implements JSONString
 {
     private final String text;
 
@@ -32,7 +32,7 @@ public class JSONLiteral
 
     /**
      * Returns the text property; this is also the value placed into the JSON string (unquoted, exactly as is).
-     *
+     *
      * @return the text
      */
     @Override
@@ -40,5 +40,9 @@ public class JSONLiteral
     {
         return text;
     }
-}
 
+    public String toJSONString()
+    {
+        return text;
+    }
+}

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONObject.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONObject.java?rev=944571&r1=944570&r2=944571&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONObject.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONObject.java Sat May 15 05:22:52 2010
@@ -37,6 +37,8 @@ package org.apache.tapestry5.json;
 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
 import org.apache.tapestry5.ioc.internal.util.InternalUtils;
 
+import java.io.CharArrayWriter;
+import java.io.PrintWriter;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -90,7 +92,7 @@ import java.util.Set;
  * <p/>
  * Finally, support for the {@link org.apache.tapestry5.json.JSONLiteral} type has been added, which allow the exact
  * output to be controlled; useful when a JSONObject is being used as a configuration object, and must contain values
- * that are not simple data, such as an inline function.
+ * that are not simple data, such as an inline function (technically making the result not JSON).
  *
  * @author JSON.org
  * @version 2
@@ -104,7 +106,7 @@ public final class JSONObject
      * JSONObject.NULL is equivalent to the value that JavaScript calls null, whilst Java's null is equivalent to the
      * value that JavaScript calls undefined.
      */
-    private static final class Null
+    private static final class Null implements JSONString
     {
         /**
          * A Null object is equal to the null value and to itself.
@@ -129,6 +131,11 @@ public final class JSONObject
         {
             return "null";
         }
+
+        public String toJSONString()
+        {
+            return "null";
+        }
     }
 
     /**
@@ -799,9 +806,11 @@ public final class JSONObject
 
     /**
      * Make a JSON text of this JSONObject. For compactness, no whitespace is added. If this would not result in a
-     * syntactically correct JSON text, then null will be returned instead.
+     * syntactically correct JSON text, then null will be returned instead
      * <p/>
      * Warning: This method assumes that the data structure is acyclical.
+     * <p>
+     * Starting in release 5.2, the result will be pretty printed for readability.
      *
      * @return a printable, displayable, portable, transmittable representation of the object, beginning with
      *         <code>{</code>&nbsp;<small>(left brace)</small> and ending with <code>}</code>&nbsp;<small>(right
@@ -810,70 +819,156 @@ public final class JSONObject
     @Override
     public String toString()
     {
-        boolean comma = false;
+        return toString(this);
+    }
+
+    /**
+     * Prints the JSONArray as a compact string (not extra punctuation). This is, essentially, what
+     * Tapestry 5.1 did inside {@link #toString()}.
+     *
+     * @since 5.2.0
+     */
+    public String toCompactString()
+    {
+        CharArrayWriter caw = new CharArrayWriter();
+        PrintWriter pw = new PrintWriter(caw);
+
+        print(pw);
+
+        pw.close();
+
+        return caw.toString();
+    }
+
+    /**
+     * Creates a {@link PrettyPrintSession} to print the value (a JSONArray or JSONObject).
+     *
+     * @since 5.2.0
+     */
+    static String toString(Object value)
+    {
+        CharArrayWriter caw = new CharArrayWriter();
+        PrintWriter pw = new PrintWriter(caw);
+
+        JSONPrintSession session = new PrettyPrintSession(pw);
+
+        printValue(session, value);
+
+        pw.close();
+
+        return caw.toString();
+    }
+
+    /**
+     * Prints the JSONObject to the writer compactly (with no extra whitespace).
+     *
+     * @since 5.2.0
+     */
+    public JSONObject print(PrintWriter writer)
+    {
+        print(new CompactSession(writer));
+
+        return this;
+    }
+
+    /**
+     * Prints the JSONObject to the writer using indentation (two spaces per indentation level).
+     *
+     * @since 5.2.0
+     */
+    public JSONObject prettyPrint(PrintWriter writer)
+    {
+        print(new PrettyPrintSession(writer));
 
-        StringBuilder buffer = new StringBuilder("{");
+        return this;
+    }
+
+    /**
+     * Prints the JSONObject using the session.
+     *
+     * @since 5.2.0
+     */
+    void print(JSONPrintSession session)
+    {
+        session.printSymbol('{');
+
+        session.indent();
+
+        boolean comma = false;
 
         for (String key : keys())
         {
             if (comma)
-                buffer.append(',');
+                session.printSymbol(',');
 
-            buffer.append(quote(key));
-            buffer.append(':');
-            buffer.append(valueToString(properties.get(key)));
+            session.newline();
+
+            session.printQuoted(key);
+
+            session.printSymbol(':');
+
+            printValue(session, properties.get(key));
 
             comma = true;
         }
 
-        buffer.append('}');
+        session.outdent();
 
-        return buffer.toString();
+        if (comma)
+            session.newline();
+
+        session.printSymbol('}');
     }
 
     /**
-     * Make a JSON text of an Object value. If the object has an value.toJSONString() method, then that method will be
-     * used to produce the JSON text. The method is required to produce a strictly conforming text. If the object does
-     * not contain a toJSONString method (which is the most common case), then a text will be produced by the rules.
-     * <p/>
-     * Warning: This method assumes that the data structure is acyclical.
+     * Prints a value (a JSONArray or JSONObject, or a value stored in an array or object) using
+     * the session.
      *
-     * @param value
-     *            The value to be serialized.
-     * @return a printable, displayable, transmittable representation of the object, beginning with <code>{</code>
-     *         &nbsp;<small>(left brace)</small> and ending with <code>}</code>&nbsp;<small>(right
-     *         brace)</small>. @ If the value is or contains an invalid number.
+     * @since 5.2.0
      */
-    static String valueToString(Object value)
+    static void printValue(JSONPrintSession session, Object value)
     {
-        if (value == null || value.equals(null)) { return "null"; }
+        if (value instanceof JSONObject)
+        {
+            ((JSONObject) value).print(session);
+            return;
+        }
+
+        if (value instanceof JSONArray)
+        {
+            ((JSONArray) value).print(session);
+            return;
+        }
 
         if (value instanceof JSONString)
         {
-            try
-            {
-                String json = ((JSONString) value).toJSONString();
+            String printValue = ((JSONString) value).toJSONString();
 
-                return quote(json);
-            }
-            catch (Exception e)
-            {
-                throw new RuntimeException(e);
-            }
+            session.print(printValue);
+
+            return;
+        }
+
+        if (value instanceof Number)
+        {
+            String printValue = numberToString((Number) value);
+            session.print(printValue);
+            return;
         }
 
-        if (value instanceof Number) { return numberToString((Number) value); }
+        if (value instanceof Boolean)
+        {
+            session.print(value.toString());
 
-        if (value instanceof Boolean || value instanceof JSONObject || value instanceof JSONArray
-                || value instanceof JSONLiteral) { return value.toString(); }
+            return;
+        }
 
-        return quote(value.toString());
+        // Otherwise it really should just be a string. Nothing else can go in.
+        session.printQuoted(value.toString());
     }
 
     /**
      * Returns true if the other object is a JSONObject and its set of properties matches this object's properties.
-     * <p/>
-     * '
      */
     @Override
     public boolean equals(Object obj)

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONPrintSession.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONPrintSession.java?rev=944571&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONPrintSession.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONPrintSession.java Sat May 15 05:22:52 2010
@@ -0,0 +1,73 @@
+// Copyright 2010 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;
+
+import java.io.PrintWriter;
+
+/**
+ * Encapsulates a {@link PrintWriter} and the rules for indentation and spacing.
+ *
+ * @since 5.2.0
+ */
+interface JSONPrintSession
+{
+    /**
+     * Prints a value as is; the value is assumed to be a string representation of a number of boolean
+     * and not require quotes. A space may be inserted before the value.
+     *
+     * @param value
+     *            unquoted value to print
+     * @return the session (for fluent method invocations)
+     */
+    JSONPrintSession print(String value);
+
+    /**
+     * Prints a value enclosed in double quotes. Any internal quotes are escaped.
+     * A space may be inserted before the value.
+     *
+     * @param value
+     *            the string to be printed enclosed in quotes
+     * @return the session (for fluent method invocations)
+     */
+    JSONPrintSession printQuoted(String value);
+
+    /**
+     * Begins a new line and the current indentation level.
+     *
+     * @return the session (for fluent method invocations)
+     */
+    JSONPrintSession newline();
+
+    /**
+     * Prints a symbol (i.e., ':', '{', '}', '[', ']', or ','). A space may
+     * be inserted before the symbol.
+     */
+
+    JSONPrintSession printSymbol(char symbol);
+
+    /**
+     * Increments the indentation level.
+     *
+     * @return new session reflecting the indentation
+     */
+    JSONPrintSession indent();
+
+    /**
+     * Decrements the indentation level.
+     *
+     * @return new session reflecting the indentation
+     */
+    JSONPrintSession outdent();
+}

Propchange: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONPrintSession.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONString.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONString.java?rev=944571&r1=944570&r2=944571&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONString.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONString.java Sat May 15 05:22:52 2010
@@ -1,10 +1,10 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 2010 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
+// 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,
@@ -15,16 +15,15 @@
 package org.apache.tapestry5.json;
 
 /**
- * The <code>JSONString</code> interface allows a <code>toJSONString()</code> method so that a class can change the
- * behavior of <code>JSONObject.toString()</code>, <code>JSONArray.toString()</code>, and
- * <code>JSONWriter.value(</code>Object<code>)</code>. The <code>toJSONString</code> method will be used instead of the
- * default behavior of using the Object's <code>toString()</code> method and quoting the result.
+ * An interface that allows an object to be stored as a {@link JSONObject} or {@link JSONArray} value.
+ * When printed, the value of {@link #toJSONString()} is printed without quotes or other substitution; it
+ * is the responsibility of the object to provide proper JSON output.
  */
 public interface JSONString
 {
     /**
      * The <code>toJSONString</code> method allows a class to produce its own JSON serialization.
-     *
+     *
      * @return A strictly syntactically correct JSON text.
      */
     public String toJSONString();

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/PrettyPrintSession.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/PrettyPrintSession.java?rev=944571&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/PrettyPrintSession.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/PrettyPrintSession.java Sat May 15 05:22:52 2010
@@ -0,0 +1,136 @@
+// Copyright 2010 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;
+
+import java.io.PrintWriter;
+
+/**
+ * Used to pretty-print JSON content, with a customizable indentation.
+ *
+ * @since 5.2.0
+ */
+class PrettyPrintSession implements JSONPrintSession
+{
+    private final PrintWriter writer;
+
+    private final String indentString;
+
+    private int indentLevel;
+
+    enum Position
+    {
+        MARGIN, INDENTED, CONTENT
+    };
+
+    private Position position = Position.MARGIN;
+
+    /** Defaults the indentation to be two spaces per indentation level. */
+    public PrettyPrintSession(PrintWriter writer)
+    {
+        this(writer, "  ");
+    }
+
+    /**
+     * @param writer
+     *            to which content is printed
+     * @param indentString
+     *            string used for indentation (written N times, once per current indent level)
+     */
+    public PrettyPrintSession(PrintWriter writer, String indentString)
+    {
+        this.writer = writer;
+        this.indentString = indentString;
+    }
+
+    public JSONPrintSession indent()
+    {
+        indentLevel++;
+
+        return this;
+    }
+
+    public JSONPrintSession newline()
+    {
+        if (position != Position.MARGIN)
+        {
+            writer.write("\n");
+            position = Position.MARGIN;
+        }
+
+        return this;
+    }
+
+    public JSONPrintSession outdent()
+    {
+        indentLevel--;
+
+        return this;
+    }
+
+    private void addIndentation()
+    {
+        if (position == Position.MARGIN)
+        {
+            for (int i = 0; i < indentLevel; i++)
+                writer.print(indentString);
+
+            position = Position.INDENTED;
+        }
+    }
+
+    private void addSep()
+    {
+        if (position == Position.CONTENT)
+        {
+            writer.print(" ");
+        }
+    }
+
+    private void prepareToPrint()
+    {
+        addIndentation();
+
+        addSep();
+    }
+
+    public JSONPrintSession print(String value)
+    {
+        prepareToPrint();
+
+        writer.print(value);
+
+        position = Position.CONTENT;
+
+        return this;
+    }
+
+    public JSONPrintSession printQuoted(String value)
+    {
+        return print(JSONObject.quote(value));
+    }
+
+    public JSONPrintSession printSymbol(char symbol)
+    {
+        addIndentation();
+
+        if (symbol != ',')
+            addSep();
+
+        writer.print(symbol);
+
+        return this;
+    }
+
+}

Propchange: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/json/PrettyPrintSession.java
------------------------------------------------------------------------------
    svn:eol-style = native

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=944571&r1=944570&r2=944571&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 Sat May 15 05:22:52 2010
@@ -1933,6 +1933,9 @@ public final class TapestryModule
     @Symbol(SymbolConstants.TAPESTRY_VERSION)
     final String tapestryVersion,
 
+    @Symbol(SymbolConstants.COMPACT_JSON)
+    final boolean compactJSON,
+
     final SymbolSource symbolSource,
 
     final AssetSource assetSource,
@@ -1967,7 +1970,7 @@ public final class TapestryModule
                 DocumentLinker linker = environment.peekRequired(DocumentLinker.class);
 
                 JavascriptSupportImpl support = new JavascriptSupportImpl(linker, javascriptStackSource,
-                        javascriptStackPathConstructor);
+                        javascriptStackPathConstructor, compactJSON);
 
                 environment.push(JavascriptSupport.class, support);
 
@@ -2130,7 +2133,7 @@ public final class TapestryModule
                 DocumentLinker linker = environment.peekRequired(DocumentLinker.class);
 
                 JavascriptSupportImpl support = new JavascriptSupportImpl(linker, javascriptStackSource,
-                        javascriptStackPathConstructor, idAllocator, true);
+                        javascriptStackPathConstructor, idAllocator, true, true);
 
                 environment.push(JavascriptSupport.class, support);
 
@@ -2440,6 +2443,7 @@ public final class TapestryModule
 
         configuration.add(SymbolConstants.SECURE_ENABLED, matchProductionMode);
         configuration.add(SymbolConstants.COMBINE_SCRIPTS, matchProductionMode);
+        configuration.add(SymbolConstants.COMPACT_JSON, matchProductionMode);
 
         configuration.add(SymbolConstants.ENCODE_LOCALE_INTO_PATH, "true");
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/JSONArrayEventResultProcessorTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/JSONArrayEventResultProcessorTest.java?rev=944571&r1=944570&r2=944571&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/JSONArrayEventResultProcessorTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/JSONArrayEventResultProcessorTest.java Sat May 15 05:22:52 2010
@@ -1,10 +1,10 @@
-//  Copyright 2008 The Apache Software Foundation
+// Copyright 2008, 2010 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
+// 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,
@@ -46,6 +46,6 @@ public class JSONArrayEventResultProcess
 
         verify();
 
-        assertEquals(writer.toString(), "[\"fred\",\"barney\"]");
+        assertEquals(writer.toString(), "[\n  \"fred\",\n  \"barney\"\n]");
     }
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/PartialMarkupDocumentLinkerTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/PartialMarkupDocumentLinkerTest.java?rev=944571&r1=944570&r2=944571&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/PartialMarkupDocumentLinkerTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/PartialMarkupDocumentLinkerTest.java Sat May 15 05:22:52 2010
@@ -1,10 +1,10 @@
-// Copyright 2008 The Apache Software Foundation
+// Copyright 2008, 2010 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
+// 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,
@@ -47,7 +47,7 @@ public class PartialMarkupDocumentLinker
 
         linker.commit(reply);
 
-        assertEquals(reply.toString(), "{\"scripts\":[\"foo.js\",\"bar.js\"]}");
+        assertEquals(reply.toCompactString(), "{\"scripts\":[\"foo.js\",\"bar.js\"]}");
 
     }
 
@@ -62,10 +62,10 @@ public class PartialMarkupDocumentLinker
         JSONObject reply = new JSONObject();
 
         linker.commit(reply);
-        
+
         JSONObject expected = new JSONObject(
-         "{\"stylesheets\":[{\"href\":\"foo.css\",\"media\":\"print\"},{\"href\":\"bar.css\"}]}");
-        
+                "{\"stylesheets\":[{\"href\":\"foo.css\",\"media\":\"print\"},{\"href\":\"bar.css\"}]}");
+
         assertEquals(reply, expected);
 
     }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ajax/JavascriptSupportImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ajax/JavascriptSupportImplTest.java?rev=944571&r1=944570&r2=944571&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ajax/JavascriptSupportImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ajax/JavascriptSupportImplTest.java Sat May 15 05:22:52 2010
@@ -43,7 +43,7 @@ public class JavascriptSupportImplTest e
 
         replay();
 
-        JavascriptSupport jss = new JavascriptSupportImpl(null, null, null);
+        JavascriptSupport jss = new JavascriptSupportImpl(null, null, null, true);
 
         assertEquals(jss.allocateClientId(resources), "tracy");
         assertEquals(jss.allocateClientId(resources), "tracy_0");
@@ -55,7 +55,7 @@ public class JavascriptSupportImplTest e
     @Test
     public void commit_with_no_javascript()
     {
-        JavascriptSupportImpl jss = new JavascriptSupportImpl(null, null, null);
+        JavascriptSupportImpl jss = new JavascriptSupportImpl(null, null, null, true);
 
         jss.commit();
     }
@@ -69,7 +69,7 @@ public class JavascriptSupportImplTest e
 
         replay();
 
-        JavascriptSupportImpl jss = new JavascriptSupportImpl(linker, null, null, new IdAllocator(), true);
+        JavascriptSupportImpl jss = new JavascriptSupportImpl(linker, null, null, new IdAllocator(), true, true);
 
         jss.addScript("doSomething();");
 
@@ -90,7 +90,7 @@ public class JavascriptSupportImplTest e
 
         replay();
 
-        JavascriptSupportImpl jss = new JavascriptSupportImpl(linker, stackSource, pathConstructor);
+        JavascriptSupportImpl jss = new JavascriptSupportImpl(linker, stackSource, pathConstructor, true);
 
         jss.addScript("doSomething();");
 
@@ -161,7 +161,7 @@ public class JavascriptSupportImplTest e
 
         replay();
 
-        JavascriptSupportImpl jss = new JavascriptSupportImpl(linker, stackSource, pathConstructor);
+        JavascriptSupportImpl jss = new JavascriptSupportImpl(linker, stackSource, pathConstructor, true);
 
         jss.addScript(InitializationPriority.IMMEDIATE, "doSomething();");
 
@@ -183,7 +183,7 @@ public class JavascriptSupportImplTest e
 
         replay();
 
-        JavascriptSupportImpl jss = new JavascriptSupportImpl(linker, stackSource, pathConstructor);
+        JavascriptSupportImpl jss = new JavascriptSupportImpl(linker, stackSource, pathConstructor, true);
 
         jss.addScript(InitializationPriority.IMMEDIATE, "immediate1();");
         jss.addScript("normal1();");
@@ -207,7 +207,7 @@ public class JavascriptSupportImplTest e
 
         replay();
 
-        JavascriptSupportImpl jss = new JavascriptSupportImpl(linker, stackSource, pathConstructor);
+        JavascriptSupportImpl jss = new JavascriptSupportImpl(linker, stackSource, pathConstructor, true);
 
         jss.addScript(InitializationPriority.EARLY, "early();");
         jss.addScript(InitializationPriority.NORMAL, "normal();");
@@ -232,7 +232,7 @@ public class JavascriptSupportImplTest e
 
         replay();
 
-        JavascriptSupportImpl jss = new JavascriptSupportImpl(linker, stackSource, pathConstructor);
+        JavascriptSupportImpl jss = new JavascriptSupportImpl(linker, stackSource, pathConstructor, true);
 
         jss.importJavascriptLibrary(library);
 
@@ -268,7 +268,7 @@ public class JavascriptSupportImplTest e
 
         replay();
 
-        JavascriptSupportImpl jss = new JavascriptSupportImpl(linker, stackSource, pathConstructor);
+        JavascriptSupportImpl jss = new JavascriptSupportImpl(linker, stackSource, pathConstructor, true);
 
         jss.importStack("custom");
         
@@ -296,7 +296,7 @@ public class JavascriptSupportImplTest e
 
         replay();
 
-        JavascriptSupportImpl jss = new JavascriptSupportImpl(linker, stackSource, pathConstructor);
+        JavascriptSupportImpl jss = new JavascriptSupportImpl(linker, stackSource, pathConstructor, true);
 
         jss.importJavascriptLibrary(library1);
         jss.importJavascriptLibrary(library2);
@@ -321,7 +321,7 @@ public class JavascriptSupportImplTest e
 
         replay();
 
-        JavascriptSupportImpl jss = new JavascriptSupportImpl(linker, stackSource, pathConstructor);
+        JavascriptSupportImpl jss = new JavascriptSupportImpl(linker, stackSource, pathConstructor, true);
 
         jss.addInitializerCall(InitializationPriority.IMMEDIATE, "setup", spec);
 
@@ -343,7 +343,7 @@ public class JavascriptSupportImplTest e
 
         replay();
 
-        JavascriptSupportImpl jss = new JavascriptSupportImpl(linker, stackSource, pathConstructor);
+        JavascriptSupportImpl jss = new JavascriptSupportImpl(linker, stackSource, pathConstructor, true);
 
         jss.addInitializerCall(InitializationPriority.IMMEDIATE, "setup", "chuck");
 
@@ -364,7 +364,7 @@ public class JavascriptSupportImplTest e
 
         replay();
 
-        JavascriptSupportImpl jss = new JavascriptSupportImpl(linker, stackSource, pathConstructor);
+        JavascriptSupportImpl jss = new JavascriptSupportImpl(linker, stackSource, pathConstructor, true);
 
         jss.addInitializerCall(InitializationPriority.IMMEDIATE, "setup", "chuck");
         jss.addInitializerCall(InitializationPriority.IMMEDIATE, "setup", "pat");
@@ -386,7 +386,7 @@ public class JavascriptSupportImplTest e
 
         replay();
 
-        JavascriptSupportImpl jss = new JavascriptSupportImpl(linker, stackSource, pathConstructor);
+        JavascriptSupportImpl jss = new JavascriptSupportImpl(linker, stackSource, pathConstructor, true);
 
         jss.addInitializerCall("setup", "chuck");
 
@@ -410,7 +410,7 @@ public class JavascriptSupportImplTest e
 
         replay();
 
-        JavascriptSupportImpl jss = new JavascriptSupportImpl(linker, stackSource, pathConstructor);
+        JavascriptSupportImpl jss = new JavascriptSupportImpl(linker, stackSource, pathConstructor, true);
 
         jss.addInitializerCall(InitializationPriority.IMMEDIATE, "setup", spec1);
         jss.addInitializerCall(InitializationPriority.IMMEDIATE, "setup", spec2);
@@ -435,7 +435,7 @@ public class JavascriptSupportImplTest e
 
         replay();
 
-        JavascriptSupportImpl jss = new JavascriptSupportImpl(linker, stackSource, pathConstructor);
+        JavascriptSupportImpl jss = new JavascriptSupportImpl(linker, stackSource, pathConstructor, true);
 
         jss.addInitializerCall(InitializationPriority.EARLY, "early", new JSONObject("id", "foo"));
         jss.addInitializerCall("normal", new JSONObject("id", "bar"));
@@ -456,7 +456,7 @@ public class JavascriptSupportImplTest e
 
         replay();
 
-        JavascriptSupportImpl jss = new JavascriptSupportImpl(linker, null, null);
+        JavascriptSupportImpl jss = new JavascriptSupportImpl(linker, null, null, true);
 
         jss.importStylesheet(stylesheet, "print");
 
@@ -474,7 +474,7 @@ public class JavascriptSupportImplTest e
 
         replay();
 
-        JavascriptSupportImpl jss = new JavascriptSupportImpl(linker, null, null);
+        JavascriptSupportImpl jss = new JavascriptSupportImpl(linker, null, null, true);
 
         jss.importStylesheet("style.css", "print");
         jss.importStylesheet("style.css", "screen");

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/json/JSONObjectTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/json/JSONObjectTest.java?rev=944571&r1=944570&r2=944571&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/json/JSONObjectTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/json/JSONObjectTest.java Sat May 15 05:22:52 2010
@@ -18,6 +18,8 @@ import org.testng.Assert;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
+import java.io.CharArrayWriter;
+import java.io.PrintWriter;
 import java.math.BigDecimal;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -43,7 +45,8 @@ public class JSONObjectTest extends Asse
 
         JSONObject fullCopy = new JSONObject(master, "fred", "barney");
 
-        assertEquals(fullCopy.toString(), "{\"fred\":\"flintstone\",\"barney\":\"rubble\"}");
+        assertEquals(fullCopy.toString(), "{\n  \"fred\" : \"flintstone\",\n  \"barney\" : \"rubble\"\n"
+                + "}");
 
         JSONObject limitedCopy2 = new JSONObject(master, "fred", "wilma");
         assertEquals(limitedCopy2.keys().size(), 1);
@@ -141,7 +144,8 @@ public class JSONObjectTest extends Asse
         object.accumulate(key, "beta");
         object.accumulate(key, "gamma");
 
-        assertEquals(object.toString(), "{\"key\":[\"alpha\",\"beta\",\"gamma\"]}");
+        assertEquals(object.toString(), "{\n  \"key\" : [\n    \"alpha\",\n    \"beta\",\n"
+                + "    \"gamma\"\n  ]\n}");
 
         JSONArray array = object.getJSONArray(key);
 
@@ -164,7 +168,8 @@ public class JSONObjectTest extends Asse
 
         array.put("gamma");
 
-        assertEquals(object.toString(), "{\"key\":[\"alpha\",\"beta\",\"gamma\"]}");
+        assertEquals(object.toString(), "{\n  \"key\" : [\n    \"alpha\",\n    \"beta\",\n"
+                + "    \"gamma\"\n  ]\n}");
     }
 
     @Test
@@ -189,11 +194,12 @@ public class JSONObjectTest extends Asse
 
         object.append(key, "alpha");
 
-        assertEquals(object.toString(), "{\"fubar\":[\"alpha\"]}");
+        assertEquals(object.toString(), "{\n  \"fubar\" : [\n    \"alpha\"\n  ]\n}");
 
         object.append(key, "beta");
 
-        assertEquals(object.toString(), "{\"fubar\":[\"alpha\",\"beta\"]}");
+        assertEquals(object.toString(), "{\n  \"fubar\" : [\n    \"alpha\",\n    \"beta\"\n  ]\n"
+                + "}");
     }
 
     @Test
@@ -370,6 +376,14 @@ public class JSONObjectTest extends Asse
     }
 
     @Test
+    public void boolean_as_value()
+    {
+        JSONObject object = new JSONObject().put("t", true).put("f", false);
+
+        assertEquals(object.toString(), "{\n  \"f\" : false,\n  \"t\" : true\n}");
+    }
+
+    @Test
     public void length()
     {
         JSONObject object = new JSONObject();
@@ -432,7 +446,7 @@ public class JSONObjectTest extends Asse
 
         object.put("nullkey", JSONObject.NULL);
 
-        assertEquals(object.toString(), "{\"nullkey\":null}");
+        assertEquals(object.toString(), "{\n  \"nullkey\" : null\n}");
 
         assertTrue(object.isNull("nullkey"));
     }
@@ -510,7 +524,7 @@ public class JSONObjectTest extends Asse
 
         object.put("key", new BigDecimal("100.0000000"));
 
-        assertEquals(object.toString(), "{\"key\":100}");
+        assertEquals(object.toString(), "{\n  \"key\" : 100\n}");
     }
 
     @Test
@@ -609,7 +623,10 @@ public class JSONObjectTest extends Asse
 
         object.put("key", string);
 
-        assertEquals(object.toString(), "{\"key\":\"*VALUE*\"}");
+        // The implementation of this in Tapestry 5.1 put quotes around *VALUE*. That did not seem to
+        // be in accordance with intent, so in 5.2 the toJSONString value is printed without quotes.
+
+        assertEquals(object.toString(), "{\n  \"key\" : *VALUE*\n}");
     }
 
     @Test
@@ -673,7 +690,8 @@ public class JSONObjectTest extends Asse
     @Test
     public void json_array_from_values()
     {
-        assertEquals(new JSONArray("fred", "barney", "wilma").toString(), "[\"fred\",\"barney\",\"wilma\"]");
+        assertEquals(new JSONArray("fred", "barney", "wilma").toString(), "[\n  \"fred\",\n  \"barney\",\n"
+                + "  \"wilma\"\n]");
     }
 
     @Test
@@ -896,6 +914,44 @@ public class JSONObjectTest extends Asse
 
         obj.put("callback", new JSONLiteral("function(x) { $('bar').show(); }"));
 
-        assertEquals(obj.toString(), "{\"callback\":function(x) { $('bar').show(); }}");
+        assertEquals(obj.toString(), "{\n  \"callback\" : function(x) { $('bar').show(); }\n}");
+    }
+
+    @Test
+    public void object_print_and_pretty_print()
+    {
+        JSONObject o = new JSONObject("fred", "flintstone", "barney", "rubble");
+
+        CharArrayWriter caw = new CharArrayWriter();
+        PrintWriter pw = new PrintWriter(caw);
+
+        o.prettyPrint(pw);
+
+        String pretty = caw.toString();
+
+        assertEquals(o.toCompactString(), "{\"fred\":\"flintstone\",\"barney\":\"rubble\"}");
+        assertEquals(pretty, "{\n  \"fred\" : \"flintstone\",\n  \"barney\" : \"rubble\"\n}");
+    }
+
+    @Test
+    public void array_print_and_pretty_print()
+    {
+        JSONArray a = new JSONArray("fred", "barney");
+
+        CharArrayWriter caw = new CharArrayWriter();
+        PrintWriter pw = new PrintWriter(caw);
+
+        a.print(pw);
+
+        String compact = caw.toString();
+
+        caw.reset();
+
+        a.prettyPrint(pw);
+
+        String pretty = caw.toString();
+
+        assertEquals(compact, "[\"fred\",\"barney\"]");
+        assertEquals(pretty, "[\n  \"fred\",\n  \"barney\"\n]");
     }
 }