http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/13edb4e0/core/spi/src/main/java/org/json/JSONWriter.java ---------------------------------------------------------------------- diff --git a/core/spi/src/main/java/org/json/JSONWriter.java b/core/spi/src/main/java/org/json/JSONWriter.java new file mode 100644 index 0000000..c1328c0 --- /dev/null +++ b/core/spi/src/main/java/org/json/JSONWriter.java @@ -0,0 +1,429 @@ +/* + * Copyright (c) 2009, Rickard Ãberg. All Rights Reserved. + * + * 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.json; + +import java.io.IOException; +import java.io.Writer; + +/* +Copyright (c) 2006 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. +*/ + +/** + * JSONWriter provides a quick and convenient way of producing JSON text. + * The texts produced strictly conform to JSON syntax rules. No whitespace is + * added, so the results are ready for transmission or storage. Each instance of + * JSONWriter can produce one JSON text. + * <p/> + * A JSONWriter instance provides a <code>value</code> method for appending + * values to the + * text, and a <code>key</code> + * method for adding keys before values in objects. There are <code>array</code> + * and <code>endArray</code> methods that make and bound array values, and + * <code>object</code> and <code>endObject</code> methods which make and bound + * object values. All of these methods return the JSONWriter instance, + * permitting a cascade style. For example, <pre> + * new JSONWriter(myWriter) + * .object() + * .key("JSON") + * .value("Hello, World!") + * .endObject();</pre> which writes <pre> + * {"JSON":"Hello, World!"}</pre> + * <p/> + * The first method called must be <code>array</code> or <code>object</code>. + * There are no methods for adding commas or colons. JSONWriter adds them for + * you. Objects and arrays can be nested up to 20 levels deep. + * <p/> + * This can sometimes be easier than using a JSONObject to build a string. + */ +public class JSONWriter +{ + private static final int maxdepth = 20; + + /** + * The comma flag determines if a comma should be output before the next + * value. + */ + private boolean comma; + + /** + * The current mode. Values: + * 'a' (array), + * 'd' (done), + * 'i' (initial), + * 'k' (key), + * 'o' (object). + */ + protected char mode; + + /** + * The object/array stack. + */ + private JSONObject stack[]; + + /** + * The stack top index. A value of 0 indicates that the stack is empty. + */ + private int top; + + /** + * The writer that will receive the output. + */ + protected Writer writer; + + /** + * Make a fresh JSONWriter. It can be used to build one JSON text. + */ + public JSONWriter( Writer w ) + { + this.comma = false; + this.mode = 'i'; + this.stack = new JSONObject[ maxdepth ]; + this.top = 0; + this.writer = w; + } + + /** + * Append a value. + * + * @param s A string value. + * + * @return this + * + * @throws JSONException If the value is out of sequence. + */ + private JSONWriter append( String s ) + throws JSONException + { + if( s == null ) + { + throw new JSONException( "Null pointer" ); + } + if( this.mode == 'o' || this.mode == 'a' ) + { + try + { + if( this.comma && this.mode == 'a' ) + { + this.writer.write( ',' ); + } + this.writer.write( s ); + } + catch( IOException e ) + { + throw new JSONException( e ); + } + if( this.mode == 'o' ) + { + this.mode = 'k'; + } + this.comma = true; + return this; + } + throw new JSONException( "Value out of sequence." ); + } + + /** + * Begin appending a new array. All values until the balancing + * <code>endArray</code> will be appended to this array. The + * <code>endArray</code> method must be called to mark the array's end. + * + * @return this + * + * @throws JSONException If the nesting is too deep, or if the object is + * started in the wrong place (for example as a key or after the end of the + * outermost array or object). + */ + public JSONWriter array() + throws JSONException + { + if( this.mode == 'i' || this.mode == 'o' || this.mode == 'a' ) + { + this.push( null ); + this.append( "[" ); + this.comma = false; + return this; + } + throw new JSONException( "Misplaced array." ); + } + + /** + * End something. + * + * @param m Mode + * @param c Closing character + * + * @return this + * + * @throws JSONException If unbalanced. + */ + private JSONWriter end( char m, char c ) + throws JSONException + { + if( this.mode != m ) + { + throw new JSONException( m == 'o' ? "Misplaced endObject." : + "Misplaced endArray." ); + } + this.pop( m ); + try + { + this.writer.write( c ); + } + catch( IOException e ) + { + throw new JSONException( e ); + } + this.comma = true; + return this; + } + + /** + * End an array. This method most be called to balance calls to + * <code>array</code>. + * + * @return this + * + * @throws JSONException If incorrectly nested. + */ + public JSONWriter endArray() + throws JSONException + { + return this.end( 'a', ']' ); + } + + /** + * End an object. This method most be called to balance calls to + * <code>object</code>. + * + * @return this + * + * @throws JSONException If incorrectly nested. + */ + public JSONWriter endObject() + throws JSONException + { + return this.end( 'k', '}' ); + } + + /** + * Append a key. The key will be associated with the next value. In an + * object, every value must be preceded by a key. + * + * @param s A key string. + * + * @return this + * + * @throws JSONException If the key is out of place. For example, keys + * do not belong in arrays or if the key is null. + */ + public JSONWriter key( String s ) + throws JSONException + { + if( s == null ) + { + throw new JSONException( "Null key." ); + } + if( this.mode == 'k' ) + { + try + { + stack[ top - 1 ].putOnce( s, Boolean.TRUE ); + if( this.comma ) + { + this.writer.write( ',' ); + } + this.writer.write( JSONObject.quote( s ) ); + this.writer.write( ':' ); + this.comma = false; + this.mode = 'o'; + return this; + } + catch( IOException e ) + { + throw new JSONException( e ); + } + } + throw new JSONException( "Misplaced key." ); + } + + /** + * Begin appending a new object. All keys and values until the balancing + * <code>endObject</code> will be appended to this object. The + * <code>endObject</code> method must be called to mark the object's end. + * + * @return this + * + * @throws JSONException If the nesting is too deep, or if the object is + * started in the wrong place (for example as a key or after the end of the + * outermost array or object). + */ + public JSONWriter object() + throws JSONException + { + if( this.mode == 'i' ) + { + this.mode = 'o'; + } + if( this.mode == 'o' || this.mode == 'a' ) + { + this.append( "{" ); + this.push( new JSONObject() ); + this.comma = false; + return this; + } + throw new JSONException( "Misplaced object." ); + } + + /** + * Pop an array or object scope. + * + * @param c The scope to close. + * + * @throws JSONException If nesting is wrong. + */ + private void pop( char c ) + throws JSONException + { + if( this.top <= 0 ) + { + throw new JSONException( "Nesting error." ); + } + char m = this.stack[ this.top - 1 ] == null ? 'a' : 'k'; + if( m != c ) + { + throw new JSONException( "Nesting error." ); + } + this.top -= 1; + this.mode = this.top == 0 ? 'd' : this.stack[ this.top - 1 ] == null ? 'a' : 'k'; + } + + /** + * Push an array or object scope. + * + * @param jo The scope to open. + * + * @throws JSONException If nesting is too deep. + */ + private void push( JSONObject jo ) + throws JSONException + { + if( this.top >= maxdepth ) + { + throw new JSONException( "Nesting too deep." ); + } + this.stack[ this.top ] = jo; + this.mode = jo == null ? 'a' : 'k'; + this.top += 1; + } + + /** + * Append either the value <code>true</code> or the value + * <code>false</code>. + * + * @param b A boolean. + * + * @return this + * + * @throws JSONException + */ + public JSONWriter value( boolean b ) + throws JSONException + { + return this.append( b ? "true" : "false" ); + } + + /** + * Append a double value. + * + * @param d A double. + * + * @return this + * + * @throws JSONException If the number is not finite. + */ + public JSONWriter value( double d ) + throws JSONException + { + return this.value( new Double( d ) ); + } + + /** + * Append a long value. + * + * @param l A long. + * + * @return this + * + * @throws JSONException + */ + public JSONWriter value( long l ) + throws JSONException + { + return this.append( Long.toString( l ) ); + } + + /** + * Append an object value. + * + * @param o The object to append. It can be null, or a Boolean, Number, + * String, JSONObject, or JSONArray, or an object with a toJSONString() + * method. + * + * @return this + * + * @throws JSONException If the value is out of sequence. + */ + public JSONWriter value( Object o ) + throws JSONException + { + return this.append( JSONObject.valueToString( o ) ); + } + + /** + * Append JSON formatted string as-is + * + * @param json + * + * @return + * + * @throws JSONException + */ + public JSONWriter json( String json ) + throws JSONException + { + return this.append( json ); + } +} \ No newline at end of file
http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/13edb4e0/core/spi/src/main/java/org/json/package.html ---------------------------------------------------------------------- diff --git a/core/spi/src/main/java/org/json/package.html b/core/spi/src/main/java/org/json/package.html new file mode 100644 index 0000000..6dc0ff7 --- /dev/null +++ b/core/spi/src/main/java/org/json/package.html @@ -0,0 +1,8 @@ +<html> + <body> + <h2>JSON in Java.</h2> + <p> + See <a href="http://www.json.org/java/">json.org/java</a>. + </p> + </body> +</html> \ No newline at end of file
