001// Licensed under the Apache License, Version 2.0 (the "License"); 002// you may not use this file except in compliance with the License. 003// You may obtain a copy of the License at 004// 005// http://www.apache.org/licenses/LICENSE-2.0 006// 007// Unless required by applicable law or agreed to in writing, software 008// distributed under the License is distributed on an "AS IS" BASIS, 009// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 010// See the License for the specific language governing permissions and 011// limitations under the License. 012 013package org.apache.tapestry5.json; 014 015import java.io.PrintWriter; 016import java.io.Serializable; 017 018/** 019 * Base class for {@link JSONArray} and {@link JSONObject} that exists to organize the code 020 * for printing such objects (either compact or pretty). 021 * 022 * @since 5.2.0 023 */ 024public abstract class JSONCollection implements Serializable 025{ 026 /** 027 * Converts this JSON collection into a parsable string representation. 028 * 029 * Warning: This method assumes that the data structure is acyclical. 030 * 031 * Starting in release 5.2, the result will be pretty printed for readability. 032 * 033 * @return a printable, displayable, portable, transmittable representation of the object, beginning with 034 * <code>{</code> <small>(left brace)</small> and ending with <code>}</code> <small>(right 035 * brace)</small>. 036 */ 037 @Override 038 public String toString() 039 { 040 StringBuilder out = new StringBuilder(estimateCapacity()); 041 042 JSONPrintSession session = new PrettyPrintSession(out); 043 044 print(session); 045 046 return out.toString(); 047 } 048 049 /** 050 * Converts the JSONObject to a compact or pretty-print string representation 051 * 052 * @param compact 053 * if true, return minimal format string. 054 * @since 5.2.0 055 */ 056 public String toString(boolean compact) 057 { 058 return compact ? toCompactString() : toString(); 059 } 060 061 /** 062 * Prints the JSONObject as a compact string (not extra punctuation). This is, essentially, what 063 * Tapestry 5.1 did inside {@link #toString()}. 064 */ 065 public String toCompactString() 066 { 067 StringBuilder out = new StringBuilder(estimateCapacity()); 068 069 JSONPrintSession session = new CompactSession(out); 070 071 print(session); 072 073 return out.toString(); 074 } 075 076 /** 077 * A cheap starting capacity for the {@link StringBuilder} backing {@link #toString()} / 078 * {@link #toCompactString()}, to avoid repeated grow-and-copy cycles for non-trivial trees. 079 * Scales with the top-level collection's element count only; recursing into nested 080 * collections isn't worth the extra bookkeeping for a rough estimate. 081 */ 082 private int estimateCapacity() 083 { 084 return Math.max(256, size() * 32); 085 } 086 087 /** 088 * The number of top-level entries (name/value pairs for {@link JSONObject}, elements for 089 * {@link JSONArray}), used only to estimate a starting buffer capacity. 090 */ 091 abstract int size(); 092 093 /** 094 * Prints the JSONObject to the write (compactly or not). 095 * 096 * @param writer 097 * to write content to 098 * @param compact 099 * if true, then write compactly, if false, write with pretty printing 100 * @since 5.2.1 101 */ 102 public void print(PrintWriter writer, boolean compact) 103 { 104 JSONPrintSession session = compact ? new CompactSession(writer) : new PrettyPrintSession(writer); 105 106 print(session); 107 } 108 109 /** 110 * Prints the JSONObject to the writer compactly (with no extra whitespace). 111 */ 112 public void print(PrintWriter writer) 113 { 114 print(writer, true); 115 } 116 117 /** 118 * Prints the JSONObject to the writer using indentation (two spaces per indentation level). 119 */ 120 public void prettyPrint(PrintWriter writer) 121 { 122 print(writer, false); 123 } 124 125 /** 126 * Print the collection in a parsable format using the session to (optionally) inject extra 127 * whitespace (for "pretty printing"). 128 */ 129 abstract void print(JSONPrintSession session); 130}