json-lib-2.3/0000755000175000017500000000000011257573775012102 5ustar mkochmkochjson-lib-2.3/net/0000755000175000017500000000000011226107170012642 5ustar mkochmkochjson-lib-2.3/net/sf/0000755000175000017500000000000011226107170013252 5ustar mkochmkochjson-lib-2.3/net/sf/json/0000755000175000017500000000000011226107170014223 5ustar mkochmkochjson-lib-2.3/net/sf/json/test/0000755000175000017500000000000011226107170015202 5ustar mkochmkochjson-lib-2.3/net/sf/json/test/JSONAssert.java0000644000175000017500000004544711226107170020016 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.test; import java.util.Iterator; import junit.framework.Assert; import net.sf.ezmorph.Morpher; import net.sf.ezmorph.object.IdentityObjectMorpher; import net.sf.json.JSON; import net.sf.json.JSONArray; import net.sf.json.JSONException; import net.sf.json.JSONFunction; import net.sf.json.JSONNull; import net.sf.json.JSONObject; import net.sf.json.JSONSerializer; import net.sf.json.util.JSONUtils; /** * Provides assertions on equality for JSON strings and JSON types. * * @author Andres Almiray */ public class JSONAssert extends Assert { /** * Asserts that two JSON values are equal. */ public static void assertEquals( JSON expected, JSON actual ) { assertEquals( null, expected, actual ); } /** * Asserts that two JSONArrays are equal. */ public static void assertEquals( JSONArray expected, JSONArray actual ) { assertEquals( null, expected, actual ); } /** * Asserts that two JSONArrays are equal. */ public static void assertEquals( JSONArray expected, String actual ) { assertEquals( null, expected, actual ); } /** * Asserts that two JSONFunctions are equal. */ public static void assertEquals( JSONFunction expected, String actual ) { assertEquals( null, expected, actual ); } /** * Asserts that two JSONNulls are equal. */ public static void assertEquals( JSONNull expected, String actual ) { assertEquals( null, expected, actual ); } /** * Asserts that two JSONObjects are equal. */ public static void assertEquals( JSONObject expected, JSONObject actual ) { assertEquals( null, expected, actual ); } /** * Asserts that two JSONObjects are equal. */ public static void assertEquals( JSONObject expected, String actual ) { assertEquals( null, expected, actual ); } /** * Asserts that two JSON values are equal. */ public static void assertEquals( String message, JSON expected, JSON actual ) { String header = message == null ? "" : message + ": "; if( expected == null ){ fail( header + "expected was null" ); } if( actual == null ){ fail( header + "actual was null" ); } if( expected == actual || expected.equals( actual ) ){ return; } if( expected instanceof JSONArray ){ if( actual instanceof JSONArray ){ assertEquals( header, (JSONArray) expected, (JSONArray) actual ); }else{ fail( header + "actual is not a JSONArray" ); } }else if( expected instanceof JSONObject ){ if( actual instanceof JSONObject ){ assertEquals( header, (JSONObject) expected, (JSONObject) actual ); }else{ fail( header + "actual is not a JSONObject" ); } }else if( expected instanceof JSONNull ){ if( actual instanceof JSONNull ){ return; }else{ fail( header + "actual is not a JSONNull" ); } } } /** * Asserts that two JSONArrays are equal. */ public static void assertEquals( String expected, JSONArray actual ) { assertEquals( null, expected, actual ); } /** * Asserts that two JSONArrays are equal. */ public static void assertEquals( String message, JSONArray expected, JSONArray actual ) { String header = message == null ? "" : message + ": "; if( expected == null ){ fail( header + "expected array was null" ); } if( actual == null ){ fail( header + "actual array was null" ); } if( expected == actual || expected.equals( actual ) ){ return; } if( actual.size() != expected.size() ){ fail( header + "arrays sizes differed, expected.length()=" + expected.size() + " actual.length()=" + actual.size() ); } int max = expected.size(); for( int i = 0; i < max; i++ ){ Object o1 = expected.get( i ); Object o2 = actual.get( i ); // handle nulls if( JSONNull.getInstance() .equals( o1 ) ){ if( JSONNull.getInstance() .equals( o2 ) ){ continue; }else{ fail( header + "arrays first differed at element [" + i + "];" ); } }else{ if( JSONNull.getInstance() .equals( o2 ) ){ fail( header + "arrays first differed at element [" + i + "];" ); } } if( o1 instanceof JSONArray && o2 instanceof JSONArray ){ JSONArray e = (JSONArray) o1; JSONArray a = (JSONArray) o2; assertEquals( header + "arrays first differed at element " + i + ";", e, a ); }else{ if( o1 instanceof String && o2 instanceof JSONFunction ){ assertEquals( header + "arrays first differed at element [" + i + "];", (String) o1, (JSONFunction) o2 ); }else if( o1 instanceof JSONFunction && o2 instanceof String ){ assertEquals( header + "arrays first differed at element [" + i + "];", (JSONFunction) o1, (String) o2 ); }else if( o1 instanceof JSONObject && o2 instanceof JSONObject ){ assertEquals( header + "arrays first differed at element [" + i + "];", (JSONObject) o1, (JSONObject) o2 ); }else if( o1 instanceof JSONArray && o2 instanceof JSONArray ){ assertEquals( header + "arrays first differed at element [" + i + "];", (JSONArray) o1, (JSONArray) o2 ); }else if( o1 instanceof JSONFunction && o2 instanceof JSONFunction ){ assertEquals( header + "arrays first differed at element [" + i + "];", (JSONFunction) o1, (JSONFunction) o2 ); }else{ if( o1 instanceof String ){ assertEquals( header + "arrays first differed at element [" + i + "];", (String) o1, String.valueOf( o2 ) ); }else if( o2 instanceof String ){ assertEquals( header + "arrays first differed at element [" + i + "];", String.valueOf( o1 ), (String) o2 ); }else{ Morpher m1 = JSONUtils.getMorpherRegistry() .getMorpherFor( o1.getClass() ); Morpher m2 = JSONUtils.getMorpherRegistry() .getMorpherFor( o2.getClass() ); if( m1 != null && m1 != IdentityObjectMorpher.getInstance() ){ assertEquals( header + "arrays first differed at element [" + i + "];", o1, JSONUtils.getMorpherRegistry() .morph( o1.getClass(), o2 ) ); }else if( m2 != null && m2 != IdentityObjectMorpher.getInstance() ){ assertEquals( header + "arrays first differed at element [" + i + "];", JSONUtils.getMorpherRegistry() .morph( o1.getClass(), o1 ), o2 ); }else{ assertEquals( header + "arrays first differed at element [" + i + "];", o1, o2 ); } } } } } } /** * Asserts that two JSONArrays are equal. */ public static void assertEquals( String message, JSONArray expected, String actual ) { try{ assertEquals( message, expected, JSONArray.fromObject( actual ) ); }catch( JSONException e ){ String header = message == null ? "" : message + ": "; fail( header + "actual is not a JSONArray" ); } } /** * Asserts that two JSONFunctions are equal. */ public static void assertEquals( String expected, JSONFunction actual ) { assertEquals( null, expected, actual ); } /** * Asserts that two JSONFunctions are equal. */ public static void assertEquals( String message, JSONFunction expected, String actual ) { String header = message == null ? "" : message + ": "; if( expected == null ){ fail( header + "expected function was null" ); } if( actual == null ){ fail( header + "actual string was null" ); } try{ assertEquals( header, expected, JSONFunction.parse( actual ) ); }catch( JSONException jsone ){ fail( header + "'" + actual + "' is not a function" ); } } /** * Asserts that two JSONNulls are equal. */ public static void assertEquals( String expected, JSONNull actual ) { assertEquals( null, expected, actual ); } /** * Asserts that two JSONNulls are equal. */ public static void assertEquals( String message, JSONNull expected, String actual ) { String header = message == null ? "" : message + ": "; if( actual == null ){ fail( header + "actual string was null" ); }else if( expected == null ){ assertEquals( header, "null", actual ); }else{ assertEquals( header, expected.toString(), actual ); } } /** * Asserts that two JSONObjects are equal. */ public static void assertEquals( String expected, JSONObject actual ) { assertEquals( null, expected, actual ); } /** * Asserts that two JSONObjects are equal. */ public static void assertEquals( String message, JSONObject expected, JSONObject actual ) { String header = message == null ? "" : message + ": "; if( expected == null ){ fail( header + "expected object was null" ); } if( actual == null ){ fail( header + "actual object was null" ); } if( expected == actual /* || expected.equals( actual ) */){ return; } if( expected.isNullObject() ){ if( actual.isNullObject() ){ return; }else{ fail( header + "actual is not a null JSONObject" ); } }else{ if( actual.isNullObject() ){ fail( header + "actual is a null JSONObject" ); } } assertEquals( header + "names sizes differed, expected.names().length()=" + expected.names() .size() + " actual.names().length()=" + actual.names() .size(), expected.names() .size(), actual.names() .size() ); for( Iterator keys = expected.keys(); keys.hasNext(); ){ String key = (String) keys.next(); Object o1 = expected.opt( key ); Object o2 = actual.opt( key ); if( JSONNull.getInstance() .equals( o1 ) ){ if( JSONNull.getInstance() .equals( o2 ) ){ continue; }else{ fail( header + "objects differed at key [" + key + "];" ); } }else{ if( JSONNull.getInstance() .equals( o2 ) ){ fail( header + "objects differed at key [" + key + "];" ); } } if( o1 instanceof String && o2 instanceof JSONFunction ){ assertEquals( header + "objects differed at key [" + key + "];", (String) o1, (JSONFunction) o2 ); }else if( o1 instanceof JSONFunction && o2 instanceof String ){ assertEquals( header + "objects differed at key [" + key + "];", (JSONFunction) o1, (String) o2 ); }else if( o1 instanceof JSONObject && o2 instanceof JSONObject ){ assertEquals( header + "objects differed at key [" + key + "];", (JSONObject) o1, (JSONObject) o2 ); }else if( o1 instanceof JSONArray && o2 instanceof JSONArray ){ assertEquals( header + "objects differed at key [" + key + "];", (JSONArray) o1, (JSONArray) o2 ); }else if( o1 instanceof JSONFunction && o2 instanceof JSONFunction ){ assertEquals( header + "objects differed at key [" + key + "];", (JSONFunction) o1, (JSONFunction) o2 ); }else{ if( o1 instanceof String ){ assertEquals( header + "objects differed at key [" + key + "];", (String) o1, String.valueOf( o2 ) ); }else if( o2 instanceof String ){ assertEquals( header + "objects differed at key [" + key + "];", String.valueOf( o1 ), (String) o2 ); }else{ Morpher m1 = JSONUtils.getMorpherRegistry() .getMorpherFor( o1.getClass() ); Morpher m2 = JSONUtils.getMorpherRegistry() .getMorpherFor( o2.getClass() ); if( m1 != null && m1 != IdentityObjectMorpher.getInstance() ){ assertEquals( header + "objects differed at key [" + key + "];", o1, JSONUtils.getMorpherRegistry() .morph( o1.getClass(), o2 ) ); }else if( m2 != null && m2 != IdentityObjectMorpher.getInstance() ){ assertEquals( header + "objects differed at key [" + key + "];", JSONUtils.getMorpherRegistry() .morph( o1.getClass(), o1 ), o2 ); }else{ assertEquals( header + "objects differed at key [" + key + "];", o1, o2 ); } } } } } /** * Asserts that two JSONObjects are equal. */ public static void assertEquals( String message, JSONObject expected, String actual ) { try{ assertEquals( message, expected, JSONObject.fromObject( actual ) ); }catch( JSONException e ){ String header = message == null ? "" : message + ": "; fail( header + "actual is not a JSONObject" ); } } /** * Asserts that two JSONArrays are equal. */ public static void assertEquals( String message, String expected, JSONArray actual ) { try{ assertEquals( message, JSONArray.fromObject( expected ), actual ); }catch( JSONException e ){ String header = message == null ? "" : message + ": "; fail( header + "expected is not a JSONArray" ); } } /** * Asserts that two JSONFunctions are equal. */ public static void assertEquals( String message, String expected, JSONFunction actual ) { String header = message == null ? "" : message + ": "; if( expected == null ){ fail( header + "expected string was null" ); } if( actual == null ){ fail( header + "actual function was null" ); } try{ assertEquals( header, JSONFunction.parse( expected ), actual ); }catch( JSONException jsone ){ fail( header + "'" + expected + "' is not a function" ); } } /** * Asserts that two JSONNulls are equal. */ public static void assertEquals( String message, String expected, JSONNull actual ) { String header = message == null ? "" : message + ": "; if( expected == null ){ fail( header + "expected was null" ); }else if( actual == null ){ assertEquals( header, expected, "null" ); }else{ assertEquals( header, expected, actual.toString() ); } } /** * Asserts that two JSONObjects are equal. */ public static void assertEquals( String message, String expected, JSONObject actual ) { try{ assertEquals( message, JSONObject.fromObject( expected ), actual ); }catch( JSONException e ){ String header = message == null ? "" : message + ": "; fail( header + "expected is not a JSONObject" ); } } /** * Asserts that two JSON strings are equal. */ public static void assertJsonEquals( String expected, String actual ) { assertJsonEquals( null, expected, actual ); } /** * Asserts that two JSON strings are equal. */ public static void assertJsonEquals( String message, String expected, String actual ) { String header = message == null ? "" : message + ": "; if( expected == null ){ fail( header + "expected was null" ); } if( actual == null ){ fail( header + "actual was null" ); } JSON json1 = null; JSON json2 = null; try{ json1 = JSONSerializer.toJSON( expected ); }catch( JSONException jsone ){ fail( header + "expected is not a valid JSON string" ); } try{ json2 = JSONSerializer.toJSON( actual ); }catch( JSONException jsone ){ fail( header + "actual is not a valid JSON string" ); } assertEquals( header, json1, json2 ); } /** * Asserts that a JSON value is not null.
* Fails if: * */ public static void assertNotNull( JSON json ) { assertNotNull( null, json ); } /** * Asserts that a JSON value is not null.
* Fails if: * */ public static void assertNotNull( String message, JSON json ) { String header = message == null ? "" : message + ": "; if( json instanceof JSONObject ){ assertFalse( header + "Object is null", ((JSONObject) json).isNullObject() ); }else if( JSONNull.getInstance() .equals( json ) ){ fail( header + "Object is null" ); } } /** * Asserts that a JSON value is null.
* Fails if: * */ public static void assertNull( JSON json ) { assertNull( null, json ); } /** * Asserts that a JSON value is null.
* Fails if: * */ public static void assertNull( String message, JSON json ) { String header = message == null ? "" : message + ": "; if( json instanceof JSONObject ){ assertTrue( header + "Object is not null", ((JSONObject) json).isNullObject() ); }else if( !JSONNull.getInstance() .equals( json ) ){ fail( header + "Object is not null" ); } } }json-lib-2.3/net/sf/json/AbstractJSON.java0000644000175000017500000002171611226107170017332 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json; import java.lang.ref.SoftReference; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import net.sf.json.util.JSONTokener; import net.sf.json.util.JSONUtils; import net.sf.json.util.JsonEventListener; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Base class for JSONObject and JSONArray. * * @author Andres Almiray */ abstract class AbstractJSON { private static class CycleSet extends ThreadLocal { protected Object initialValue() { return new SoftReference(new HashSet()); } public Set getSet() { Set set = (Set) ((SoftReference)get()).get(); if( set == null ) { set = new HashSet(); set(new SoftReference(set)); } return set; } } private static CycleSet cycleSet = new CycleSet(); private static final Log log = LogFactory.getLog( AbstractJSON.class ); /** * Adds a reference for cycle detection check. * * @param instance the reference to add * @return true if the instance has not been added previously, false * otherwise. */ protected static boolean addInstance( Object instance ) { return getCycleSet().add( instance ); } /** * Fires an end of array event. */ protected static void fireArrayEndEvent( JsonConfig jsonConfig ) { if( jsonConfig.isEventTriggeringEnabled() ){ for( Iterator listeners = jsonConfig.getJsonEventListeners() .iterator(); listeners.hasNext(); ){ JsonEventListener listener = (JsonEventListener) listeners.next(); try{ listener.onArrayEnd(); }catch( RuntimeException e ){ log.warn( e ); } } } } /** * Fires a start of array event. */ protected static void fireArrayStartEvent( JsonConfig jsonConfig ) { if( jsonConfig.isEventTriggeringEnabled() ){ for( Iterator listeners = jsonConfig.getJsonEventListeners() .iterator(); listeners.hasNext(); ){ JsonEventListener listener = (JsonEventListener) listeners.next(); try{ listener.onArrayStart(); }catch( RuntimeException e ){ log.warn( e ); } } } } /** * Fires an element added event. * * @param index the index where the element was added * @param element the added element */ protected static void fireElementAddedEvent( int index, Object element, JsonConfig jsonConfig ) { if( jsonConfig.isEventTriggeringEnabled() ){ for( Iterator listeners = jsonConfig.getJsonEventListeners() .iterator(); listeners.hasNext(); ){ JsonEventListener listener = (JsonEventListener) listeners.next(); try{ listener.onElementAdded( index, element ); }catch( RuntimeException e ){ log.warn( e ); } } } } /** * Fires an error event. * * @param jsone the thrown exception */ protected static void fireErrorEvent( JSONException jsone, JsonConfig jsonConfig ) { if( jsonConfig.isEventTriggeringEnabled() ){ for( Iterator listeners = jsonConfig.getJsonEventListeners() .iterator(); listeners.hasNext(); ){ JsonEventListener listener = (JsonEventListener) listeners.next(); try{ listener.onError( jsone ); }catch( RuntimeException e ){ log.warn( e ); } } } } /** * Fires an end of object event. */ protected static void fireObjectEndEvent( JsonConfig jsonConfig ) { if( jsonConfig.isEventTriggeringEnabled() ){ for( Iterator listeners = jsonConfig.getJsonEventListeners() .iterator(); listeners.hasNext(); ){ JsonEventListener listener = (JsonEventListener) listeners.next(); try{ listener.onObjectEnd(); }catch( RuntimeException e ){ log.warn( e ); } } } } /** * Fires a start of object event. */ protected static void fireObjectStartEvent( JsonConfig jsonConfig ) { if( jsonConfig.isEventTriggeringEnabled() ){ for( Iterator listeners = jsonConfig.getJsonEventListeners() .iterator(); listeners.hasNext(); ){ JsonEventListener listener = (JsonEventListener) listeners.next(); try{ listener.onObjectStart(); }catch( RuntimeException e ){ log.warn( e ); } } } } /** * Fires a property set event. * * @param key the name of the property * @param value the value of the property * @param accumulated if the value has been accumulated over 'key' */ protected static void firePropertySetEvent( String key, Object value, boolean accumulated, JsonConfig jsonConfig ) { if( jsonConfig.isEventTriggeringEnabled() ){ for( Iterator listeners = jsonConfig.getJsonEventListeners() .iterator(); listeners.hasNext(); ){ JsonEventListener listener = (JsonEventListener) listeners.next(); try{ listener.onPropertySet( key, value, accumulated ); }catch( RuntimeException e ){ log.warn( e ); } } } } /** * Fires a warning event. * * @param warning the warning message */ protected static void fireWarnEvent( String warning, JsonConfig jsonConfig ) { if( jsonConfig.isEventTriggeringEnabled() ){ for( Iterator listeners = jsonConfig.getJsonEventListeners() .iterator(); listeners.hasNext(); ){ JsonEventListener listener = (JsonEventListener) listeners.next(); try{ listener.onWarning( warning ); }catch( RuntimeException e ){ log.warn( e ); } } } } /** * Removes a reference for cycle detection check. */ protected static void removeInstance( Object instance ) { getCycleSet().remove( instance ); } protected Object _processValue( Object value, JsonConfig jsonConfig ) { if( JSONNull.getInstance().equals( value ) ) { return JSONNull.getInstance(); } else if( Class.class.isAssignableFrom( value.getClass() ) || value instanceof Class ) { return ((Class) value).getName(); } else if( JSONUtils.isFunction( value ) ) { if( value instanceof String ) { value = JSONFunction.parse( (String) value ); } return value; } else if( value instanceof JSONString ) { return JSONSerializer.toJSON( (JSONString) value, jsonConfig ); } else if( value instanceof JSON ) { return JSONSerializer.toJSON( value, jsonConfig ); } else if( JSONUtils.isArray( value ) ) { return JSONArray.fromObject( value, jsonConfig ); } else if( JSONUtils.isString( value ) ) { String str = String.valueOf( value ); if( JSONUtils.hasQuotes( str ) ){ str = JSONUtils.stripQuotes( str ); if( JSONUtils.isFunction( str )){ return JSONUtils.DOUBLE_QUOTE + str + JSONUtils.DOUBLE_QUOTE; } return str; } else if( JSONUtils.isJsonKeyword( str, jsonConfig ) ) { if( jsonConfig.isJavascriptCompliant() && "undefined".equals( str )){ return JSONNull.getInstance(); } return str; } else if( JSONUtils.mayBeJSON( str ) ) { try { return JSONSerializer.toJSON( str, jsonConfig ); } catch( JSONException jsone ) { return str; } } return str; } else if( JSONUtils.isNumber( value ) ) { JSONUtils.testValidity( value ); return JSONUtils.transformNumber( (Number) value ); } else if( JSONUtils.isBoolean( value ) ) { return value; } else { JSONObject jsonObject = JSONObject.fromObject( value, jsonConfig ); if( jsonObject.isNullObject() ) { return JSONNull.getInstance(); } else { return jsonObject; } } } private static Set getCycleSet() { return cycleSet.getSet(); } }json-lib-2.3/net/sf/json/JSONFunction.java0000644000175000017500000001112011226107170017340 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json; import java.io.Serializable; import net.sf.json.util.JSONUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; /** * JSONFunction represents a javaScript function's text. * * @author Andres Almiray */ public class JSONFunction implements Serializable { /** constant array for empty parameters */ private static final String[] EMPTY_PARAM_ARRAY = new String[0]; /** * Constructs a JSONFunction from a text representation */ public static JSONFunction parse( String str ) { if( !JSONUtils.isFunction( str ) ) { throw new JSONException( "String is not a function. " + str ); } else { String params = JSONUtils.getFunctionParams( str ); String text = JSONUtils.getFunctionBody( str ); return new JSONFunction( (params != null) ? StringUtils.split( params, "," ) : null, text != null ? text : "" ); } } /** the parameters of this function */ private String[] params; /** the text of this function */ private String text; /** * Constructs a JSONFunction with no parameters. * * @param text The text of the function */ public JSONFunction( String text ) { this( null, text ); } /** * Constructs a JSONFunction with parameters. * * @param params The parameters of the function * @param text The text of the function */ public JSONFunction( String[] params, String text ) { this.text = (text != null) ? text.trim() : ""; if( params != null ){ if( params.length == 1 && params[0].trim() .equals( "" ) ){ this.params = EMPTY_PARAM_ARRAY; }else{ this.params = new String[params.length]; System.arraycopy( params, 0, this.params, 0, params.length ); // remove empty spaces for( int i = 0; i < params.length; i++ ){ this.params[i] = this.params[i].trim(); } } }else{ this.params = EMPTY_PARAM_ARRAY; } } public boolean equals( Object obj ) { if( this == obj ){ return true; } if( obj == null ){ return false; } if( obj instanceof String ){ try{ JSONFunction other = parse( (String) obj ); return equals( other ); }catch( JSONException e ){ return false; } } if( !(obj instanceof JSONFunction) ){ return false; } JSONFunction other = (JSONFunction) obj; if( params.length != other.params.length ){ return false; } EqualsBuilder builder = new EqualsBuilder(); for( int i = 0; i < params.length; i++ ){ builder.append( params[i], other.params[i] ); } builder.append( text, other.text ); return builder.isEquals(); } /** * Returns the parameters of this function. */ public String[] getParams() { return params; } /** * Reeturns the text of this function. */ public String getText() { return text; } public int hashCode() { HashCodeBuilder builder = new HashCodeBuilder(); for( int i = 0; i < params.length; i++ ){ builder.append( params[i] ); } builder.append( text ); return builder.toHashCode(); } /** * Returns the string representation of this function. */ public String toString() { StringBuffer b = new StringBuffer( "function(" ); if( params.length > 0 ){ for( int i = 0; i < params.length - 1; i++ ){ b.append( params[i] ) .append( ',' ); } b.append( params[params.length - 1] ); } b.append( "){" ); if( text.length() > 0 ){ b.append( ' ' ) .append( text ) .append( ' ' ); } b.append( '}' ); return b.toString(); } }json-lib-2.3/net/sf/json/JSONObject.java0000644000175000017500000030706511226107170017001 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json; import java.beans.PropertyDescriptor; import java.io.IOException; import java.io.Writer; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import net.sf.ezmorph.Morpher; import net.sf.ezmorph.array.ObjectArrayMorpher; import net.sf.ezmorph.bean.BeanMorpher; import net.sf.ezmorph.object.IdentityObjectMorpher; import net.sf.json.processors.JsonBeanProcessor; import net.sf.json.processors.JsonValueProcessor; import net.sf.json.processors.JsonVerifier; import net.sf.json.processors.PropertyNameProcessor; import net.sf.json.regexp.RegexpUtils; import net.sf.json.util.CycleDetectionStrategy; import net.sf.json.util.JSONTokener; import net.sf.json.util.JSONUtils; import net.sf.json.util.PropertyFilter; import net.sf.json.util.PropertySetStrategy; import org.apache.commons.beanutils.DynaBean; import org.apache.commons.beanutils.DynaProperty; import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.collections.map.ListOrderedMap; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * A JSONObject is an unordered collection of name/value pairs. Its external * form is a string wrapped in curly braces with colons between the names and * values, and commas between the values and names. The internal form is an * object having get and opt methods for accessing * the values by name, and put methods for adding or replacing * values by name. The values can be any of these types: Boolean, * JSONArray, JSONObject, Number, * String, or the JSONNull object. A JSONObject * constructor can be used to convert an external form JSON text into an * internal form whose values can be retrieved with the get and * opt methods, or to convert values into a JSON text using the * element and toString methods. A * get method returns a value if one can be found, and throws an * exception if one cannot be found. An opt method returns a * default value instead of throwing an exception, and so is useful for * obtaining optional values. *

* The generic get() and opt() methods return an * object, which you can cast or query for type. There are also typed * get and opt methods that do type checking and * type coercion for you. *

* The put methods adds values to an object. For example, * *

 *     myString = new JSONObject().put("JSON", "Hello, World!").toString();
* * produces the string {"JSON": "Hello, World"}. *

* The texts produced by the toString methods strictly conform to * the JSON syntax rules. The constructors are more forgiving in the texts they * will accept: *

    *
  • An extra , (comma) may appear just * before the closing brace.
  • *
  • Strings may be quoted with ' (single quote).
  • *
  • 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: * { } [ ] / \ : , = ; # and if they do not look like numbers and * if they are not the reserved words true, false, * or null.
  • *
  • Keys can be followed by = or => as well as * by :.
  • *
  • Values can be followed by ; (semicolon) * as well as by , (comma).
  • *
  • Numbers may have the 0- (octal) or * 0x- (hex) prefix.
  • *
  • Comments written in the slashshlash, slashstar, and hash conventions * will be ignored.
  • *
* * @author JSON.org */ public final class JSONObject extends AbstractJSON implements JSON, Map, Comparable { private static final Log log = LogFactory.getLog( JSONObject.class ); /** * Creates a JSONObject.
* Inspects the object type to call the correct JSONObject factory method. * Accepts JSON formatted strings, Maps, DynaBeans and JavaBeans. * * @param object * @throws JSONException if the object can not be converted to a proper * JSONObject. */ public static JSONObject fromObject( Object object ) { return fromObject( object, new JsonConfig() ); } /** * Creates a JSONObject.
* Inspects the object type to call the correct JSONObject factory method. * Accepts JSON formatted strings, Maps, DynaBeans and JavaBeans. * * @param object * @throws JSONException if the object can not be converted to a proper * JSONObject. */ public static JSONObject fromObject( Object object, JsonConfig jsonConfig ) { if( object == null || JSONUtils.isNull( object ) ){ return new JSONObject( true ); }else if( object instanceof JSONObject ){ return _fromJSONObject( (JSONObject) object, jsonConfig ); }else if( object instanceof DynaBean ){ return _fromDynaBean( (DynaBean) object, jsonConfig ); }else if( object instanceof JSONTokener ){ return _fromJSONTokener( (JSONTokener) object, jsonConfig ); }else if( object instanceof JSONString ){ return _fromJSONString( (JSONString) object, jsonConfig ); }else if( object instanceof Map ){ return _fromMap( (Map) object, jsonConfig ); }else if( object instanceof String ){ return _fromString( (String) object, jsonConfig ); }else if( JSONUtils.isNumber( object ) || JSONUtils.isBoolean( object ) || JSONUtils.isString( object ) ){ return new JSONObject(); }else if( JSONUtils.isArray( object ) ){ throw new JSONException( "'object' is an array. Use JSONArray instead" ); }else{ return _fromBean( object, jsonConfig ); } } /** * Creates a JSONDynaBean from a JSONObject. */ public static Object toBean( JSONObject jsonObject ) { if( jsonObject == null || jsonObject.isNullObject() ){ return null; } DynaBean dynaBean = null; JsonConfig jsonConfig = new JsonConfig(); Map props = JSONUtils.getProperties( jsonObject ); dynaBean = JSONUtils.newDynaBean( jsonObject, jsonConfig ); for( Iterator entries = jsonObject.names( jsonConfig ) .iterator(); entries.hasNext(); ){ String name = (String) entries.next(); String key = JSONUtils.convertToJavaIdentifier( name, jsonConfig ); Class type = (Class) props.get( name ); Object value = jsonObject.get( name ); try{ if( !JSONUtils.isNull( value ) ){ if( value instanceof JSONArray ){ dynaBean.set( key, JSONArray.toCollection( (JSONArray) value ) ); }else if( String.class.isAssignableFrom( type ) || Boolean.class.isAssignableFrom( type ) || JSONUtils.isNumber( type ) || Character.class.isAssignableFrom( type ) || JSONFunction.class.isAssignableFrom( type ) ){ dynaBean.set( key, value ); }else{ dynaBean.set( key, toBean( (JSONObject) value ) ); } }else{ if( type.isPrimitive() ){ // assume assigned default value log.warn( "Tried to assign null value to " + key + ":" + type.getName() ); dynaBean.set( key, JSONUtils.getMorpherRegistry() .morph( type, null ) ); }else{ dynaBean.set( key, null ); } } }catch( JSONException jsone ){ throw jsone; }catch( Exception e ){ throw new JSONException( "Error while setting property=" + name + " type" + type, e ); } } return dynaBean; } /** * Creates a bean from a JSONObject, with a specific target class.
*/ public static Object toBean( JSONObject jsonObject, Class beanClass ) { JsonConfig jsonConfig = new JsonConfig(); jsonConfig.setRootClass( beanClass ); return toBean( jsonObject, jsonConfig ); } /** * Creates a bean from a JSONObject, with a specific target class.
* If beanClass is null, this method will return a graph of DynaBeans. Any * attribute that is a JSONObject and matches a key in the classMap will be * converted to that target class.
* The classMap has the following conventions: *
    *
  • Every key must be an String.
  • *
  • Every value must be a Class.
  • *
  • A key may be a regular expression.
  • *
*/ public static Object toBean( JSONObject jsonObject, Class beanClass, Map classMap ) { JsonConfig jsonConfig = new JsonConfig(); jsonConfig.setRootClass( beanClass ); jsonConfig.setClassMap( classMap ); return toBean( jsonObject, jsonConfig ); } /** * Creates a bean from a JSONObject, with the specific configuration. */ public static Object toBean( JSONObject jsonObject, JsonConfig jsonConfig ) { if( jsonObject == null || jsonObject.isNullObject() ){ return null; } Class beanClass = jsonConfig.getRootClass(); Map classMap = jsonConfig.getClassMap(); if( beanClass == null ){ return toBean( jsonObject ); } if( classMap == null ){ classMap = Collections.EMPTY_MAP; } Object bean = null; try{ if( beanClass.isInterface() ){ if( !Map.class.isAssignableFrom( beanClass ) ){ throw new JSONException( "beanClass is an interface. " + beanClass ); }else{ bean = new HashMap(); } }else{ bean = jsonConfig.getNewBeanInstanceStrategy() .newInstance( beanClass, jsonObject ); } }catch( JSONException jsone ){ throw jsone; }catch( Exception e ){ throw new JSONException( e ); } Map props = JSONUtils.getProperties( jsonObject ); PropertyFilter javaPropertyFilter = jsonConfig.getJavaPropertyFilter(); for( Iterator entries = jsonObject.names( jsonConfig ) .iterator(); entries.hasNext(); ){ String name = (String) entries.next(); Class type = (Class) props.get( name ); Object value = jsonObject.get( name ); if( javaPropertyFilter != null && javaPropertyFilter.apply( bean, name, value ) ){ continue; } String key = Map.class.isAssignableFrom( beanClass ) && jsonConfig.isSkipJavaIdentifierTransformationInMapKeys() ? name : JSONUtils.convertToJavaIdentifier( name, jsonConfig ); PropertyNameProcessor propertyNameProcessor = jsonConfig.findJavaPropertyNameProcessor( beanClass ); if( propertyNameProcessor != null ){ key = propertyNameProcessor.processPropertyName( beanClass, key ); } try{ if( Map.class.isAssignableFrom( beanClass ) ){ // no type info available for conversion if( JSONUtils.isNull( value ) ){ setProperty( bean, key, value, jsonConfig ); }else if( value instanceof JSONArray ){ setProperty( bean, key, convertPropertyValueToCollection( key, value, jsonConfig, name, classMap, List.class ), jsonConfig ); }else if( String.class.isAssignableFrom( type ) || JSONUtils.isBoolean( type ) || JSONUtils.isNumber( type ) || JSONUtils.isString( type ) || JSONFunction.class.isAssignableFrom( type ) ){ if( jsonConfig.isHandleJettisonEmptyElement() && "".equals( value ) ){ setProperty( bean, key, null, jsonConfig ); }else{ setProperty( bean, key, value, jsonConfig ); } }else{ Class targetClass = findTargetClass( key, classMap ); targetClass = targetClass == null ? findTargetClass( name, classMap ) : targetClass; JsonConfig jsc = jsonConfig.copy(); jsc.setRootClass( targetClass ); jsc.setClassMap( classMap ); if( targetClass != null ){ setProperty( bean, key, toBean( (JSONObject) value, jsc ), jsonConfig ); }else{ setProperty( bean, key, toBean( (JSONObject) value ), jsonConfig ); } } }else{ PropertyDescriptor pd = PropertyUtils.getPropertyDescriptor( bean, key ); if( pd != null && pd.getWriteMethod() == null ){ log.info( "Property '" + key + "' of "+ bean.getClass()+" has no write method. SKIPPED." ); continue; } if( pd != null ){ Class targetType = pd.getPropertyType(); if( !JSONUtils.isNull( value ) ){ if( value instanceof JSONArray ){ if( List.class.isAssignableFrom( pd.getPropertyType() ) ){ setProperty( bean, key, convertPropertyValueToCollection( key, value, jsonConfig, name, classMap, pd.getPropertyType() ), jsonConfig ); }else if( Set.class.isAssignableFrom( pd.getPropertyType() ) ){ setProperty( bean, key, convertPropertyValueToCollection( key, value, jsonConfig, name, classMap, pd.getPropertyType() ), jsonConfig ); }else{ setProperty( bean, key, convertPropertyValueToArray( key, value, targetType, jsonConfig, classMap ), jsonConfig ); } }else if( String.class.isAssignableFrom( type ) || JSONUtils.isBoolean( type ) || JSONUtils.isNumber( type ) || JSONUtils.isString( type ) || JSONFunction.class.isAssignableFrom( type ) ){ if( pd != null ){ if( jsonConfig.isHandleJettisonEmptyElement() && "".equals( value ) ){ setProperty( bean, key, null, jsonConfig ); }else if( !targetType.isInstance( value ) ){ setProperty( bean, key, morphPropertyValue( key, value, type, targetType ), jsonConfig ); }else{ setProperty( bean, key, value, jsonConfig ); } }else if( beanClass == null || bean instanceof Map ){ setProperty( bean, key, value, jsonConfig ); }else{ log.warn( "Tried to assign property " + key + ":" + type.getName() + " to bean of class " + bean.getClass() .getName() ); } }else{ if( jsonConfig.isHandleJettisonSingleElementArray() ){ JSONArray array = new JSONArray().element( value, jsonConfig ); Class newTargetClass = findTargetClass( key, classMap ); newTargetClass = newTargetClass == null ? findTargetClass( name, classMap ) : newTargetClass; JsonConfig jsc = jsonConfig.copy(); jsc.setRootClass( newTargetClass ); jsc.setClassMap( classMap ); if( targetType.isArray() ){ setProperty( bean, key, JSONArray.toArray( array, jsc ), jsonConfig ); }else if( JSONArray.class.isAssignableFrom( targetType ) ){ setProperty( bean, key, array, jsonConfig ); }else if( List.class.isAssignableFrom( targetType ) || Set.class.isAssignableFrom( targetType ) ){ jsc.setCollectionType( targetType ); setProperty( bean, key, JSONArray.toCollection( array, jsc ), jsonConfig ); }else{ setProperty( bean, key, toBean( (JSONObject) value, jsc ), jsonConfig ); } }else{ if( targetType == Object.class || targetType.isInterface() ) { Class targetTypeCopy = targetType; targetType = findTargetClass( key, classMap ); targetType = targetType == null ? findTargetClass( name, classMap ) : targetType; targetType = targetType == null && targetTypeCopy.isInterface() ? targetTypeCopy : targetType; } JsonConfig jsc = jsonConfig.copy(); jsc.setRootClass( targetType ); jsc.setClassMap( classMap ); setProperty( bean, key, toBean( (JSONObject) value, jsc ), jsonConfig ); } } }else{ if( type.isPrimitive() ){ // assume assigned default value log.warn( "Tried to assign null value to " + key + ":" + type.getName() ); setProperty( bean, key, JSONUtils.getMorpherRegistry() .morph( type, null ), jsonConfig ); }else{ setProperty( bean, key, null, jsonConfig ); } } }else{ // pd is null if( !JSONUtils.isNull( value ) ){ if( value instanceof JSONArray ){ setProperty( bean, key, convertPropertyValueToCollection( key, value, jsonConfig, name, classMap, List.class ), jsonConfig ); }else if( String.class.isAssignableFrom( type ) || JSONUtils.isBoolean( type ) || JSONUtils.isNumber( type ) || JSONUtils.isString( type ) || JSONFunction.class.isAssignableFrom( type ) ){ if( beanClass == null || bean instanceof Map || jsonConfig.getPropertySetStrategy() != null || !jsonConfig.isIgnorePublicFields() ){ setProperty( bean, key, value, jsonConfig ); }else{ log.warn( "Tried to assign property " + key + ":" + type.getName() + " to bean of class " + bean.getClass() .getName() ); } }else{ if( jsonConfig.isHandleJettisonSingleElementArray() ){ Class newTargetClass = findTargetClass( key, classMap ); newTargetClass = newTargetClass == null ? findTargetClass( name, classMap ) : newTargetClass; JsonConfig jsc = jsonConfig.copy(); jsc.setRootClass( newTargetClass ); jsc.setClassMap( classMap ); setProperty( bean, key, toBean( (JSONObject) value, jsc ), jsonConfig ); }else{ setProperty( bean, key, value, jsonConfig ); } } }else{ if( type.isPrimitive() ){ // assume assigned default value log.warn( "Tried to assign null value to " + key + ":" + type.getName() ); setProperty( bean, key, JSONUtils.getMorpherRegistry() .morph( type, null ), jsonConfig ); }else{ setProperty( bean, key, null, jsonConfig ); } } } } }catch( JSONException jsone ){ throw jsone; }catch( Exception e ){ throw new JSONException( "Error while setting property=" + name + " type " + type, e ); } } return bean; } /** * Creates a bean from a JSONObject, with the specific configuration. */ public static Object toBean( JSONObject jsonObject, Object root, JsonConfig jsonConfig ) { if( jsonObject == null || jsonObject.isNullObject() || root == null ){ return root; } Class rootClass = root.getClass(); if( rootClass.isInterface() ){ throw new JSONException( "Root bean is an interface. " + rootClass ); } Map classMap = jsonConfig.getClassMap(); if( classMap == null ){ classMap = Collections.EMPTY_MAP; } Map props = JSONUtils.getProperties( jsonObject ); PropertyFilter javaPropertyFilter = jsonConfig.getJavaPropertyFilter(); for( Iterator entries = jsonObject.names( jsonConfig ) .iterator(); entries.hasNext(); ){ String name = (String) entries.next(); Class type = (Class) props.get( name ); Object value = jsonObject.get( name ); if( javaPropertyFilter != null && javaPropertyFilter.apply( root, name, value ) ){ continue; } String key = JSONUtils.convertToJavaIdentifier( name, jsonConfig ); try{ PropertyDescriptor pd = PropertyUtils.getPropertyDescriptor( root, key ); if( pd != null && pd.getWriteMethod() == null ){ log.info( "Property '" + key + "' of "+ root.getClass()+" has no write method. SKIPPED." ); continue; } if( !JSONUtils.isNull( value ) ){ if( value instanceof JSONArray ){ if( pd == null || List.class.isAssignableFrom( pd.getPropertyType() ) ){ Class targetClass = findTargetClass( key, classMap ); targetClass = targetClass == null ? findTargetClass( name, classMap ) : targetClass; Object newRoot = jsonConfig.getNewBeanInstanceStrategy() .newInstance( targetClass, null ); List list = JSONArray.toList( (JSONArray) value, newRoot, jsonConfig ); setProperty( root, key, list, jsonConfig ); }else{ Class innerType = JSONUtils.getInnerComponentType( pd.getPropertyType() ); Class targetInnerType = findTargetClass( key, classMap ); if( innerType.equals( Object.class ) && targetInnerType != null && !targetInnerType.equals( Object.class ) ){ innerType = targetInnerType; } Object newRoot = jsonConfig.getNewBeanInstanceStrategy() .newInstance( innerType, null ); Object array = JSONArray.toArray( (JSONArray) value, newRoot, jsonConfig ); if( innerType.isPrimitive() || JSONUtils.isNumber( innerType ) || Boolean.class.isAssignableFrom( innerType ) || JSONUtils.isString( innerType ) ){ array = JSONUtils.getMorpherRegistry() .morph( Array.newInstance( innerType, 0 ) .getClass(), array ); }else if( !array.getClass() .equals( pd.getPropertyType() ) ){ if( !pd.getPropertyType() .equals( Object.class ) ){ Morpher morpher = JSONUtils.getMorpherRegistry() .getMorpherFor( Array.newInstance( innerType, 0 ) .getClass() ); if( IdentityObjectMorpher.getInstance() .equals( morpher ) ){ ObjectArrayMorpher beanMorpher = new ObjectArrayMorpher( new BeanMorpher( innerType, JSONUtils.getMorpherRegistry() ) ); JSONUtils.getMorpherRegistry() .registerMorpher( beanMorpher ); } array = JSONUtils.getMorpherRegistry() .morph( Array.newInstance( innerType, 0 ) .getClass(), array ); } } setProperty( root, key, array, jsonConfig ); } }else if( String.class.isAssignableFrom( type ) || JSONUtils.isBoolean( type ) || JSONUtils.isNumber( type ) || JSONUtils.isString( type ) || JSONFunction.class.isAssignableFrom( type ) ){ if( pd != null ){ if( jsonConfig.isHandleJettisonEmptyElement() && "".equals( value ) ){ setProperty( root, key, null, jsonConfig ); }else if( !pd.getPropertyType() .isInstance( value ) ){ Morpher morpher = JSONUtils.getMorpherRegistry() .getMorpherFor( pd.getPropertyType() ); if( IdentityObjectMorpher.getInstance() .equals( morpher ) ){ log.warn( "Can't transform property '" + key + "' from " + type.getName() + " into " + pd.getPropertyType() .getName() + ". Will register a default BeanMorpher" ); JSONUtils.getMorpherRegistry() .registerMorpher( new BeanMorpher( pd.getPropertyType(), JSONUtils.getMorpherRegistry() ) ); } setProperty( root, key, JSONUtils.getMorpherRegistry() .morph( pd.getPropertyType(), value ), jsonConfig ); }else{ setProperty( root, key, value, jsonConfig ); } }else if( root instanceof Map ){ setProperty( root, key, value, jsonConfig ); }else{ log.warn( "Tried to assign property " + key + ":" + type.getName() + " to bean of class " + root.getClass() .getName() ); } }else{ if( pd != null ){ Class targetClass = pd.getPropertyType(); if( jsonConfig.isHandleJettisonSingleElementArray() ){ JSONArray array = new JSONArray().element( value, jsonConfig ); Class newTargetClass = findTargetClass( key, classMap ); newTargetClass = newTargetClass == null ? findTargetClass( name, classMap ) : newTargetClass; Object newRoot = jsonConfig.getNewBeanInstanceStrategy() .newInstance( newTargetClass, null ); if( targetClass.isArray() ){ setProperty( root, key, JSONArray.toArray( array, newRoot, jsonConfig ), jsonConfig ); }else if( Collection.class.isAssignableFrom( targetClass ) ){ setProperty( root, key, JSONArray.toList( array, newRoot, jsonConfig ), jsonConfig ); }else if( JSONArray.class.isAssignableFrom( targetClass ) ){ setProperty( root, key, array, jsonConfig ); }else{ setProperty( root, key, toBean( (JSONObject) value, newRoot, jsonConfig ), jsonConfig ); } }else{ if( targetClass == Object.class ){ targetClass = findTargetClass( key, classMap ); targetClass = targetClass == null ? findTargetClass( name, classMap ) : targetClass; } Object newRoot = jsonConfig.getNewBeanInstanceStrategy() .newInstance( targetClass, null ); setProperty( root, key, toBean( (JSONObject) value, newRoot, jsonConfig ), jsonConfig ); } }else if( root instanceof Map ){ Class targetClass = findTargetClass( key, classMap ); targetClass = targetClass == null ? findTargetClass( name, classMap ) : targetClass; Object newRoot = jsonConfig.getNewBeanInstanceStrategy() .newInstance( targetClass, null ); setProperty( root, key, toBean( (JSONObject) value, newRoot, jsonConfig ), jsonConfig ); }else{ log.warn( "Tried to assign property " + key + ":" + type.getName() + " to bean of class " + rootClass.getName() ); } } }else{ if( type.isPrimitive() ){ // assume assigned default value log.warn( "Tried to assign null value to " + key + ":" + type.getName() ); setProperty( root, key, JSONUtils.getMorpherRegistry() .morph( type, null ), jsonConfig ); }else{ setProperty( root, key, null, jsonConfig ); } } }catch( JSONException jsone ){ throw jsone; }catch( Exception e ){ throw new JSONException( "Error while setting property=" + name + " type " + type, e ); } } return root; } /** * Creates a JSONObject from a POJO.
* Supports nested maps, POJOs, and arrays/collections. * * @param bean An object with POJO conventions * @throws JSONException if the bean can not be converted to a proper * JSONObject. */ private static JSONObject _fromBean( Object bean, JsonConfig jsonConfig ) { if( !addInstance( bean ) ){ try{ return jsonConfig.getCycleDetectionStrategy() .handleRepeatedReferenceAsObject( bean ); }catch( JSONException jsone ){ removeInstance( bean ); fireErrorEvent( jsone, jsonConfig ); throw jsone; }catch( RuntimeException e ){ removeInstance( bean ); JSONException jsone = new JSONException( e ); fireErrorEvent( jsone, jsonConfig ); throw jsone; } } fireObjectStartEvent( jsonConfig ); JsonBeanProcessor processor = jsonConfig.findJsonBeanProcessor( bean.getClass() ); if( processor != null ){ JSONObject json = null; try{ json = processor.processBean( bean, jsonConfig ); if( json == null ){ json = (JSONObject) jsonConfig.findDefaultValueProcessor( bean.getClass() ) .getDefaultValue( bean.getClass() ); if( json == null ){ json = new JSONObject( true ); } } removeInstance( bean ); fireObjectEndEvent( jsonConfig ); }catch( JSONException jsone ){ removeInstance( bean ); fireErrorEvent( jsone, jsonConfig ); throw jsone; }catch( RuntimeException e ){ removeInstance( bean ); JSONException jsone = new JSONException( e ); fireErrorEvent( jsone, jsonConfig ); throw jsone; } return json; } Class beanClass = bean.getClass(); PropertyNameProcessor propertyNameProcessor = jsonConfig.findJsonPropertyNameProcessor( beanClass ); Collection exclusions = jsonConfig.getMergedExcludes( beanClass ); JSONObject jsonObject = new JSONObject(); try{ PropertyDescriptor[] pds = PropertyUtils.getPropertyDescriptors( bean ); PropertyFilter jsonPropertyFilter = jsonConfig.getJsonPropertyFilter(); for( int i = 0; i < pds.length; i++ ){ boolean bypass = false; String key = pds[i].getName(); if( exclusions.contains( key ) ){ continue; } if( jsonConfig.isIgnoreTransientFields() && isTransientField( key, beanClass ) ){ continue; } Class type = pds[i].getPropertyType(); try { pds[i].getReadMethod(); } catch( Exception e ) { // bug 2565295 String warning = "Property '" + key + "' of "+ beanClass+" has no read method. SKIPPED"; fireWarnEvent( warning, jsonConfig ); log.info( warning ); continue; } if( pds[i].getReadMethod() != null ){ Object value = PropertyUtils.getProperty( bean, key ); if( jsonPropertyFilter != null && jsonPropertyFilter.apply( bean, key, value ) ){ continue; } JsonValueProcessor jsonValueProcessor = jsonConfig.findJsonValueProcessor( beanClass, type, key ); if( jsonValueProcessor != null ){ value = jsonValueProcessor.processObjectValue( key, value, jsonConfig ); bypass = true; if( !JsonVerifier.isValidJsonValue( value ) ){ throw new JSONException( "Value is not a valid JSON value. " + value ); } } if( propertyNameProcessor != null ){ key = propertyNameProcessor.processPropertyName( beanClass, key ); } setValue( jsonObject, key, value, type, jsonConfig, bypass ); }else{ String warning = "Property '" + key + "' of "+ beanClass+" has no read method. SKIPPED"; fireWarnEvent( warning, jsonConfig ); log.info( warning ); } } // inspect public fields, this operation may fail under // a SecurityManager so we will eat all exceptions try { if( !jsonConfig.isIgnorePublicFields() ) { Field[] fields = beanClass.getFields(); for( int i = 0; i < fields.length; i++ ) { boolean bypass = false; Field field = fields[i]; String key = field.getName(); if( exclusions.contains( key ) ) { continue; } if( jsonConfig.isIgnoreTransientFields() && isTransientField( field ) ) { continue; } Class type = field.getType(); Object value = field.get( bean ); if( jsonPropertyFilter != null && jsonPropertyFilter.apply( bean, key, value ) ) { continue; } JsonValueProcessor jsonValueProcessor = jsonConfig.findJsonValueProcessor( beanClass, type, key ); if( jsonValueProcessor != null ) { value = jsonValueProcessor.processObjectValue( key, value, jsonConfig ); bypass = true; if( !JsonVerifier.isValidJsonValue( value ) ) { throw new JSONException( "Value is not a valid JSON value. " + value ); } } if( propertyNameProcessor != null ) { key = propertyNameProcessor.processPropertyName( beanClass, key ); } setValue( jsonObject, key, value, type, jsonConfig, bypass ); } } } catch( Exception e ){ log.trace( "Couldn't read public fields.", e ); } }catch( JSONException jsone ){ removeInstance( bean ); fireErrorEvent( jsone, jsonConfig ); throw jsone; }catch( Exception e ){ removeInstance( bean ); JSONException jsone = new JSONException( e ); fireErrorEvent( jsone, jsonConfig ); throw jsone; } removeInstance( bean ); fireObjectEndEvent( jsonConfig ); return jsonObject; } private static JSONObject _fromDynaBean( DynaBean bean, JsonConfig jsonConfig ) { if( bean == null ){ fireObjectStartEvent( jsonConfig ); fireObjectEndEvent( jsonConfig ); return new JSONObject( true ); } if( !addInstance( bean ) ){ try{ return jsonConfig.getCycleDetectionStrategy() .handleRepeatedReferenceAsObject( bean ); }catch( JSONException jsone ){ removeInstance( bean ); fireErrorEvent( jsone, jsonConfig ); throw jsone; }catch( RuntimeException e ){ removeInstance( bean ); JSONException jsone = new JSONException( e ); fireErrorEvent( jsone, jsonConfig ); throw jsone; } } fireObjectStartEvent( jsonConfig ); JSONObject jsonObject = new JSONObject(); try{ DynaProperty[] props = bean.getDynaClass() .getDynaProperties(); Collection exclusions = jsonConfig.getMergedExcludes(); PropertyFilter jsonPropertyFilter = jsonConfig.getJsonPropertyFilter(); for( int i = 0; i < props.length; i++ ){ boolean bypass = false; DynaProperty dynaProperty = props[i]; String key = dynaProperty.getName(); if( exclusions.contains( key ) ){ continue; } Class type = dynaProperty.getType(); Object value = bean.get( dynaProperty.getName() ); if( jsonPropertyFilter != null && jsonPropertyFilter.apply( bean, key, value ) ){ continue; } JsonValueProcessor jsonValueProcessor = jsonConfig.findJsonValueProcessor( type, key ); if( jsonValueProcessor != null ){ value = jsonValueProcessor.processObjectValue( key, value, jsonConfig ); bypass = true; if( !JsonVerifier.isValidJsonValue( value ) ){ throw new JSONException( "Value is not a valid JSON value. " + value ); } } setValue( jsonObject, key, value, type, jsonConfig, bypass ); } }catch( JSONException jsone ){ removeInstance( bean ); fireErrorEvent( jsone, jsonConfig ); throw jsone; }catch( RuntimeException e ){ removeInstance( bean ); JSONException jsone = new JSONException( e ); fireErrorEvent( jsone, jsonConfig ); throw jsone; } removeInstance( bean ); fireObjectEndEvent( jsonConfig ); return jsonObject; } private static JSONObject _fromJSONObject( JSONObject object, JsonConfig jsonConfig ) { if( object == null || object.isNullObject() ){ fireObjectStartEvent( jsonConfig ); fireObjectEndEvent( jsonConfig ); return new JSONObject( true ); } if( !addInstance( object ) ){ try{ return jsonConfig.getCycleDetectionStrategy() .handleRepeatedReferenceAsObject( object ); }catch( JSONException jsone ){ removeInstance( object ); fireErrorEvent( jsone, jsonConfig ); throw jsone; }catch( RuntimeException e ){ removeInstance( object ); JSONException jsone = new JSONException( e ); fireErrorEvent( jsone, jsonConfig ); throw jsone; } } fireObjectStartEvent( jsonConfig ); JSONArray sa = object.names(jsonConfig); Collection exclusions = jsonConfig.getMergedExcludes(); JSONObject jsonObject = new JSONObject(); PropertyFilter jsonPropertyFilter = jsonConfig.getJsonPropertyFilter(); for( Iterator i = sa.iterator(); i.hasNext(); ){ Object k = i.next(); if( k == null ){ throw new JSONException("JSON keys cannot be null."); } if( !(k instanceof String) && !jsonConfig.isAllowNonStringKeys()) { throw new ClassCastException("JSON keys must be strings."); } String key = String.valueOf( k ); if( "null".equals( key )){ throw new NullPointerException("JSON keys must not be null nor the 'null' string."); } if( exclusions.contains( key ) ){ continue; } Object value = object.opt( key ); if( jsonPropertyFilter != null && jsonPropertyFilter.apply( object, key, value ) ){ continue; } if( jsonObject.properties.containsKey( key ) ){ jsonObject.accumulate( key, value, jsonConfig ); firePropertySetEvent( key, value, true, jsonConfig ); }else{ jsonObject.setInternal( key, value, jsonConfig ); firePropertySetEvent( key, value, false, jsonConfig ); } } removeInstance( object ); fireObjectEndEvent( jsonConfig ); return jsonObject; } private static JSONObject _fromJSONString( JSONString string, JsonConfig jsonConfig ) { return _fromJSONTokener( new JSONTokener( string.toJSONString() ), jsonConfig ); } private static JSONObject _fromJSONTokener( JSONTokener tokener, JsonConfig jsonConfig ) { try{ char c; String key; Object value; if( tokener.matches( "null.*" ) ){ fireObjectStartEvent( jsonConfig ); fireObjectEndEvent( jsonConfig ); return new JSONObject( true ); } if( tokener.nextClean() != '{' ){ throw tokener.syntaxError( "A JSONObject text must begin with '{'" ); } fireObjectStartEvent( jsonConfig ); Collection exclusions = jsonConfig.getMergedExcludes(); PropertyFilter jsonPropertyFilter = jsonConfig.getJsonPropertyFilter(); JSONObject jsonObject = new JSONObject(); for( ;; ){ c = tokener.nextClean(); switch( c ){ case 0: throw tokener.syntaxError( "A JSONObject text must end with '}'" ); case '}': fireObjectEndEvent( jsonConfig ); return jsonObject; default: tokener.back(); key = tokener.nextValue( jsonConfig ) .toString(); } /* * The key is followed by ':'. We will also tolerate '=' or '=>'. */ c = tokener.nextClean(); if( c == '=' ){ if( tokener.next() != '>' ){ tokener.back(); } }else if( c != ':' ){ throw tokener.syntaxError( "Expected a ':' after a key" ); } char peek = tokener.peek(); boolean quoted = peek == '"' || peek == '\''; Object v = tokener.nextValue( jsonConfig ); if( quoted || !JSONUtils.isFunctionHeader( v ) ){ if( exclusions.contains( key ) ){ switch( tokener.nextClean() ){ case ';': case ',': if( tokener.nextClean() == '}' ){ fireObjectEndEvent( jsonConfig ); return jsonObject; } tokener.back(); break; case '}': fireObjectEndEvent( jsonConfig ); return jsonObject; default: throw tokener.syntaxError( "Expected a ',' or '}'" ); } continue; } if( jsonPropertyFilter == null || !jsonPropertyFilter.apply( tokener, key, v ) ){ if( quoted && v instanceof String && (JSONUtils.mayBeJSON( (String) v ) || JSONUtils.isFunction( v ))){ v = JSONUtils.DOUBLE_QUOTE + v + JSONUtils.DOUBLE_QUOTE; } if( jsonObject.properties.containsKey( key ) ){ jsonObject.accumulate( key, v, jsonConfig ); firePropertySetEvent( key, v, true, jsonConfig ); }else{ jsonObject.element( key, v, jsonConfig ); firePropertySetEvent( key, v, false, jsonConfig ); } } }else{ // read params if any String params = JSONUtils.getFunctionParams( (String) v ); // read function text int i = 0; StringBuffer sb = new StringBuffer(); for( ;; ){ char ch = tokener.next(); if( ch == 0 ){ break; } if( ch == '{' ){ i++; } if( ch == '}' ){ i--; } sb.append( ch ); if( i == 0 ){ break; } } if( i != 0 ){ throw tokener.syntaxError( "Unbalanced '{' or '}' on prop: " + v ); } // trim '{' at start and '}' at end String text = sb.toString(); text = text.substring( 1, text.length() - 1 ) .trim(); value = new JSONFunction( (params != null) ? StringUtils.split( params, "," ) : null, text ); if( jsonPropertyFilter == null || !jsonPropertyFilter.apply( tokener, key, value ) ){ if( jsonObject.properties.containsKey( key ) ){ jsonObject.accumulate( key, value, jsonConfig ); firePropertySetEvent( key, value, true, jsonConfig ); }else{ jsonObject.element( key, value, jsonConfig ); firePropertySetEvent( key, value, false, jsonConfig ); } } } /* * Pairs are separated by ','. We will also tolerate ';'. */ switch( tokener.nextClean() ){ case ';': case ',': if( tokener.nextClean() == '}' ){ fireObjectEndEvent( jsonConfig ); return jsonObject; } tokener.back(); break; case '}': fireObjectEndEvent( jsonConfig ); return jsonObject; default: throw tokener.syntaxError( "Expected a ',' or '}'" ); } } }catch( JSONException jsone ){ fireErrorEvent( jsone, jsonConfig ); throw jsone; } } private static JSONObject _fromMap( Map map, JsonConfig jsonConfig ) { if( map == null ){ fireObjectStartEvent( jsonConfig ); fireObjectEndEvent( jsonConfig ); return new JSONObject( true ); } if( !addInstance( map ) ){ try{ return jsonConfig.getCycleDetectionStrategy() .handleRepeatedReferenceAsObject( map ); }catch( JSONException jsone ){ removeInstance( map ); fireErrorEvent( jsone, jsonConfig ); throw jsone; }catch( RuntimeException e ){ removeInstance( map ); JSONException jsone = new JSONException( e ); fireErrorEvent( jsone, jsonConfig ); throw jsone; } } fireObjectStartEvent( jsonConfig ); Collection exclusions = jsonConfig.getMergedExcludes(); JSONObject jsonObject = new JSONObject(); PropertyFilter jsonPropertyFilter = jsonConfig.getJsonPropertyFilter(); try{ for( Iterator entries = map.entrySet() .iterator(); entries.hasNext(); ){ boolean bypass = false; Map.Entry entry = (Map.Entry) entries.next(); Object k = entry.getKey(); if( k == null ){ throw new JSONException("JSON keys cannot be null."); } if( !(k instanceof String) && !jsonConfig.isAllowNonStringKeys() ) { throw new ClassCastException("JSON keys must be strings."); } String key = String.valueOf( k ); if( "null".equals( key )){ throw new NullPointerException("JSON keys must not be null nor the 'null' string."); } if( exclusions.contains( key ) ){ continue; } Object value = entry.getValue(); if( jsonPropertyFilter != null && jsonPropertyFilter.apply( map, key, value ) ){ continue; } if( value != null ){ JsonValueProcessor jsonValueProcessor = jsonConfig.findJsonValueProcessor( value.getClass(), key ); if( jsonValueProcessor != null ){ value = jsonValueProcessor.processObjectValue( key, value, jsonConfig ); bypass = true; if( !JsonVerifier.isValidJsonValue( value ) ){ throw new JSONException( "Value is not a valid JSON value. " + value ); } } setValue( jsonObject, key, value, value.getClass(), jsonConfig, bypass ); }else{ if( jsonObject.properties.containsKey( key ) ){ jsonObject.accumulate( key, JSONNull.getInstance() ); firePropertySetEvent( key, JSONNull.getInstance(), true, jsonConfig ); }else{ jsonObject.element( key, JSONNull.getInstance() ); firePropertySetEvent( key, JSONNull.getInstance(), false, jsonConfig ); } } } }catch( JSONException jsone ){ removeInstance( map ); fireErrorEvent( jsone, jsonConfig ); throw jsone; }catch( RuntimeException e ){ removeInstance( map ); JSONException jsone = new JSONException( e ); fireErrorEvent( jsone, jsonConfig ); throw jsone; } removeInstance( map ); fireObjectEndEvent( jsonConfig ); return jsonObject; } private static JSONObject _fromString( String str, JsonConfig jsonConfig ) { if( str == null || "null".equals( str ) ){ fireObjectStartEvent( jsonConfig ); fireObjectEndEvent( jsonConfig ); return new JSONObject( true ); } return _fromJSONTokener( new JSONTokener( str ), jsonConfig ); } private static Object convertPropertyValueToArray( String key, Object value, Class targetType, JsonConfig jsonConfig, Map classMap ) { Class innerType = JSONUtils.getInnerComponentType( targetType ); Class targetInnerType = findTargetClass( key, classMap ); if( innerType.equals( Object.class ) && targetInnerType != null && !targetInnerType.equals( Object.class ) ){ innerType = targetInnerType; } JsonConfig jsc = jsonConfig.copy(); jsc.setRootClass( innerType ); jsc.setClassMap( classMap ); Object array = JSONArray.toArray( (JSONArray) value, jsc ); if( innerType.isPrimitive() || JSONUtils.isNumber( innerType ) || Boolean.class.isAssignableFrom( innerType ) || JSONUtils.isString( innerType ) ){ array = JSONUtils.getMorpherRegistry() .morph( Array.newInstance( innerType, 0 ) .getClass(), array ); }else if( !array.getClass() .equals( targetType ) ){ if( !targetType.equals( Object.class ) ){ Morpher morpher = JSONUtils.getMorpherRegistry() .getMorpherFor( Array.newInstance( innerType, 0 ) .getClass() ); if( IdentityObjectMorpher.getInstance() .equals( morpher ) ){ ObjectArrayMorpher beanMorpher = new ObjectArrayMorpher( new BeanMorpher( innerType, JSONUtils.getMorpherRegistry() ) ); JSONUtils.getMorpherRegistry() .registerMorpher( beanMorpher ); } array = JSONUtils.getMorpherRegistry() .morph( Array.newInstance( innerType, 0 ) .getClass(), array ); } } return array; } private static List convertPropertyValueToList( String key, Object value, JsonConfig jsonConfig, String name, Map classMap ) { Class targetClass = findTargetClass( key, classMap ); targetClass = targetClass == null ? findTargetClass( name, classMap ) : targetClass; JsonConfig jsc = jsonConfig.copy(); jsc.setRootClass( targetClass ); jsc.setClassMap( classMap ); List list = (List) JSONArray.toCollection( (JSONArray) value, jsc ); return list; } private static Collection convertPropertyValueToCollection( String key, Object value, JsonConfig jsonConfig, String name, Map classMap, Class collectionType ) { Class targetClass = findTargetClass( key, classMap ); targetClass = targetClass == null ? findTargetClass( name, classMap ) : targetClass; JsonConfig jsc = jsonConfig.copy(); jsc.setRootClass( targetClass ); jsc.setClassMap( classMap ); jsc.setCollectionType( collectionType ); return JSONArray.toCollection( (JSONArray) value, jsc ); } /** * Locates a Class associated to a specifi key.
* The key may be a regexp. */ private static Class findTargetClass( String key, Map classMap ) { // try get first Class targetClass = (Class) classMap.get( key ); if( targetClass == null ){ // try with regexp // this will hit performance as it must iterate over all the keys // and create a RegexpMatcher for each key for( Iterator i = classMap.entrySet() .iterator(); i.hasNext(); ){ Map.Entry entry = (Map.Entry) i.next(); if( RegexpUtils.getMatcher( (String) entry.getKey() ) .matches( key ) ){ targetClass = (Class) entry.getValue(); break; } } } return targetClass; } private static boolean isTransientField( String name, Class beanClass ) { try{ return isTransientField(beanClass.getDeclaredField( name )); }catch( Exception e ){ // swallow exception } return false; } private static boolean isTransientField( Field field ) { return (field.getModifiers() & Modifier.TRANSIENT) == Modifier.TRANSIENT; } private static Object morphPropertyValue( String key, Object value, Class type, Class targetType ) { Morpher morpher = JSONUtils.getMorpherRegistry() .getMorpherFor( targetType ); if( IdentityObjectMorpher.getInstance() .equals( morpher ) ){ log.warn( "Can't transform property '" + key + "' from " + type.getName() + " into " + targetType.getName() + ". Will register a default BeanMorpher" ); JSONUtils.getMorpherRegistry() .registerMorpher( new BeanMorpher( targetType, JSONUtils.getMorpherRegistry() ) ); } value = JSONUtils.getMorpherRegistry() .morph( targetType, value ); return value; } /** * Sets a property on the target bean.
* Bean may be a Map or a POJO. */ private static void setProperty( Object bean, String key, Object value, JsonConfig jsonConfig ) throws Exception { PropertySetStrategy propertySetStrategy = jsonConfig.getPropertySetStrategy() != null ? jsonConfig.getPropertySetStrategy() : PropertySetStrategy.DEFAULT; propertySetStrategy.setProperty( bean, key, value, jsonConfig ); } private static void setValue( JSONObject jsonObject, String key, Object value, Class type, JsonConfig jsonConfig, boolean bypass ) { boolean accumulated = false; if( value == null ){ value = jsonConfig.findDefaultValueProcessor( type ) .getDefaultValue( type ); if( !JsonVerifier.isValidJsonValue( value ) ){ throw new JSONException( "Value is not a valid JSON value. " + value ); } } if( jsonObject.properties.containsKey( key ) ){ if( String.class.isAssignableFrom( type ) ){ Object o = jsonObject.opt( key ); if( o instanceof JSONArray ){ ((JSONArray) o).addString( (String) value ); }else{ jsonObject.properties.put( key, new JSONArray().element( o ) .addString( (String) value ) ); } }else{ jsonObject.accumulate( key, value, jsonConfig ); } accumulated = true; }else{ if( bypass || String.class.isAssignableFrom( type ) ){ jsonObject.properties.put( key, value ); }else{ jsonObject.setInternal( key, value, jsonConfig ); } } value = jsonObject.opt( key ); if( accumulated ){ JSONArray array = (JSONArray) value; value = array.get( array.size() - 1 ); } firePropertySetEvent( key, value, accumulated, jsonConfig ); } // ------------------------------------------------------ /** identifies this object as null */ private boolean nullObject; /** * The Map where the JSONObject's properties are kept. */ private Map properties; /** * Construct an empty JSONObject. */ public JSONObject() { this.properties = new ListOrderedMap(); } /** * Creates a JSONObject that is null. */ public JSONObject( boolean isNull ) { this(); this.nullObject = isNull; } /** * Accumulate values under a key. It is similar to the element method except * that if there is already an object stored under the key then a JSONArray * is stored under the key to hold all of the accumulated values. If there is * already a JSONArray, then the new value is appended to it. In contrast, * the replace method replaces the previous value. * * @param key A key string. * @param value An object to be accumulated under the key. * @return this. * @throws JSONException If the value is an invalid number or if the key is * null. */ public JSONObject accumulate( String key, boolean value ) { return _accumulate( key, value ? Boolean.TRUE : Boolean.FALSE, new JsonConfig() ); } /** * Accumulate values under a key. It is similar to the element method except * that if there is already an object stored under the key then a JSONArray * is stored under the key to hold all of the accumulated values. If there is * already a JSONArray, then the new value is appended to it. In contrast, * the replace method replaces the previous value. * * @param key A key string. * @param value An object to be accumulated under the key. * @return this. * @throws JSONException If the value is an invalid number or if the key is * null. */ public JSONObject accumulate( String key, double value ) { return _accumulate( key, new Double( value ), new JsonConfig() ); } /** * Accumulate values under a key. It is similar to the element method except * that if there is already an object stored under the key then a JSONArray * is stored under the key to hold all of the accumulated values. If there is * already a JSONArray, then the new value is appended to it. In contrast, * the replace method replaces the previous value. * * @param key A key string. * @param value An object to be accumulated under the key. * @return this. * @throws JSONException If the value is an invalid number or if the key is * null. */ public JSONObject accumulate( String key, int value ) { return _accumulate( key, new Integer( value ), new JsonConfig() ); } /** * Accumulate values under a key. It is similar to the element method except * that if there is already an object stored under the key then a JSONArray * is stored under the key to hold all of the accumulated values. If there is * already a JSONArray, then the new value is appended to it. In contrast, * the replace method replaces the previous value. * * @param key A key string. * @param value An object to be accumulated under the key. * @return this. * @throws JSONException If the value is an invalid number or if the key is * null. */ public JSONObject accumulate( String key, long value ) { return _accumulate( key, new Long( value ), new JsonConfig() ); } /** * Accumulate values under a key. It is similar to the element method except * that if there is already an object stored under the key then a JSONArray * is stored under the key to hold all of the accumulated values. If there is * already a JSONArray, then the new value is appended to it. In contrast, * the replace method replaces the previous value. * * @param key A key string. * @param value An object to be accumulated under the key. * @return this. * @throws JSONException If the value is an invalid number or if the key is * null. */ public JSONObject accumulate( String key, Object value ) { return _accumulate( key, value, new JsonConfig() ); } /** * Accumulate values under a key. It is similar to the element method except * that if there is already an object stored under the key then a JSONArray * is stored under the key to hold all of the accumulated values. If there is * already a JSONArray, then the new value is appended to it. In contrast, * the replace method replaces the previous value. * * @param key A key string. * @param value An object to be accumulated under the key. * @return this. * @throws JSONException If the value is an invalid number or if the key is * null. */ public JSONObject accumulate( String key, Object value, JsonConfig jsonConfig ) { return _accumulate( key, value, jsonConfig ); } public void accumulateAll( Map map ) { accumulateAll( map, new JsonConfig() ); } public void accumulateAll( Map map, JsonConfig jsonConfig ) { if( map instanceof JSONObject ){ for( Iterator entries = map.entrySet() .iterator(); entries.hasNext(); ){ Map.Entry entry = (Map.Entry) entries.next(); String key = (String) entry.getKey(); Object value = entry.getValue(); accumulate( key, value, jsonConfig ); } }else{ for( Iterator entries = map.entrySet() .iterator(); entries.hasNext(); ){ Map.Entry entry = (Map.Entry) entries.next(); String key = String.valueOf( entry.getKey() ); Object value = entry.getValue(); accumulate( key, value, jsonConfig ); } } } public void clear() { properties.clear(); } public int compareTo( Object obj ) { if( obj != null && (obj instanceof JSONObject) ){ JSONObject other = (JSONObject) obj; int size1 = size(); int size2 = other.size(); if( size1 < size2 ){ return -1; }else if( size1 > size2 ){ return 1; }else if( this.equals( other ) ){ return 0; } } return -1; } public boolean containsKey( Object key ) { return properties.containsKey( key ); } public boolean containsValue( Object value ) { return containsValue( value, new JsonConfig() ); } public boolean containsValue( Object value, JsonConfig jsonConfig ) { try{ value = processValue( value, jsonConfig ); }catch( JSONException e ){ return false; } return properties.containsValue( value ); } /** * Remove a name and its value, if present. * * @param key A key string. * @return this. */ public JSONObject discard( String key ) { verifyIsNull(); this.properties.remove( key ); return this; } /** * Put a key/boolean pair in the JSONObject. * * @param key A key string. * @param value A boolean which is the value. * @return this. * @throws JSONException If the key is null. */ public JSONObject element( String key, boolean value ) { verifyIsNull(); return element( key, value ? Boolean.TRUE : Boolean.FALSE ); } /** * Put a key/value pair in the JSONObject, where the value will be a * JSONArray which is produced from a Collection. * * @param key A key string. * @param value A Collection value. * @return this. * @throws JSONException */ public JSONObject element( String key, Collection value ) { return element( key, value, new JsonConfig() ); } /** * Put a key/value pair in the JSONObject, where the value will be a * JSONArray which is produced from a Collection. * * @param key A key string. * @param value A Collection value. * @return this. * @throws JSONException */ public JSONObject element( String key, Collection value, JsonConfig jsonConfig ) { verifyIsNull(); if( !(value instanceof JSONArray) ){ value = JSONArray.fromObject( value, jsonConfig ); } return setInternal( key, value, jsonConfig ); } /** * Put a key/double pair in the JSONObject. * * @param key A key string. * @param value A double which is the value. * @return this. * @throws JSONException If the key is null or if the number is invalid. */ public JSONObject element( String key, double value ) { verifyIsNull(); Double d = new Double( value ); JSONUtils.testValidity( d ); return element( key, d ); } /** * Put a key/int pair in the JSONObject. * * @param key A key string. * @param value An int which is the value. * @return this. * @throws JSONException If the key is null. */ public JSONObject element( String key, int value ) { verifyIsNull(); return element( key, new Integer( value ) ); } /** * Put a key/long pair in the JSONObject. * * @param key A key string. * @param value A long which is the value. * @return this. * @throws JSONException If the key is null. */ public JSONObject element( String key, long value ) { verifyIsNull(); return element( key, new Long( value ) ); } /** * Put a key/value pair in the JSONObject, where the value will be a * JSONObject which is produced from a Map. * * @param key A key string. * @param value A Map value. * @return this. * @throws JSONException */ public JSONObject element( String key, Map value ) { return element( key, value, new JsonConfig() ); } /** * Put a key/value pair in the JSONObject, where the value will be a * JSONObject which is produced from a Map. * * @param key A key string. * @param value A Map value. * @return this. * @throws JSONException */ public JSONObject element( String key, Map value, JsonConfig jsonConfig ) { verifyIsNull(); if( value instanceof JSONObject ){ return setInternal( key, value, jsonConfig ); }else{ return element( key, JSONObject.fromObject( value, jsonConfig ), jsonConfig ); } } /** * Put a key/value pair in the JSONObject. If the value is null, then the key * will be removed from the JSONObject if it is present.
* If there is a previous value assigned to the key, it will call accumulate. * * @param key A key string. * @param value An object which is the value. It should be of one of these * types: Boolean, Double, Integer, JSONArray, JSONObject, Long, * String, or the JSONNull object. * @return this. * @throws JSONException If the value is non-finite number or if the key is * null. */ public JSONObject element( String key, Object value ) { return element( key, value, new JsonConfig() ); } /** * Put a key/value pair in the JSONObject. If the value is null, then the key * will be removed from the JSONObject if it is present.
* If there is a previous value assigned to the key, it will call accumulate. * * @param key A key string. * @param value An object which is the value. It should be of one of these * types: Boolean, Double, Integer, JSONArray, JSONObject, Long, * String, or the JSONNull object. * @return this. * @throws JSONException If the value is non-finite number or if the key is * null. */ public JSONObject element( String key, Object value, JsonConfig jsonConfig ) { verifyIsNull(); if( key == null ){ throw new JSONException( "Null key." ); } if( value != null ){ value = processValue( key, value, jsonConfig ); _setInternal( key, value, jsonConfig ); }else{ remove( key ); } return this; } /** * Put a key/value pair in the JSONObject, but only if the key and the value * are both non-null. * * @param key A key string. * @param value An object which is the value. It should be of one of these * types: Boolean, Double, Integer, JSONArray, JSONObject, Long, * String, or the JSONNull object. * @return this. * @throws JSONException If the value is a non-finite number. */ public JSONObject elementOpt( String key, Object value ) { return elementOpt( key, value, new JsonConfig() ); } /** * Put a key/value pair in the JSONObject, but only if the key and the value * are both non-null. * * @param key A key string. * @param value An object which is the value. It should be of one of these * types: Boolean, Double, Integer, JSONArray, JSONObject, Long, * String, or the JSONNull object. * @return this. * @throws JSONException If the value is a non-finite number. */ public JSONObject elementOpt( String key, Object value, JsonConfig jsonConfig ) { verifyIsNull(); if( key != null && value != null ){ element( key, value, jsonConfig ); } return this; } public Set entrySet() { return Collections.unmodifiableSet( properties.entrySet() ); } public boolean equals( Object obj ) { if( obj == this ){ return true; } if( obj == null ){ return false; } if( !(obj instanceof JSONObject) ){ return false; } JSONObject other = (JSONObject) obj; if( isNullObject() ){ if( other.isNullObject() ){ return true; }else{ return false; } }else{ if( other.isNullObject() ){ return false; } } if( other.size() != size() ){ return false; } for( Iterator keys = properties.keySet() .iterator(); keys.hasNext(); ){ String key = (String) keys.next(); if( !other.properties.containsKey( key ) ){ return false; } Object o1 = properties.get( key ); Object o2 = other.properties.get( key ); if( JSONNull.getInstance() .equals( o1 ) ){ if( JSONNull.getInstance() .equals( o2 ) ){ continue; }else{ return false; } }else{ if( JSONNull.getInstance() .equals( o2 ) ){ return false; } } if( o1 instanceof String && o2 instanceof JSONFunction ){ if( !o1.equals( String.valueOf( o2 ) ) ){ return false; } }else if( o1 instanceof JSONFunction && o2 instanceof String ){ if( !o2.equals( String.valueOf( o1 ) ) ){ return false; } }else if( o1 instanceof JSONObject && o2 instanceof JSONObject ){ if( !o1.equals( o2 ) ){ return false; } }else if( o1 instanceof JSONArray && o2 instanceof JSONArray ){ if( !o1.equals( o2 ) ){ return false; } }else if( o1 instanceof JSONFunction && o2 instanceof JSONFunction ){ if( !o1.equals( o2 ) ){ return false; } }else{ if( o1 instanceof String ){ if( !o1.equals( String.valueOf( o2 ) ) ){ return false; } }else if( o2 instanceof String ){ if( !o2.equals( String.valueOf( o1 ) ) ){ return false; } }else{ Morpher m1 = JSONUtils.getMorpherRegistry() .getMorpherFor( o1.getClass() ); Morpher m2 = JSONUtils.getMorpherRegistry() .getMorpherFor( o2.getClass() ); if( m1 != null && m1 != IdentityObjectMorpher.getInstance() ){ if( !o1.equals( JSONUtils.getMorpherRegistry() .morph( o1.getClass(), o2 ) ) ){ return false; } }else if( m2 != null && m2 != IdentityObjectMorpher.getInstance() ){ if( !JSONUtils.getMorpherRegistry() .morph( o1.getClass(), o1 ) .equals( o2 ) ){ return false; } }else{ if( !o1.equals( o2 ) ){ return false; } } } } } return true; } public Object get( Object key ) { if( key instanceof String ){ return get( (String) key ); } return null; } /** * Get the value object associated with a key. * * @param key A key string. * @return The object associated with the key. * @throws JSONException if this.isNull() returns true. */ public Object get( String key ) { verifyIsNull(); return this.properties.get( key ); } /** * Get the boolean value associated with a key. * * @param key A key string. * @return The truth. * @throws JSONException if the value is not a Boolean or the String "true" * or "false". */ public boolean getBoolean( String key ) { verifyIsNull(); Object o = get( key ); if( o != null ){ if( o.equals( Boolean.FALSE ) || (o instanceof String && ((String) o).equalsIgnoreCase( "false" )) ){ return false; }else if( o.equals( Boolean.TRUE ) || (o instanceof String && ((String) o).equalsIgnoreCase( "true" )) ){ return true; } } throw new JSONException( "JSONObject[" + JSONUtils.quote( key ) + "] is not a Boolean." ); } /** * Get the double value associated with a key. * * @param key A key string. * @return The numeric value. * @throws JSONException if the key is not found or if the value is not a * Number object and cannot be converted to a number. */ public double getDouble( String key ) { verifyIsNull(); Object o = get( key ); if( o != null ){ try{ return o instanceof Number ? ((Number) o).doubleValue() : Double.parseDouble( (String) o ); }catch( Exception e ){ throw new JSONException( "JSONObject[" + JSONUtils.quote( key ) + "] is not a number." ); } } throw new JSONException( "JSONObject[" + JSONUtils.quote( key ) + "] is not a number." ); } /** * Get the int value associated with a key. If the number value is too large * for an int, it will be clipped. * * @param key A key string. * @return The integer value. * @throws JSONException if the key is not found or if the value cannot be * converted to an integer. */ public int getInt( String key ) { verifyIsNull(); Object o = get( key ); if( o != null ){ return o instanceof Number ? ((Number) o).intValue() : (int) getDouble( key ); } throw new JSONException( "JSONObject[" + JSONUtils.quote( key ) + "] is not a number." ); } /** * Get the JSONArray value associated with a key. * * @param key A key string. * @return A JSONArray which is the value. * @throws JSONException if the key is not found or if the value is not a * JSONArray. */ public JSONArray getJSONArray( String key ) { verifyIsNull(); Object o = get( key ); if( o != null && o instanceof JSONArray ){ return (JSONArray) o; } throw new JSONException( "JSONObject[" + JSONUtils.quote( key ) + "] is not a JSONArray." ); } /** * Get the JSONObject value associated with a key. * * @param key A key string. * @return A JSONObject which is the value. * @throws JSONException if the key is not found or if the value is not a * JSONObject. */ public JSONObject getJSONObject( String key ) { verifyIsNull(); Object o = get( key ); if( JSONNull.getInstance() .equals( o ) ){ return new JSONObject( true ); }else if( o instanceof JSONObject ){ return (JSONObject) o; } throw new JSONException( "JSONObject[" + JSONUtils.quote( key ) + "] is not a JSONObject." ); } /** * Get the long value associated with a key. If the number value is too long * for a long, it will be clipped. * * @param key A key string. * @return The long value. * @throws JSONException if the key is not found or if the value cannot be * converted to a long. */ public long getLong( String key ) { verifyIsNull(); Object o = get( key ); if( o != null ){ return o instanceof Number ? ((Number) o).longValue() : (long) getDouble( key ); } throw new JSONException( "JSONObject[" + JSONUtils.quote( key ) + "] is not a number." ); } /** * Get the string associated with a key. * * @param key A key string. * @return A string which is the value. * @throws JSONException if the key is not found. */ public String getString( String key ) { verifyIsNull(); Object o = get( key ); if( o != null ){ return o.toString(); } throw new JSONException( "JSONObject[" + JSONUtils.quote( key ) + "] not found." ); } /** * Determine if the JSONObject contains a specific key. * * @param key A key string. * @return true if the key exists in the JSONObject. */ public boolean has( String key ) { verifyIsNull(); return this.properties.containsKey( key ); } public int hashCode() { int hashcode = 19; if( isNullObject() ){ return hashcode + JSONNull.getInstance() .hashCode(); } for( Iterator entries = properties.entrySet() .iterator(); entries.hasNext(); ){ Map.Entry entry = (Map.Entry) entries.next(); Object key = entry.getKey(); Object value = entry.getValue(); hashcode += key.hashCode() + JSONUtils.hashCode( value ); } return hashcode; } public boolean isArray() { return false; } public boolean isEmpty() { // verifyIsNull(); return this.properties.isEmpty(); } /** * Returs if this object is a null JSONObject. */ public boolean isNullObject() { return nullObject; } /** * Get an enumeration of the keys of the JSONObject. * * @return An iterator of the keys. */ public Iterator keys() { verifyIsNull(); return keySet().iterator(); } public Set keySet() { return Collections.unmodifiableSet( properties.keySet() ); } /** * Produce a JSONArray containing the names of the elements of this * JSONObject. * * @return A JSONArray containing the key strings, or null if the JSONObject * is empty. */ public JSONArray names() { return names( new JsonConfig() ); } /** * Produce a JSONArray containing the names of the elements of this * JSONObject. * * @return A JSONArray containing the key strings, or null if the JSONObject * is empty. */ public JSONArray names( JsonConfig jsonConfig ) { verifyIsNull(); JSONArray ja = new JSONArray(); Iterator keys = keys(); while( keys.hasNext() ){ ja.element( keys.next(), jsonConfig ); } return ja; } /** * Get an optional value associated with a key. * * @param key A key string. * @return An object which is the value, or null if there is no value. */ public Object opt( String key ) { verifyIsNull(); return key == null ? null : this.properties.get( key ); } /** * Get an optional boolean associated with a key. It returns false if there * is no such key, or if the value is not Boolean.TRUE or the String "true". * * @param key A key string. * @return The truth. */ public boolean optBoolean( String key ) { verifyIsNull(); return optBoolean( key, false ); } /** * Get an optional boolean associated with a key. It returns the defaultValue * if there is no such key, or if it is not a Boolean or the String "true" or * "false" (case insensitive). * * @param key A key string. * @param defaultValue The default. * @return The truth. */ public boolean optBoolean( String key, boolean defaultValue ) { verifyIsNull(); try{ return getBoolean( key ); }catch( Exception e ){ return defaultValue; } } /** * Get an optional double associated with a key, or NaN if there is no such * key or if its value is not a number. If the value is a string, an attempt * will be made to evaluate it as a number. * * @param key A string which is the key. * @return An object which is the value. */ public double optDouble( String key ) { verifyIsNull(); return optDouble( key, Double.NaN ); } /** * Get an optional double associated with a key, or the defaultValue if there * is no such key or if its value is not a number. If the value is a string, * an attempt will be made to evaluate it as a number. * * @param key A key string. * @param defaultValue The default. * @return An object which is the value. */ public double optDouble( String key, double defaultValue ) { verifyIsNull(); try{ Object o = opt( key ); return o instanceof Number ? ((Number) o).doubleValue() : new Double( (String) o ).doubleValue(); }catch( Exception e ){ return defaultValue; } } /** * Get an optional int value associated with a key, or zero if there is no * such key or if the value is not a number. If the value is a string, an * attempt will be made to evaluate it as a number. * * @param key A key string. * @return An object which is the value. */ public int optInt( String key ) { verifyIsNull(); return optInt( key, 0 ); } /** * Get an optional int value associated with a key, or the default if there * is no such key or if the value is not a number. If the value is a string, * an attempt will be made to evaluate it as a number. * * @param key A key string. * @param defaultValue The default. * @return An object which is the value. */ public int optInt( String key, int defaultValue ) { verifyIsNull(); try{ return getInt( key ); }catch( Exception e ){ return defaultValue; } } /** * Get an optional JSONArray associated with a key. It returns null if there * is no such key, or if its value is not a JSONArray. * * @param key A key string. * @return A JSONArray which is the value. */ public JSONArray optJSONArray( String key ) { verifyIsNull(); Object o = opt( key ); return o instanceof JSONArray ? (JSONArray) o : null; } /** * Get an optional JSONObject associated with a key. It returns null if there * is no such key, or if its value is not a JSONObject. * * @param key A key string. * @return A JSONObject which is the value. */ public JSONObject optJSONObject( String key ) { verifyIsNull(); Object o = opt( key ); return o instanceof JSONObject ? (JSONObject) o : null; } /** * Get an optional long value associated with a key, or zero if there is no * such key or if the value is not a number. If the value is a string, an * attempt will be made to evaluate it as a number. * * @param key A key string. * @return An object which is the value. */ public long optLong( String key ) { verifyIsNull(); return optLong( key, 0 ); } /** * Get an optional long value associated with a key, or the default if there * is no such key or if the value is not a number. If the value is a string, * an attempt will be made to evaluate it as a number. * * @param key A key string. * @param defaultValue The default. * @return An object which is the value. */ public long optLong( String key, long defaultValue ) { verifyIsNull(); try{ return getLong( key ); }catch( Exception e ){ return defaultValue; } } /** * Get an optional string associated with a key. It returns an empty string * if there is no such key. If the value is not a string and is not null, * then it is coverted to a string. * * @param key A key string. * @return A string which is the value. */ public String optString( String key ) { verifyIsNull(); return optString( key, "" ); } /** * Get an optional string associated with a key. It returns the defaultValue * if there is no such key. * * @param key A key string. * @param defaultValue The default. * @return A string which is the value. */ public String optString( String key, String defaultValue ) { verifyIsNull(); Object o = opt( key ); return o != null ? o.toString() : defaultValue; } public Object put( Object key, Object value ) { if( key == null ){ throw new IllegalArgumentException( "key is null." ); } Object previous = properties.get( key ); element( String.valueOf( key ), value ); return previous; } public void putAll( Map map ) { putAll( map, new JsonConfig() ); } public void putAll( Map map, JsonConfig jsonConfig ) { if( map instanceof JSONObject ){ for( Iterator entries = map.entrySet() .iterator(); entries.hasNext(); ){ Map.Entry entry = (Map.Entry) entries.next(); String key = (String) entry.getKey(); Object value = entry.getValue(); this.properties.put( key, value ); } }else{ for( Iterator entries = map.entrySet() .iterator(); entries.hasNext(); ){ Map.Entry entry = (Map.Entry) entries.next(); String key = String.valueOf( entry.getKey() ); Object value = entry.getValue(); element( key, value, jsonConfig ); } } } public Object remove( Object key ) { return properties.remove( key ); } /** * Remove a name and its value, if present. * * @param key The name to be removed. * @return The value that was associated with the name, or null if there was * no value. */ public Object remove( String key ) { verifyIsNull(); return this.properties.remove( key ); } /** * Get the number of keys stored in the JSONObject. * * @return The number of keys in the JSONObject. */ public int size() { // verifyIsNull(); return this.properties.size(); } /** * Produce a JSONArray containing the values of the members of this * JSONObject. * * @param names A JSONArray containing a list of key strings. This determines * the sequence of the values in the result. * @return A JSONArray of values. * @throws JSONException If any of the values are non-finite numbers. */ public JSONArray toJSONArray( JSONArray names ) { verifyIsNull(); if( names == null || names.size() == 0 ){ return null; } JSONArray ja = new JSONArray(); for( int i = 0; i < names.size(); i += 1 ){ ja.element( this.opt( names.getString( i ) ) ); } return ja; } /** * 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. *

* Warning: This method assumes that the data structure is acyclical. * * @return a printable, displayable, portable, transmittable representation * of the object, beginning with { (left * brace) and ending with } (right * brace). */ public String toString() { if( isNullObject() ){ return JSONNull.getInstance() .toString(); } try{ Iterator keys = keys(); StringBuffer sb = new StringBuffer( "{" ); while( keys.hasNext() ){ if( sb.length() > 1 ){ sb.append( ',' ); } Object o = keys.next(); sb.append( JSONUtils.quote( o.toString() ) ); sb.append( ':' ); sb.append( JSONUtils.valueToString( this.properties.get( o ) ) ); } sb.append( '}' ); return sb.toString(); }catch( Exception e ){ return null; } } /** * Make a prettyprinted JSON text of this JSONObject. *

* Warning: This method assumes that the data structure is acyclical. * * @param indentFactor The number of spaces to add to each level of * indentation. * @return a printable, displayable, portable, transmittable representation * of the object, beginning with { (left * brace) and ending with } (right * brace). * @throws JSONException If the object contains an invalid number. */ public String toString( int indentFactor ) { if( isNullObject() ){ return JSONNull.getInstance() .toString(); } if( indentFactor == 0 ){ return this.toString(); } return toString( indentFactor, 0 ); } /** * Make a prettyprinted JSON text of this JSONObject. *

* Warning: This method assumes that the data structure is acyclical. * * @param indentFactor The number of spaces to add to each level of * indentation. * @param indent The indentation of the top level. * @return a printable, displayable, transmittable representation of the * object, beginning with { (left brace) * and ending with } (right brace). * @throws JSONException If the object contains an invalid number. */ public String toString( int indentFactor, int indent ) { if( isNullObject() ){ return JSONNull.getInstance() .toString(); } int i; int n = size(); if( n == 0 ){ return "{}"; } if( indentFactor == 0 ){ return this.toString(); } Iterator keys = keys(); StringBuffer sb = new StringBuffer( "{" ); int newindent = indent + indentFactor; Object o; if( n == 1 ){ o = keys.next(); sb.append( JSONUtils.quote( o.toString() ) ); sb.append( ": " ); sb.append( JSONUtils.valueToString( this.properties.get( o ), indentFactor, indent ) ); }else{ while( keys.hasNext() ){ o = keys.next(); if( sb.length() > 1 ){ sb.append( ",\n" ); }else{ sb.append( '\n' ); } for( i = 0; i < newindent; i += 1 ){ sb.append( ' ' ); } sb.append( JSONUtils.quote( o.toString() ) ); sb.append( ": " ); sb.append( JSONUtils.valueToString( this.properties.get( o ), indentFactor, newindent ) ); } if( sb.length() > 1 ){ sb.append( '\n' ); for( i = 0; i < indent; i += 1 ){ sb.append( ' ' ); } } for( i = 0; i < indent; i += 1 ){ sb.insert( 0, ' ' ); } } sb.append( '}' ); return sb.toString(); } public Collection values() { return Collections.unmodifiableCollection( properties.values() ); } /** * Write the contents of the JSONObject as JSON text to a writer. For * compactness, no whitespace is added. *

* Warning: This method assumes that the data structure is acyclical. * * @return The writer. * @throws JSONException */ public Writer write( Writer writer ) { try{ if( isNullObject() ){ writer.write( JSONNull.getInstance() .toString() ); return writer; } boolean b = false; Iterator keys = keys(); writer.write( '{' ); while( keys.hasNext() ){ if( b ){ writer.write( ',' ); } Object k = keys.next(); writer.write( JSONUtils.quote( k.toString() ) ); writer.write( ':' ); Object v = this.properties.get( k ); if( v instanceof JSONObject ){ ((JSONObject) v).write( writer ); }else if( v instanceof JSONArray ){ ((JSONArray) v).write( writer ); }else{ writer.write( JSONUtils.valueToString( v ) ); } b = true; } writer.write( '}' ); return writer; }catch( IOException e ){ throw new JSONException( e ); } } private JSONObject _accumulate( String key, Object value, JsonConfig jsonConfig ) { if( isNullObject() ){ throw new JSONException( "Can't accumulate on null object" ); } if( !has( key ) ){ setInternal( key, value, jsonConfig ); }else{ Object o = opt( key ); if( o instanceof JSONArray ){ ((JSONArray) o).element( value, jsonConfig ); }else{ setInternal( key, new JSONArray().element( o ) .element( value, jsonConfig ), jsonConfig ); } } return this; } protected Object _processValue( Object value, JsonConfig jsonConfig ) { if( value instanceof JSONTokener ) { return _fromJSONTokener( (JSONTokener) value, jsonConfig ); } return super._processValue( value, jsonConfig ); } /** * Put a key/value pair in the JSONObject. * * @param key A key string. * @param value An object which is the value. It should be of one of these * types: Boolean, Double, Integer, JSONArray, JSONObject, Long, * String, or the JSONNull object. * @return this. * @throws JSONException If the value is non-finite number or if the key is * null. */ private JSONObject _setInternal( String key, Object value, JsonConfig jsonConfig ) { verifyIsNull(); if( key == null ){ throw new JSONException( "Null key." ); } if( JSONUtils.isString( value ) && JSONUtils.mayBeJSON( String.valueOf( value ) ) ){ this.properties.put( key, value ); }else{ /* Object jo = _processValue( value, jsonConfig ); if( CycleDetectionStrategy.IGNORE_PROPERTY_OBJ == jo || CycleDetectionStrategy.IGNORE_PROPERTY_ARR == jo ){ // do nothing }else{ this.properties.put( key, jo ); } */ if( CycleDetectionStrategy.IGNORE_PROPERTY_OBJ == value || CycleDetectionStrategy.IGNORE_PROPERTY_ARR == value ){ // do nothing }else{ this.properties.put( key, value ); } } return this; } private Object processValue( Object value, JsonConfig jsonConfig ) { if( value != null ){ JsonValueProcessor processor = jsonConfig.findJsonValueProcessor( value.getClass() ); if( processor != null ){ value = processor.processObjectValue( null, value, jsonConfig ); if( !JsonVerifier.isValidJsonValue( value ) ){ throw new JSONException( "Value is not a valid JSON value. " + value ); } } } return _processValue( value, jsonConfig ); } private Object processValue( String key, Object value, JsonConfig jsonConfig ) { if( value != null ){ JsonValueProcessor processor = jsonConfig.findJsonValueProcessor( value.getClass(), key ); if( processor != null ){ value = processor.processObjectValue( null, value, jsonConfig ); if( !JsonVerifier.isValidJsonValue( value ) ){ throw new JSONException( "Value is not a valid JSON value. " + value ); } } } return _processValue( value, jsonConfig ); } /** * Put a key/value pair in the JSONObject. * * @param key A key string. * @param value An object which is the value. It should be of one of these * types: Boolean, Double, Integer, JSONArray, JSONObject, Long, * String, or the JSONNull object. * @return this. * @throws JSONException If the value is non-finite number or if the key is * null. */ private JSONObject setInternal( String key, Object value, JsonConfig jsonConfig ) { return _setInternal( key, processValue( key, value, jsonConfig ), jsonConfig ); } /** * Checks if this object is a "null" object. */ private void verifyIsNull() { if( isNullObject() ){ throw new JSONException( "null object" ); } } }json-lib-2.3/net/sf/json/filters/0000755000175000017500000000000011226107170015673 5ustar mkochmkochjson-lib-2.3/net/sf/json/filters/FalsePropertyFilter.java0000644000175000017500000000162511226107170022507 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.filters; import net.sf.json.util.PropertyFilter; /** * @author Andres Almiray */ public class FalsePropertyFilter implements PropertyFilter { public boolean apply( Object source, String name, Object value ) { return false; } }json-lib-2.3/net/sf/json/filters/AndPropertyFilter.java0000644000175000017500000000242611226107170022157 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.filters; import net.sf.json.util.PropertyFilter; /** * @author Andres Almiray */ public class AndPropertyFilter implements PropertyFilter { private PropertyFilter filter1; private PropertyFilter filter2; public AndPropertyFilter( PropertyFilter filter1, PropertyFilter filter2 ) { this.filter1 = filter1; this.filter2 = filter2; } public boolean apply( Object source, String name, Object value ) { if( filter1 != null && filter1.apply( source, name, value ) && filter2 != null && filter2.apply( source, name, value ) ){ return true; } return false; } }json-lib-2.3/net/sf/json/filters/CompositePropertyFilter.java0000644000175000017500000000357211226107170023422 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.filters; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import net.sf.json.util.PropertyFilter; /** * @author Andres Almiray */ public class CompositePropertyFilter implements PropertyFilter { private List filters = new ArrayList(); public CompositePropertyFilter() { this( null ); } public CompositePropertyFilter( List filters ) { if( filters != null ){ for( Iterator i = filters.iterator(); i.hasNext(); ){ Object filter = i.next(); if( filter instanceof PropertyFilter ){ this.filters.add( filter ); } } } } public void addPropertyFilter( PropertyFilter filter ) { if( filter != null ){ filters.add( filter ); } } public boolean apply( Object source, String name, Object value ) { for( Iterator i = filters.iterator(); i.hasNext(); ){ PropertyFilter filter = (PropertyFilter) i.next(); if( filter.apply( source, name, value ) ){ return true; } } return false; } public void removePropertyFilter( PropertyFilter filter ) { if( filter != null ){ filters.remove( filter ); } } }json-lib-2.3/net/sf/json/filters/TruePropertyFilter.java0000644000175000017500000000162311226107170022372 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.filters; import net.sf.json.util.PropertyFilter; /** * @author Andres Almiray */ public class TruePropertyFilter implements PropertyFilter { public boolean apply( Object source, String name, Object value ) { return true; } }json-lib-2.3/net/sf/json/filters/OrPropertyFilter.java0000644000175000017500000000243011226107170022030 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.filters; import net.sf.json.util.PropertyFilter; /** * @author Andres Almiray */ public class OrPropertyFilter implements PropertyFilter { private PropertyFilter filter1; private PropertyFilter filter2; public OrPropertyFilter( PropertyFilter filter1, PropertyFilter filter2 ) { this.filter1 = filter1; this.filter2 = filter2; } public boolean apply( Object source, String name, Object value ) { if( (filter1 != null && filter1.apply( source, name, value )) || (filter2 != null && filter2.apply( source, name, value )) ){ return true; } return false; } }json-lib-2.3/net/sf/json/filters/NotPropertyFilter.java0000644000175000017500000000215111226107170022210 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.filters; import net.sf.json.util.PropertyFilter; /** * @author Andres Almiray */ public class NotPropertyFilter implements PropertyFilter { private PropertyFilter filter; public NotPropertyFilter( PropertyFilter filter ) { this.filter = filter; } public boolean apply( Object source, String name, Object value ) { if( filter != null ){ return !filter.apply( source, name, value ); } return false; } }json-lib-2.3/net/sf/json/filters/MappingPropertyFilter.java0000644000175000017500000000441111226107170023044 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.filters; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import net.sf.json.util.PropertyFilter; /** * @author Andres Almiray */ public abstract class MappingPropertyFilter implements PropertyFilter { private Map filters = new HashMap(); public MappingPropertyFilter() { this( null ); } public MappingPropertyFilter( Map filters ) { if( filters != null ){ for( Iterator i = filters.entrySet() .iterator(); i.hasNext(); ){ Map.Entry entry = (Map.Entry) i.next(); Object key = entry.getKey(); Object filter = entry.getValue(); if( filter instanceof PropertyFilter ){ this.filters.put( key, filter ); } } } } public void addPropertyFilter( Object target, PropertyFilter filter ) { if( filter != null ){ filters.put( target, filter ); } } public boolean apply( Object source, String name, Object value ) { for( Iterator i = filters.entrySet() .iterator(); i.hasNext(); ){ Map.Entry entry = (Map.Entry) i.next(); Object key = entry.getKey(); if( keyMatches( key, source, name, value ) ){ PropertyFilter filter = (PropertyFilter) entry.getValue(); return filter.apply( source, name, value ); } } return false; } public void removePropertyFilter( Object target ) { if( target != null ){ filters.remove( target ); } } protected abstract boolean keyMatches( Object key, Object source, String name, Object value ); }json-lib-2.3/net/sf/json/xml/0000755000175000017500000000000011226107170015023 5ustar mkochmkochjson-lib-2.3/net/sf/json/xml/JSONTypes.java0000644000175000017500000000172511226107170017471 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.xml; /** * @author Andres Almiray */ public interface JSONTypes { String ARRAY = "array"; String BOOLEAN = "boolean"; String FLOAT = "float"; String FUNCTION = "function"; String INTEGER = "integer"; String NUMBER = "number"; String OBJECT = "object"; String STRING = "string"; }json-lib-2.3/net/sf/json/xml/XMLSerializer.java0000644000175000017500000014334211226107170020367 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.xml; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.StringReader; import java.io.UnsupportedEncodingException; import java.util.Arrays; import java.util.Iterator; import java.util.Map; import java.util.TreeMap; import net.sf.json.JSON; import net.sf.json.JSONArray; import net.sf.json.JSONException; import net.sf.json.JSONFunction; import net.sf.json.JSONNull; import net.sf.json.JSONObject; import net.sf.json.util.JSONUtils; import nu.xom.Attribute; import nu.xom.Builder; import nu.xom.Document; import nu.xom.Element; import nu.xom.Elements; import nu.xom.Node; import nu.xom.Serializer; import nu.xom.Text; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Utility class for transforming JSON to XML an back.
* When transforming JSONObject and JSONArray instances to XML, this class will * add hints for converting back to JSON.
* Examples:
* *

 * JSONObject json = JSONObject.fromObject("{\"name\":\"json\",\"bool\":true,\"int\":1}");
 * String xml = new XMLSerializer().write( json );
 * <o class="object">
 <name type="string">json</name>
 <bool type="boolean">true</bool>
 <int type="number">1</int>
 </o>
 * 
 * JSONArray json = JSONArray.fromObject("[1,2,3]");
 * String xml = new XMLSerializer().write( json );
 * <a class="array">
 <e type="number">1</e>
 <e type="number">2</e>
 <e type="number">3</e>
 </a>
 * 
* * @author Andres Almiray */ public class XMLSerializer { private static final String[] EMPTY_ARRAY = new String[0]; private static final String JSON_PREFIX = "json_"; private static final Log log = LogFactory.getLog( XMLSerializer.class ); /** the name for an JSONArray Element */ private String arrayName; /** the name for an JSONArray's element Element */ private String elementName; /** list of properties to be expanded from child to parent */ private String[] expandableProperties; private boolean forceTopLevelObject; /** flag to be tolerant for incomplete namespace prefixes */ private boolean namespaceLenient; /** Map of namespaces per element */ private Map namespacesPerElement = new TreeMap(); /** the name for an JSONObject Element */ private String objectName; /** flag for trimming namespace prefix from element name */ private boolean removeNamespacePrefixFromElements; /** the name for the root Element */ private String rootName; /** Map of namespaces for root element */ private Map rootNamespace = new TreeMap(); /** flag for skipping namespaces while reading */ private boolean skipNamespaces; /** flag for skipping whitespace elements while reading */ private boolean skipWhitespace; /** flag for trimming spaces from string values */ private boolean trimSpaces; /** flag for type hints naming compatibility */ private boolean typeHintsCompatibility; /** flag for adding JSON types hints as attributes */ private boolean typeHintsEnabled; /** * Creates a new XMLSerializer with default options.
*
    *
  • objectName: 'o'
  • *
  • arrayName: 'a'
  • *
  • elementName: 'e'
  • *
  • typeHinstEnabled: true
  • *
  • typeHinstCompatibility: true
  • *
  • namespaceLenient: false
  • *
  • expandableProperties: []
  • *
  • skipNamespaces: false
  • *
  • removeNameSpacePrefixFromElement: false
  • *
  • trimSpaces: false
  • *
*/ public XMLSerializer() { setObjectName( "o" ); setArrayName( "a" ); setElementName( "e" ); setTypeHintsEnabled( true ); setTypeHintsCompatibility( true ); setNamespaceLenient( false ); setSkipNamespaces( false ); setRemoveNamespacePrefixFromElements( false ); setTrimSpaces( false ); setExpandableProperties( EMPTY_ARRAY ); setSkipNamespaces( false ); } /** * Adds a namespace declaration to the root element. * * @param prefix namespace prefix * @param uri namespace uri */ public void addNamespace( String prefix, String uri ) { addNamespace( prefix, uri, null ); } /** * Adds a namespace declaration to an element.
* If the elementName param is null or blank, the namespace declaration will * be added to the root element. * * @param prefix namespace prefix * @param uri namespace uri * @param elementName name of target element */ public void addNamespace( String prefix, String uri, String elementName ) { if( StringUtils.isBlank( uri ) ){ return; } if( prefix == null ){ prefix = ""; } if( StringUtils.isBlank( elementName ) ){ rootNamespace.put( prefix.trim(), uri.trim() ); }else{ Map nameSpaces = (Map) namespacesPerElement.get( elementName ); if( nameSpaces == null ){ nameSpaces = new TreeMap(); namespacesPerElement.put( elementName, nameSpaces ); } nameSpaces.put( prefix, uri ); } } /** * Removes all namespaces declarations (from root an elements). */ public void clearNamespaces() { rootNamespace.clear(); namespacesPerElement.clear(); } /** * Removes all namespace declarations from an element.
* If the elementName param is null or blank, the declarations will be * removed from the root element. * * @param elementName name of target element */ public void clearNamespaces( String elementName ) { if( StringUtils.isBlank( elementName ) ){ rootNamespace.clear(); }else{ namespacesPerElement.remove( elementName ); } } /** * Returns the name used for JSONArray. */ public String getArrayName() { return arrayName; } /** * Returns the name used for JSONArray elements. */ public String getElementName() { return elementName; } /** * Returns a list of properties to be expanded from child to parent. */ public String[] getExpandableProperties() { return expandableProperties; } /** * Returns the name used for JSONArray. */ public String getObjectName() { return objectName; } /** * Returns the name used for the root element. */ public String getRootName() { return rootName; } public boolean isForceTopLevelObject() { return forceTopLevelObject; } /** * Returns wether this serializer is tolerant to namespaces without URIs or * not. */ public boolean isNamespaceLenient() { return namespaceLenient; } /** * Returns wether this serializer will remove namespace prefix from elements * or not. */ public boolean isRemoveNamespacePrefixFromElements() { return removeNamespacePrefixFromElements; } /** * Returns wether this serializer will skip adding namespace declarations to * elements or not. */ public boolean isSkipNamespaces() { return skipNamespaces; } /** * Returns wether this serializer will skip whitespace or not. */ public boolean isSkipWhitespace() { return skipWhitespace; } /** * Returns wether this serializer will trim leading and trealing whitespace * from values or not. */ public boolean isTrimSpaces() { return trimSpaces; } /** * Returns true if types hints will have a 'json_' prefix or not. */ public boolean isTypeHintsCompatibility() { return typeHintsCompatibility; } /** * Returns true if JSON types will be included as attributes. */ public boolean isTypeHintsEnabled() { return typeHintsEnabled; } /** * Creates a JSON value from a XML string. * * @param xml A well-formed xml document in a String * @return a JSONNull, JSONObject or JSONArray * @throws JSONException if the conversion from XML to JSON can't be made for * I/O or format reasons. */ public JSON read( String xml ) { JSON json = null; try{ Document doc = new Builder().build( new StringReader( xml ) ); Element root = doc.getRootElement(); if( isNullObject( root ) ){ return JSONNull.getInstance(); } String defaultType = getType( root, JSONTypes.STRING ); if( isArray( root, true ) ){ json = processArrayElement( root, defaultType ); if( forceTopLevelObject ){ String key = removeNamespacePrefix( root.getQualifiedName() ); json = new JSONObject().element( key, json ); } }else{ json = processObjectElement( root, defaultType ); if( forceTopLevelObject ) { String key = removeNamespacePrefix( root.getQualifiedName() ); json = new JSONObject().element( key, json ); } } }catch( JSONException jsone ){ throw jsone; }catch( Exception e ){ throw new JSONException( e ); } return json; } /** * Creates a JSON value from a File. * * @param file * @return a JSONNull, JSONObject or JSONArray * @throws JSONException if the conversion from XML to JSON can't be made for * I/O or format reasons. */ public JSON readFromFile( File file ) { if( file == null ){ throw new JSONException( "File is null" ); } if( !file.canRead() ){ throw new JSONException( "Can't read input file" ); } if( file.isDirectory() ){ throw new JSONException( "File is a directory" ); } try{ return readFromStream( new FileInputStream( file ) ); }catch( IOException ioe ){ throw new JSONException( ioe ); } } /** * Creates a JSON value from a File. * * @param path * @return a JSONNull, JSONObject or JSONArray * @throws JSONException if the conversion from XML to JSON can't be made for * I/O or format reasons. */ public JSON readFromFile( String path ) { return readFromStream( Thread.currentThread() .getContextClassLoader() .getResourceAsStream( path ) ); } /** * Creates a JSON value from an input stream. * * @param stream * @return a JSONNull, JSONObject or JSONArray * @throws JSONException if the conversion from XML to JSON can't be made for * I/O or format reasons. */ public JSON readFromStream( InputStream stream ) { try{ StringBuffer xml = new StringBuffer(); BufferedReader in = new BufferedReader( new InputStreamReader( stream ) ); String line = null; while( (line = in.readLine()) != null ){ xml.append( line ); } return read( xml.toString() ); }catch( IOException ioe ){ throw new JSONException( ioe ); } } /** * Removes a namespace from the root element. * * @param prefix namespace prefix */ public void removeNamespace( String prefix ) { removeNamespace( prefix, null ); } /** * Removes a namespace from the root element.
* If the elementName is null or blank, the namespace will be removed from * the root element. * * @param prefix namespace prefix * @param elementName name of target element */ public void removeNamespace( String prefix, String elementName ) { if( prefix == null ){ prefix = ""; } if( StringUtils.isBlank( elementName ) ){ rootNamespace.remove( prefix.trim() ); }else{ Map nameSpaces = (Map) namespacesPerElement.get( elementName ); nameSpaces.remove( prefix ); } } /** * Sets the name used for JSONArray.
* Default is 'a'. */ public void setArrayName( String arrayName ) { this.arrayName = StringUtils.isBlank( arrayName ) ? "a" : arrayName; } /** * Sets the name used for JSONArray elements.
* Default is 'e'. */ public void setElementName( String elementName ) { this.elementName = StringUtils.isBlank( elementName ) ? "e" : elementName; } /** * Sets the list of properties to be expanded from child to parent. */ public void setExpandableProperties( String[] expandableProperties ) { this.expandableProperties = expandableProperties == null ? EMPTY_ARRAY : expandableProperties; } public void setForceTopLevelObject( boolean forceTopLevelObject ) { this.forceTopLevelObject = forceTopLevelObject; } /** * Sets the namespace declaration to the root element.
* Any previous values are discarded. * * @param prefix namespace prefix * @param uri namespace uri */ public void setNamespace( String prefix, String uri ) { setNamespace( prefix, uri, null ); } /** * Adds a namespace declaration to an element.
* Any previous values are discarded. If the elementName param is null or * blank, the namespace declaration will be added to the root element. * * @param prefix namespace prefix * @param uri namespace uri * @param elementName name of target element */ public void setNamespace( String prefix, String uri, String elementName ) { if( StringUtils.isBlank( uri ) ){ return; } if( prefix == null ){ prefix = ""; } if( StringUtils.isBlank( elementName ) ){ rootNamespace.clear(); rootNamespace.put( prefix.trim(), uri.trim() ); }else{ Map nameSpaces = (Map) namespacesPerElement.get( elementName ); if( nameSpaces == null ){ nameSpaces = new TreeMap(); namespacesPerElement.put( elementName, nameSpaces ); } nameSpaces.clear(); nameSpaces.put( prefix, uri ); } } /** * Sets wether this serializer is tolerant to namespaces without URIs or not. */ public void setNamespaceLenient( boolean namespaceLenient ) { this.namespaceLenient = namespaceLenient; } /** * Sets the name used for JSONObject.
* Default is 'o'. */ public void setObjectName( String objectName ) { this.objectName = StringUtils.isBlank( objectName ) ? "o" : objectName; } /** * Sets if this serializer will remove namespace prefix from elements when * reading. */ public void setRemoveNamespacePrefixFromElements( boolean removeNamespacePrefixFromElements ) { this.removeNamespacePrefixFromElements = removeNamespacePrefixFromElements; } /** * Sets the name used for the root element. */ public void setRootName( String rootName ) { this.rootName = StringUtils.isBlank( rootName ) ? null : rootName; } /** * Sets if this serializer will skip adding namespace declarations to * elements when reading. */ public void setSkipNamespaces( boolean skipNamespaces ) { this.skipNamespaces = skipNamespaces; } /** * Sets if this serializer will skip whitespace when reading. */ public void setSkipWhitespace( boolean skipWhitespace ) { this.skipWhitespace = skipWhitespace; } /** * Sets if this serializer will trim leading and trealing whitespace from * values when reading. */ public void setTrimSpaces( boolean trimSpaces ) { this.trimSpaces = trimSpaces; } /** * Sets wether types hints will have a 'json_' prefix or not. */ public void setTypeHintsCompatibility( boolean typeHintsCompatibility ) { this.typeHintsCompatibility = typeHintsCompatibility; } /** * Sets wether JSON types will be included as attributes. */ public void setTypeHintsEnabled( boolean typeHintsEnabled ) { this.typeHintsEnabled = typeHintsEnabled; } /** * Writes a JSON value into a XML string with UTF-8 encoding.
* * @param json The JSON value to transform * @return a String representation of a well-formed xml document. * @throws JSONException if the conversion from JSON to XML can't be made for * I/O reasons. */ public String write( JSON json ) { return write( json, null ); } /** * Writes a JSON value into a XML string with an specific encoding.
* If the encoding string is null it will use UTF-8. * * @param json The JSON value to transform * @param encoding The xml encoding to use * @return a String representation of a well-formed xml document. * @throws JSONException if the conversion from JSON to XML can't be made for * I/O reasons or the encoding is not supported. */ public String write( JSON json, String encoding ) { if( JSONNull.getInstance() .equals( json ) ){ Element root = null; root = newElement( getRootName() == null ? getObjectName() : getRootName() ); root.addAttribute( new Attribute( addJsonPrefix( "null" ), "true" ) ); Document doc = new Document( root ); return writeDocument( doc, encoding ); }else if( json instanceof JSONArray ){ JSONArray jsonArray = (JSONArray) json; Element root = processJSONArray( jsonArray, newElement( getRootName() == null ? getArrayName() : getRootName() ), expandableProperties ); Document doc = new Document( root ); return writeDocument( doc, encoding ); }else{ JSONObject jsonObject = (JSONObject) json; Element root = null; if( jsonObject.isNullObject() ){ root = newElement( getObjectName() ); root.addAttribute( new Attribute( addJsonPrefix( "null" ), "true" ) ); }else{ root = processJSONObject( jsonObject, newElement( getRootName() == null ? getObjectName() : getRootName() ), expandableProperties, true ); } Document doc = new Document( root ); return writeDocument( doc, encoding ); } } private String addJsonPrefix( String str ) { if( !isTypeHintsCompatibility() ){ return JSON_PREFIX + str; } return str; } private void addNameSpaceToElement( Element element ) { String elementName = null; if( element instanceof CustomElement ){ elementName = ((CustomElement) element).getQName(); }else{ elementName = element.getQualifiedName(); } Map nameSpaces = (Map) namespacesPerElement.get( elementName ); if( nameSpaces != null && !nameSpaces.isEmpty() ){ setNamespaceLenient( true ); for( Iterator entries = nameSpaces.entrySet() .iterator(); entries.hasNext(); ){ Map.Entry entry = (Map.Entry) entries.next(); String prefix = (String) entry.getKey(); String uri = (String) entry.getValue(); if( StringUtils.isBlank( prefix ) ){ element.setNamespaceURI( uri ); }else{ element.addNamespaceDeclaration( prefix, uri ); } } } } private boolean checkChildElements( Element element, boolean isTopLevel ) { int childCount = element.getChildCount(); Elements elements = element.getChildElements(); int elementCount = elements.size(); if( childCount == 1 && element.getChild( 0 ) instanceof Text ){ return isTopLevel; } if( childCount == elementCount ){ if( elementCount == 0 ){ return true; } if( elementCount == 1 ){ if( skipWhitespace || element.getChild( 0 ) instanceof Text ){ return true; }else{ return false; } } } if( childCount > elementCount ){ for( int i = 0; i < childCount; i++ ){ Node node = element.getChild( i ); if( node instanceof Text ){ Text text = (Text) node; if( StringUtils.isNotBlank( StringUtils.strip( text.getValue() ) ) && !skipWhitespace ){ return false; } } } } String childName = elements.get( 0 ) .getQualifiedName(); for( int i = 1; i < elementCount; i++ ){ if( childName.compareTo( elements.get( i ) .getQualifiedName() ) != 0 ){ return false; } } return true; } private String getClass( Element element ) { Attribute attribute = element.getAttribute( addJsonPrefix( "class" ) ); String clazz = null; if( attribute != null ){ String clazzText = attribute.getValue() .trim(); if( JSONTypes.OBJECT.compareToIgnoreCase( clazzText ) == 0 ){ clazz = JSONTypes.OBJECT; }else if( JSONTypes.ARRAY.compareToIgnoreCase( clazzText ) == 0 ){ clazz = JSONTypes.ARRAY; } } return clazz; } private String getType( Element element ) { return getType( element, null ); } private String getType( Element element, String defaultType ) { Attribute attribute = element.getAttribute( addJsonPrefix( "type" ) ); String type = null; if( attribute != null ){ String typeText = attribute.getValue() .trim(); if( JSONTypes.BOOLEAN.compareToIgnoreCase( typeText ) == 0 ){ type = JSONTypes.BOOLEAN; }else if( JSONTypes.NUMBER.compareToIgnoreCase( typeText ) == 0 ){ type = JSONTypes.NUMBER; }else if( JSONTypes.INTEGER.compareToIgnoreCase( typeText ) == 0 ){ type = JSONTypes.INTEGER; }else if( JSONTypes.FLOAT.compareToIgnoreCase( typeText ) == 0 ){ type = JSONTypes.FLOAT; }else if( JSONTypes.OBJECT.compareToIgnoreCase( typeText ) == 0 ){ type = JSONTypes.OBJECT; }else if( JSONTypes.ARRAY.compareToIgnoreCase( typeText ) == 0 ){ type = JSONTypes.ARRAY; }else if( JSONTypes.STRING.compareToIgnoreCase( typeText ) == 0 ){ type = JSONTypes.STRING; }else if( JSONTypes.FUNCTION.compareToIgnoreCase( typeText ) == 0 ){ type = JSONTypes.FUNCTION; } }else{ if( defaultType != null ){ log.info( "Using default type " + defaultType ); type = defaultType; } } return type; } private boolean hasNamespaces( Element element ) { int namespaces = 0; for( int i = 0; i < element.getNamespaceDeclarationCount(); i++ ){ String prefix = element.getNamespacePrefix( i ); String uri = element.getNamespaceURI( prefix ); if( StringUtils.isBlank( uri ) ){ continue; } namespaces++; } return namespaces > 0; } private boolean isArray( Element element, boolean isTopLevel ) { boolean isArray = false; String clazz = getClass( element ); if( clazz != null && clazz.equals( JSONTypes.ARRAY ) ){ isArray = true; }else if( element.getAttributeCount() == 0 ){ isArray = checkChildElements( element, isTopLevel ); }else if( element.getAttributeCount() == 1 && (element.getAttribute( addJsonPrefix( "class" ) ) != null || element.getAttribute( addJsonPrefix( "type" ) ) != null) ){ isArray = checkChildElements( element, isTopLevel ); }else if( element.getAttributeCount() == 2 && (element.getAttribute( addJsonPrefix( "class" ) ) != null && element.getAttribute( addJsonPrefix( "type" ) ) != null) ){ isArray = checkChildElements( element, isTopLevel ); } if( isArray ){ // check namespace for( int j = 0; j < element.getNamespaceDeclarationCount(); j++ ){ String prefix = element.getNamespacePrefix( j ); String uri = element.getNamespaceURI( prefix ); if( !StringUtils.isBlank( uri ) ){ return false; } } } return isArray; } private boolean isFunction( Element element ) { int attrCount = element.getAttributeCount(); if( attrCount > 0 ){ Attribute typeAttr = element.getAttribute( addJsonPrefix( "type" ) ); Attribute paramsAttr = element.getAttribute( addJsonPrefix( "params" ) ); if( attrCount == 1 && paramsAttr != null ){ return true; } if( attrCount == 2 && paramsAttr != null && typeAttr != null && (typeAttr.getValue() .compareToIgnoreCase( JSONTypes.STRING ) == 0 || typeAttr.getValue() .compareToIgnoreCase( JSONTypes.FUNCTION ) == 0) ){ return true; } } return false; } private boolean isNullObject( Element element ) { if( element.getChildCount() == 0 ){ if( element.getAttributeCount() == 0 ){ return true; }else if( element.getAttribute( addJsonPrefix( "null" ) ) != null ){ return true; }else if( element.getAttributeCount() == 1 && (element.getAttribute( addJsonPrefix( "class" ) ) != null || element.getAttribute( addJsonPrefix( "type" ) ) != null) ){ return true; }else if( element.getAttributeCount() == 2 && (element.getAttribute( addJsonPrefix( "class" ) ) != null && element.getAttribute( addJsonPrefix( "type" ) ) != null) ){ return true; } } if( skipWhitespace && element.getChildCount() == 1 && element.getChild( 0 ) instanceof Text ){ return true; } return false; } private boolean isObject( Element element, boolean isTopLevel ) { boolean isObject = false; if( !isArray( element, isTopLevel ) && !isFunction( element ) ){ if( hasNamespaces( element ) ){ return true; } int attributeCount = element.getAttributeCount(); if( attributeCount > 0 ){ int attrs = element.getAttribute( addJsonPrefix( "null" )) == null ? 0 : 1; attrs += element.getAttribute( addJsonPrefix( "class" )) == null ? 0: 1; attrs += element.getAttribute( addJsonPrefix( "type" ))== null ? 0 : 1; switch( attributeCount ){ case 1: if( attrs == 0){ return true; } break; case 2: if( attrs < 2 ){ return true; } break; case 3: if( attrs < 3 ){ return true; } break; default: return true; } } int childCount = element.getChildCount(); if( childCount == 1 && element.getChild( 0 ) instanceof Text ){ return isTopLevel; } isObject = true; } return isObject; } private Element newElement( String name ) { if( name.indexOf( ':' ) != -1 ){ namespaceLenient = true; } return namespaceLenient ? new CustomElement( name ) : new Element( name ); } private JSON processArrayElement( Element element, String defaultType ) { JSONArray jsonArray = new JSONArray(); // process children (including text) int childCount = element.getChildCount(); for( int i = 0; i < childCount; i++ ){ Node child = element.getChild( i ); if( child instanceof Text ){ Text text = (Text) child; if( StringUtils.isNotBlank( StringUtils.strip( text.getValue() ) ) ){ jsonArray.element( text.getValue() ); } }else if( child instanceof Element ){ setValue( jsonArray, (Element) child, defaultType ); } } return jsonArray; } private Object processElement( Element element, String type ) { if( isNullObject( element ) ){ return JSONNull.getInstance(); }else if( isArray( element, false ) ){ return processArrayElement( element, type ); }else if( isObject( element, false ) ){ return processObjectElement( element, type ); }else{ return trimSpaceFromValue( element.getValue() ); } } private Element processJSONArray( JSONArray array, Element root, String[] expandableProperties ) { int l = array.size(); for( int i = 0; i < l; i++ ){ Object value = array.get( i ); Element element = processJSONValue( value, root, null, expandableProperties ); root.appendChild( element ); } return root; } private Element processJSONObject( JSONObject jsonObject, Element root, String[] expandableProperties, boolean isRoot ) { if( jsonObject.isNullObject() ){ root.addAttribute( new Attribute( addJsonPrefix( "null" ), "true" ) ); return root; }else if( jsonObject.isEmpty() ){ return root; } if( isRoot ){ if( !rootNamespace.isEmpty() ){ setNamespaceLenient( true ); for( Iterator entries = rootNamespace.entrySet() .iterator(); entries.hasNext(); ){ Map.Entry entry = (Map.Entry) entries.next(); String prefix = (String) entry.getKey(); String uri = (String) entry.getValue(); if( StringUtils.isBlank( prefix ) ){ root.setNamespaceURI( uri ); }else{ root.addNamespaceDeclaration( prefix, uri ); } } } } addNameSpaceToElement( root ); Object[] names = jsonObject.names() .toArray(); Arrays.sort( names ); Element element = null; for( int i = 0; i < names.length; i++ ){ String name = (String) names[i]; Object value = jsonObject.get( name ); if( name.startsWith( "@xmlns" ) ){ setNamespaceLenient( true ); int colon = name.indexOf( ':' ); if( colon == -1 ){ // do not override if already defined by nameSpaceMaps if( StringUtils.isBlank( root.getNamespaceURI() ) ){ root.setNamespaceURI( String.valueOf( value ) ); } }else{ String prefix = name.substring( colon + 1 ); if( StringUtils.isBlank( root.getNamespaceURI( prefix ) ) ){ root.addNamespaceDeclaration( prefix, String.valueOf( value ) ); } } }else if( name.startsWith( "@" ) ){ root.addAttribute( new Attribute( name.substring( 1 ), String.valueOf( value ) ) ); }else if( name.equals( "#text" ) ){ if( value instanceof JSONArray ){ root.appendChild( ((JSONArray) value).join( "", true ) ); }else{ root.appendChild( String.valueOf( value ) ); } }else if( value instanceof JSONArray && (((JSONArray) value).isExpandElements() || ArrayUtils.contains( expandableProperties, name )) ){ JSONArray array = (JSONArray) value; int l = array.size(); for( int j = 0; j < l; j++ ){ Object item = array.get( j ); element = newElement( name ); if( item instanceof JSONObject ){ element = processJSONValue( (JSONObject) item, root, element, expandableProperties ); }else if( item instanceof JSONArray ){ element = processJSONValue( (JSONArray) item, root, element, expandableProperties ); }else{ element = processJSONValue( item, root, element, expandableProperties ); } addNameSpaceToElement( element ); root.appendChild( element ); } }else{ element = newElement( name ); element = processJSONValue( value, root, element, expandableProperties ); addNameSpaceToElement( element ); root.appendChild( element ); } } return root; } private Element processJSONValue( Object value, Element root, Element target, String[] expandableProperties ) { if( target == null ){ target = newElement( getElementName() ); } if( JSONUtils.isBoolean( value ) ){ if( isTypeHintsEnabled() ){ target.addAttribute( new Attribute( addJsonPrefix( "type" ), JSONTypes.BOOLEAN ) ); } target.appendChild( value.toString() ); }else if( JSONUtils.isNumber( value ) ){ if( isTypeHintsEnabled() ){ target.addAttribute( new Attribute( addJsonPrefix( "type" ), JSONTypes.NUMBER ) ); } target.appendChild( value.toString() ); }else if( JSONUtils.isFunction( value ) ){ if( value instanceof String ){ value = JSONFunction.parse( (String) value ); } JSONFunction func = (JSONFunction) value; if( isTypeHintsEnabled() ){ target.addAttribute( new Attribute( addJsonPrefix( "type" ), JSONTypes.FUNCTION ) ); } String params = ArrayUtils.toString( func.getParams() ); params = params.substring( 1 ); params = params.substring( 0, params.length() - 1 ); target.addAttribute( new Attribute( addJsonPrefix( "params" ), params ) ); target.appendChild( new Text( "" ) ); }else if( JSONUtils.isString( value ) ){ if( isTypeHintsEnabled() ){ target.addAttribute( new Attribute( addJsonPrefix( "type" ), JSONTypes.STRING ) ); } target.appendChild( value.toString() ); }else if( value instanceof JSONArray ){ if( isTypeHintsEnabled() ){ target.addAttribute( new Attribute( addJsonPrefix( "class" ), JSONTypes.ARRAY ) ); } target = processJSONArray( (JSONArray) value, target, expandableProperties ); }else if( value instanceof JSONObject ){ if( isTypeHintsEnabled() ){ target.addAttribute( new Attribute( addJsonPrefix( "class" ), JSONTypes.OBJECT ) ); } target = processJSONObject( (JSONObject) value, target, expandableProperties, false ); }else if( JSONUtils.isNull( value ) ){ if( isTypeHintsEnabled() ){ target.addAttribute( new Attribute( addJsonPrefix( "class" ), JSONTypes.OBJECT ) ); } target.addAttribute( new Attribute( addJsonPrefix( "null" ), "true" ) ); } return target; } private JSON processObjectElement( Element element, String defaultType ) { if( isNullObject( element ) ){ return JSONNull.getInstance(); } JSONObject jsonObject = new JSONObject(); if( !skipNamespaces ){ for( int j = 0; j < element.getNamespaceDeclarationCount(); j++ ){ String prefix = element.getNamespacePrefix( j ); String uri = element.getNamespaceURI( prefix ); if( StringUtils.isBlank( uri ) ){ continue; } if( !StringUtils.isBlank( prefix ) ){ prefix = ":" + prefix; } setOrAccumulate( jsonObject, "@xmlns" + prefix, trimSpaceFromValue( uri ) ); } } // process attributes first int attrCount = element.getAttributeCount(); for( int i = 0; i < attrCount; i++ ){ Attribute attr = element.getAttribute( i ); String attrname = attr.getQualifiedName(); if( isTypeHintsEnabled() && (addJsonPrefix( "class" ).compareToIgnoreCase( attrname ) == 0 || addJsonPrefix( "type" ).compareToIgnoreCase( attrname ) == 0) ){ continue; } String attrvalue = attr.getValue(); setOrAccumulate( jsonObject, "@" + removeNamespacePrefix( attrname ), trimSpaceFromValue( attrvalue ) ); } // process children (including text) int childCount = element.getChildCount(); for( int i = 0; i < childCount; i++ ){ Node child = element.getChild( i ); if( child instanceof Text ){ Text text = (Text) child; if( StringUtils.isNotBlank( StringUtils.strip( text.getValue() ) ) ){ setOrAccumulate( jsonObject, "#text", trimSpaceFromValue( text.getValue() ) ); } }else if( child instanceof Element ){ setValue( jsonObject, (Element) child, defaultType ); } } return jsonObject; } private String removeNamespacePrefix( String name ) { if( isRemoveNamespacePrefixFromElements() ){ int colon = name.indexOf( ':' ); return colon != -1 ? name.substring( colon + 1 ) : name; } return name; } private void setOrAccumulate( JSONObject jsonObject, String key, Object value ) { if( jsonObject.has( key ) ){ jsonObject.accumulate( key, value ); Object val = jsonObject.get( key ); if( val instanceof JSONArray ){ ((JSONArray) val).setExpandElements( true ); } }else{ jsonObject.element( key, value ); } } private void setValue( JSONArray jsonArray, Element element, String defaultType ) { String clazz = getClass( element ); String type = getType( element ); type = (type == null) ? defaultType : type; if( hasNamespaces( element ) && !skipNamespaces ){ jsonArray.element( simplifyValue( null, processElement( element, type ) ) ); return; }else if( element.getAttributeCount() > 0 ){ if( isFunction( element ) ){ Attribute paramsAttribute = element.getAttribute( addJsonPrefix( "params" ) ); String[] params = null; String text = element.getValue(); params = StringUtils.split( paramsAttribute.getValue(), "," ); jsonArray.element( new JSONFunction( params, text ) ); return; }else{ jsonArray.element( simplifyValue( null, processElement( element, type ) ) ); return; } } boolean classProcessed = false; if( clazz != null ){ if( clazz.compareToIgnoreCase( JSONTypes.ARRAY ) == 0 ){ jsonArray.element( processArrayElement( element, type ) ); classProcessed = true; }else if( clazz.compareToIgnoreCase( JSONTypes.OBJECT ) == 0 ){ jsonArray.element( simplifyValue( null, processObjectElement( element, type ) ) ); classProcessed = true; } } if( !classProcessed ){ if( type.compareToIgnoreCase( JSONTypes.BOOLEAN ) == 0 ){ jsonArray.element( Boolean.valueOf( element.getValue() ) ); }else if( type.compareToIgnoreCase( JSONTypes.NUMBER ) == 0 ){ // try integer first try{ jsonArray.element( Integer.valueOf( element.getValue() ) ); }catch( NumberFormatException e ){ jsonArray.element( Double.valueOf( element.getValue() ) ); } }else if( type.compareToIgnoreCase( JSONTypes.INTEGER ) == 0 ){ jsonArray.element( Integer.valueOf( element.getValue() ) ); }else if( type.compareToIgnoreCase( JSONTypes.FLOAT ) == 0 ){ jsonArray.element( Double.valueOf( element.getValue() ) ); }else if( type.compareToIgnoreCase( JSONTypes.FUNCTION ) == 0 ){ String[] params = null; String text = element.getValue(); Attribute paramsAttribute = element.getAttribute( addJsonPrefix( "params" ) ); if( paramsAttribute != null ){ params = StringUtils.split( paramsAttribute.getValue(), "," ); } jsonArray.element( new JSONFunction( params, text ) ); }else if( type.compareToIgnoreCase( JSONTypes.STRING ) == 0 ){ // see if by any chance has a 'params' attribute Attribute paramsAttribute = element.getAttribute( addJsonPrefix( "params" ) ); if( paramsAttribute != null ){ String[] params = null; String text = element.getValue(); params = StringUtils.split( paramsAttribute.getValue(), "," ); jsonArray.element( new JSONFunction( params, text ) ); }else{ if( isArray( element, false ) ){ jsonArray.element( processArrayElement( element, defaultType ) ); }else if( isObject( element, false ) ){ jsonArray.element( simplifyValue( null, processObjectElement( element, defaultType ) ) ); }else{ jsonArray.element( trimSpaceFromValue( element.getValue() ) ); } } } } } private void setValue( JSONObject jsonObject, Element element, String defaultType ) { String clazz = getClass( element ); String type = getType( element ); type = (type == null) ? defaultType : type; String key = removeNamespacePrefix( element.getQualifiedName() ); if( hasNamespaces( element ) && !skipNamespaces ){ setOrAccumulate( jsonObject, key, simplifyValue( jsonObject, processElement( element, type ) ) ); return; }else if( element.getAttributeCount() > 0 ){ if( isFunction( element ) ){ Attribute paramsAttribute = element.getAttribute( addJsonPrefix( "params" ) ); String text = element.getValue(); String[] params = StringUtils.split( paramsAttribute.getValue(), "," ); setOrAccumulate( jsonObject, key, new JSONFunction( params, text ) ); return; }/*else{ setOrAccumulate( jsonObject, key, simplifyValue( jsonObject, processElement( element, type ) ) ); return; }*/ } boolean classProcessed = false; if( clazz != null ){ if( clazz.compareToIgnoreCase( JSONTypes.ARRAY ) == 0 ){ setOrAccumulate( jsonObject, key, processArrayElement( element, type ) ); classProcessed = true; }else if( clazz.compareToIgnoreCase( JSONTypes.OBJECT ) == 0 ){ setOrAccumulate( jsonObject, key, simplifyValue( jsonObject, processObjectElement( element, type ) ) ); classProcessed = true; } } if( !classProcessed ){ if( type.compareToIgnoreCase( JSONTypes.BOOLEAN ) == 0 ){ setOrAccumulate( jsonObject, key, Boolean.valueOf( element.getValue() ) ); }else if( type.compareToIgnoreCase( JSONTypes.NUMBER ) == 0 ){ // try integer first try{ setOrAccumulate( jsonObject, key, Integer.valueOf( element.getValue() ) ); }catch( NumberFormatException e ){ setOrAccumulate( jsonObject, key, Double.valueOf( element.getValue() ) ); } }else if( type.compareToIgnoreCase( JSONTypes.INTEGER ) == 0 ){ setOrAccumulate( jsonObject, key, Integer.valueOf( element.getValue() ) ); }else if( type.compareToIgnoreCase( JSONTypes.FLOAT ) == 0 ){ setOrAccumulate( jsonObject, key, Double.valueOf( element.getValue() ) ); }else if( type.compareToIgnoreCase( JSONTypes.FUNCTION ) == 0 ){ String[] params = null; String text = element.getValue(); Attribute paramsAttribute = element.getAttribute( addJsonPrefix( "params" ) ); if( paramsAttribute != null ){ params = StringUtils.split( paramsAttribute.getValue(), "," ); } setOrAccumulate( jsonObject, key, new JSONFunction( params, text ) ); }else if( type.compareToIgnoreCase( JSONTypes.STRING ) == 0 ){ // see if by any chance has a 'params' attribute Attribute paramsAttribute = element.getAttribute( addJsonPrefix( "params" ) ); if( paramsAttribute != null ){ String[] params = null; String text = element.getValue(); params = StringUtils.split( paramsAttribute.getValue(), "," ); setOrAccumulate( jsonObject, key, new JSONFunction( params, text ) ); }else{ if( isArray( element, false ) ){ setOrAccumulate( jsonObject, key, processArrayElement( element, defaultType ) ); }else if( isObject( element, false ) ){ setOrAccumulate( jsonObject, key, simplifyValue( jsonObject, processObjectElement( element, defaultType ) ) ); }else{ setOrAccumulate( jsonObject, key, trimSpaceFromValue( element.getValue() ) ); } } } } } private Object simplifyValue( JSONObject parent, Object json ) { if( json instanceof JSONObject ){ JSONObject object = (JSONObject) json; if( parent != null ){ // remove all duplicated @xmlns from child for( Iterator entries = parent.entrySet() .iterator(); entries.hasNext(); ){ Map.Entry entry = (Map.Entry) entries.next(); String key = (String) entry.getKey(); Object value = entry.getValue(); if( key.startsWith( "@xmlns" ) && value.equals( object.opt( key ) ) ){ object.remove( key ); } } } if( object.size() == 1 && object.has( "#text" ) ){ return object.get( "#text" ); } } return json; } private String trimSpaceFromValue( String value ) { if( isTrimSpaces() ){ return value.trim(); } return value; } private String writeDocument( Document doc, String encoding ) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); try{ XomSerializer serializer = (encoding == null) ? new XomSerializer( baos ) : new XomSerializer( baos, encoding ); serializer.write( doc ); encoding = serializer.getEncoding(); }catch( IOException ioe ){ throw new JSONException( ioe ); } String str = null; try{ str = baos.toString( encoding ); }catch( UnsupportedEncodingException uee ){ throw new JSONException( uee ); } return str; } private static class CustomElement extends Element { private static String getName( String name ) { int colon = name.indexOf( ':' ); if( colon != -1 ){ return name.substring( colon + 1 ); } return name; } private static String getPrefix( String name ) { int colon = name.indexOf( ':' ); if( colon != -1 ){ return name.substring( 0, colon ); } return ""; } private String prefix; public CustomElement( String name ) { super( CustomElement.getName( name ) ); prefix = CustomElement.getPrefix( name ); } public final String getQName() { if( prefix.length() == 0 ){ return getLocalName(); }else{ return prefix + ":" + getLocalName(); } } } private class XomSerializer extends Serializer { public XomSerializer( OutputStream out ) { super( out ); } public XomSerializer( OutputStream out, String encoding ) throws UnsupportedEncodingException { super( out, encoding ); } protected void write( Text text ) throws IOException { String value = text.getValue(); if( value.startsWith( "" ) ){ value = value.substring( 9 ); value = value.substring( 0, value.length() - 3 ); writeRaw( "" ); }else{ super.write( text ); } } protected void writeEmptyElementTag( Element element ) throws IOException { if( element instanceof CustomElement && isNamespaceLenient() ){ writeTagBeginning( (CustomElement) element ); writeRaw( "/>" ); }else{ super.writeEmptyElementTag( element ); } } protected void writeEndTag( Element element ) throws IOException { if( element instanceof CustomElement && isNamespaceLenient() ){ writeRaw( "" ); }else{ super.writeEndTag( element ); } } protected void writeNamespaceDeclaration( String prefix, String uri ) throws IOException { if( !StringUtils.isBlank( uri ) ){ super.writeNamespaceDeclaration( prefix, uri ); } } protected void writeStartTag( Element element ) throws IOException { if( element instanceof CustomElement && isNamespaceLenient() ){ writeTagBeginning( (CustomElement) element ); writeRaw( ">" ); }else{ super.writeStartTag( element ); } } private void writeTagBeginning( CustomElement element ) throws IOException { writeRaw( "<" ); writeRaw( element.getQName() ); writeAttributes( element ); writeNamespaceDeclarations( element ); } } }json-lib-2.3/net/sf/json/JSONString.java0000644000175000017500000000246211226107170017032 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json; /** * The JSONString interface allows a toJSONString() * method so that a class can change the behavior of * JSONObject.toString(), JSONArray.toString(), * and JSONWriter.value(Object). The * toJSONString method will be used instead of the default * behavior of using the Object's toString() method and quoting * the result. */ public interface JSONString { /** * The toJSONString method allows a class to produce its own * JSON serialization. * * @return A strictly syntactically correct JSON text. */ public String toJSONString(); } json-lib-2.3/net/sf/json/util/0000755000175000017500000000000011226107170015200 5ustar mkochmkochjson-lib-2.3/net/sf/json/util/CycleDetectionStrategy.java0000644000175000017500000000707711226107170022477 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.util; import net.sf.json.JSONArray; import net.sf.json.JSONException; import net.sf.json.JSONObject; /** * Base class for cycle detection in a hierarchy.
* The JSON spec forbides cycles in a hierarchy and most parsers will raise and * error when a cycle is detected. This class defines a contract for handling * those cycles and two base implementations: *
    *
  • STRICT - will throw a JSONException if a cycle is found.
  • *
  • LENIENT - will return an empty array or null object if a cycle is found.
  • *
* * @author Andres Almiray */ public abstract class CycleDetectionStrategy { public static final JSONArray IGNORE_PROPERTY_ARR = new JSONArray(); public static final JSONObject IGNORE_PROPERTY_OBJ = new JSONObject(); /** Returns empty array and null object */ public static final CycleDetectionStrategy LENIENT = new LenientCycleDetectionStrategy(); /** * Returns a special object (IGNORE_PROPERTY_OBJ) that indicates the entire * property should be ignored */ public static final CycleDetectionStrategy NOPROP = new LenientNoRefCycleDetectionStrategy(); /** Throws a JSONException */ public static final CycleDetectionStrategy STRICT = new StrictCycleDetectionStrategy(); /** * Handle a repeated reference
* Must return a valid JSONArray or null. * * @param reference the repeated reference. */ public abstract JSONArray handleRepeatedReferenceAsArray( Object reference ); /** * Handle a repeated reference
* Must return a valid JSONObject or null. * * @param reference the repeated reference. */ public abstract JSONObject handleRepeatedReferenceAsObject( Object reference ); private static final class LenientCycleDetectionStrategy extends CycleDetectionStrategy { public JSONArray handleRepeatedReferenceAsArray( Object reference ) { return new JSONArray(); } public JSONObject handleRepeatedReferenceAsObject( Object reference ) { return new JSONObject( true ); } } /** * A cycle detection strategy that prevents any mention of the possible * conflict from appearing. * * @author small */ private static final class LenientNoRefCycleDetectionStrategy extends CycleDetectionStrategy { public JSONArray handleRepeatedReferenceAsArray( Object reference ) { return IGNORE_PROPERTY_ARR; } public JSONObject handleRepeatedReferenceAsObject( Object reference ) { return IGNORE_PROPERTY_OBJ; } } private static final class StrictCycleDetectionStrategy extends CycleDetectionStrategy { public JSONArray handleRepeatedReferenceAsArray( Object reference ) { throw new JSONException( "There is a cycle in the hierarchy!" ); } public JSONObject handleRepeatedReferenceAsObject( Object reference ) { throw new JSONException( "There is a cycle in the hierarchy!" ); } } }json-lib-2.3/net/sf/json/util/JSONTokener.java0000644000175000017500000003430511226107170020151 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.util; import net.sf.json.JSONArray; import net.sf.json.JSONException; import net.sf.json.JSONNull; import net.sf.json.JSONObject; import net.sf.json.JsonConfig; import net.sf.json.regexp.RegexpUtils; /** * A JSONTokener takes a source string and extracts characters and tokens from * it. It is used by the JSONObject and JSONArray constructors to parse JSON * source strings. * * @author JSON.org * @version 4 */ public class JSONTokener { /** * Get the hex value of a character (base16). * * @param c A character between '0' and '9' or between 'A' and 'F' or between * 'a' and 'f'. * @return An int between 0 and 15, or -1 if c was not a hex digit. */ public static int dehexchar( char c ) { if( c >= '0' && c <= '9' ){ return c - '0'; } if( c >= 'A' && c <= 'F' ){ return c - ('A' - 10); } if( c >= 'a' && c <= 'f' ){ return c - ('a' - 10); } return -1; } /** * The index of the next character. */ private int myIndex; /** * The source string being tokenized. */ private String mySource; /** * Construct a JSONTokener from a string. * * @param s A source string. */ public JSONTokener( String s ) { this.myIndex = 0; if( s!= null ) { s = s.trim(); } else { s = ""; } if( s.length() > 0 ){ char first = s.charAt( 0 ); char last = s.charAt( s.length() - 1 ); if( first == '[' && last != ']' ) { throw syntaxError( "Found starting '[' but missing ']' at the end." ); } if( first == '{' && last != '}' ) { throw syntaxError( "Found starting '{' but missing '}' at the end." ); } } this.mySource = s; } /** * Back up one character. This provides a sort of lookahead capability, so * that you can test for a digit or letter before attempting to parse the * next number or identifier. */ public void back() { if( this.myIndex > 0 ){ this.myIndex -= 1; } } public int length() { if( this.mySource == null ){ return 0; } return this.mySource.length(); } public boolean matches( String pattern ) { String str = this.mySource.substring( this.myIndex ); return RegexpUtils.getMatcher( pattern ) .matches( str ); } /** * Determine if the source string still contains characters that next() can * consume. * * @return true if not yet at the end of the source. */ public boolean more() { return this.myIndex < this.mySource.length(); } /** * Get the next character in the source string. * * @return The next character, or 0 if past the end of the source string. */ public char next() { if( more() ){ char c = this.mySource.charAt( this.myIndex ); this.myIndex += 1; return c; } return 0; } /** * Consume the next character, and check that it matches a specified * character. * * @param c The character to match. * @return The character. * @throws JSONException if the character does not match. */ public char next( char c ) { char n = next(); if( n != c ){ throw syntaxError( "Expected '" + c + "' and instead saw '" + n + "'." ); } return n; } /** * Get the next n characters. * * @param n The number of characters to take. * @return A string of n characters. * @throws JSONException Substring bounds error if there are not n characters * remaining in the source string. */ public String next( int n ) { int i = this.myIndex; int j = i + n; if( j >= this.mySource.length() ){ throw syntaxError( "Substring bounds error" ); } this.myIndex += n; return this.mySource.substring( i, j ); } /** * Get the next char in the string, skipping whitespace and comments * (slashslash, slashstar, and hash). * * @throws JSONException * @return A character, or 0 if there are no more characters. */ public char nextClean() { for( ;; ){ char c = next(); if( c == '/' ){ switch( next() ){ case '/': do{ c = next(); }while( c != '\n' && c != '\r' && c != 0 ); break; case '*': for( ;; ){ c = next(); if( c == 0 ){ throw syntaxError( "Unclosed comment." ); } if( c == '*' ){ if( next() == '/' ){ break; } back(); } } break; default: back(); return '/'; } }else if( c == '#' ){ do{ c = next(); }while( c != '\n' && c != '\r' && c != 0 ); }else if( c == 0 || c > ' ' ){ return c; } } } /** * Return the characters up to the next close quote character. Backslash * processing is done. The formal JSON format does not allow strings in * single quotes, but an implementation is allowed to accept them. * * @param quote The quoting character, either " (double * quote) or ' (single quote). * @return A String. * @throws JSONException Unterminated string. */ public String nextString( char quote ) { char c; StringBuffer sb = new StringBuffer(); for( ;; ){ c = next(); switch( c ){ case 0: case '\n': case '\r': throw syntaxError( "Unterminated string" ); case '\\': c = next(); switch( c ){ case 'b': sb.append( '\b' ); break; case 't': sb.append( '\t' ); break; case 'n': sb.append( '\n' ); break; case 'f': sb.append( '\f' ); break; case 'r': sb.append( '\r' ); break; case 'u': sb.append( (char) Integer.parseInt( next( 4 ), 16 ) ); break; case 'x': sb.append( (char) Integer.parseInt( next( 2 ), 16 ) ); break; default: sb.append( c ); } break; default: if( c == quote ){ return sb.toString(); } sb.append( c ); } } } /** * Get the text up but not including the specified character or the end of * line, whichever comes first. * * @param d A delimiter character. * @return A string. */ public String nextTo( char d ) { StringBuffer sb = new StringBuffer(); for( ;; ){ char c = next(); if( c == d || c == 0 || c == '\n' || c == '\r' ){ if( c != 0 ){ back(); } return sb.toString() .trim(); } sb.append( c ); } } /** * Get the text up but not including one of the specified delimeter * characters or the end of line, whichever comes first. * * @param delimiters A set of delimiter characters. * @return A string, trimmed. */ public String nextTo( String delimiters ) { char c; StringBuffer sb = new StringBuffer(); for( ;; ){ c = next(); if( delimiters.indexOf( c ) >= 0 || c == 0 || c == '\n' || c == '\r' ){ if( c != 0 ){ back(); } return sb.toString() .trim(); } sb.append( c ); } } /** * Get the next value. The value can be a Boolean, Double, Integer, * JSONArray, JSONObject, Long, or String, or the JSONObject.NULL object. * * @throws JSONException If syntax error. * @return An object. */ public Object nextValue() { return nextValue( new JsonConfig() ); } /** * Get the next value. The value can be a Boolean, Double, Integer, * JSONArray, JSONObject, Long, or String, or the JSONObject.NULL object. * * @throws JSONException If syntax error. * @return An object. */ public Object nextValue( JsonConfig jsonConfig ) { char c = nextClean(); String s; switch( c ){ case '"': case '\'': return nextString( c ); case '{': back(); return JSONObject.fromObject( this, jsonConfig ); case '[': back(); return JSONArray.fromObject( this, jsonConfig ); default: // empty } /* * Handle unquoted text. This could be the values true, false, or null, or * it can be a number. An implementation (such as this one) is allowed to * also accept non-standard forms. Accumulate characters until we reach * the end of the text or a formatting character. */ StringBuffer sb = new StringBuffer(); char b = c; while( c >= ' ' && ",:]}/\\\"[{;=#".indexOf( c ) < 0 ){ sb.append( c ); c = next(); } back(); /* * If it is true, false, or null, return the proper value. */ s = sb.toString() .trim(); if( s.equals( "" ) ){ throw syntaxError( "Missing value." ); } if( s.equalsIgnoreCase( "true" ) ){ return Boolean.TRUE; } if( s.equalsIgnoreCase( "false" ) ){ return Boolean.FALSE; } if( s.equals( "null" ) || (jsonConfig.isJavascriptCompliant() && s.equals("undefined"))){ return JSONNull.getInstance(); } /* * If it might be a number, try converting it. We support the 0- and 0x- * conventions. If a number cannot be produced, then the value will just * be a string. Note that the 0-, 0x-, plus, and implied string * conventions are non-standard. A JSON parser is free to accept non-JSON * forms as long as it accepts all correct JSON forms. */ if( (b >= '0' && b <= '9') || b == '.' || b == '-' || b == '+' ){ if( b == '0' ){ if( s.length() > 2 && (s.charAt( 1 ) == 'x' || s.charAt( 1 ) == 'X') ){ try{ return new Integer( Integer.parseInt( s.substring( 2 ), 16 ) ); }catch( Exception e ){ /* Ignore the error */ } }else{ try{ return new Integer( Integer.parseInt( s, 8 ) ); }catch( Exception e ){ /* Ignore the error */ } } } try{ return new Integer( s ); }catch( Exception e ){ try{ return new Long( s ); }catch( Exception f ){ try{ return new Double( s ); }catch( Exception g ){ return s; } } } } if( JSONUtils.isFunctionHeader( s ) || JSONUtils.isFunction( s ) ){ return s; } switch( peek() ){ case ',': case '}': case '{': case '[': case ']': throw new JSONException( "Unquotted string '" + s + "'" ); } return s; } /** * Look at the next character in the source string. * * @return The next character, or 0 if past the end of the source string. */ public char peek() { if( more() ){ char c = this.mySource.charAt( this.myIndex ); return c; } return 0; } public void reset() { this.myIndex = 0; } /** * Skip characters until past the requested string. If it is not found, we * are left at the end of the source. * * @param to A string to skip past. */ public void skipPast( String to ) { this.myIndex = this.mySource.indexOf( to, this.myIndex ); if( this.myIndex < 0 ){ this.myIndex = this.mySource.length(); }else{ this.myIndex += to.length(); } } /** * Skip characters until the next character is the requested character. If * the requested character is not found, no characters are skipped. * * @param to A character to skip to. * @return The requested character, or zero if the requested character is not * found. */ public char skipTo( char to ) { char c; int index = this.myIndex; do{ c = next(); if( c == 0 ){ this.myIndex = index; return c; } }while( c != to ); back(); return c; } /** * Make a JSONException to signal a syntax error. * * @param message The error message. * @return A JSONException object, suitable for throwing */ public JSONException syntaxError( String message ) { return new JSONException( message + toString() ); } /** * Make a printable string of this JSONTokener. * * @return " at character [this.myIndex] of [this.mySource]" */ public String toString() { return " at character " + this.myIndex + " of " + this.mySource; } }json-lib-2.3/net/sf/json/util/PropertySetStrategy.java0000644000175000017500000000507611226107170022076 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.util; import java.lang.reflect.Field; import java.util.Map; import net.sf.json.JSONException; import net.sf.json.JsonConfig; import org.apache.commons.beanutils.PropertyUtils; /** * Defines a custom setter to be used when setting object values.
* Specify with JsonConfig.setJsonPropertySetter(). * * @author Gino Miceli * @author Andres Almiray */ public abstract class PropertySetStrategy { public static final PropertySetStrategy DEFAULT = new DefaultPropertySetStrategy(); public abstract void setProperty( Object bean, String key, Object value ) throws JSONException; public void setProperty( Object bean, String key, Object value, JsonConfig jsonConfig ) throws JSONException { setProperty( bean, key, value ); } private static final class DefaultPropertySetStrategy extends PropertySetStrategy { public void setProperty( Object bean, String key, Object value ) throws JSONException { setProperty( bean, key, value, new JsonConfig()); } public void setProperty( Object bean, String key, Object value, JsonConfig jsonConfig ) throws JSONException { if( bean instanceof Map ){ ((Map) bean).put( key, value ); } else { if( !jsonConfig.isIgnorePublicFields() ) { try { Field field = bean.getClass().getField( key ); if( field != null ) field.set( bean, value ); } catch( Exception e ){ _setProperty( bean, key, value ); } } else { _setProperty( bean, key, value ); } } } private void _setProperty( Object bean, String key, Object value ) { try { PropertyUtils.setSimpleProperty( bean, key, value ); } catch( Exception e ) { throw new JSONException( e ); } } } }json-lib-2.3/net/sf/json/util/WebHijackPreventionStrategy.java0000644000175000017500000000357611226107170023502 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.util; /** * Defines base implementations for preventing WebHijack in AJAX applications. * The default implementations are: *
    *
  • COMMENTS - wraps the string with /* *\/
  • *
  • INFINITE_LOOP - prepends "while(1);"
  • *
* * @author Andres Almiray */ public abstract class WebHijackPreventionStrategy { /** Wraps the string with /* *\/ */ public static final WebHijackPreventionStrategy COMMENTS = new CommentWebHijackPreventionStrategy(); /** Prepends "while(1);" */ public static final WebHijackPreventionStrategy INFINITE_LOOP = new InfiniteLoopWebHijackPreventionStrategy(); /** * Transforms the input with the desired strategy.
* * @param str a json string * @return String - the transformed json string */ public abstract String protect( String str ); private static final class CommentWebHijackPreventionStrategy extends WebHijackPreventionStrategy { public String protect( String str ) { return "/*" + str + "*/"; } } private static final class InfiniteLoopWebHijackPreventionStrategy extends WebHijackPreventionStrategy { public String protect( String str ) { return "while(1);" + str; } } }json-lib-2.3/net/sf/json/util/JSONUtils.java0000644000175000017500000006522011226107170017642 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.util; import java.math.BigDecimal; import java.math.BigInteger; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import net.sf.ezmorph.MorphUtils; import net.sf.ezmorph.MorpherRegistry; import net.sf.ezmorph.bean.MorphDynaBean; import net.sf.ezmorph.bean.MorphDynaClass; import net.sf.json.JSON; import net.sf.json.JSONArray; import net.sf.json.JSONException; import net.sf.json.JSONFunction; import net.sf.json.JSONNull; import net.sf.json.JSONObject; import net.sf.json.JSONString; import net.sf.json.JsonConfig; import net.sf.json.regexp.RegexpUtils; import org.apache.commons.beanutils.DynaBean; /** * Provides useful methods on java objects and JSON values. * * @author Andres Almiray * @version 7 */ public final class JSONUtils { /** Constant for char " */ public static final String DOUBLE_QUOTE = "\""; /** Constant for char ' */ public static final String SINGLE_QUOTE = "'"; private static final String FUNCTION_BODY_PATTERN = "^function[ ]?\\(.*?\\)[ \n\t]*\\{(.*?)\\}$"; private static final String FUNCTION_HEADER_PATTERN = "^function[ ]?\\(.*?\\)$"; private static final String FUNCTION_PARAMS_PATTERN = "^function[ ]?\\((.*?)\\).*"; private static final String FUNCTION_PATTERN = "^function[ ]?\\(.*?\\)[ \n\t]*\\{.*?\\}$"; private static final String FUNCTION_PREFIX = "function"; private static final MorpherRegistry morpherRegistry = new MorpherRegistry(); static{ // register standard morphers MorphUtils.registerStandardMorphers( morpherRegistry ); } /** * Transforms the string into a valid Java Identifier.
* The default strategy is JavaIdentifierTransformer.NOOP * * @throws JSONException if the string can not be transformed. */ public static String convertToJavaIdentifier( String key ) { return convertToJavaIdentifier( key, new JsonConfig() ); } /** * Transforms the string into a valid Java Identifier.
* The default strategy is JavaIdentifierTransformer.NOOP * * @throws JSONException if the string can not be transformed. */ public static String convertToJavaIdentifier( String key, JsonConfig jsonConfig ) { try{ return jsonConfig.getJavaIdentifierTransformer() .transformToJavaIdentifier( key ); }catch( JSONException jsone ){ throw jsone; }catch( Exception e ){ throw new JSONException( e ); } } /** * Produce a string from a double. The string "null" will be returned if the * number is not finite. * * @param d A double. * @return A String. */ public static String doubleToString( double d ) { if( Double.isInfinite( d ) || Double.isNaN( d ) ){ return "null"; } // Shave off trailing zeros and decimal point, if possible. String s = Double.toString( d ); if( s.indexOf( '.' ) > 0 && s.indexOf( 'e' ) < 0 && s.indexOf( 'E' ) < 0 ){ while( s.endsWith( "0" ) ){ s = s.substring( 0, s.length() - 1 ); } if( s.endsWith( "." ) ){ s = s.substring( 0, s.length() - 1 ); } } return s; } /** * Returns the body of a function literal. */ public static String getFunctionBody( String function ) { return RegexpUtils.getMatcher( FUNCTION_BODY_PATTERN, true ).getGroupIfMatches( function, 1 ); } /** * Returns the params of a function literal. */ public static String getFunctionParams( String function ) { return RegexpUtils.getMatcher( FUNCTION_PARAMS_PATTERN, true ).getGroupIfMatches( function, 1 ); } /** * Returns the inner-most component type of an Array. */ public static Class getInnerComponentType( Class type ) { if( !type.isArray() ){ return type; } return getInnerComponentType( type.getComponentType() ); } /** * Returns the singleton MorpherRegistry. */ public static MorpherRegistry getMorpherRegistry() { return morpherRegistry; } /** * Creates a Map with all the properties of the JSONObject. */ public static Map getProperties( JSONObject jsonObject ) { Map properties = new HashMap(); for( Iterator keys = jsonObject.keys(); keys.hasNext(); ){ String key = (String) keys.next(); /* * String parsedKey = key; if( !JSONUtils.isJavaIdentifier( parsedKey ) ){ * parsedKey = JSONUtils.convertToJavaIdentifier( key ); } */ properties.put( key, getTypeClass( jsonObject.get( key ) ) ); } return properties; } /** * Returns the JSON type.
* Values are Object, String, Boolean, Number(subclasses) & JSONFunction. */ public static Class getTypeClass( Object obj ) { if( isNull( obj ) ){ return Object.class; }else if( isArray( obj ) ){ return List.class; }else if( isFunction( obj ) ){ return JSONFunction.class; }else if( isBoolean( obj ) ){ return Boolean.class; }else if( isNumber( obj ) ){ Number n = (Number) obj; if( isInteger( n ) ){ return Integer.class; }else if( isLong( n ) ){ return Long.class; }else if( isFloat( n ) ){ return Float.class; }else if( isBigInteger( n ) ){ return BigInteger.class; }else if( isBigDecimal( n ) ){ return BigDecimal.class; }else if( isDouble( n ) ){ return Double.class; }else{ throw new JSONException( "Unsupported type" ); } }else if( isString( obj ) ){ return String.class; }else if( isObject( obj ) ){ return Object.class; }else{ throw new JSONException( "Unsupported type" ); } } /** * Returns the hashcode of value.
* If null it will return JSONNull.getInstance().hashCode().
* If value is JSON, JSONFunction or String, value.hashCode is returned, * otherwise the value is transformed to a String an its hashcode is * returned. */ public static int hashCode( Object value ) { if( value == null ){ return JSONNull.getInstance() .hashCode(); }else if( value instanceof JSON || value instanceof String || value instanceof JSONFunction ){ return value.hashCode(); }else{ return String.valueOf( value ) .hashCode(); } } /** * Tests if a Class represents an array or Collection. */ public static boolean isArray( Class clazz ) { return clazz != null && (clazz.isArray() || Collection.class.isAssignableFrom( clazz ) || (JSONArray.class.isAssignableFrom( clazz ))); } /** * Tests if obj is an array or Collection. */ public static boolean isArray( Object obj ) { if( (obj != null && obj.getClass() .isArray()) || (obj instanceof Collection) || (obj instanceof JSONArray) ){ return true; } return false; } /** * Tests if Class represents a Boolean or primitive boolean */ public static boolean isBoolean( Class clazz ) { return clazz != null && (Boolean.TYPE.isAssignableFrom( clazz ) || Boolean.class.isAssignableFrom( clazz )); } /** * Tests if obj is a Boolean or primitive boolean */ public static boolean isBoolean( Object obj ) { if( (obj instanceof Boolean) || (obj != null && obj.getClass() == Boolean.TYPE) ){ return true; } return false; } /** * Tests if Class represents a primitive double or wrapper.
*/ public static boolean isDouble( Class clazz ) { return clazz != null && (Double.TYPE.isAssignableFrom( clazz ) || Double.class.isAssignableFrom( clazz )); } /** * Tests if obj is javaScript function.
* Obj must be a non-null String and match "^function[ ]?\\(.*\\)[ * ]?\\{.*\\}$" */ public static boolean isFunction( Object obj ) { if( obj instanceof String ){ String str = (String) obj; return str.startsWith( FUNCTION_PREFIX ) && RegexpUtils.getMatcher( FUNCTION_PATTERN, true ).matches( str ); } if( obj instanceof JSONFunction ){ return true; } return false; } /** * Tests if obj is javaScript function header.
* Obj must be a non-null String and match "^function[ ]?\\(.*\\)$" */ public static boolean isFunctionHeader( Object obj ) { if( obj instanceof String ){ String str = (String) obj; return str.startsWith( FUNCTION_PREFIX ) && RegexpUtils.getMatcher( FUNCTION_HEADER_PATTERN, true ).matches( str ); } return false; } /** * Returns trus if str represents a valid Java identifier. */ public static boolean isJavaIdentifier( String str ) { if( str.length() == 0 || !Character.isJavaIdentifierStart( str.charAt( 0 ) ) ){ return false; } for( int i = 1; i < str.length(); i++ ){ if( !Character.isJavaIdentifierPart( str.charAt( i ) ) ){ return false; } } return true; } /** * Tests if the obj is a javaScript null. */ public static boolean isNull( Object obj ) { if( obj instanceof JSONObject ){ return ((JSONObject) obj).isNullObject(); } return JSONNull.getInstance() .equals( obj ); } /** * Tests if Class represents a primitive number or wrapper.
*/ public static boolean isNumber( Class clazz ) { return clazz != null && (Byte.TYPE.isAssignableFrom( clazz ) || Short.TYPE.isAssignableFrom( clazz ) || Integer.TYPE.isAssignableFrom( clazz ) || Long.TYPE.isAssignableFrom( clazz ) || Float.TYPE.isAssignableFrom( clazz ) || Double.TYPE.isAssignableFrom( clazz ) || Number.class.isAssignableFrom( clazz )); } /** * Tests if obj is a primitive number or wrapper.
*/ public static boolean isNumber( Object obj ) { if( (obj != null && obj.getClass() == Byte.TYPE) || (obj != null && obj.getClass() == Short.TYPE) || (obj != null && obj.getClass() == Integer.TYPE) || (obj != null && obj.getClass() == Long.TYPE) || (obj != null && obj.getClass() == Float.TYPE) || (obj != null && obj.getClass() == Double.TYPE) ){ return true; } return obj instanceof Number; } /** * Tests if obj is not a boolean, number, string or array. */ public static boolean isObject( Object obj ) { return !isNumber( obj ) && !isString( obj ) && !isBoolean( obj ) && !isArray( obj ) && !isFunction( obj ) || isNull( obj ); } /** * Tests if Class represents a String or a char */ public static boolean isString( Class clazz ) { return clazz != null && (String.class.isAssignableFrom( clazz ) || (Character.TYPE.isAssignableFrom( clazz ) || Character.class.isAssignableFrom( clazz ))); } /** * Tests if obj is a String or a char */ public static boolean isString( Object obj ) { if( (obj instanceof String) || (obj instanceof Character) || (obj != null && (obj.getClass() == Character.TYPE || String.class.isAssignableFrom( obj.getClass() ))) ){ return true; } return false; } /** * Tests if the String possibly represents a valid JSON String.
* Valid JSON strings are: *
    *
  • "null"
  • *
  • starts with "[" and ends with "]"
  • *
  • starts with "{" and ends with "}"
  • *
*/ public static boolean mayBeJSON( String string ) { return string != null && ("null".equals( string ) || (string.startsWith( "[" ) && string.endsWith( "]" )) || (string.startsWith( "{" ) && string.endsWith( "}" ))); } /** * Creates a new MorphDynaBean from a JSONObject. The MorphDynaBean will have * all the properties of the original JSONObject with the most accurate type. * Values of properties are not copied. */ public static DynaBean newDynaBean( JSONObject jsonObject ) { return newDynaBean( jsonObject, new JsonConfig() ); } /** * Creates a new MorphDynaBean from a JSONObject. The MorphDynaBean will have * all the properties of the original JSONObject with the most accurate type. * Values of properties are not copied. */ public static DynaBean newDynaBean( JSONObject jsonObject, JsonConfig jsonConfig ) { Map props = getProperties( jsonObject ); for( Iterator entries = props.entrySet() .iterator(); entries.hasNext(); ){ Map.Entry entry = (Map.Entry) entries.next(); String key = (String) entry.getKey(); if( !JSONUtils.isJavaIdentifier( key ) ){ String parsedKey = JSONUtils.convertToJavaIdentifier( key, jsonConfig ); if( parsedKey.compareTo( key ) != 0 ){ props.put( parsedKey, props.remove( key ) ); } } } MorphDynaClass dynaClass = new MorphDynaClass( props ); MorphDynaBean dynaBean = null; try{ dynaBean = (MorphDynaBean) dynaClass.newInstance(); dynaBean.setDynaBeanClass( dynaClass ); }catch( Exception e ){ throw new JSONException( e ); } return dynaBean; } /** * Produce a string from a Number. * * @param n A Number * @return A String. * @throws JSONException If n is a non-finite number. */ public static String numberToString( Number n ) { if( n == null ){ throw new JSONException( "Null pointer" ); } testValidity( n ); // Shave off trailing zeros and decimal point, if possible. String s = n.toString(); if( s.indexOf( '.' ) > 0 && s.indexOf( 'e' ) < 0 && s.indexOf( 'E' ) < 0 ){ while( s.endsWith( "0" ) ){ s = s.substring( 0, s.length() - 1 ); } if( s.endsWith( "." ) ){ s = s.substring( 0, s.length() - 1 ); } } return s; } /** * Produce a string in double quotes with backslash sequences in all the * right places. A backslash will be inserted within * CAUTION: if string represents a * javascript function, translation of characters will not take place. This * will produce a non-conformant JSON text. * * @param string A String * @return A String correctly formatted for insertion in a JSON text. */ public static String quote( String string ) { if( isFunction( string ) ) { return string; } if( string == null || string.length() == 0 ) { return "\"\""; } char b; char c = 0; int i; int len = string.length(); StringBuffer sb = new StringBuffer( len * 2 ); String t; char[] chars = string.toCharArray(); char[] buffer = new char[1030]; int bufferIndex = 0; sb.append( '"' ); for( i = 0; i < len; i += 1 ) { if( bufferIndex > 1024 ) { sb.append( buffer, 0, bufferIndex ); bufferIndex = 0; } b = c; c = chars[i]; switch( c ) { case '\\': case '"': buffer[bufferIndex++] = '\\'; buffer[bufferIndex++] = c; break; case '/': if( b == '<' ) { buffer[bufferIndex++] = '\\'; } buffer[bufferIndex++] = c; break; default: if( c < ' ' ) { switch( c ) { case '\b': buffer[bufferIndex++] = '\\'; buffer[bufferIndex++] = 'b'; break; case '\t': buffer[bufferIndex++] = '\\'; buffer[bufferIndex++] = 't'; break; case '\n': buffer[bufferIndex++] = '\\'; buffer[bufferIndex++] = 'n'; break; case '\f': buffer[bufferIndex++] = '\\'; buffer[bufferIndex++] = 'f'; break; case '\r': buffer[bufferIndex++] = '\\'; buffer[bufferIndex++] = 'r'; break; default: t = "000" + Integer.toHexString( c ); int tLength = t.length(); buffer[bufferIndex++] = '\\'; buffer[bufferIndex++] = 'u'; buffer[bufferIndex++] = t.charAt( tLength - 4 ); buffer[bufferIndex++] = t.charAt( tLength - 3 ); buffer[bufferIndex++] = t.charAt( tLength - 2 ); buffer[bufferIndex++] = t.charAt( tLength - 1 ); } } else { buffer[bufferIndex++] = c; } } } sb.append( buffer, 0, bufferIndex ); sb.append( '"' ); return sb.toString(); } /** * Strips any single-quotes or double-quotes from both sides of the string. */ public static String stripQuotes( String input ) { if( input.length() < 2 ){ return input; }else if( input.startsWith( SINGLE_QUOTE ) && input.endsWith( SINGLE_QUOTE ) ){ return input.substring( 1, input.length() - 1 ); }else if( input.startsWith( DOUBLE_QUOTE ) && input.endsWith( DOUBLE_QUOTE ) ){ return input.substring( 1, input.length() - 1 ); }else{ return input; } } /** * Returns true if the input has single-quotes or double-quotes at both sides. */ public static boolean hasQuotes( String input ) { if( input == null || input.length() < 2 ){ return false; } return input.startsWith( SINGLE_QUOTE ) && input.endsWith( SINGLE_QUOTE ) || input.startsWith( DOUBLE_QUOTE ) && input.endsWith( DOUBLE_QUOTE ); } public static boolean isJsonKeyword( String input, JsonConfig jsonConfig ) { if( input == null ){ return false; } return "null".equals( input ) || "true".equals( input ) || "false".equals( input ) || (jsonConfig.isJavascriptCompliant() && "undefined".equals( input )); } /** * Throw an exception if the object is an NaN or infinite number. * * @param o The object to test. * @throws JSONException If o is a non-finite number. */ public static void testValidity( Object o ) { if( o != null ){ if( o instanceof Double ){ if( ((Double) o).isInfinite() || ((Double) o).isNaN() ){ throw new JSONException( "JSON does not allow non-finite numbers" ); } }else if( o instanceof Float ){ if( ((Float) o).isInfinite() || ((Float) o).isNaN() ){ throw new JSONException( "JSON does not allow non-finite numbers." ); } }else if( o instanceof BigDecimal || o instanceof BigInteger ){ // ok return; } } } /** * Transforms a Number into a valid javascript number.
* Float gets promoted to Double.
* Byte and Short get promoted to Integer.
* Long gets downgraded to Integer if possible.
*/ public static Number transformNumber( Number input ) { if( input instanceof Float ){ return new Double( input.toString() ); }else if( input instanceof Short ){ return new Integer( input.intValue() ); }else if( input instanceof Byte ){ return new Integer( input.intValue() ); }else if( input instanceof Long ){ Long max = new Long( Integer.MAX_VALUE ); if( input.longValue() <= max.longValue() && input.longValue() >= Integer.MIN_VALUE ){ return new Integer( input.intValue() ); } } return input; } /** * 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. *

* Warning: This method assumes that the data structure is acyclical. * * @param value The value to be serialized. * @return a printable, displayable, transmittable representation of the * object, beginning with { (left brace) * and ending with } (right brace). * @throws JSONException If the value is or contains an invalid number. */ public static String valueToString( Object value ) { if( value == null || isNull( value ) ){ return "null"; } if( value instanceof JSONFunction ){ return ((JSONFunction) value).toString(); } if( value instanceof JSONString ){ Object o; try{ o = ((JSONString) value).toJSONString(); }catch( Exception e ){ throw new JSONException( e ); } if( o instanceof String ){ return (String) o; } throw new JSONException( "Bad value from toJSONString: " + o ); } if( value instanceof Number ){ return numberToString( (Number) value ); } if( value instanceof Boolean || value instanceof JSONObject || value instanceof JSONArray ){ return value.toString(); } return quote( value.toString() ); } /** * Make a prettyprinted JSON text of an object value. *

* Warning: This method assumes that the data structure is acyclical. * * @param value The value to be serialized. * @param indentFactor The number of spaces to add to each level of * indentation. * @param indent The indentation of the top level. * @return a printable, displayable, transmittable representation of the * object, beginning with { (left brace) * and ending with } (right brace). * @throws JSONException If the object contains an invalid number. */ public static String valueToString( Object value, int indentFactor, int indent ) { if( value == null || isNull( value ) ){ return "null"; } if( value instanceof JSONFunction ){ return ((JSONFunction) value).toString(); } if( value instanceof JSONString ){ return ((JSONString) value).toJSONString(); } if( value instanceof Number ){ return numberToString( (Number) value ); } if( value instanceof Boolean ){ return value.toString(); } if( value instanceof JSONObject ){ return ((JSONObject) value).toString( indentFactor, indent ); } if( value instanceof JSONArray ){ return ((JSONArray) value).toString( indentFactor, indent ); } return quote( value.toString() ); } /** * Finds out if n represents a BigInteger * * @return true if n is instanceOf BigInteger or the literal value can be * evaluated as a BigInteger */ private static boolean isBigDecimal( Number n ) { if( n instanceof BigDecimal ){ return true; } try{ new BigDecimal( String.valueOf( n ) ); return true; }catch( NumberFormatException e ){ return false; } } /** * Finds out if n represents a BigInteger * * @return true if n is instanceOf BigInteger or the literal value can be * evaluated as a BigInteger */ private static boolean isBigInteger( Number n ) { if( n instanceof BigInteger ){ return true; } try{ new BigInteger( String.valueOf( n ) ); return true; }catch( NumberFormatException e ){ return false; } } /** * Finds out if n represents a Double. * * @return true if n is instanceOf Double or the literal value can be * evaluated as a Double. */ private static boolean isDouble( Number n ) { if( n instanceof Double ){ return true; } try{ double d = Double.parseDouble( String.valueOf( n ) ); return !Double.isInfinite( d ); }catch( NumberFormatException e ){ return false; } } /** * Finds out if n represents a Float. * * @return true if n is instanceOf Float or the literal value can be * evaluated as a Float. */ private static boolean isFloat( Number n ) { if( n instanceof Float ){ return true; } try{ float f = Float.parseFloat( String.valueOf( n ) ); return !Float.isInfinite( f ); }catch( NumberFormatException e ){ return false; } } /** * Finds out if n represents an Integer. * * @return true if n is instanceOf Integer or the literal value can be * evaluated as an Integer. */ private static boolean isInteger( Number n ) { if( n instanceof Integer ){ return true; } try{ Integer.parseInt( String.valueOf( n ) ); return true; }catch( NumberFormatException e ){ return false; } } /** * Finds out if n represents a Long. * * @return true if n is instanceOf Long or the literal value can be evaluated * as a Long. */ private static boolean isLong( Number n ) { if( n instanceof Long ){ return true; } try{ Long.parseLong( String.valueOf( n ) ); return true; }catch( NumberFormatException e ){ return false; } } private JSONUtils() { super(); } }json-lib-2.3/net/sf/json/util/PropertyExclusionClassMatcher.java0000644000175000017500000000317511226107170024061 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.util; import java.util.Set; /** * Base class for finding a matching property exlucsion.
*

    *
  • DEFAULT - matches the target class with equals().
  • *
* * @author Andres Almiray */ public abstract class PropertyExclusionClassMatcher { /** Matches the target with equals() */ public static final PropertyExclusionClassMatcher DEFAULT = new DefaultPropertyExclusionClassMatcher(); /** * Returns the matching class calculated with the target class and the * provided set. * * @param target the target class to match * @param set a set of possible matches */ public abstract Object getMatch( Class target, Set set ); private static final class DefaultPropertyExclusionClassMatcher extends PropertyExclusionClassMatcher { public Object getMatch( Class target, Set set ) { if( target != null && set != null && set.contains( target ) ){ return target; } return null; } } }json-lib-2.3/net/sf/json/util/EnumMorpher.java0000644000175000017500000000277211226107170020314 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.util; import net.sf.ezmorph.ObjectMorpher; /** * @author Andres Almiray */ public class EnumMorpher implements ObjectMorpher { private Class enumClass; public EnumMorpher( Class enumClass ) { if( enumClass == null ){ throw new IllegalArgumentException( "enumClass is null" ); } if( !Enum.class.isAssignableFrom( enumClass ) ){ throw new IllegalArgumentException( "enumClass is not an Enum class" ); } this.enumClass = enumClass; } public Object morph( Object value ) { if( value == null ){ return enumClass.cast( null ); } return Enum.valueOf( enumClass, String.valueOf( value ) ); } public Class morphsTo() { return enumClass; } public boolean supports( Class clazz ) { return String.class.isAssignableFrom( clazz ); } }json-lib-2.3/net/sf/json/util/PropertyFilter.java0000644000175000017500000000201211226107170021030 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.util; /** * @author Andres Almiray */ public interface PropertyFilter { /** * @param source the owner of the property * @param name the name of the property * @param value the value of the property * @return true if the property will be filtered out, false otherwise */ boolean apply( Object source, String name, Object value ); }json-lib-2.3/net/sf/json/util/WebUtils.java0000644000175000017500000001127411226107170017606 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.util; import java.util.Iterator; import net.sf.json.JSON; import net.sf.json.JSONArray; import net.sf.json.JSONNull; import net.sf.json.JSONObject; /** * Provides useful methods for working with JSON and web. * * @author Andres Almiray */ public class WebUtils { private static final WebHijackPreventionStrategy DEFAULT_WEB_HIJACK_PREVENTION_STRATEGY = WebHijackPreventionStrategy.INFINITE_LOOP; private static WebHijackPreventionStrategy webHijackPreventionStrategy = DEFAULT_WEB_HIJACK_PREVENTION_STRATEGY; /** * Returns the configured WebHijackPreventionStrategy. */ public static WebHijackPreventionStrategy getWebHijackPreventionStrategy() { return webHijackPreventionStrategy; } /** * Transforms the input Json string using the configured * WebHijackPreventionStrategy.
* * @param json the input string * @return String a transformed json string */ public static String protect( JSON json ) { return protect( json, false ); } /** * Transforms the input Json string using the configured * WebHijackPreventionStrategy.
* * @param json the input string * @param shrink if redundant key quotes may be eliminated. * @return String a transformed json string */ public static String protect( JSON json, boolean shrink ) { String output = !shrink ? json.toString( 0 ) : toString( json ); return webHijackPreventionStrategy.protect( output ); } /** * Sets a WebHijackPreventionStrategy.
* Will use default value (WebHijackPreventionStrategy.INFINITE_LOOP) if * null. */ public static void setWebHijackPreventionStrategy( WebHijackPreventionStrategy strategy ) { webHijackPreventionStrategy = strategy == null ? DEFAULT_WEB_HIJACK_PREVENTION_STRATEGY : strategy; } /** * Returns a string represenation of a JSON value.
* When an object property name does not contain a space (' ') or a colon * (':'), the quotes are omitted. This is done to reduce the amount of bytes * sent to a web browser.
USE WITH CAUTION. */ public static String toString( JSON json ) { if( json instanceof JSONObject ){ return toString( (JSONObject) json ); }else if( json instanceof JSONArray ){ return toString( (JSONArray) json ); }else{ return toString( (JSONNull) json ); } } private static String join( JSONArray jsonArray ) { int len = jsonArray.size(); StringBuffer sb = new StringBuffer(); for( int i = 0; i < len; i += 1 ){ if( i > 0 ){ sb.append( "," ); } Object value = jsonArray.get( i ); sb.append( toString( value ) ); } return sb.toString(); } private static String quote( String str ) { if( str.indexOf( " " ) > -1 || str.indexOf( ":" ) > -1 ){ return JSONUtils.quote( str ); }else{ return str; } } private static String toString( JSONArray jsonArray ) { try{ return '[' + join( jsonArray ) + ']'; }catch( Exception e ){ return null; } } private static String toString( JSONNull jsonNull ) { return jsonNull.toString(); } private static String toString( JSONObject jsonObject ) { if( jsonObject.isNullObject() ){ return JSONNull.getInstance() .toString(); } Iterator keys = jsonObject.keys(); StringBuffer sb = new StringBuffer( "{" ); while( keys.hasNext() ){ if( sb.length() > 1 ){ sb.append( ',' ); } Object o = keys.next(); sb.append( quote( o.toString() ) ); sb.append( ':' ); sb.append( toString( jsonObject.get( String.valueOf( o ) ) ) ); } sb.append( '}' ); return sb.toString(); } private static String toString( Object object ) { if( object instanceof JSON ){ return toString( (JSON) object ); }else{ return JSONUtils.valueToString( object ); } } private WebUtils() { } }json-lib-2.3/net/sf/json/util/JSONStringer.java0000644000175000017500000000523011226107170020332 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.util; import java.io.StringWriter; /** * JSONStringer 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 * JSONStringer can produce one JSON text. *

* A JSONStringer instance provides a value method for appending * values to the text, and a key method for adding keys before * values in objects. There are array and endArray * methods that make and bound array values, and object and * endObject methods which make and bound object values. All of * these methods return the JSONWriter instance, permitting cascade style. For * example, * *

 * myString = new JSONStringer()
 *     .object()
 *         .key("JSON")
 *         .value("Hello, World!")
 *     .endObject()
 *     .toString();
* * which produces the string * *
 * {"JSON":"Hello, World!"}
* *

* The first method called must be array or object. * There are no methods for adding commas or colons. JSONStringer adds them for * you. Objects and arrays can be nested up to 20 levels deep. *

* This can sometimes be easier than using a JSONObject to build a string. * * @author JSON.org * @version 2 */ public class JSONStringer extends JSONBuilder { /** * Make a fresh JSONStringer. It can be used to build one JSON text. */ public JSONStringer() { super( new StringWriter() ); } /** * Return the JSON text. This method is used to obtain the product of the * JSONStringer instance. It will return null if there was a * problem in the construction of the JSON text (such as the calls to * array were not properly balanced with calls to * endArray). * * @return The JSON text. */ public String toString() { return this.mode == 'd' ? this.writer.toString() : null; } } json-lib-2.3/net/sf/json/util/JSONBuilder.java0000644000175000017500000002153711226107170020133 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.util; import java.io.IOException; import java.io.Writer; import net.sf.json.JSONException; /** * JSONBuilder 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. *

* A JSONBuilder instance provides a value method for appending * values to the text, and a key method for adding keys before * values in objects. There are array and endArray * methods that make and bound array values, and object and * endObject methods which make and bound object values. All of * these methods return the JSONBuilder instance, permitting a cascade style. * For example, * *

 * new JSONBuilder(myWriter)
 *     .object()
 *         .key("JSON")
 *         .value("Hello, World!")
 *     .endObject();
* * which writes * *
 * {"JSON":"Hello, World!"}
* *

* The first method called must be array or object. * There are no methods for adding commas or colons. JSONBuilder adds them for * you. Objects and arrays can be nested up to 20 levels deep. *

* This can sometimes be easier than using a JSONObject to build a string. * * @author JSON.org * @version 1 */ public class JSONBuilder { 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 char 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 JSONBuilder. It can be used to build one JSON text. */ public JSONBuilder( Writer w ) { this.comma = false; this.mode = 'i'; this.stack = new char[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 JSONBuilder append( String s ) { 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 * endArray will be appended to this array. The * endArray 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 JSONBuilder array() { if( this.mode == 'i' || this.mode == 'o' || this.mode == 'a' ){ this.push( 'a' ); 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 JSONBuilder end( char m, char c ) { 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 * array. * * @return this * @throws JSONException If incorrectly nested. */ public JSONBuilder endArray() { return this.end( 'a', ']' ); } /** * End an object. This method most be called to balance calls to * object. * * @return this * @throws JSONException If incorrectly nested. */ public JSONBuilder endObject() { 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 JSONBuilder key( String s ) { if( s == null ){ throw new JSONException( "Null key." ); } if( this.mode == 'k' ){ try{ if( this.comma ){ this.writer.write( ',' ); } this.writer.write( JSONUtils.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 * endObject will be appended to this object. The * endObject 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 JSONBuilder object() { if( this.mode == 'i' ){ this.mode = 'o'; } if( this.mode == 'o' || this.mode == 'a' ){ this.append( "{" ); this.push( 'k' ); 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 ) { if( this.top <= 0 || this.stack[this.top - 1] != c ){ throw new JSONException( "Nesting error." ); } this.top -= 1; this.mode = this.top == 0 ? 'd' : this.stack[this.top - 1]; } /** * Push an array or object scope. * * @param c The scope to open. * @throws JSONException If nesting is too deep. */ private void push( char c ) { if( this.top >= MAXDEPTH ){ throw new JSONException( "Nesting too deep." ); } this.stack[this.top] = c; this.mode = c; this.top += 1; } /** * Append either the value true or the value * false. * * @param b A boolean. * @return this * @throws JSONException */ public JSONBuilder value( boolean b ) { 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 JSONBuilder value( double d ) { return this.value( new Double( d ) ); } /** * Append a long value. * * @param l A long. * @return this * @throws JSONException */ public JSONBuilder value( long l ) { 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 JSONBuilder value( Object o ) { return this.append( JSONUtils.valueToString( o ) ); } } json-lib-2.3/net/sf/json/util/JsonEventListener.java0000644000175000017500000000404111226107170021463 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.util; import net.sf.json.JSONException; /** * Defines the contract to handle JsonEvents when building an object or array. * * @author Andres Almiray */ public interface JsonEventListener { /** * Ttriggered when reaching the end of an array. */ void onArrayEnd(); /** * triggered when the start of an array is encountered. */ void onArrayStart(); /** * Triggered when an element has been added to the current array. * * @param index the index where the element was added * @param element the added element */ void onElementAdded( int index, Object element ); /** * Triggered when an exception is thrown. * * @param jsone the thrown exception */ void onError( JSONException jsone ); /** * triggered when reaching the end of an object. */ void onObjectEnd(); /** * Triggered when the start of an object is encountered. */ void onObjectStart(); /** * Triggered when a property is set on an object * * @param key the name of the property * @param value the value of the property * @param accumulated if the value has been accumulated over 'key' */ void onPropertySet( String key, Object value, boolean accumulated ); /** * Triggered when a warning is encountered. * * @param warning the warning message */ void onWarning( String warning ); }json-lib-2.3/net/sf/json/util/JavaIdentifierTransformer.java0000644000175000017500000001405411226107170023156 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.util; import net.sf.json.JSONException; import org.apache.commons.lang.StringUtils; /** * Transforms a string into a valid Java identifier.
* There are five predefined strategies: *

    *
  • NOOP: does not perform transformation.
  • *
  • CAMEL_CASE: follows the camel case convention, deletes non * JavaIndentifierPart chars.
  • *
  • UNDERSCORE: transform whitespace and non JavaIdentifierPart chars to * '_'.
  • *
  • WHITESPACE: deletes whitespace and non JavaIdentifierPart chars.
  • *
  • STRICT: always throws a JSONException, does not perform transformation.
  • *
* * @author Andres Almiray */ public abstract class JavaIdentifierTransformer { /** CamelCase transformer 'camel case' => 'camelCase' */ public static final JavaIdentifierTransformer CAMEL_CASE = new CamelCaseJavaIdentifierTransformer(); /** Noop transformer '@invalid' => '@invalid' */ public static final JavaIdentifierTransformer NOOP = new NoopJavaIdentifierTransformer(); /** Strict transformer '@invalid' => JSONException */ public static final JavaIdentifierTransformer STRICT = new StrictJavaIdentifierTransformer(); /** Underscore transformer 'under score' => 'under_score' */ public static final JavaIdentifierTransformer UNDERSCORE = new UnderscoreJavaIdentifierTransformer(); /** Whitespace transformer 'white space' => 'whitespace' */ public static final JavaIdentifierTransformer WHITESPACE = new WhiteSpaceJavaIdentifierTransformer(); public abstract String transformToJavaIdentifier( String str ); /** * Removes all non JavaIdentifier chars from the start of the string. * * @throws JSONException if the resulting string has zero length. */ protected final String shaveOffNonJavaIdentifierStartChars( String str ) { String str2 = str; // shave off first char if not valid boolean ready = false; while( !ready ){ if( !Character.isJavaIdentifierStart( str2.charAt( 0 ) ) ){ str2 = str2.substring( 1 ); if( str2.length() == 0 ){ throw new JSONException( "Can't convert '" + str + "' to a valid Java identifier" ); } }else{ ready = true; } } return str2; } private static final class CamelCaseJavaIdentifierTransformer extends JavaIdentifierTransformer { public String transformToJavaIdentifier( String str ) { if( str == null ){ return null; } String str2 = shaveOffNonJavaIdentifierStartChars( str ); char[] chars = str2.toCharArray(); int pos = 0; StringBuffer buf = new StringBuffer(); boolean toUpperCaseNextChar = false; while( pos < chars.length ){ if( !Character.isJavaIdentifierPart( chars[pos] ) || Character.isWhitespace( chars[pos] ) ){ toUpperCaseNextChar = true; }else{ if( toUpperCaseNextChar ){ buf.append( Character.toUpperCase( chars[pos] ) ); toUpperCaseNextChar = false; }else{ buf.append( chars[pos] ); } } pos++; } return buf.toString(); } } private static final class NoopJavaIdentifierTransformer extends JavaIdentifierTransformer { public String transformToJavaIdentifier( String str ) { return str; } } private static final class StrictJavaIdentifierTransformer extends JavaIdentifierTransformer { public String transformToJavaIdentifier( String str ) { throw new JSONException( "'" + str + "' is not a valid Java identifier." ); } } private static final class UnderscoreJavaIdentifierTransformer extends JavaIdentifierTransformer { public String transformToJavaIdentifier( String str ) { if( str == null ){ return null; } String str2 = shaveOffNonJavaIdentifierStartChars( str ); char[] chars = str2.toCharArray(); int pos = 0; StringBuffer buf = new StringBuffer(); boolean toUnderScorePreviousChar = false; while( pos < chars.length ){ if( !Character.isJavaIdentifierPart( chars[pos] ) || Character.isWhitespace( chars[pos] ) ){ toUnderScorePreviousChar = true; }else{ if( toUnderScorePreviousChar ){ buf.append( "_" ); toUnderScorePreviousChar = false; } buf.append( chars[pos] ); } pos++; } if( buf.charAt( buf.length() - 1 ) == '_' ){ buf.deleteCharAt( buf.length() - 1 ); } return buf.toString(); } } private static final class WhiteSpaceJavaIdentifierTransformer extends JavaIdentifierTransformer { public String transformToJavaIdentifier( String str ) { if( str == null ){ return null; } String str2 = shaveOffNonJavaIdentifierStartChars( str ); str2 = StringUtils.deleteWhitespace( str2 ); char[] chars = str2.toCharArray(); int pos = 0; StringBuffer buf = new StringBuffer(); while( pos < chars.length ){ if( Character.isJavaIdentifierPart( chars[pos] ) ){ buf.append( chars[pos] ); } pos++; } return buf.toString(); } } }json-lib-2.3/net/sf/json/util/NewBeanInstanceStrategy.java0000644000175000017500000000542411226107170022577 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.util; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import net.sf.json.JSONObject; /** * Base class for creating Bean instances.
*
    *
  • DEFAULT - calls Class.newInstance().
  • *
* * @author Andres Almiray */ public abstract class NewBeanInstanceStrategy { /** Calls Class.newInstance() */ public static final NewBeanInstanceStrategy DEFAULT = new DefaultNewBeanInstanceStrategy(); /** * Creates a new instance. * * @param target the source class * @param source additional properties that may be needed to create the * instance */ public abstract Object newInstance( Class target, JSONObject source ) throws InstantiationException, IllegalAccessException, SecurityException, NoSuchMethodException, InvocationTargetException; private static final class DefaultNewBeanInstanceStrategy extends NewBeanInstanceStrategy { private static final Object[] EMPTY_ARGS = new Object[0]; private static final Class[] EMPTY_PARAM_TYPES = new Class[0]; public Object newInstance( Class target, JSONObject source ) throws InstantiationException, IllegalAccessException, SecurityException, NoSuchMethodException, InvocationTargetException { if( target != null ){ Constructor c = target.getDeclaredConstructor( EMPTY_PARAM_TYPES ); c.setAccessible( true ); try { return c.newInstance( EMPTY_ARGS ); } catch ( InstantiationException e ) { // getCause() was added on jdk 1.4 String cause = ""; try { cause = e.getCause() != null ? "\n"+e.getCause().getMessage() : ""; } catch( Throwable t ) { /* ignore */ } throw new InstantiationException( "Instantiation of \"" + target + "\" failed. " + "It's probably because class is an interface, " + "abstract class, array class, primitive type or void." + cause ); } } return null; } } }json-lib-2.3/net/sf/json/regexp/0000755000175000017500000000000011226107170015515 5ustar mkochmkochjson-lib-2.3/net/sf/json/regexp/JdkRegexpMatcher.java0000644000175000017500000000302211226107170021544 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.regexp; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * JDK 1.4+ RegexpMatcher implementation. * * @author Andres Almiray */ public class JdkRegexpMatcher implements RegexpMatcher { private final Pattern pattern; public JdkRegexpMatcher( String pattern ) { this( pattern, false ); } public JdkRegexpMatcher( String pattern, boolean multiline ) { if( multiline ) { this.pattern = Pattern.compile( pattern, Pattern.MULTILINE ); } else { this.pattern = Pattern.compile( pattern ); } } public String getGroupIfMatches( String str, int group ) { Matcher matcher = pattern.matcher( str ); if( matcher.matches() ) { return matcher.group( group ); } return ""; } public boolean matches( String str ) { return pattern.matcher( str ).matches(); } }json-lib-2.3/net/sf/json/regexp/Perl5RegexpMatcher.java0000644000175000017500000000424511226107170022033 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.regexp; import org.apache.commons.lang.exception.NestableRuntimeException; import org.apache.oro.text.regex.MalformedPatternException; import org.apache.oro.text.regex.Pattern; import org.apache.oro.text.regex.PatternMatcher; import org.apache.oro.text.regex.Perl5Compiler; import org.apache.oro.text.regex.Perl5Matcher; /** * Jakarta-oro RegexpMatcher Implementation.
* Runs on older JVMs (1.3.1). You must have oro-2.0.8.jar configured in your classpath. * * @author Andres Almiray */ public class Perl5RegexpMatcher implements RegexpMatcher { private static final Perl5Compiler compiler = new Perl5Compiler(); private Pattern pattern; public Perl5RegexpMatcher( String pattern ) { this( pattern, false ); } public Perl5RegexpMatcher( String pattern, boolean multiline ) { try { if( multiline ) { this.pattern = compiler.compile( pattern, Perl5Compiler.READ_ONLY_MASK | Perl5Compiler.MULTILINE_MASK ); } else { this.pattern = compiler.compile( pattern, Perl5Compiler.READ_ONLY_MASK ); } } catch( MalformedPatternException mpe ) { throw new NestableRuntimeException( mpe ); } } public String getGroupIfMatches( String str, int group ) { PatternMatcher matcher = new Perl5Matcher(); if( matcher.matches( str, pattern ) ) { return matcher.getMatch().group( 1 ); } return ""; } public boolean matches( String str ) { return new Perl5Matcher().matches( str, pattern ); } }json-lib-2.3/net/sf/json/regexp/RegexpUtils.java0000644000175000017500000000375311226107170020643 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.regexp; /** * Convenience utility for working withRegexpMatcher.
* * @author Andres Almiray */ public class RegexpUtils { private static String javaVersion = "1.3.1"; static{ javaVersion = System.getProperty( "java.version" ); } /** * Returns a RegexpMatcher that works in a specific environment.
* When in a JVM 1.3.1 it will return a Perl5RegexpMatcher, if the JVM is * younger (1.4+) it will return a JdkRegexpMatcher. */ public static RegexpMatcher getMatcher( String pattern ) { if( isJDK13() ){ return new Perl5RegexpMatcher( pattern ); }else{ return new JdkRegexpMatcher( pattern ); } } /** * Returns a RegexpMatcher that works in a specific environment.
* When in a JVM 1.3.1 it will return a Perl5RegexpMatcher, if the JVM is * younger (1.4+) it will return a JdkRegexpMatcher. */ public static RegexpMatcher getMatcher( String pattern, boolean multiline ) { if( isJDK13() ){ return new Perl5RegexpMatcher( pattern, true ); }else{ return new JdkRegexpMatcher( pattern, true ); } } /** * Queries the environment for the supported JDK version. */ public static boolean isJDK13() { return javaVersion.indexOf( "1.3" ) != -1; } private RegexpUtils() { } }json-lib-2.3/net/sf/json/regexp/RegexpMatcher.java0000644000175000017500000000230011226107170021111 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.regexp; /** * Abstraction for regexp handling. * * @author Andres Almiray */ public interface RegexpMatcher { /** * Returns the specified group if the string matches the Pattern.
* The Pattern will be managed internally by the RegexpMatcher * implementation. */ String getGroupIfMatches( String str, int group ); /** * Returns true is the string macthes the Pattern.
* The Pattern will be managed internally by the RegexpMatcher * implementation. */ boolean matches( String str ); }json-lib-2.3/net/sf/json/JSON.java0000644000175000017500000000567211226107170015651 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json; import java.io.Writer; import java.io.Serializable; /** * Marker interface, identifies a valid JSON value.
* A JSON value may be a {@link JSONObject}, a {@link JSONArray} or a * {@link JSONNull}. * * @author Andres Almiray */ public interface JSON extends Serializable { /** * Returns true if this object is a JSONArray, false otherwise. */ boolean isArray(); /** * Returns true if this object has no elements or keys. * * @throws JSONException if called on a 'null' object */ boolean isEmpty(); /** * Returns the number of properties in an object or the size of the array. * * @return the size of an json object or array * @throws JSONException if called on a 'null' object */ int size(); /** * Make a prettyprinted JSON text. *

* Warning: This method assumes that the data structure is acyclical. * * @param indentFactor The number of spaces to add to each level of * indentation. * @return a printable, displayable, portable, transmittable representation * of the object, beginning with { (left * brace) and ending with } (right * brace). * @throws JSONException If the object contains an invalid number. */ String toString( int indentFactor ); /** * Make a prettyprinted JSON text. *

* Warning: This method assumes that the data structure is acyclical. * * @param indentFactor The number of spaces to add to each level of * indentation. * @param indent The indentation of the top level. * @return a printable, displayable, transmittable representation of the * object, beginning with { (left brace) * and ending with } (right brace). * @throws JSONException If the object contains an invalid number. */ String toString( int indentFactor, int indent ); /** * Write the contents as JSON text to a writer. For compactness, no * whitespace is added. *

* Warning: This method assumes that the data structure is acyclical. * * @return The writer. * @throws JSONException */ Writer write( Writer writer ); }json-lib-2.3/net/sf/json/JSONArray.java0000644000175000017500000025611511226107170016650 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json; import java.beans.PropertyDescriptor; import java.io.IOException; import java.io.Writer; import java.lang.annotation.Annotation; import java.lang.reflect.Array; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collection; import java.util.ConcurrentModificationException; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import java.util.Map; import java.util.NoSuchElementException; import java.util.Set; import net.sf.ezmorph.Morpher; import net.sf.ezmorph.object.IdentityObjectMorpher; import net.sf.json.processors.JsonValueProcessor; import net.sf.json.processors.JsonVerifier; import net.sf.json.util.JSONTokener; import net.sf.json.util.JSONUtils; import org.apache.commons.lang.StringUtils; /** * 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 get and opt * methods for accessing the values by index, and element methods * for adding or replacing values. The values can be any of these types: * Boolean, JSONArray, JSONObject, * Number, String, or the * JSONNull object. *

* The constructor can convert a JSON text into a Java object. The * toString method converts to JSON text. *

* A get method returns a value if one can be found, and throws * an exception if one cannot be found. An opt method returns a * default value instead of throwing an exception, and so is useful for * obtaining optional values. *

* The generic get() and opt() methods return an * object which you can cast or query for type. There are also typed * get and opt methods that do type checking and * type coersion for you. *

* The texts produced by the toString methods strictly conform to * JSON syntax rules. The constructors are more forgiving in the texts they will * accept: *

    *
  • An extra , (comma) may appear just * before the closing bracket.
  • *
  • The null value will be inserted when there is * , (comma) elision.
  • *
  • Strings may be quoted with ' (single quote).
  • *
  • 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: * { } [ ] / \ : , = ; # and if they do not look like numbers and * if they are not the reserved words true, false, * or null.
  • *
  • Values can be separated by ; (semicolon) * as well as by , (comma).
  • *
  • Numbers may have the 0- (octal) or * 0x- (hex) prefix.
  • *
  • Comments written in the slashshlash, slashstar, and hash conventions * will be ignored.
  • *
* * @author JSON.org */ public final class JSONArray extends AbstractJSON implements JSON, List, Comparable { /** * Creates a JSONArray.
* Inspects the object type to call the correct JSONArray factory method. * Accepts JSON formatted strings, arrays, Collections and Enums. * * @param object * @throws JSONException if the object can not be converted to a proper * JSONArray. */ public static JSONArray fromObject( Object object ) { return fromObject( object, new JsonConfig() ); } /** * Creates a JSONArray.
* Inspects the object type to call the correct JSONArray factory method. * Accepts JSON formatted strings, arrays, Collections and Enums. * * @param object * @throws JSONException if the object can not be converted to a proper * JSONArray. */ public static JSONArray fromObject( Object object, JsonConfig jsonConfig ) { if( object instanceof JSONString ){ return _fromJSONString( (JSONString) object, jsonConfig ); }else if( object instanceof JSONArray ){ return _fromJSONArray( (JSONArray) object, jsonConfig ); }else if( object instanceof Collection ){ return _fromCollection( (Collection) object, jsonConfig ); }else if( object instanceof JSONTokener ){ return _fromJSONTokener( (JSONTokener) object, jsonConfig ); }else if( object instanceof String ){ return _fromString( (String) object, jsonConfig ); }else if( object != null && object.getClass() .isArray() ){ Class type = object.getClass() .getComponentType(); if( !type.isPrimitive() ){ return _fromArray( (Object[]) object, jsonConfig ); }else{ if( type == Boolean.TYPE ){ return _fromArray( (boolean[]) object, jsonConfig ); }else if( type == Byte.TYPE ){ return _fromArray( (byte[]) object, jsonConfig ); }else if( type == Short.TYPE ){ return _fromArray( (short[]) object, jsonConfig ); }else if( type == Integer.TYPE ){ return _fromArray( (int[]) object, jsonConfig ); }else if( type == Long.TYPE ){ return _fromArray( (long[]) object, jsonConfig ); }else if( type == Float.TYPE ){ return _fromArray( (float[]) object, jsonConfig ); }else if( type == Double.TYPE ){ return _fromArray( (double[]) object, jsonConfig ); }else if( type == Character.TYPE ){ return _fromArray( (char[]) object, jsonConfig ); }else{ throw new JSONException( "Unsupported type" ); } } }else if( JSONUtils.isBoolean( object ) || JSONUtils.isFunction( object ) || JSONUtils.isNumber( object ) || JSONUtils.isNull( object ) || JSONUtils.isString( object ) || object instanceof JSON ){ fireArrayStartEvent( jsonConfig ); JSONArray jsonArray = new JSONArray().element( object, jsonConfig ); fireElementAddedEvent( 0, jsonArray.get( 0 ), jsonConfig ); fireArrayStartEvent( jsonConfig ); return jsonArray; }else if( object instanceof Enum ){ return _fromArray( (Enum) object, jsonConfig ); }else if( object instanceof Annotation || (object != null && object.getClass() .isAnnotation()) ){ throw new JSONException( "Unsupported type" ); }else if( JSONUtils.isObject( object ) ){ fireArrayStartEvent( jsonConfig ); JSONArray jsonArray = new JSONArray().element( JSONObject.fromObject( object, jsonConfig ) ); fireElementAddedEvent( 0, jsonArray.get( 0 ), jsonConfig ); fireArrayStartEvent( jsonConfig ); return jsonArray; }else{ throw new JSONException( "Unsupported type" ); } } /** * Get the collection type from a getter or setter, or null if no type was * found.
* Contributed by [Matt Small @ WaveMaker]. */ public static Class[] getCollectionType( PropertyDescriptor pd, boolean useGetter ) throws JSONException { Type type; if( useGetter ){ Method m = pd.getReadMethod(); type = m.getGenericReturnType(); }else{ Method m = pd.getWriteMethod(); Type[] gpts = m.getGenericParameterTypes(); if( 1 != gpts.length ){ throw new JSONException( "method " + m + " is not a standard setter" ); } type = gpts[0]; } if( !(type instanceof ParameterizedType) ){ return null; // throw new JSONException("type not instanceof ParameterizedType: // "+type.getClass()); } ParameterizedType pType = (ParameterizedType) type; Type[] actualTypes = pType.getActualTypeArguments(); Class[] ret = new Class[actualTypes.length]; for( int i = 0; i < ret.length; i++ ){ ret[i] = (Class) actualTypes[i]; } return ret; } /** * Returns the number of dimensions suited for a java array. */ public static int[] getDimensions( JSONArray jsonArray ) { // short circuit for empty arrays if( jsonArray == null || jsonArray.isEmpty() ){ return new int[] { 0 }; } List dims = new ArrayList(); processArrayDimensions( jsonArray, dims, 0 ); int[] dimensions = new int[dims.size()]; int j = 0; for( Iterator i = dims.iterator(); i.hasNext(); ){ dimensions[j++] = ((Integer) i.next()).intValue(); } return dimensions; } /** * Creates a java array from a JSONArray. */ public static Object toArray( JSONArray jsonArray ) { return toArray( jsonArray, new JsonConfig() ); } /** * Creates a java array from a JSONArray. */ public static Object toArray( JSONArray jsonArray, Class objectClass ) { JsonConfig jsonConfig = new JsonConfig(); jsonConfig.setRootClass( objectClass ); return toArray( jsonArray, jsonConfig ); } /** * Creates a java array from a JSONArray.
* Any attribute is a JSONObject and matches a key in the classMap, it will * be converted to that target class.
* The classMap has the following conventions: *
    *
  • Every key must be an String.
  • *
  • Every value must be a Class.
  • *
  • A key may be a regular expression.
  • *
*/ public static Object toArray( JSONArray jsonArray, Class objectClass, Map classMap ) { JsonConfig jsonConfig = new JsonConfig(); jsonConfig.setRootClass( objectClass ); jsonConfig.setClassMap( classMap ); return toArray( jsonArray, jsonConfig ); } /** * Creates a java array from a JSONArray.
*/ public static Object toArray( JSONArray jsonArray, JsonConfig jsonConfig ) { Class objectClass = jsonConfig.getRootClass(); Map classMap = jsonConfig.getClassMap(); if( jsonArray.size() == 0 ){ return Array.newInstance( objectClass == null ? Object.class : objectClass, 0 ); } int[] dimensions = JSONArray.getDimensions( jsonArray ); Object array = Array.newInstance( objectClass == null ? Object.class : objectClass, dimensions ); int size = jsonArray.size(); for( int i = 0; i < size; i++ ){ Object value = jsonArray.get( i ); if( JSONUtils.isNull( value ) ){ Array.set( array, i, null ); }else{ Class type = value.getClass(); if( JSONArray.class.isAssignableFrom( type ) ){ Array.set( array, i, toArray( (JSONArray) value, objectClass, classMap ) ); }else if( String.class.isAssignableFrom( type ) || Boolean.class.isAssignableFrom( type ) || Character.class.isAssignableFrom( type ) || JSONFunction.class.isAssignableFrom( type ) ){ if( objectClass != null && !objectClass.isAssignableFrom( type ) ){ value = JSONUtils.getMorpherRegistry() .morph( objectClass, value ); } Array.set( array, i, value ); }else if( JSONUtils.isNumber( type ) ){ if( objectClass != null && (Byte.class.isAssignableFrom( objectClass ) || Byte.TYPE.isAssignableFrom( objectClass )) ){ Array.set( array, i, Byte.valueOf( String.valueOf( value ) ) ); }else if( objectClass != null && (Short.class.isAssignableFrom( objectClass ) || Short.TYPE.isAssignableFrom( objectClass )) ){ Array.set( array, i, Short.valueOf( String.valueOf( value ) ) ); }else{ Array.set( array, i, value ); } }else{ if( objectClass != null ){ JsonConfig jsc = jsonConfig.copy(); jsc.setRootClass( objectClass ); jsc.setClassMap( classMap ); Array.set( array, i, JSONObject.toBean( (JSONObject) value, jsc ) ); }else{ Array.set( array, i, JSONObject.toBean( (JSONObject) value ) ); } } } } return array; } /** * Creates a java array from a JSONArray.
*/ public static Object toArray( JSONArray jsonArray, Object root, JsonConfig jsonConfig ) { Class objectClass = root.getClass(); if( jsonArray.size() == 0 ){ return Array.newInstance( objectClass, 0 ); } int[] dimensions = JSONArray.getDimensions( jsonArray ); Object array = Array.newInstance( objectClass == null ? Object.class : objectClass, dimensions ); int size = jsonArray.size(); for( int i = 0; i < size; i++ ){ Object value = jsonArray.get( i ); if( JSONUtils.isNull( value ) ){ Array.set( array, i, null ); }else{ Class type = value.getClass(); if( JSONArray.class.isAssignableFrom( type ) ){ Array.set( array, i, toArray( (JSONArray) value, root, jsonConfig ) ); }else if( String.class.isAssignableFrom( type ) || Boolean.class.isAssignableFrom( type ) || JSONUtils.isNumber( type ) || Character.class.isAssignableFrom( type ) || JSONFunction.class.isAssignableFrom( type ) ){ if( objectClass != null && !objectClass.isAssignableFrom( type ) ){ value = JSONUtils.getMorpherRegistry() .morph( objectClass, value ); } Array.set( array, i, value ); }else{ try{ Object newRoot = jsonConfig.getNewBeanInstanceStrategy() .newInstance( root.getClass(), null ); Array.set( array, i, JSONObject.toBean( (JSONObject) value, newRoot, jsonConfig ) ); }catch( JSONException jsone ){ throw jsone; }catch( Exception e ){ throw new JSONException( e ); } } } } return array; } /** * Returns a List or a Set taking generics into account.
*/ public static Collection toCollection( JSONArray jsonArray ) { return toCollection( jsonArray, new JsonConfig() ); } /** * Returns a List or a Set taking generics into account.
*/ public static Collection toCollection( JSONArray jsonArray, Class objectClass ) { JsonConfig jsonConfig = new JsonConfig(); jsonConfig.setRootClass( objectClass ); return toCollection( jsonArray, jsonConfig ); } /** * Returns a List or a Set taking generics into account.
* Contributed by [Matt Small @ WaveMaker]. */ public static Collection toCollection( JSONArray jsonArray, JsonConfig jsonConfig ) { Collection collection = null; Class collectionType = jsonConfig.getCollectionType(); if( collectionType.isInterface() ){ if( collectionType.equals( List.class ) ){ collection = new ArrayList(); }else if( collectionType.equals( Set.class ) ){ collection = new HashSet(); }else{ throw new JSONException( "unknown interface: " + collectionType ); } }else{ try{ collection = (Collection) collectionType.newInstance(); }catch( InstantiationException e ){ throw new JSONException( e ); }catch( IllegalAccessException e ){ throw new JSONException( e ); } } Class objectClass = jsonConfig.getRootClass(); Map classMap = jsonConfig.getClassMap(); int size = jsonArray.size(); for( int i = 0; i < size; i++ ){ Object value = jsonArray.get( i ); if( JSONUtils.isNull( value ) ){ collection.add( null ); }else{ Class type = value.getClass(); if( JSONArray.class.isAssignableFrom( value.getClass() ) ){ collection.add( toCollection( (JSONArray) value, jsonConfig ) ); }else if( String.class.isAssignableFrom( type ) || Boolean.class.isAssignableFrom( type ) || JSONUtils.isNumber( type ) || Character.class.isAssignableFrom( type ) || JSONFunction.class.isAssignableFrom( type ) ){ if( !value.getClass() .isAssignableFrom( type ) ){ throw new JSONException( "can't assign value " + value + " of type " + value.getClass() + " to Collection of type " + type ); } collection.add( value ); }else{ if( objectClass != null ){ JsonConfig jsc = jsonConfig.copy(); jsc.setRootClass( objectClass ); jsc.setClassMap( classMap ); collection.add( JSONObject.toBean( (JSONObject) value, jsc ) ); }else{ collection.add( JSONObject.toBean( (JSONObject) value ) ); } } } } return collection; } /* public static Collection toCollection( JSONArray jsonArray, JsonConfig jsonConfig ) { Collection collection = null; Class collectionType = jsonConfig.getCollectionType(); Class enclosedType = jsonConfig.getEnclosedType(); if( collectionType.isInterface() ){ if( collectionType.equals( List.class ) ){ collection = new ArrayList(); }else if( collectionType.equals( Set.class ) ){ collection = new HashSet(); }else{ throw new JSONException( "unknown interface: " + collectionType ); } }else{ try{ collection = (Collection) collectionType.newInstance(); }catch( InstantiationException e ){ throw new JSONException( e ); }catch( IllegalAccessException e ){ throw new JSONException( e ); } } Class objectClass = jsonConfig.getRootClass(); Map classMap = jsonConfig.getClassMap(); int size = jsonArray.size(); for( int i = 0; i < size; i++ ){ Object value = jsonArray.get( i ); Class enclosedTypeE = enclosedType; if( null == enclosedTypeE ){ enclosedTypeE = value.getClass(); } if( JSONUtils.isNull( value ) ){ collection.add( null ); }else{ if( JSONArray.class.isAssignableFrom( value.getClass() ) ){ //throw new RuntimeException( "can't have nested collections" ); collection.add( toCollection( (JSONArray) value, jsonConfig ) ); }else if( String.class.isAssignableFrom( enclosedTypeE ) || Boolean.class.isAssignableFrom( enclosedTypeE ) || JSONUtils.isNumber( enclosedTypeE ) || Character.class.isAssignableFrom( enclosedTypeE ) || JSONFunction.class.isAssignableFrom( enclosedTypeE ) ){ if( !value.getClass() .isAssignableFrom( enclosedTypeE ) ){ throw new JSONException( "can't assign value " + value + " of type " + value.getClass() + " to Collection of type " + enclosedTypeE ); } collection.add( value ); }else{ try{ if( JSON.class.isAssignableFrom( enclosedTypeE ) ){ ret.add( JSONObject.toBean( (JSONObject) value ) ); }else{ Object newRoot = enclosedTypeE.newInstance(); ret.add( JSONObject.toBean( (JSONObject) value, newRoot, jsonConfig ) ); } }catch( JSONException jsone ){ throw jsone; }catch( Exception e ){ throw new JSONException( e ); } if( objectClass != null ){ JsonConfig jsc = jsonConfig.copy(); jsc.setRootClass( objectClass ); jsc.setClassMap( classMap ); collection.add( JSONObject.toBean( (JSONObject) value, jsc ) ); }else{ collection.add( JSONObject.toBean( (JSONObject) value ) ); } } } } return collection; } */ /** * Creates a List from a JSONArray.
* * @deprecated replaced by toCollection * @see #toCollection(JSONArray) */ public static List toList( JSONArray jsonArray ) { return toList( jsonArray, new JsonConfig() ); } /** * Creates a List from a JSONArray. * * @deprecated replaced by toCollection * @see #toCollection(JSONArray,Class) */ public static List toList( JSONArray jsonArray, Class objectClass ) { JsonConfig jsonConfig = new JsonConfig(); jsonConfig.setRootClass( objectClass ); return toList( jsonArray, jsonConfig ); } /** * Creates a List from a JSONArray.
* Any attribute is a JSONObject and matches a key in the classMap, it will * be converted to that target class.
* The classMap has the following conventions: *
    *
  • Every key must be an String.
  • *
  • Every value must be a Class.
  • *
  • A key may be a regular expression.
  • *
* * @deprecated replaced by toCollection * @see #toCollection(JSONArray,Class,Map) */ public static List toList( JSONArray jsonArray, Class objectClass, Map classMap ) { JsonConfig jsonConfig = new JsonConfig(); jsonConfig.setRootClass( objectClass ); jsonConfig.setClassMap( classMap ); return toList( jsonArray, jsonConfig ); } /** * Creates a List from a JSONArray.
* * @deprecated replaced by toCollection * @see #toCollection(JSONArray,JsonConfig) */ public static List toList( JSONArray jsonArray, JsonConfig jsonConfig ) { if( jsonArray.size() == 0 ){ return new ArrayList(); } Class objectClass = jsonConfig.getRootClass(); Map classMap = jsonConfig.getClassMap(); List list = new ArrayList(); int size = jsonArray.size(); for( int i = 0; i < size; i++ ){ Object value = jsonArray.get( i ); if( JSONUtils.isNull( value ) ){ list.add( null ); }else{ Class type = value.getClass(); if( JSONArray.class.isAssignableFrom( type ) ){ list.add( toList( (JSONArray) value, objectClass, classMap ) ); }else if( String.class.isAssignableFrom( type ) || Boolean.class.isAssignableFrom( type ) || JSONUtils.isNumber( type ) || Character.class.isAssignableFrom( type ) || JSONFunction.class.isAssignableFrom( type ) ){ if( objectClass != null && !objectClass.isAssignableFrom( type ) ){ value = JSONUtils.getMorpherRegistry() .morph( objectClass, value ); } list.add( value ); }else{ if( objectClass != null ){ JsonConfig jsc = jsonConfig.copy(); jsc.setRootClass( objectClass ); jsc.setClassMap( classMap ); list.add( JSONObject.toBean( (JSONObject) value, jsc ) ); }else{ list.add( JSONObject.toBean( (JSONObject) value ) ); } } } } return list; } /** * Creates a List from a JSONArray.
*/ public static List toList( JSONArray jsonArray, Object root, JsonConfig jsonConfig ) { if( jsonArray.size() == 0 || root == null ){ return new ArrayList(); } List list = new ArrayList(); int size = jsonArray.size(); for( int i = 0; i < size; i++ ){ Object value = jsonArray.get( i ); if( JSONUtils.isNull( value ) ){ list.add( null ); }else{ Class type = value.getClass(); if( JSONArray.class.isAssignableFrom( type ) ){ list.add( toList( (JSONArray) value, root, jsonConfig ) ); }else if( String.class.isAssignableFrom( type ) || Boolean.class.isAssignableFrom( type ) || JSONUtils.isNumber( type ) || Character.class.isAssignableFrom( type ) || JSONFunction.class.isAssignableFrom( type ) ){ list.add( value ); }else{ try{ Object newRoot = jsonConfig.getNewBeanInstanceStrategy() .newInstance( root.getClass(), null ); list.add( JSONObject.toBean( (JSONObject) value, newRoot, jsonConfig ) ); }catch( JSONException jsone ){ throw jsone; }catch( Exception e ){ throw new JSONException( e ); } } } } return list; } /** * Construct a JSONArray from an boolean[].
* * @param array An boolean[] array. */ private static JSONArray _fromArray( boolean[] array, JsonConfig jsonConfig ) { if( !addInstance( array ) ){ try{ return jsonConfig.getCycleDetectionStrategy() .handleRepeatedReferenceAsArray( array ); }catch( JSONException jsone ){ removeInstance( array ); fireErrorEvent( jsone, jsonConfig ); throw jsone; }catch( RuntimeException e ){ removeInstance( array ); JSONException jsone = new JSONException( e ); fireErrorEvent( jsone, jsonConfig ); throw jsone; } } fireArrayStartEvent( jsonConfig ); JSONArray jsonArray = new JSONArray(); for( int i = 0; i < array.length; i++ ){ Boolean b = array[i] ? Boolean.TRUE : Boolean.FALSE; jsonArray.addValue( b, jsonConfig ); fireElementAddedEvent( i, b, jsonConfig ); } removeInstance( array ); fireArrayEndEvent( jsonConfig ); return jsonArray; } /** * Construct a JSONArray from an byte[].
* * @param array An byte[] array. */ private static JSONArray _fromArray( byte[] array, JsonConfig jsonConfig ) { if( !addInstance( array ) ){ try{ return jsonConfig.getCycleDetectionStrategy() .handleRepeatedReferenceAsArray( array ); }catch( JSONException jsone ){ removeInstance( array ); fireErrorEvent( jsone, jsonConfig ); throw jsone; }catch( RuntimeException e ){ removeInstance( array ); JSONException jsone = new JSONException( e ); fireErrorEvent( jsone, jsonConfig ); throw jsone; } } fireArrayStartEvent( jsonConfig ); JSONArray jsonArray = new JSONArray(); for( int i = 0; i < array.length; i++ ){ Number n = JSONUtils.transformNumber( new Byte( array[i] ) ); jsonArray.addValue( n, jsonConfig ); fireElementAddedEvent( i, n, jsonConfig ); } removeInstance( array ); fireArrayEndEvent( jsonConfig ); return jsonArray; } /** * Construct a JSONArray from an char[].
* * @param array An char[] array. */ private static JSONArray _fromArray( char[] array, JsonConfig jsonConfig ) { if( !addInstance( array ) ){ try{ return jsonConfig.getCycleDetectionStrategy() .handleRepeatedReferenceAsArray( array ); }catch( JSONException jsone ){ removeInstance( array ); fireErrorEvent( jsone, jsonConfig ); throw jsone; }catch( RuntimeException e ){ removeInstance( array ); JSONException jsone = new JSONException( e ); fireErrorEvent( jsone, jsonConfig ); throw jsone; } } fireArrayStartEvent( jsonConfig ); JSONArray jsonArray = new JSONArray(); for( int i = 0; i < array.length; i++ ){ Character c = new Character( array[i] ); jsonArray.addValue( c, jsonConfig ); fireElementAddedEvent( i, c, jsonConfig ); } removeInstance( array ); fireArrayEndEvent( jsonConfig ); return jsonArray; } /** * Construct a JSONArray from an double[].
* * @param array An double[] array. */ private static JSONArray _fromArray( double[] array, JsonConfig jsonConfig ) { if( !addInstance( array ) ){ try{ return jsonConfig.getCycleDetectionStrategy() .handleRepeatedReferenceAsArray( array ); }catch( JSONException jsone ){ removeInstance( array ); fireErrorEvent( jsone, jsonConfig ); throw jsone; }catch( RuntimeException e ){ removeInstance( array ); JSONException jsone = new JSONException( e ); fireErrorEvent( jsone, jsonConfig ); throw jsone; } } fireArrayStartEvent( jsonConfig ); JSONArray jsonArray = new JSONArray(); try{ for( int i = 0; i < array.length; i++ ){ Double d = new Double( array[i] ); JSONUtils.testValidity( d ); jsonArray.addValue( d, jsonConfig ); fireElementAddedEvent( i, d, jsonConfig ); } }catch( JSONException jsone ){ removeInstance( array ); fireErrorEvent( jsone, jsonConfig ); throw jsone; } removeInstance( array ); fireArrayEndEvent( jsonConfig ); return jsonArray; } /** * Construct a JSONArray from an Enum value. * * @param e A enum value. * @throws JSONException If there is a syntax error. */ private static JSONArray _fromArray( Enum e, JsonConfig jsonConfig ) { if( !addInstance( e ) ){ try{ return jsonConfig.getCycleDetectionStrategy() .handleRepeatedReferenceAsArray( e ); }catch( JSONException jsone ){ removeInstance( e ); fireErrorEvent( jsone, jsonConfig ); throw jsone; }catch( RuntimeException re ){ removeInstance( e ); JSONException jsone = new JSONException( re ); fireErrorEvent( jsone, jsonConfig ); throw jsone; } } fireArrayStartEvent( jsonConfig ); JSONArray jsonArray = new JSONArray(); if( e != null ){ jsonArray.addValue( e, jsonConfig ); fireElementAddedEvent( 0, jsonArray.get( 0 ), jsonConfig ); }else{ JSONException jsone = new JSONException( "enum value is null" ); removeInstance( e ); fireErrorEvent( jsone, jsonConfig ); throw jsone; } removeInstance( e ); fireArrayEndEvent( jsonConfig ); return jsonArray; } /** * Construct a JSONArray from an float[].
* * @param array An float[] array. */ private static JSONArray _fromArray( float[] array, JsonConfig jsonConfig ) { if( !addInstance( array ) ){ try{ return jsonConfig.getCycleDetectionStrategy() .handleRepeatedReferenceAsArray( array ); }catch( JSONException jsone ){ removeInstance( array ); fireErrorEvent( jsone, jsonConfig ); throw jsone; }catch( RuntimeException e ){ removeInstance( array ); JSONException jsone = new JSONException( e ); fireErrorEvent( jsone, jsonConfig ); throw jsone; } } fireArrayStartEvent( jsonConfig ); JSONArray jsonArray = new JSONArray(); try{ for( int i = 0; i < array.length; i++ ){ Float f = new Float( array[i] ); JSONUtils.testValidity( f ); jsonArray.addValue( f, jsonConfig ); fireElementAddedEvent( i, f, jsonConfig ); } }catch( JSONException jsone ){ removeInstance( array ); fireErrorEvent( jsone, jsonConfig ); throw jsone; } removeInstance( array ); fireArrayEndEvent( jsonConfig ); return jsonArray; } /** * Construct a JSONArray from an int[].
* * @param array An int[] array. */ private static JSONArray _fromArray( int[] array, JsonConfig jsonConfig ) { if( !addInstance( array ) ){ try{ return jsonConfig.getCycleDetectionStrategy() .handleRepeatedReferenceAsArray( array ); }catch( JSONException jsone ){ removeInstance( array ); fireErrorEvent( jsone, jsonConfig ); throw jsone; }catch( RuntimeException e ){ removeInstance( array ); JSONException jsone = new JSONException( e ); fireErrorEvent( jsone, jsonConfig ); throw jsone; } } fireArrayStartEvent( jsonConfig ); JSONArray jsonArray = new JSONArray(); for( int i = 0; i < array.length; i++ ){ Number n = new Integer( array[i] ); jsonArray.addValue( n, jsonConfig ); fireElementAddedEvent( i, n, jsonConfig ); } removeInstance( array ); fireArrayEndEvent( jsonConfig ); return jsonArray; } /** * Construct a JSONArray from an long[].
* * @param array An long[] array. */ private static JSONArray _fromArray( long[] array, JsonConfig jsonConfig ) { if( !addInstance( array ) ){ try{ return jsonConfig.getCycleDetectionStrategy() .handleRepeatedReferenceAsArray( array ); }catch( JSONException jsone ){ removeInstance( array ); fireErrorEvent( jsone, jsonConfig ); throw jsone; }catch( RuntimeException e ){ removeInstance( array ); JSONException jsone = new JSONException( e ); fireErrorEvent( jsone, jsonConfig ); throw jsone; } } fireArrayStartEvent( jsonConfig ); JSONArray jsonArray = new JSONArray(); for( int i = 0; i < array.length; i++ ){ Number n = JSONUtils.transformNumber( new Long( array[i] ) ); jsonArray.addValue( n, jsonConfig ); fireElementAddedEvent( i, n, jsonConfig ); } removeInstance( array ); fireArrayEndEvent( jsonConfig ); return jsonArray; } // ------------------------------------------------------ private static JSONArray _fromArray( Object[] array, JsonConfig jsonConfig ) { if( !addInstance( array ) ){ try{ return jsonConfig.getCycleDetectionStrategy() .handleRepeatedReferenceAsArray( array ); }catch( JSONException jsone ){ removeInstance( array ); fireErrorEvent( jsone, jsonConfig ); throw jsone; }catch( RuntimeException e ){ removeInstance( array ); JSONException jsone = new JSONException( e ); fireErrorEvent( jsone, jsonConfig ); throw jsone; } } fireArrayStartEvent( jsonConfig ); JSONArray jsonArray = new JSONArray(); try{ for( int i = 0; i < array.length; i++ ){ Object element = array[i]; jsonArray.addValue( element, jsonConfig ); fireElementAddedEvent( i, jsonArray.get( i ), jsonConfig ); } }catch( JSONException jsone ){ removeInstance( array ); fireErrorEvent( jsone, jsonConfig ); throw jsone; }catch( RuntimeException e ){ removeInstance( array ); JSONException jsone = new JSONException( e ); fireErrorEvent( jsone, jsonConfig ); throw jsone; } removeInstance( array ); fireArrayEndEvent( jsonConfig ); return jsonArray; } /** * Construct a JSONArray from an short[].
* * @param array An short[] array. */ private static JSONArray _fromArray( short[] array, JsonConfig jsonConfig ) { if( !addInstance( array ) ){ try{ return jsonConfig.getCycleDetectionStrategy() .handleRepeatedReferenceAsArray( array ); }catch( JSONException jsone ){ removeInstance( array ); fireErrorEvent( jsone, jsonConfig ); throw jsone; }catch( RuntimeException e ){ removeInstance( array ); JSONException jsone = new JSONException( e ); fireErrorEvent( jsone, jsonConfig ); throw jsone; } } fireArrayStartEvent( jsonConfig ); JSONArray jsonArray = new JSONArray(); for( int i = 0; i < array.length; i++ ){ Number n = JSONUtils.transformNumber( new Short( array[i] ) ); jsonArray.addValue( n, jsonConfig ); fireElementAddedEvent( i, n, jsonConfig ); } removeInstance( array ); fireArrayEndEvent( jsonConfig ); return jsonArray; } private static JSONArray _fromCollection( Collection collection, JsonConfig jsonConfig ) { if( !addInstance( collection ) ){ try{ return jsonConfig.getCycleDetectionStrategy() .handleRepeatedReferenceAsArray( collection ); }catch( JSONException jsone ){ removeInstance( collection ); fireErrorEvent( jsone, jsonConfig ); throw jsone; }catch( RuntimeException e ){ removeInstance( collection ); JSONException jsone = new JSONException( e ); fireErrorEvent( jsone, jsonConfig ); throw jsone; } } fireArrayStartEvent( jsonConfig ); JSONArray jsonArray = new JSONArray(); try{ int i = 0; for( Iterator elements = collection.iterator(); elements.hasNext(); ){ Object element = elements.next(); jsonArray.addValue( element, jsonConfig ); fireElementAddedEvent( i, jsonArray.get( i++ ), jsonConfig ); } }catch( JSONException jsone ){ removeInstance( collection ); fireErrorEvent( jsone, jsonConfig ); throw jsone; }catch( RuntimeException e ){ removeInstance( collection ); JSONException jsone = new JSONException( e ); fireErrorEvent( jsone, jsonConfig ); throw jsone; } removeInstance( collection ); fireArrayEndEvent( jsonConfig ); return jsonArray; } private static JSONArray _fromJSONArray( JSONArray array, JsonConfig jsonConfig ) { if( !addInstance( array ) ){ try{ return jsonConfig.getCycleDetectionStrategy() .handleRepeatedReferenceAsArray( array ); }catch( JSONException jsone ){ removeInstance( array ); fireErrorEvent( jsone, jsonConfig ); throw jsone; }catch( RuntimeException e ){ removeInstance( array ); JSONException jsone = new JSONException( e ); fireErrorEvent( jsone, jsonConfig ); throw jsone; } } fireArrayStartEvent( jsonConfig ); JSONArray jsonArray = new JSONArray(); int index = 0; for( Iterator elements = array.iterator(); elements.hasNext(); ){ Object element = elements.next(); jsonArray.addValue( element, jsonConfig ); fireElementAddedEvent( index++, element, jsonConfig ); } removeInstance( array ); fireArrayEndEvent( jsonConfig ); return jsonArray; } private static JSONArray _fromJSONString( JSONString string, JsonConfig jsonConfig ) { return _fromJSONTokener( new JSONTokener( string.toJSONString() ), jsonConfig ); } private static JSONArray _fromJSONTokener( JSONTokener tokener, JsonConfig jsonConfig ) { JSONArray jsonArray = new JSONArray(); int index = 0; try{ if( tokener.nextClean() != '[' ){ throw tokener.syntaxError( "A JSONArray text must start with '['" ); } fireArrayStartEvent( jsonConfig ); if( tokener.nextClean() == ']' ){ fireArrayEndEvent( jsonConfig ); return jsonArray; } tokener.back(); for( ;; ){ if( tokener.nextClean() == ',' ){ tokener.back(); jsonArray.elements.add( JSONNull.getInstance() ); fireElementAddedEvent( index, jsonArray.get( index++ ), jsonConfig ); }else{ tokener.back(); Object v = tokener.nextValue( jsonConfig ); if( !JSONUtils.isFunctionHeader( v ) ){ if( v instanceof String && JSONUtils.mayBeJSON( (String) v ) ){ jsonArray.addValue( JSONUtils.DOUBLE_QUOTE + v + JSONUtils.DOUBLE_QUOTE, jsonConfig ); }else{ jsonArray.addValue( v, jsonConfig ); } fireElementAddedEvent( index, jsonArray.get( index++ ), jsonConfig ); }else{ // read params if any String params = JSONUtils.getFunctionParams( (String) v ); // read function text int i = 0; StringBuffer sb = new StringBuffer(); for( ;; ){ char ch = tokener.next(); if( ch == 0 ){ break; } if( ch == '{' ){ i++; } if( ch == '}' ){ i--; } sb.append( ch ); if( i == 0 ){ break; } } if( i != 0 ){ throw tokener.syntaxError( "Unbalanced '{' or '}' on prop: " + v ); } // trim '{' at start and '}' at end String text = sb.toString(); text = text.substring( 1, text.length() - 1 ) .trim(); jsonArray.addValue( new JSONFunction( (params != null) ? StringUtils.split( params, "," ) : null, text ), jsonConfig ); fireElementAddedEvent( index, jsonArray.get( index++ ), jsonConfig ); } } switch( tokener.nextClean() ){ case ';': case ',': if( tokener.nextClean() == ']' ){ fireArrayEndEvent( jsonConfig ); return jsonArray; } tokener.back(); break; case ']': fireArrayEndEvent( jsonConfig ); return jsonArray; default: throw tokener.syntaxError( "Expected a ',' or ']'" ); } } }catch( JSONException jsone ){ fireErrorEvent( jsone, jsonConfig ); throw jsone; } } private static JSONArray _fromString( String string, JsonConfig jsonConfig ) { return _fromJSONTokener( new JSONTokener( string ), jsonConfig ); } private static void processArrayDimensions( JSONArray jsonArray, List dims, int index ) { if( dims.size() <= index ){ dims.add( new Integer( jsonArray.size() ) ); }else{ int i = ((Integer) dims.get( index )).intValue(); if( jsonArray.size() > i ){ dims.set( index, new Integer( jsonArray.size() ) ); } } for( Iterator i = jsonArray.iterator(); i.hasNext(); ){ Object item = i.next(); if( item instanceof JSONArray ){ processArrayDimensions( (JSONArray) item, dims, index + 1 ); } } } // ------------------------------------------------------ /** * The List where the JSONArray's properties are kept. */ private List elements; /** * A flag for XML processing. */ private boolean expandElements; /** * Construct an empty JSONArray. */ public JSONArray() { this.elements = new ArrayList(); } public void add( int index, Object value ) { add( index, value, new JsonConfig() ); } public void add( int index, Object value, JsonConfig jsonConfig ) { this.elements.add( index, processValue( value, jsonConfig ) ); } public boolean add( Object value ) { return add( value, new JsonConfig() ); } public boolean add( Object value, JsonConfig jsonConfig ) { element( value, jsonConfig ); return true; } public boolean addAll( Collection collection ) { return addAll( collection, new JsonConfig() ); } public boolean addAll( Collection collection, JsonConfig jsonConfig ) { if( collection == null || collection.size() == 0 ){ return false; } for( Iterator i = collection.iterator(); i.hasNext(); ){ element( i.next(), jsonConfig ); } return true; } public boolean addAll( int index, Collection collection ) { return addAll( index, collection, new JsonConfig() ); } public boolean addAll( int index, Collection collection, JsonConfig jsonConfig ) { if( collection == null || collection.size() == 0 ){ return false; } int offset = 0; for( Iterator i = collection.iterator(); i.hasNext(); ){ this.elements.add( index + (offset++), processValue( i.next(), jsonConfig ) ); } return true; } public void clear() { elements.clear(); } public int compareTo( Object obj ) { if( obj != null && (obj instanceof JSONArray) ){ JSONArray other = (JSONArray) obj; int size1 = size(); int size2 = other.size(); if( size1 < size2 ){ return -1; }else if( size1 > size2 ){ return 1; }else if( this.equals( other ) ){ return 0; } } return -1; } public boolean contains( Object o ) { return contains( o, new JsonConfig() ); } public boolean contains( Object o, JsonConfig jsonConfig ) { return elements.contains( processValue( o, jsonConfig ) ); } public boolean containsAll( Collection collection ) { return containsAll( collection, new JsonConfig() ); } public boolean containsAll( Collection collection, JsonConfig jsonConfig ) { return elements.containsAll( fromObject( collection, jsonConfig ) ); } /** * Remove an element, if present. * * @param index the index of the element. * @return this. */ public JSONArray discard( int index ) { elements.remove( index ); return this; } /** * Remove an element, if present. * * @param index the element. * @return this. */ public JSONArray discard( Object o ) { elements.remove( o ); return this; } /** * Append a boolean value. This increases the array's length by one. * * @param value A boolean value. * @return this. */ public JSONArray element( boolean value ) { return element( value ? Boolean.TRUE : Boolean.FALSE ); } /** * Append a value in the JSONArray, where the value will be a JSONArray which * is produced from a Collection. * * @param value A Collection value. * @return this. */ public JSONArray element( Collection value ) { return element( value, new JsonConfig() ); } /** * Append a value in the JSONArray, where the value will be a JSONArray which * is produced from a Collection. * * @param value A Collection value. * @return this. */ public JSONArray element( Collection value, JsonConfig jsonConfig ) { if( value instanceof JSONArray ){ elements.add( value ); return this; }else{ return element( _fromCollection( value, jsonConfig ) ); } } /** * Append a double value. This increases the array's length by one. * * @param value A double value. * @throws JSONException if the value is not finite. * @return this. */ public JSONArray element( double value ) { Double d = new Double( value ); JSONUtils.testValidity( d ); return element( d ); } /** * Append an int value. This increases the array's length by one. * * @param value An int value. * @return this. */ public JSONArray element( int value ) { return element( new Integer( value ) ); } /** * Put or replace a boolean 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 A boolean value. * @return this. * @throws JSONException If the index is negative. */ public JSONArray element( int index, boolean value ) { return element( index, value ? Boolean.TRUE : Boolean.FALSE ); } /** * Put a value in the JSONArray, where the value will be a JSONArray which is * produced from a Collection. * * @param index The subscript. * @param value A Collection value. * @return this. * @throws JSONException If the index is negative or if the value is not * finite. */ public JSONArray element( int index, Collection value ) { return element( index, value, new JsonConfig() ); } /** * Put a value in the JSONArray, where the value will be a JSONArray which is * produced from a Collection. * * @param index The subscript. * @param value A Collection value. * @return this. * @throws JSONException If the index is negative or if the value is not * finite. */ public JSONArray element( int index, Collection value, JsonConfig jsonConfig ) { if( value instanceof JSONArray ){ if( index < 0 ){ throw new JSONException( "JSONArray[" + index + "] not found." ); } if( index < size() ){ elements.set( index, value ); }else{ while( index != size() ){ element( JSONNull.getInstance() ); } element( value, jsonConfig ); } return this; }else{ return element( index, _fromCollection( value, jsonConfig ) ); } } /** * Put or replace a double value. 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 A double value. * @return this. * @throws JSONException If the index is negative or if the value is not * finite. */ public JSONArray element( int index, double value ) { return element( index, new Double( value ) ); } /** * Put or replace an int value. 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 An int value. * @return this. * @throws JSONException If the index is negative. */ public JSONArray element( int index, int value ) { return element( index, new Integer( value ) ); } /** * Put or replace a long value. 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 A long value. * @return this. * @throws JSONException If the index is negative. */ public JSONArray element( int index, long value ) { return element( index, new Long( value ) ); } /** * Put a value in the JSONArray, where the value will be a JSONObject which * is produced from a Map. * * @param index The subscript. * @param value The Map value. * @return this. * @throws JSONException If the index is negative or if the the value is an * invalid number. */ public JSONArray element( int index, Map value ) { return element( index, value, new JsonConfig() ); } /** * Put a value in the JSONArray, where the value will be a JSONObject which * is produced from a Map. * * @param index The subscript. * @param value The Map value. * @return this. * @throws JSONException If the index is negative or if the the value is an * invalid number. */ public JSONArray element( int index, Map value, JsonConfig jsonConfig ) { if( value instanceof JSONObject ){ if( index < 0 ){ throw new JSONException( "JSONArray[" + index + "] not found." ); } if( index < size() ){ elements.set( index, value ); }else{ while( index != size() ){ element( JSONNull.getInstance() ); } element( value, jsonConfig ); } return this; }else{ return element( index, JSONObject.fromObject( value, jsonConfig ) ); } } /** * 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 An object value. The value should be a Boolean, Double, * Integer, JSONArray, JSONObject, JSONFunction, Long, String, * JSONString or the JSONNull object. * @return this. * @throws JSONException If the index is negative or if the the value is an * invalid number. */ public JSONArray element( int index, Object value ) { return element( index, value, new JsonConfig() ); } /** * 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 An object value. The value should be a Boolean, Double, * Integer, JSONArray, JSONObject, JSONFunction, Long, String, * JSONString or the JSONNull object. * @return this. * @throws JSONException If the index is negative or if the the value is an * invalid number. */ public JSONArray element( int index, Object value, JsonConfig jsonConfig ) { JSONUtils.testValidity( value ); if( index < 0 ){ throw new JSONException( "JSONArray[" + index + "] not found." ); } if( index < size() ){ this.elements.set( index, processValue( value, jsonConfig ) ); }else{ while( index != size() ){ element( JSONNull.getInstance() ); } element( value, jsonConfig ); } return this; } /** * Put or replace a String 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.
* The string may be a valid JSON formatted string, in tha case, it will be * transformed to a JSONArray, JSONObject or JSONNull. * * @param index The subscript. * @param value A String value. * @return this. * @throws JSONException If the index is negative or if the the value is an * invalid number. */ public JSONArray element( int index, String value ) { return element( index, value, new JsonConfig() ); } /** * Put or replace a String 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.
* The string may be a valid JSON formatted string, in tha case, it will be * transformed to a JSONArray, JSONObject or JSONNull. * * @param index The subscript. * @param value A String value. * @return this. * @throws JSONException If the index is negative or if the the value is an * invalid number. */ public JSONArray element( int index, String value, JsonConfig jsonConfig ) { if( index < 0 ){ throw new JSONException( "JSONArray[" + index + "] not found." ); } if( index < size() ){ if( value == null ){ this.elements.set( index, "" ); }else if( JSONUtils.mayBeJSON( value ) ){ try{ this.elements.set( index, JSONSerializer.toJSON( value, jsonConfig ) ); }catch( JSONException jsone ){ this.elements.set( index, JSONUtils.stripQuotes( value ) ); } }else{ this.elements.set( index, JSONUtils.stripQuotes( value ) ); } }else{ while( index != size() ){ element( JSONNull.getInstance() ); } element( value, jsonConfig ); } return this; } /** * Append an JSON value. This increases the array's length by one. * * @param value An JSON value. * @return this. */ public JSONArray element( JSONNull value ) { this.elements.add( value ); return this; } /** * Append an JSON value. This increases the array's length by one. * * @param value An JSON value. * @return this. */ public JSONArray element( JSONObject value ) { this.elements.add( value ); return this; } /** * Append an long value. This increases the array's length by one. * * @param value A long value. * @return this. */ public JSONArray element( long value ) { return element( JSONUtils.transformNumber( new Long( value ) ) ); } /** * Put a value in the JSONArray, where the value will be a JSONObject which * is produced from a Map. * * @param value A Map value. * @return this. */ public JSONArray element( Map value ) { return element( value, new JsonConfig() ); } /** * Put a value in the JSONArray, where the value will be a JSONObject which * is produced from a Map. * * @param value A Map value. * @return this. */ public JSONArray element( Map value, JsonConfig jsonConfig ) { if( value instanceof JSONObject ){ elements.add( value ); return this; }else{ return element( JSONObject.fromObject( value, jsonConfig ) ); } } /** * 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, JSONFunction, Long, String, * JSONString or the JSONNull object. * @return this. */ public JSONArray element( Object value ) { return element( value, new JsonConfig() ); } /** * 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, JSONFunction, Long, String, * JSONString or the JSONNull object. * @return this. */ public JSONArray element( Object value, JsonConfig jsonConfig ) { return addValue( value, jsonConfig ); } /** * Append a String value. This increases the array's length by one.
* The string may be a valid JSON formatted string, in tha case, it will be * transformed to a JSONArray, JSONObject or JSONNull. * * @param value A String value. * @return this. */ public JSONArray element( String value ) { return element( value, new JsonConfig() ); } /** * Append a String value. This increases the array's length by one.
* The string may be a valid JSON formatted string, in tha case, it will be * transformed to a JSONArray, JSONObject or JSONNull. * * @param value A String value. * @return this. */ public JSONArray element( String value, JsonConfig jsonConfig ) { if( value == null ) { this.elements.add(""); } else if( JSONUtils.hasQuotes( value )) { this.elements.add(value); } else if( JSONNull.getInstance().equals( value )) { this.elements.add( JSONNull.getInstance() ); } else if( JSONUtils.isJsonKeyword(value,jsonConfig)) { if( jsonConfig.isJavascriptCompliant() && "undefined".equals( value )){ this.elements.add( JSONNull.getInstance() ); }else{ this.elements.add(value); } } else if( JSONUtils.mayBeJSON( value ) ){ try{ this.elements.add( JSONSerializer.toJSON( value, jsonConfig ) ); }catch( JSONException jsone ){ this.elements.add( value ); } } else { this.elements.add(value); } return this; } public boolean equals( Object obj ) { if( obj == this ){ return true; } if( obj == null ){ return false; } if( !(obj instanceof JSONArray) ){ return false; } JSONArray other = (JSONArray) obj; if( other.size() != size() ){ return false; } int max = size(); for( int i = 0; i < max; i++ ){ Object o1 = get( i ); Object o2 = other.get( i ); // handle nulls if( JSONNull.getInstance() .equals( o1 ) ){ if( JSONNull.getInstance() .equals( o2 ) ){ continue; }else{ return false; } }else{ if( JSONNull.getInstance() .equals( o2 ) ){ return false; } } if( o1 instanceof JSONArray && o2 instanceof JSONArray ){ JSONArray e = (JSONArray) o1; JSONArray a = (JSONArray) o2; if( !a.equals( e ) ){ return false; } }else{ if( o1 instanceof String && o2 instanceof JSONFunction ){ if( !o1.equals( String.valueOf( o2 ) ) ){ return false; } }else if( o1 instanceof JSONFunction && o2 instanceof String ){ if( !o2.equals( String.valueOf( o1 ) ) ){ return false; } }else if( o1 instanceof JSONObject && o2 instanceof JSONObject ){ if( !o1.equals( o2 ) ){ return false; } }else if( o1 instanceof JSONArray && o2 instanceof JSONArray ){ if( !o1.equals( o2 ) ){ return false; } }else if( o1 instanceof JSONFunction && o2 instanceof JSONFunction ){ if( !o1.equals( o2 ) ){ return false; } }else{ if( o1 instanceof String ){ if( !o1.equals( String.valueOf( o2 ) ) ){ return false; } }else if( o2 instanceof String ){ if( !o2.equals( String.valueOf( o1 ) ) ){ return false; } }else{ Morpher m1 = JSONUtils.getMorpherRegistry() .getMorpherFor( o1.getClass() ); Morpher m2 = JSONUtils.getMorpherRegistry() .getMorpherFor( o2.getClass() ); if( m1 != null && m1 != IdentityObjectMorpher.getInstance() ){ if( !o1.equals( JSONUtils.getMorpherRegistry() .morph( o1.getClass(), o2 ) ) ){ return false; } }else if( m2 != null && m2 != IdentityObjectMorpher.getInstance() ){ if( !JSONUtils.getMorpherRegistry() .morph( o1.getClass(), o1 ) .equals( o2 ) ){ return false; } }else{ if( !o1.equals( o2 ) ){ return false; } } } } } } return true; } /** * Get the object value associated with an index. * * @param index The index must be between 0 and size() - 1. * @return An object value. */ public Object get( int index ) { /* * Object o = opt( index ); if( o == null ){ throw new JSONException( * "JSONArray[" + index + "] not found." ); } return o; */ return this.elements.get( index ); } /** * 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 size() - 1. * @return The truth. * @throws JSONException If there is no value for the index or if the value * is not convertable to boolean. */ public boolean getBoolean( int index ) { Object o = get( index ); if( o != null ){ if( o.equals( Boolean.FALSE ) || (o instanceof String && ((String) o).equalsIgnoreCase( "false" )) ){ return false; }else if( o.equals( Boolean.TRUE ) || (o instanceof String && ((String) o).equalsIgnoreCase( "true" )) ){ return true; } } throw new JSONException( "JSONArray[" + index + "] is not a Boolean." ); } /** * Get the double value associated with an index. * * @param index The index must be between 0 and size() - 1. * @return The value. * @throws JSONException If the key is not found or if the value cannot be * converted to a number. */ public double getDouble( int index ) { Object o = get( index ); if( o != null ){ try{ return o instanceof Number ? ((Number) o).doubleValue() : Double.parseDouble( (String) o ); }catch( Exception e ){ throw new JSONException( "JSONArray[" + index + "] is not a number." ); } } throw new JSONException( "JSONArray[" + index + "] is not a number." ); } /** * Get the int value associated with an index. * * @param index The index must be between 0 and size() - 1. * @return The value. * @throws JSONException 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 ) { Object o = get( index ); if( o != null ){ return o instanceof Number ? ((Number) o).intValue() : (int) getDouble( index ); } throw new JSONException( "JSONArray[" + index + "] is not a number." ); } /** * Get the JSONArray associated with an index. * * @param index The index must be between 0 and size() - 1. * @return A JSONArray value. * @throws JSONException 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 != null && o instanceof JSONArray ){ return (JSONArray) o; } throw new JSONException( "JSONArray[" + index + "] is not a JSONArray." ); } /** * Get the JSONObject associated with an index. * * @param index subscript * @return A JSONObject value. * @throws JSONException 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( JSONNull.getInstance() .equals( o ) ){ return new JSONObject( true ); }else if( o instanceof JSONObject ){ return (JSONObject) o; } throw new JSONException( "JSONArray[" + index + "] is not a JSONObject." ); } /** * Get the long value associated with an index. * * @param index The index must be between 0 and size() - 1. * @return The value. * @throws JSONException If the key is not found or if the value cannot be * converted to a number. */ public long getLong( int index ) { Object o = get( index ); if( o != null ){ return o instanceof Number ? ((Number) o).longValue() : (long) getDouble( index ); } throw new JSONException( "JSONArray[" + index + "] is not a number." ); } /** * Get the string associated with an index. * * @param index The index must be between 0 and size() - 1. * @return A string value. * @throws JSONException If there is no value for the index. */ public String getString( int index ) { Object o = get( index ); if( o != null ){ return o.toString(); } throw new JSONException( "JSONArray[" + index + "] not found." ); } public int hashCode() { int hashcode = 29; for( Iterator e = elements.iterator(); e.hasNext(); ){ Object element = e.next(); hashcode += JSONUtils.hashCode( element ); } return hashcode; } public int indexOf( Object o ) { return elements.indexOf( o ); } public boolean isArray() { return true; } public boolean isEmpty() { return this.elements.isEmpty(); } public boolean isExpandElements() { return expandElements; } /** * Returns an Iterator for this JSONArray */ public Iterator iterator() { return new JSONArrayListIterator(); } /** * Make a string from the contents of this JSONArray. The * separator 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 JSONException If the array contains an invalid number. */ public String join( String separator ) { return join( separator, false ); } /** * Make a string from the contents of this JSONArray. The * separator 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 JSONException If the array contains an invalid number. */ public String join( String separator, boolean stripQuotes ) { int len = size(); StringBuffer sb = new StringBuffer(); for( int i = 0; i < len; i += 1 ){ if( i > 0 ){ sb.append( separator ); } String value = JSONUtils.valueToString( this.elements.get( i ) ); sb.append( stripQuotes ? JSONUtils.stripQuotes( value ) : value ); } return sb.toString(); } public int lastIndexOf( Object o ) { return elements.lastIndexOf( o ); } public ListIterator listIterator() { return listIterator( 0 ); } public ListIterator listIterator( int index ) { if( index < 0 || index > size() ) throw new IndexOutOfBoundsException( "Index: " + index ); return new JSONArrayListIterator( index ); } /** * Get the optional object value associated with an index. * * @param index The index must be between 0 and size() - 1. * @return An object value, or null if there is no object at that index. */ public Object opt( int index ) { return (index < 0 || index >= size()) ? null : this.elements.get( index ); } /** * Get the optional boolean value associated with an index. It returns false * if there is no value at that index, or if the value is not Boolean.TRUE or * the String "true". * * @param index The index must be between 0 and size() - 1. * @return The truth. */ public boolean optBoolean( int index ) { return optBoolean( index, false ); } /** * Get the optional boolean value associated with an index. It returns the * defaultValue if there is no value at that index or if it is not a Boolean * or the String "true" or "false" (case insensitive). * * @param index The index must be between 0 and size() - 1. * @param defaultValue A boolean default. * @return The truth. */ public boolean optBoolean( int index, boolean defaultValue ) { try{ return getBoolean( index ); }catch( Exception e ){ return defaultValue; } } /** * Get the optional double value associated with an index. NaN is returned if * there is no value for the index, or if the value is not a number and * cannot be converted to a number. * * @param index The index must be between 0 and size() - 1. * @return The value. */ public double optDouble( int index ) { return optDouble( index, Double.NaN ); } /** * Get the optional double value associated with an index. The defaultValue * is returned if there is no value for the index, or if the value is not a * number and cannot be converted to a number. * * @param index subscript * @param defaultValue The default value. * @return The value. */ public double optDouble( int index, double defaultValue ) { try{ return getDouble( index ); }catch( Exception e ){ return defaultValue; } } /** * Get the optional int value associated with an index. Zero is returned if * there is no value for the index, or if the value is not a number and * cannot be converted to a number. * * @param index The index must be between 0 and size() - 1. * @return The value. */ public int optInt( int index ) { return optInt( index, 0 ); } /** * Get the optional int value associated with an index. The defaultValue is * returned if there is no value for the index, or if the value is not a * number and cannot be converted to a number. * * @param index The index must be between 0 and size() - 1. * @param defaultValue The default value. * @return The value. */ public int optInt( int index, int defaultValue ) { try{ return getInt( index ); }catch( Exception e ){ return defaultValue; } } /** * Get the optional JSONArray associated with an index. * * @param index subscript * @return A JSONArray value, or null if the index has no value, or if the * value is not a JSONArray. */ public JSONArray optJSONArray( int index ) { Object o = opt( index ); return o instanceof JSONArray ? (JSONArray) o : null; } /** * Get the optional JSONObject associated with an index. Null is returned if * the key is not found, or null if the index has no value, or if the value * is not a JSONObject. * * @param index The index must be between 0 and size() - 1. * @return A JSONObject value. */ public JSONObject optJSONObject( int index ) { Object o = opt( index ); return o instanceof JSONObject ? (JSONObject) o : null; } /** * Get the optional long value associated with an index. Zero is returned if * there is no value for the index, or if the value is not a number and * cannot be converted to a number. * * @param index The index must be between 0 and size() - 1. * @return The value. */ public long optLong( int index ) { return optLong( index, 0 ); } /** * Get the optional long value associated with an index. The defaultValue is * returned if there is no value for the index, or if the value is not a * number and cannot be converted to a number. * * @param index The index must be between 0 and size() - 1. * @param defaultValue The default value. * @return The value. */ public long optLong( int index, long defaultValue ) { try{ return getLong( index ); }catch( Exception e ){ return defaultValue; } } /** * Get the optional string value associated with an index. It returns an * empty string if there is no value at that index. If the value is not a * string and is not null, then it is coverted to a string. * * @param index The index must be between 0 and size() - 1. * @return A String value. */ public String optString( int index ) { return optString( index, "" ); } /** * Get the optional string associated with an index. The defaultValue is * returned if the key is not found. * * @param index The index must be between 0 and size() - 1. * @param defaultValue The default value. * @return A String value. */ public String optString( int index, String defaultValue ) { Object o = opt( index ); return o != null ? o.toString() : defaultValue; } public Object remove( int index ) { return elements.remove( index ); } public boolean remove( Object o ) { return elements.remove( o ); } public boolean removeAll( Collection collection ) { return removeAll( collection, new JsonConfig() ); } public boolean removeAll( Collection collection, JsonConfig jsonConfig ) { return elements.removeAll( fromObject( collection, jsonConfig ) ); } public boolean retainAll( Collection collection ) { return retainAll( collection, new JsonConfig() ); } public boolean retainAll( Collection collection, JsonConfig jsonConfig ) { return elements.retainAll( fromObject( collection, jsonConfig ) ); } public Object set( int index, Object value ) { return set( index, value, new JsonConfig() ); } public Object set( int index, Object value, JsonConfig jsonConfig ) { Object previous = get( index ); element( index, value, jsonConfig ); return previous; } public void setExpandElements( boolean expandElements ) { this.expandElements = expandElements; } /** * Get the number of elements in the JSONArray, included nulls. * * @return The length (or size). */ public int size() { return this.elements.size(); } public List subList( int fromIndex, int toIndex ) { return elements.subList( fromIndex, toIndex ); } /** * Produce an Object[] with the contents of this JSONArray. */ public Object[] toArray() { return this.elements.toArray(); } public Object[] toArray( Object[] array ) { return elements.toArray( array ); } /** * Produce a JSONObject by combining a JSONArray of names with the values of * this JSONArray. * * @param names A JSONArray containing a list of key strings. These will be * paired with the values. * @return A JSONObject, or null if there are no names or if this JSONArray * has no values. * @throws JSONException If any of the names are null. */ public JSONObject toJSONObject( JSONArray names ) { if( names == null || names.size() == 0 || size() == 0 ){ return null; } JSONObject jo = new JSONObject(); for( int i = 0; i < names.size(); i++ ){ jo.element( names.getString( i ), this.opt( i ) ); } return jo; } /** * 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. *

* Warning: This method assumes that the data structure is acyclical. * * @return a printable, displayable, transmittable representation of the * array. */ public String toString() { try{ return '[' + join( "," ) + ']'; }catch( Exception e ){ return null; } } /** * Make a prettyprinted JSON text of this JSONArray. Warning: This method * assumes that the data structure is acyclical. * * @param indentFactor The number of spaces to add to each level of * indentation. * @return a printable, displayable, transmittable representation of the * object, beginning with [ (left * bracket) and ending with ] (right * bracket). * @throws JSONException */ public String toString( int indentFactor ) { if( indentFactor == 0 ){ return this.toString(); } return toString( indentFactor, 0 ); } /** * Make a prettyprinted JSON text of this JSONArray. Warning: This method * assumes that the data structure is acyclical. * * @param indentFactor The number of spaces to add to each level of * indentation. * @param indent The indention of the top level. * @return a printable, displayable, transmittable representation of the * array. * @throws JSONException */ public String toString( int indentFactor, int indent ) { int len = size(); if( len == 0 ){ return "[]"; } if( indentFactor == 0 ){ return this.toString(); } int i; StringBuffer sb = new StringBuffer( "[" ); if( len == 1 ){ sb.append( JSONUtils.valueToString( this.elements.get( 0 ), indentFactor, indent ) ); }else{ int newindent = indent + indentFactor; sb.append( '\n' ); for( i = 0; i < len; i += 1 ){ if( i > 0 ){ sb.append( ",\n" ); } for( int j = 0; j < newindent; j += 1 ){ sb.append( ' ' ); } sb.append( JSONUtils.valueToString( this.elements.get( i ), indentFactor, newindent ) ); } sb.append( '\n' ); for( i = 0; i < indent; i += 1 ){ sb.append( ' ' ); } for( i = 0; i < indent; i += 1 ){ sb.insert( 0, ' ' ); } } sb.append( ']' ); return sb.toString(); } /** * Write the contents of the JSONArray as JSON text to a writer. For * compactness, no whitespace is added. *

* Warning: This method assumes that the data structure is acyclical. * * @return The writer. * @throws JSONException */ public Writer write( Writer writer ) { try{ boolean b = false; int len = size(); writer.write( '[' ); for( int i = 0; i < len; i += 1 ){ if( b ){ writer.write( ',' ); } Object v = this.elements.get( i ); if( v instanceof JSONObject ){ ((JSONObject) v).write( writer ); }else if( v instanceof JSONArray ){ ((JSONArray) v).write( writer ); }else{ writer.write( JSONUtils.valueToString( v ) ); } b = true; } writer.write( ']' ); return writer; }catch( IOException e ){ throw new JSONException( e ); } } /** * Adds a String without performing any conversion on it. */ protected JSONArray addString( String str ) { if( str != null ){ elements.add( str ); } return this; } /** * 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, JSONFunction, Long, String, * JSONString or the JSONNull object. * @return this. */ private JSONArray _addValue( Object value, JsonConfig jsonConfig ) { this.elements.add(value); return this; } protected Object _processValue( Object value, JsonConfig jsonConfig ) { if( value instanceof JSONTokener ) { return _fromJSONTokener( (JSONTokener) value, jsonConfig ); }else if( value != null && Enum.class.isAssignableFrom( value.getClass() ) ){ return ((Enum) value).name(); }else if( value instanceof Annotation || (value != null && value.getClass() .isAnnotation()) ){ throw new JSONException( "Unsupported type" ); } return super._processValue( value, jsonConfig ); } /** * 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, JSONFunction, Long, String, * JSONString or the JSONNull object. * @return this. */ private JSONArray addValue( Object value, JsonConfig jsonConfig ) { return _addValue( processValue( value, jsonConfig ), jsonConfig ); } private Object processValue( Object value, JsonConfig jsonConfig ) { if( value != null ){ JsonValueProcessor jsonValueProcessor = jsonConfig.findJsonValueProcessor( value.getClass() ); if( jsonValueProcessor != null ){ value = jsonValueProcessor.processArrayValue( value, jsonConfig ); if( !JsonVerifier.isValidJsonValue( value ) ){ throw new JSONException( "Value is not a valid JSON value. " + value ); } } } return _processValue( value, jsonConfig ); } private class JSONArrayListIterator implements ListIterator { int currentIndex = 0; int lastIndex = -1; JSONArrayListIterator() { } JSONArrayListIterator( int index ) { currentIndex = index; } public boolean hasNext() { return currentIndex != size(); } public Object next() { try { Object next = get( currentIndex ); lastIndex = currentIndex++; return next; } catch( IndexOutOfBoundsException e ) { throw new NoSuchElementException(); } } public void remove() { if( lastIndex == -1 ) throw new IllegalStateException(); try { JSONArray.this.remove( lastIndex ); if( lastIndex < currentIndex ){ currentIndex--; } lastIndex = -1; } catch( IndexOutOfBoundsException e ) { throw new ConcurrentModificationException(); } } public boolean hasPrevious() { return currentIndex != 0; } public Object previous() { try { int index = currentIndex - 1; Object previous = get( index ); lastIndex = currentIndex = index; return previous; } catch( IndexOutOfBoundsException e ) { throw new NoSuchElementException(); } } public int nextIndex() { return currentIndex; } public int previousIndex() { return currentIndex - 1; } public void set( Object obj ) { if( lastIndex == -1 ){ throw new IllegalStateException(); } try { JSONArray.this.set( lastIndex, obj ); } catch( IndexOutOfBoundsException ex ) { throw new ConcurrentModificationException(); } } public void add( Object obj ) { try { JSONArray.this.add( currentIndex++, obj ); lastIndex = -1; } catch( IndexOutOfBoundsException ex ) { throw new ConcurrentModificationException(); } } } } json-lib-2.3/net/sf/json/JSONNull.java0000644000175000017500000000512111226107170016471 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json; import java.io.IOException; import java.io.Writer; /** * JSONNull is equivalent to the value that JavaScript calls null, whilst Java's * null is equivalent to the value that JavaScript calls undefined. * * @author JSON.org */ public final class JSONNull implements JSON { /** singleton instance */ private static JSONNull instance; static{ instance = new JSONNull(); } /** * Returns the singleton instance of JSONNull */ public static JSONNull getInstance() { return instance; } private JSONNull() { } /** * A Null object is equal to the null value and to itself. * * @param object An object to test for nullness. * @return true if the object parameter is the JSONObject.NULL object or * null. */ public boolean equals( Object object ) { return object == null || object == this || object == instance || (object instanceof JSONObject && ((JSONObject) object).isNullObject()) || "null".equals( object ); } public int hashCode() { return 37 + "null".hashCode(); } public boolean isArray() { return false; } public boolean isEmpty() { throw new JSONException( "Object is null" ); } public int size() { throw new JSONException( "Object is null" ); } /** * Get the "null" string value. * * @return The string "null". */ public String toString() { return "null"; } public String toString( int indentFactor ) { return toString(); } public String toString( int indentFactor, int indent ) { StringBuffer sb = new StringBuffer(); for( int i = 0; i < indent; i += 1 ){ sb.append( ' ' ); } sb.append( toString() ); return sb.toString(); } public Writer write( Writer writer ) { try{ writer.write( toString() ); return writer; }catch( IOException e ){ throw new JSONException( e ); } } }json-lib-2.3/net/sf/json/groovy/0000755000175000017500000000000011226107170015550 5ustar mkochmkochjson-lib-2.3/net/sf/json/groovy/JsonSlurper.java0000644000175000017500000000460211226107170020703 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.groovy; import groovy.lang.GroovyObjectSupport; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.net.URL; import net.sf.json.JSON; import net.sf.json.JSONSerializer; import net.sf.json.JsonConfig; /** * A Helper class modeled after XmlSlurper * * @author Andres Almiray */ public class JsonSlurper extends GroovyObjectSupport { private JsonConfig jsonConfig; public JsonSlurper() { this( new JsonConfig() ); } public JsonSlurper( JsonConfig jsonConfig ) { this.jsonConfig = jsonConfig != null ? jsonConfig : new JsonConfig(); } public JSON parse( File file ) throws IOException { return parse( new FileReader( file ) ); } public JSON parse( URL url ) throws IOException { return parse( url.openConnection().getInputStream() ); } public JSON parse( InputStream input ) throws IOException { return parse( new InputStreamReader( input ) ); } public JSON parse( String uri ) throws IOException { return parse( new URL( uri ) ); } public JSON parse( Reader reader ) throws IOException { // unfortunately JSONSerializer can't process the text as a stream // so we must read the full content first and then parse it StringBuffer buffer = new StringBuffer(); BufferedReader in = new BufferedReader( reader ); String line = null; while( (line = in.readLine()) != null ) { buffer.append( line ).append( "\n" ); } return parseText( buffer.toString() ); } public JSON parseText( String text ) { return JSONSerializer.toJSON( text, jsonConfig ); } }json-lib-2.3/net/sf/json/groovy/JsonGroovyBuilder.java0000644000175000017500000002204311226107170022042 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.groovy; import groovy.lang.Closure; import groovy.lang.GString; import groovy.lang.GroovyObjectSupport; import groovy.lang.MissingMethodException; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Stack; import net.sf.json.JSON; import net.sf.json.JSONArray; import net.sf.json.JSONException; import net.sf.json.JSONObject; import net.sf.json.JSONSerializer; /** * A Groovy builder for JSON values. * *

def books1 = builder.books {
   book = [title: "The Definitive Guide to Grails", author: "Graeme Rocher"]
   book = [title: "The Definitive Guide to Grails", author: "Graeme Rocher"]
}

def books2 = builder.books {
   book = new Book(title: "The Definitive Guide to Grails",
                   author: "Graeme Rocher")
   book = new Book(title: "The Definitive Guide to Grails",
                   author: "Graeme Rocher")
}

def books3 = builder.books {
   book = {
      title = "The Definitive Guide to Grails"
      author= "Graeme Rocher"
   }
   book = {
      title = "The Definitive Guide to Grails"
      author= "Graeme Rocher"
   }
}

def books4 = builder.books {
   book {
      title = "The Definitive Guide to Grails"
      author= "Graeme Rocher"
   }
   book {
      title = "The Definitive Guide to Grails"
      author= "Graeme Rocher"
   }
}

def books5 = builder.books {
   2.times {
      book = {
         title = "The Definitive Guide to Grails"
         author= "Graeme Rocher"
      }
   }
}

def books6 = builder.books {
   2.times {
      book {
         title = "The Definitive Guide to Grails"
         author= "Graeme Rocher"
      }
   }
}


 all 6 books variables output the same JSON

{"books": {
   "book": [{
         "title": "The Definitive Guide to Grails",
         "author": "Graeme Rocher"
      },{
         "title": "The Definitive Guide to Grails",
         "author": "Graeme Rocher"
      }]
   }
}
* * @author Andres Almiray */ public class JsonGroovyBuilder extends GroovyObjectSupport { private static final String JSON = "json"; private JSON current; private Map properties; private Stack stack; public JsonGroovyBuilder() { stack = new Stack(); properties = new HashMap(); } public Object getProperty( String name ) { if( !stack.isEmpty() ){ Object top = stack.peek(); if( top instanceof JSONObject ){ JSONObject json = (JSONObject) top; if( json.containsKey( name ) ){ return json.get( name ); }else{ return _getProperty( name ); } }else{ return _getProperty( name ); } }else{ return _getProperty( name ); } } public Object invokeMethod( String name, Object arg ) { if( JSON.equals( name ) && stack.isEmpty() ){ return createObject( name, arg ); } Object[] args = (Object[]) arg; if( args.length == 0 ){ throw new MissingMethodException( name, getClass(), args ); } Object value = null; if( args.length > 1 ){ JSONArray array = new JSONArray(); stack.push( array ); for( int i = 0; i < args.length; i++ ){ if( args[i] instanceof Closure ){ append( name, createObject( (Closure) args[i] ) ); }else if( args[i] instanceof Map ){ append( name, createObject( (Map) args[i] ) ); }else if( args[i] instanceof List ){ append( name, createArray( (List) args[i] ) ); }else{ _append( name, args[i], (JSON) stack.peek() ); } } stack.pop(); }else{ if( args[0] instanceof Closure ){ value = createObject( (Closure) args[0] ); }else if( args[0] instanceof Map ){ value = createObject( (Map) args[0] ); }else if( args[0] instanceof List ){ value = createArray( (List) args[0] ); } } if( stack.isEmpty() ){ JSONObject object = new JSONObject(); object.accumulate( name, current ); current = object; }else{ JSON top = (JSON) stack.peek(); if( top instanceof JSONObject ){ append( name, current == null ? value : current ); } } return current; } public void setProperty( String name, Object value ) { if( value instanceof GString ){ value = value.toString(); try{ value = JSONSerializer.toJSON( value ); }catch( JSONException jsone ){ // its a String literal } }else if( value instanceof Closure ){ value = createObject( (Closure) value ); }else if( value instanceof Map ){ value = createObject( (Map) value ); }else if( value instanceof List ){ value = createArray( (List) value ); } append( name, value ); } private Object _getProperty( String name ) { if( properties.containsKey( name ) ){ return properties.get( name ); }else{ return super.getProperty( name ); } } private void append( String key, Object value ) { Object target = null; if( !stack.isEmpty() ){ target = stack.peek(); current = (JSON) target; _append( key, value, current ); }else{ properties.put( key, value ); } } private void _append( String key, Object value, JSON target ) { if( target instanceof JSONObject ){ ((JSONObject) target).accumulate( key, value ); }else if( target instanceof JSONArray ){ ((JSONArray) target).element( value ); } } private JSON createArray( List list ) { JSONArray array = new JSONArray(); stack.push( array ); for( Iterator elements = list.iterator(); elements.hasNext(); ){ Object element = elements.next(); if( element instanceof Closure ){ element = createObject( (Closure) element ); }else if( element instanceof Map ){ element = createObject( (Map) element ); }else if( element instanceof List ){ element = createArray( (List) element ); } array.element( element ); } stack.pop(); return array; } private JSON createObject( Closure closure ) { JSONObject object = new JSONObject(); stack.push( object ); closure.setDelegate( this ); closure.call(); stack.pop(); return object; } private JSON createObject( Map map ) { JSONObject object = new JSONObject(); stack.push( object ); for( Iterator properties = map.entrySet() .iterator(); properties.hasNext(); ){ Map.Entry property = (Map.Entry) properties.next(); String key = String.valueOf( property.getKey() ); Object value = property.getValue(); if( value instanceof Closure ){ value = createObject( (Closure) value ); }else if( value instanceof Map ){ value = createObject( (Map) value ); }else if( value instanceof List ){ value = createArray( (List) value ); } object.element( key, value ); } stack.pop(); return object; } private JSON createObject( String name, Object arg ) { Object[] args = (Object[]) arg; if( args.length == 0 ){ throw new MissingMethodException( name, getClass(), args ); } if( args.length == 1 ){ if( args[0] instanceof Closure ){ return createObject( (Closure) args[0] ); }else if( args[0] instanceof Map ){ return createObject( (Map) args[0] ); }else if( args[0] instanceof List ){ return createArray( (List) args[0] ); }else{ throw new JSONException( "Unsupported type" ); } }else{ JSONArray array = new JSONArray(); stack.push( array ); for( int i = 0; i < args.length; i++ ){ if( args[i] instanceof Closure ){ append( name, createObject( (Closure) args[i] ) ); }else if( args[i] instanceof Map ){ append( name, createObject( (Map) args[i] ) ); }else if( args[i] instanceof List ){ append( name, createArray( (List) args[i] ) ); }else{ _append( name, args[i], (JSON) stack.peek() ); } } stack.pop(); return array; } } }json-lib-2.3/net/sf/json/JSONException.java0000644000175000017500000000236711226107170017526 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json; import org.apache.commons.lang.exception.NestableRuntimeException; /** * The JSONException is thrown when things are amiss. * * @author JSON.org * @version 4 */ public class JSONException extends NestableRuntimeException { private static final long serialVersionUID = 6995087065217051815L; public JSONException() { super(); } public JSONException( String msg ) { super( msg, null ); } public JSONException( String msg, Throwable cause ) { super( msg, cause ); } public JSONException( Throwable cause ) { super( (cause == null ? null : cause.toString()), cause ); } }json-lib-2.3/net/sf/json/JSONSerializer.java0000644000175000017500000001170311226107170017673 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json; import net.sf.json.util.JSONTokener; import net.sf.json.util.JSONUtils; /** * Transforms java objects into JSON and back.
* Transformation from java to JSON is pretty straightforward, but the other way * around needs certain configuration, otherwise the java objects produced will * be DynaBeans and Lists, because the JSON notation does not carry any * information on java classes.
* * @author Andres Almiray */ public class JSONSerializer { /** * Transform a JSON value to a java object.
* Depending on the configured values for conversion this will return a * DynaBean, a bean, a List, or and array. * * @param json a JSON value * @return depends on the nature of the source object (JSONObject, JSONArray, * JSONNull). */ public static Object toJava( JSON json ) { return toJava( json, new JsonConfig() ); } /** * Transform a JSON value to a java object.
* Depending on the configured values for conversion this will return a * DynaBean, a bean, a List, or and array. * * @param json a JSON value * @param jsonConfig additional configuration * @return depends on the nature of the source object (JSONObject, JSONArray, * JSONNull) and the configured rootClass, classMap and arrayMode */ public static Object toJava( JSON json, JsonConfig jsonConfig ) { if( JSONUtils.isNull( json ) ){ return null; } Object object = null; if( json instanceof JSONArray ){ if( jsonConfig.getArrayMode() == JsonConfig.MODE_OBJECT_ARRAY ){ object = JSONArray.toArray( (JSONArray) json, jsonConfig ); }else{ object = JSONArray.toCollection( (JSONArray) json, jsonConfig ); } }else{ object = JSONObject.toBean( (JSONObject) json, jsonConfig ); } return object; } /** * Creates a JSONObject, JSONArray or a JSONNull from object.
* Accepts JSON formatted strings, Maps, arrays, Collections, DynaBeans and * JavaBeans. * * @param object any java Object * @throws JSONException if the object can not be converted */ public static JSON toJSON( Object object ) { return toJSON( object, new JsonConfig() ); } /** * Creates a JSONObject, JSONArray or a JSONNull from object.
* Accepts JSON formatted strings, Maps, arrays, Collections, DynaBeans and * JavaBeans. * * @param object any java Object * @param jsonConfig additional configuration * @throws JSONException if the object can not be converted */ public static JSON toJSON( Object object, JsonConfig jsonConfig ) { JSON json = null; if( object == null ){ json = JSONNull.getInstance(); }else if( object instanceof JSONString ){ json = toJSON( (JSONString) object, jsonConfig ); }else if( object instanceof String ){ json = toJSON( (String) object, jsonConfig ); }else if( JSONUtils.isArray( object ) ){ json = JSONArray.fromObject( object, jsonConfig ); }else{ try{ json = JSONObject.fromObject( object, jsonConfig ); }catch( JSONException e ){ if( object instanceof JSONTokener ){ ((JSONTokener) object).reset(); } json = JSONArray.fromObject( object, jsonConfig ); } } return json; } /** * Creates a JSONObject, JSONArray or a JSONNull from a JSONString. * * @throws JSONException if the string is not a valid JSON string */ private static JSON toJSON( JSONString string, JsonConfig jsonConfig ) { return toJSON( string.toJSONString(), jsonConfig ); } /** * Creates a JSONObject, JSONArray or a JSONNull from a JSONString. * * @throws JSONException if the string is not a valid JSON string */ private static JSON toJSON( String string, JsonConfig jsonConfig ) { JSON json = null; if( string.startsWith( "[" ) ){ json = JSONArray.fromObject( string, jsonConfig ); }else if( string.startsWith( "{" ) ){ json = JSONObject.fromObject( string, jsonConfig ); }else if( "null".equals( string ) ){ json = JSONNull.getInstance(); }else{ throw new JSONException( "Invalid JSON String" ); } return json; } }json-lib-2.3/net/sf/json/processors/0000755000175000017500000000000011226107170016425 5ustar mkochmkochjson-lib-2.3/net/sf/json/processors/DefaultValueProcessor.java0000644000175000017500000000177311226107170023561 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.processors; /** * Defines the default value for a type when its value is null. * * @author Andres Almiray */ public interface DefaultValueProcessor { /** * Returns an appropriate default value for a type. * * @param type * @return the default value for instances of type */ Object getDefaultValue( Class type ); }json-lib-2.3/net/sf/json/processors/JsonBeanProcessorMatcher.java0000644000175000017500000000315111226107170024173 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.processors; import java.util.Set; /** * Base class for finding a matching JsonBeanProcessor.
*
    *
  • DEFAULT - matches the target class with equals().
  • *
* * @author Andres Almiray */ public abstract class JsonBeanProcessorMatcher { /** Matches the target with equals() */ public static final JsonBeanProcessorMatcher DEFAULT = new DefaultJsonBeanProcessorMatcher(); /** * Returns the matching class calculated with the target class and the * provided set. * * @param target the target class to match * @param set a set of possible matches */ public abstract Object getMatch( Class target, Set set ); private static final class DefaultJsonBeanProcessorMatcher extends JsonBeanProcessorMatcher { public Object getMatch( Class target, Set set ) { if( target != null && set != null && set.contains( target ) ){ return target; } return null; } } }json-lib-2.3/net/sf/json/processors/DefaultValueProcessorMatcher.java0000644000175000017500000000321211226107170025053 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.processors; import java.util.Set; /** * Base class for finding a matching DefaultValueProcessor.
*
    *
  • DEFAULT - matches the target class with equals().
  • *
* * @author Andres Almiray */ public abstract class DefaultValueProcessorMatcher { /** Matches the target with equals() */ public static final DefaultValueProcessorMatcher DEFAULT = new DefaultDefaultValueProcessorMatcher(); /** * Returns the matching class calculated with the target class and the * provided set. * * @param target the target class to match * @param set a set of possible matches */ public abstract Object getMatch( Class target, Set set ); private static final class DefaultDefaultValueProcessorMatcher extends DefaultValueProcessorMatcher { public Object getMatch( Class target, Set set ) { if( target != null && set != null && set.contains( target ) ){ return target; } return null; } } }json-lib-2.3/net/sf/json/processors/JsDateJsonValueProcessor.java0000644000175000017500000000264511226107170024200 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.processors; import net.sf.json.JsonConfig; /** * Transforms a java.util.Date property into a JSONObject ideal for JsDate * conversion * * @author Andres Almiray */ public class JsDateJsonValueProcessor implements JsonValueProcessor { private JsonBeanProcessor processor; public JsDateJsonValueProcessor() { processor = new JsDateJsonBeanProcessor(); } public Object processArrayValue( Object value, JsonConfig jsonConfig ) { return process( value, jsonConfig ); } public Object processObjectValue( String key, Object value, JsonConfig jsonConfig ) { return process( value, jsonConfig ); } private Object process( Object value, JsonConfig jsonConfig ) { return processor.processBean( value, jsonConfig ); } }json-lib-2.3/net/sf/json/processors/PropertyNameProcessorMatcher.java0000644000175000017500000000320111226107170025115 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.processors; import java.util.Set; /** * Base class for finding a matching PropertyNameProcessor.
*
    *
  • DEFAULT - matches the target class with equals().
  • *
* * @author Andres Almiray */ public abstract class PropertyNameProcessorMatcher { /** Matches the target with equals() */ public static final PropertyNameProcessorMatcher DEFAULT = new DefaultPropertyNameProcessorMatcher(); /** * Returns the matching class calculated with the target class and the * provided set. * * @param target the target class to match * @param set a set of possible matches */ public abstract Object getMatch( Class target, Set set ); private static final class DefaultPropertyNameProcessorMatcher extends PropertyNameProcessorMatcher { public Object getMatch( Class target, Set set ) { if( target != null && set != null && set.contains( target ) ){ return target; } return null; } } }json-lib-2.3/net/sf/json/processors/JsonBeanProcessor.java0000644000175000017500000000241611226107170022672 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.processors; import net.sf.json.JSONException; import net.sf.json.JSONObject; import net.sf.json.JsonConfig; /** * Base interface for custom serialization per Bean. * * @author Andres Almiray */ public interface JsonBeanProcessor { /** * Processes the bean an returns a suitable JSONObject representation. * * @param bean the input bean * @param jsonConfig the current configuration environment * @return a JSONObject that represents the input bean * @throws JSONException if an error occurs during transformation */ JSONObject processBean( Object bean, JsonConfig jsonConfig ); }json-lib-2.3/net/sf/json/processors/JsDateJsonBeanProcessor.java0000644000175000017500000000411111226107170023757 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.processors; import java.util.Calendar; import java.util.Date; import net.sf.json.JSONObject; import net.sf.json.JsonConfig; /** * Transforms a java.util.Date into a JSONObject ideal for JsDate conversion.
* Example:
* *
 {
 "minutes": 13,
 "seconds": 14,
 "hours": 12,
 "month": 5,
 "year": 2007,
 "day": 17,
 "milliseconds": 150
 }
 
* * @author Andres Almiray */ public class JsDateJsonBeanProcessor implements JsonBeanProcessor { /** * Processes the input bean into a compatible JsDate.
*/ public JSONObject processBean( Object bean, JsonConfig jsonConfig ) { JSONObject jsonObject = null; if( bean instanceof java.sql.Date ){ bean = new Date( ((java.sql.Date) bean).getTime() ); } if( bean instanceof Date ){ Calendar c = Calendar.getInstance(); c.setTime( (Date) bean ); jsonObject = new JSONObject().element( "year", c.get( Calendar.YEAR ) ) .element( "month", c.get( Calendar.MONTH ) ) .element( "day", c.get( Calendar.DAY_OF_MONTH ) ) .element( "hours", c.get( Calendar.HOUR_OF_DAY ) ) .element( "minutes", c.get( Calendar.MINUTE ) ) .element( "seconds", c.get( Calendar.SECOND ) ) .element( "milliseconds", c.get( Calendar.MILLISECOND ) ); }else{ jsonObject = new JSONObject( true ); } return jsonObject; } }json-lib-2.3/net/sf/json/processors/DefaultDefaultValueProcessor.java0000644000175000017500000000266311226107170025065 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.processors; import net.sf.json.JSONArray; import net.sf.json.JSONNull; import net.sf.json.util.JSONUtils; /** * Base implementation for DefaultDefaultValueProcessor. * * @author Andres Almiray */ public class DefaultDefaultValueProcessor implements DefaultValueProcessor { public Object getDefaultValue( Class type ) { if( JSONUtils.isArray( type ) ){ return new JSONArray(); }else if( JSONUtils.isNumber( type ) ){ if( JSONUtils.isDouble( type ) ){ return new Double( 0 ); }else{ return new Integer( 0 ); } }else if( JSONUtils.isBoolean( type ) ){ return Boolean.FALSE; }else if( JSONUtils.isString( type ) ){ return ""; } return JSONNull.getInstance(); } }json-lib-2.3/net/sf/json/processors/PropertyNameProcessor.java0000644000175000017500000000206011226107170023613 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.processors; /** * Base interface for mutating property names of a Bean. * * @author Andres Almiray */ public interface PropertyNameProcessor { /** * Processes the property name. * * @param beanClass the input bean's class * @param name the current property name * @return an updated property name */ String processPropertyName( Class beanClass, String name ); }json-lib-2.3/net/sf/json/processors/JsonVerifier.java0000644000175000017500000000320411226107170021674 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.processors; import java.math.BigDecimal; import java.math.BigInteger; import net.sf.json.JSON; import net.sf.json.JSONFunction; import net.sf.json.JSONNull; import net.sf.json.JSONString; /** * Verifies if a value is a valid JSON value. * * @author Andres Almiray */ public final class JsonVerifier { /** * Verifies if value is a valid JSON value. * * @param value the value to verify */ public static boolean isValidJsonValue( Object value ) { if( JSONNull.getInstance() .equals( value ) || value instanceof JSON || value instanceof Boolean || value instanceof Byte || value instanceof Short || value instanceof Integer || value instanceof Long || value instanceof Double || value instanceof BigInteger || value instanceof BigDecimal || value instanceof JSONFunction || value instanceof JSONString || value instanceof String ){ return true; } return false; } }json-lib-2.3/net/sf/json/processors/JsonValueProcessor.java0000644000175000017500000000306611226107170023103 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.processors; import net.sf.json.JSONException; import net.sf.json.JsonConfig; /** * Base interface for custom serialization per property. * * @author Andres Almiray */ public interface JsonValueProcessor { /** * Processes the value an returns a suitable JSON value. * * @param value the input value * @return a valid JSON value that represents the input value * @throws JSONException if an error occurs during transformation */ Object processArrayValue( Object value, JsonConfig jsonConfig ); /** * Processes the value an returns a suitable JSON value. * * @param key the name of the property * @param value the value of the property * @return a valid JSON value that represents the input property * @throws JSONException if an error occurs during transformation */ Object processObjectValue( String key, Object value, JsonConfig jsonConfig ); }json-lib-2.3/net/sf/json/processors/JsonValueProcessorMatcher.java0000644000175000017500000000315711226107170024410 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json.processors; import java.util.Set; /** * Base class for finding a matching JsonValueProcessor.
*
    *
  • DEFAULT - matches the target class with equals().
  • *
* * @author Andres Almiray */ public abstract class JsonValueProcessorMatcher { /** Matches the target with equals() */ public static final JsonValueProcessorMatcher DEFAULT = new DefaultJsonValueProcessorMatcher(); /** * Returns the matching class calculated with the target class and the * provided set. * * @param target the target class to match * @param set a set of possible matches */ public abstract Object getMatch( Class target, Set set ); private static final class DefaultJsonValueProcessorMatcher extends JsonValueProcessorMatcher { public Object getMatch( Class target, Set set ) { if( target != null && set != null && set.contains( target ) ){ return target; } return null; } } }json-lib-2.3/net/sf/json/JsonConfig.java0000644000175000017500000014037511226107170017137 0ustar mkochmkoch/* * Copyright 2002-2009 the original author or authors. * * 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 net.sf.json; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import net.sf.json.processors.DefaultDefaultValueProcessor; import net.sf.json.processors.DefaultValueProcessor; import net.sf.json.processors.DefaultValueProcessorMatcher; import net.sf.json.processors.JsonBeanProcessor; import net.sf.json.processors.JsonBeanProcessorMatcher; import net.sf.json.processors.JsonValueProcessor; import net.sf.json.processors.JsonValueProcessorMatcher; import net.sf.json.processors.PropertyNameProcessor; import net.sf.json.processors.PropertyNameProcessorMatcher; import net.sf.json.util.CycleDetectionStrategy; import net.sf.json.util.JavaIdentifierTransformer; import net.sf.json.util.JsonEventListener; import net.sf.json.util.NewBeanInstanceStrategy; import net.sf.json.util.PropertyExclusionClassMatcher; import net.sf.json.util.PropertyFilter; import net.sf.json.util.PropertySetStrategy; import org.apache.commons.collections.map.MultiKeyMap; import org.apache.commons.lang.StringUtils; /** * Utility class that helps configuring the serialization process. * * @author Andres Almiray */ public class JsonConfig { public static final DefaultValueProcessorMatcher DEFAULT_DEFAULT_VALUE_PROCESSOR_MATCHER = DefaultValueProcessorMatcher.DEFAULT; public static final JsonBeanProcessorMatcher DEFAULT_JSON_BEAN_PROCESSOR_MATCHER = JsonBeanProcessorMatcher.DEFAULT; public static final JsonValueProcessorMatcher DEFAULT_JSON_VALUE_PROCESSOR_MATCHER = JsonValueProcessorMatcher.DEFAULT; public static final NewBeanInstanceStrategy DEFAULT_NEW_BEAN_INSTANCE_STRATEGY = NewBeanInstanceStrategy.DEFAULT; public static final PropertyExclusionClassMatcher DEFAULT_PROPERTY_EXCLUSION_CLASS_MATCHER = PropertyExclusionClassMatcher.DEFAULT; public static final PropertyNameProcessorMatcher DEFAULT_PROPERTY_NAME_PROCESSOR_MATCHER = PropertyNameProcessorMatcher.DEFAULT; public static final int MODE_LIST = 1; public static final int MODE_OBJECT_ARRAY = 2; public static final int MODE_SET = 2; private static final Class DEFAULT_COLLECTION_TYPE = List.class; private static final CycleDetectionStrategy DEFAULT_CYCLE_DETECTION_STRATEGY = CycleDetectionStrategy.STRICT; private static final String[] DEFAULT_EXCLUDES = new String[] { "class", "declaringClass", "metaClass" }; private static final JavaIdentifierTransformer DEFAULT_JAVA_IDENTIFIER_TRANSFORMER = JavaIdentifierTransformer.NOOP; private static final DefaultValueProcessor DEFAULT_VALUE_PROCESSOR = new DefaultDefaultValueProcessor(); private static final String[] EMPTY_EXCLUDES = new String[0]; /** Array conversion mode */ private int arrayMode = MODE_LIST; private MultiKeyMap beanKeyMap = new MultiKeyMap(); private Map beanProcessorMap = new HashMap(); private MultiKeyMap beanTypeMap = new MultiKeyMap(); /** Map of attribute/class */ private Map classMap; private Class collectionType = DEFAULT_COLLECTION_TYPE; private CycleDetectionStrategy cycleDetectionStrategy = DEFAULT_CYCLE_DETECTION_STRATEGY; private Map defaultValueMap = new HashMap(); private DefaultValueProcessorMatcher defaultValueProcessorMatcher = DEFAULT_DEFAULT_VALUE_PROCESSOR_MATCHER; private Class enclosedType; private List eventListeners = new ArrayList(); private String[] excludes = EMPTY_EXCLUDES; private Map exclusionMap = new HashMap(); private boolean handleJettisonEmptyElement; private boolean handleJettisonSingleElementArray; private boolean ignoreDefaultExcludes; //private boolean ignoreJPATransient; private boolean ignoreTransientFields; private boolean ignorePublicFields = true; private boolean javascriptCompliant; private JavaIdentifierTransformer javaIdentifierTransformer = DEFAULT_JAVA_IDENTIFIER_TRANSFORMER; private PropertyFilter javaPropertyFilter; private Map javaPropertyNameProcessorMap = new HashMap(); private PropertyNameProcessorMatcher javaPropertyNameProcessorMatcher = DEFAULT_PROPERTY_NAME_PROCESSOR_MATCHER; private JsonBeanProcessorMatcher jsonBeanProcessorMatcher = DEFAULT_JSON_BEAN_PROCESSOR_MATCHER; private PropertyFilter jsonPropertyFilter; private Map jsonPropertyNameProcessorMap = new HashMap(); private PropertyNameProcessorMatcher jsonPropertyNameProcessorMatcher = DEFAULT_PROPERTY_NAME_PROCESSOR_MATCHER; private JsonValueProcessorMatcher jsonValueProcessorMatcher = DEFAULT_JSON_VALUE_PROCESSOR_MATCHER; private Map keyMap = new HashMap(); private NewBeanInstanceStrategy newBeanInstanceStrategy = DEFAULT_NEW_BEAN_INSTANCE_STRATEGY; private PropertyExclusionClassMatcher propertyExclusionClassMatcher = DEFAULT_PROPERTY_EXCLUSION_CLASS_MATCHER; private PropertySetStrategy propertySetStrategy; /** Root class used when converting to an specific bean */ private Class rootClass; private boolean skipJavaIdentifierTransformationInMapKeys; private boolean triggerEvents; private Map typeMap = new HashMap(); private List ignoreFieldAnnotations = new ArrayList(); private boolean allowNonStringKeys = false; public JsonConfig() { } /** * Registers a listener for JSON events.
* The events will be triggered only when using the static builders and if event triggering is * enabled.
* [Java -> JSON] * * @see #enableEventTriggering * @see #disableEventTriggering * @see #removeJsonEventListener(JsonEventListener) * @param listener a listener for events */ public synchronized void addJsonEventListener( JsonEventListener listener ) { if( !eventListeners.contains( listener ) ) { eventListeners.add( listener ); } } /** * Removes all registered PropertyNameProcessors.
* [JSON -> Java] */ public void clearJavaPropertyNameProcessors() { javaPropertyNameProcessorMap.clear(); } /** * Removes all registered JsonBeanProcessors.
* [Java -> JSON] */ public void clearJsonBeanProcessors() { beanProcessorMap.clear(); } /** * Removes all registered listener for JSON Events.
* [Java -> JSON] */ public synchronized void clearJsonEventListeners() { eventListeners.clear(); } /** * Removes all registered PropertyNameProcessors.
* [Java -> JSON] */ public void clearJsonPropertyNameProcessors() { jsonPropertyNameProcessorMap.clear(); } /** * Removes all registered JsonValueProcessors.
* [Java -> JSON] */ public void clearJsonValueProcessors() { beanKeyMap.clear(); beanTypeMap.clear(); keyMap.clear(); typeMap.clear(); } /** * Removes all property exclusions registered per class.
* [Java -> JSON] */ public void clearPropertyExclusions() { exclusionMap.clear(); } /** * Removes all registered PropertyNameProcessors.
* [JSON -> Java] * * @deprecated use clearJavaPropertyNameProcessors() instead */ public void clearPropertyNameProcessors() { clearJavaPropertyNameProcessors(); } public JsonConfig copy() { JsonConfig jsc = new JsonConfig(); jsc.beanKeyMap.putAll( beanKeyMap ); jsc.beanTypeMap.putAll( beanTypeMap ); jsc.classMap = new HashMap(); if( classMap != null ) { jsc.classMap.putAll( classMap ); } jsc.cycleDetectionStrategy = cycleDetectionStrategy; if( eventListeners != null ) { jsc.eventListeners.addAll( eventListeners ); } if( excludes != null ) { jsc.excludes = new String[excludes.length]; System.arraycopy( excludes, 0, jsc.excludes, 0, excludes.length ); } jsc.handleJettisonEmptyElement = handleJettisonEmptyElement; jsc.handleJettisonSingleElementArray = handleJettisonSingleElementArray; jsc.ignoreDefaultExcludes = ignoreDefaultExcludes; jsc.ignoreTransientFields = ignoreTransientFields; jsc.ignorePublicFields = ignorePublicFields; jsc.javaIdentifierTransformer = javaIdentifierTransformer; jsc.javascriptCompliant = javascriptCompliant; jsc.keyMap.putAll( keyMap ); jsc.beanProcessorMap.putAll( beanProcessorMap ); jsc.rootClass = rootClass; jsc.skipJavaIdentifierTransformationInMapKeys = skipJavaIdentifierTransformationInMapKeys; jsc.triggerEvents = triggerEvents; jsc.typeMap.putAll( typeMap ); jsc.jsonPropertyFilter = jsonPropertyFilter; jsc.javaPropertyFilter = javaPropertyFilter; jsc.jsonBeanProcessorMatcher = jsonBeanProcessorMatcher; jsc.newBeanInstanceStrategy = newBeanInstanceStrategy; jsc.defaultValueProcessorMatcher = defaultValueProcessorMatcher; jsc.defaultValueMap.putAll( defaultValueMap ); jsc.propertySetStrategy = propertySetStrategy; //jsc.ignoreJPATransient = ignoreJPATransient; jsc.collectionType = collectionType; jsc.enclosedType = enclosedType; jsc.jsonValueProcessorMatcher = jsonValueProcessorMatcher; jsc.javaPropertyNameProcessorMatcher = javaPropertyNameProcessorMatcher; jsc.javaPropertyNameProcessorMap.putAll( javaPropertyNameProcessorMap ); jsc.jsonPropertyNameProcessorMatcher = jsonPropertyNameProcessorMatcher; jsc.jsonPropertyNameProcessorMap.putAll( jsonPropertyNameProcessorMap ); jsc.propertyExclusionClassMatcher = propertyExclusionClassMatcher; jsc.exclusionMap.putAll( exclusionMap ); jsc.ignoreFieldAnnotations.addAll( ignoreFieldAnnotations ); jsc.allowNonStringKeys = allowNonStringKeys; return jsc; } /** * Disables event triggering when building.
* [Java -> JSON] */ public void disableEventTriggering() { triggerEvents = false; } /** * Enables event triggering when building.
* [Java -> JSON] */ public void enableEventTriggering() { triggerEvents = true; } /** * Finds a DefaultValueProcessor registered to the target class.
* Returns null if none is registered.
* [Java -> JSON] * * @param target a class used for searching a DefaultValueProcessor. */ public DefaultValueProcessor findDefaultValueProcessor( Class target ) { if( !defaultValueMap.isEmpty() ) { Object key = defaultValueProcessorMatcher.getMatch( target, defaultValueMap.keySet() ); DefaultValueProcessor processor = (DefaultValueProcessor) defaultValueMap.get( key ); if( processor != null ) { return processor; } } return DEFAULT_VALUE_PROCESSOR; } /** * Finds a PropertyNameProcessor registered to the target class.
* Returns null if none is registered.
* [JSON -> Java] * * @param propertyType a class used for searching a PropertyNameProcessor. */ public PropertyNameProcessor findJavaPropertyNameProcessor( Class beanClass ) { if( !javaPropertyNameProcessorMap.isEmpty() ) { Object key = javaPropertyNameProcessorMatcher.getMatch( beanClass, javaPropertyNameProcessorMap.keySet() ); return (PropertyNameProcessor) javaPropertyNameProcessorMap.get( key ); } return null; } /** * Finds a JsonBeanProcessor registered to the target class.
* Returns null if none is registered.
* [Java -> JSON] * * @param target a class used for searching a JsonBeanProcessor. */ public JsonBeanProcessor findJsonBeanProcessor( Class target ) { if( !beanProcessorMap.isEmpty() ) { Object key = jsonBeanProcessorMatcher.getMatch( target, beanProcessorMap.keySet() ); return (JsonBeanProcessor) beanProcessorMap.get( key ); } return null; } /** * Finds a PropertyNameProcessor registered to the target class.
* Returns null if none is registered.
* [Java -> JSON] * * @param propertyType a class used for searching a PropertyNameProcessor. */ public PropertyNameProcessor findJsonPropertyNameProcessor( Class beanClass ) { if( !jsonPropertyNameProcessorMap.isEmpty() ) { Object key = jsonPropertyNameProcessorMatcher.getMatch( beanClass, jsonPropertyNameProcessorMap.keySet() ); return (PropertyNameProcessor) jsonPropertyNameProcessorMap.get( key ); } return null; } /** * Finds a JsonValueProcessor registered to the target type.
* Returns null if none is registered.
* [Java -> JSON] * * @param propertyType a class used for searching a JsonValueProcessor. */ public JsonValueProcessor findJsonValueProcessor( Class propertyType ) { if( !typeMap.isEmpty() ) { Object key = jsonValueProcessorMatcher.getMatch( propertyType, typeMap.keySet() ); return (JsonValueProcessor) typeMap.get( key ); } return null; } /** * Finds a JsonValueProcessor.
* It will search the registered JsonValueProcessors in the following order: *
    *
  1. beanClass, key
  2. *
  3. beanClass, type
  4. *
  5. key
  6. *
  7. type
  8. *
* Returns null if none is registered.
* [Java -> JSON] * * @param beanClass the class to which the property may belong * @param propertyType the type of the property * @param key the name of the property which may belong to the target class */ public JsonValueProcessor findJsonValueProcessor( Class beanClass, Class propertyType, String key ) { JsonValueProcessor jsonValueProcessor = null; jsonValueProcessor = (JsonValueProcessor) beanKeyMap.get( beanClass, key ); if( jsonValueProcessor != null ) { return jsonValueProcessor; } jsonValueProcessor = (JsonValueProcessor) beanTypeMap.get( beanClass, propertyType ); if( jsonValueProcessor != null ) { return jsonValueProcessor; } jsonValueProcessor = (JsonValueProcessor) keyMap.get( key ); if( jsonValueProcessor != null ) { return jsonValueProcessor; } Object tkey = jsonValueProcessorMatcher.getMatch( propertyType, typeMap.keySet() ); jsonValueProcessor = (JsonValueProcessor) typeMap.get( tkey ); if( jsonValueProcessor != null ) { return jsonValueProcessor; } return null; } /** * Finds a JsonValueProcessor.
* It will search the registered JsonValueProcessors in the following order: *
    *
  1. key
  2. *
  3. type
  4. *
* Returns null if none is registered.
* [Java -> JSON] * * @param propertyType the type of the property * @param key the name of the property which may belong to the target class */ public JsonValueProcessor findJsonValueProcessor( Class propertyType, String key ) { JsonValueProcessor jsonValueProcessor = null; jsonValueProcessor = (JsonValueProcessor) keyMap.get( key ); if( jsonValueProcessor != null ) { return jsonValueProcessor; } Object tkey = jsonValueProcessorMatcher.getMatch( propertyType, typeMap.keySet() ); jsonValueProcessor = (JsonValueProcessor) typeMap.get( tkey ); if( jsonValueProcessor != null ) { return jsonValueProcessor; } return null; } /** * Finds a PropertyNameProcessor registered to the target class.
* Returns null if none is registered.
* [JSON -> Java] * * @param propertyType a class used for searching a PropertyNameProcessor. * * @deprecated use findJavaPropertyNameProcessor() instead */ public PropertyNameProcessor findPropertyNameProcessor( Class beanClass ) { return findJavaPropertyNameProcessor( beanClass ); } /** * Returns the current array mode conversion.
* [JSON -> Java] * * @return MODE_OBJECT_ARRAY, MODE_LIST or MODE_SET */ public int getArrayMode() { return arrayMode; } /** * Returns the current attribute/class Map.
* [JSON -> Java] * * @return a Map of classes, every key identifies a property or a regexp */ public Map getClassMap() { return classMap; } /** * Returns the current collection type used for collection transformations.
* [JSON -> Java] * * @return the target collection class for conversion */ public Class getCollectionType() { return collectionType; } /** * Returns the configured CycleDetectionStrategy.
* Default value is CycleDetectionStrategy.STRICT
* [Java -> JSON] */ public CycleDetectionStrategy getCycleDetectionStrategy() { return cycleDetectionStrategy; } /** * Returns the configured DefaultValueProcessorMatcher.
* Default value is DefaultValueProcessorMatcher.DEFAULT
* [Java -> JSON] */ public DefaultValueProcessorMatcher getDefaultValueProcessorMatcher() { return defaultValueProcessorMatcher; } /** * Returns the current enclosed type for generic collection transformations.
* [JSON -> Java] * * @return the target type for conversion */ public Class getEnclosedType() { return enclosedType; } /** * Returns the configured properties for exclusion.
* [Java -> JSON] */ public String[] getExcludes() { return excludes; } /** * Returns the configured JavaIdentifierTransformer.
* Default value is JavaIdentifierTransformer.NOOP
* [JSON -> Java] */ public JavaIdentifierTransformer getJavaIdentifierTransformer() { return javaIdentifierTransformer; } /** * Returns the configured property filter when serializing to Java.
* [JSON -> Java] */ public PropertyFilter getJavaPropertyFilter() { return javaPropertyFilter; } /** * Returns the configured PropertyNameProcessorMatcher.
* Default value is PropertyNameProcessorMatcher.DEFAULT
* [JSON -> Java] */ public PropertyNameProcessorMatcher getJavaPropertyNameProcessorMatcher() { return javaPropertyNameProcessorMatcher; } /** * Returns the configured JsonBeanProcessorMatcher.
* Default value is JsonBeanProcessorMatcher.DEFAULT
* [JSON -> Java] */ public JsonBeanProcessorMatcher getJsonBeanProcessorMatcher() { return jsonBeanProcessorMatcher; } /** * Returns a list of registered listeners for JSON events.
* [JSON -> Java] */ public synchronized List getJsonEventListeners() { return eventListeners; } /** * Returns the configured property filter when serializing to JSON.
* [Java -> JSON] */ public PropertyFilter getJsonPropertyFilter() { return jsonPropertyFilter; } /** * Returns the configured PropertyNameProcessorMatcher.
* Default value is PropertyNameProcessorMatcher.DEFAULT
* [Java -> JSON] */ public PropertyNameProcessorMatcher getJsonPropertyNameProcessorMatcher() { return javaPropertyNameProcessorMatcher; } /** * Returns the configured JsonValueProcessorMatcher.
* Default value is JsonValueProcessorMatcher.DEFAULT
* [Java -> JSON] */ public JsonValueProcessorMatcher getJsonValueProcessorMatcher() { return jsonValueProcessorMatcher; } /** * Returns a set of default excludes with user-defined excludes.
* [Java -> JSON] */ public Collection getMergedExcludes() { Collection exclusions = new HashSet(); for( int i = 0; i < excludes.length; i++ ) { String exclusion = excludes[i]; if( !StringUtils.isBlank( excludes[i] ) ) { exclusions.add( exclusion.trim() ); } } if( !ignoreDefaultExcludes ) { for( int i = 0; i < DEFAULT_EXCLUDES.length; i++ ) { if( !exclusions.contains( DEFAULT_EXCLUDES[i] ) ) { exclusions.add( DEFAULT_EXCLUDES[i] ); } } } return exclusions; } /** * Returns a set of default excludes with user-defined excludes.
* Takes into account any additional excludes per matching class. * [Java -> JSON] */ public Collection getMergedExcludes( Class target ) { if( target == null ) { return getMergedExcludes(); } Collection exclusionSet = getMergedExcludes(); if( !exclusionMap.isEmpty() ) { Object key = propertyExclusionClassMatcher.getMatch( target, exclusionMap.keySet() ); Set set = (Set) exclusionMap.get( key ); if( set != null && !set.isEmpty() ) { for( Iterator i = set.iterator(); i.hasNext(); ) { Object e = i.next(); if( !exclusionSet.contains( e ) ) { exclusionSet.add( e ); } } } } return exclusionSet; } /** * Returns the configured NewBeanInstanceStrategy.
* Default value is NewBeanInstanceStrategy.DEFAULT
* [JSON -> Java] */ public NewBeanInstanceStrategy getNewBeanInstanceStrategy() { return newBeanInstanceStrategy; } /** * Returns the configured PropertyExclusionClassMatcher.
* Default value is PropertyExclusionClassMatcher.DEFAULT
* [JSON -> Java] */ public PropertyExclusionClassMatcher getPropertyExclusionClassMatcher() { return propertyExclusionClassMatcher; } /** * Returns the configured PropertyNameProcessorMatcher.
* Default value is PropertyNameProcessorMatcher.DEFAULT
* [JSON -> Java] * * @deprecated use getJavaPropertyNameProcessorMatcher() instead */ public PropertyNameProcessorMatcher getPropertyNameProcessorMatcher() { return getJavaPropertyNameProcessorMatcher(); } /** * Returns the configured PropertySetStrategy.
* Default value is PropertySetStrategy.DEFAULT
* [JSON -> Java] */ public PropertySetStrategy getPropertySetStrategy() { return propertySetStrategy; } /** * Returns the current root Class.
* [JSON -> Java] * * @return the target class for conversion */ public Class getRootClass() { return rootClass; } /** * Returns true if non-String keys are allowed on JSONObject.
* Default value is false
* [Java -> JSON] */ public boolean isAllowNonStringKeys() { return allowNonStringKeys; } /** * Returns true if event triggering is enabled during building.
* Default value is false
* [Java -> JSON] */ public boolean isEventTriggeringEnabled() { return triggerEvents; } /** * Returns true if this Jettison convention will be handled when converting to Java.
* Jettison assumes that "" (empty string) can be assigned to empty elements (objects), which * clearly violates the JSON spec.
* [JSON -> Java] */ public boolean isHandleJettisonEmptyElement() { return handleJettisonEmptyElement; } /** * Returns true if this jettison convention will be handled when converting to Java.
* Jettison states the following JSON {'media':{'title':'hello'}} can be set as a single element * JSONArray (media is the array).
* [JSON -> Java] */ public boolean isHandleJettisonSingleElementArray() { return handleJettisonSingleElementArray; } /** * Returns true if default excludes will not be used.
* Default value is false.
* [Java -> JSON] */ public boolean isIgnoreDefaultExcludes() { return ignoreDefaultExcludes; } /** * Returns true if JPA Transient annotated methods should be ignored.
* Default value is false.
* [Java -> JSON] */ public boolean isIgnoreJPATransient() { return ignoreFieldAnnotations.contains("javax.persistence.Transient"); } /** * Returns true if transient fields of a bean will be ignored.
* Default value is false.
* [Java -> JSON] */ public boolean isIgnoreTransientFields() { return ignoreTransientFields; } /** * Returns true if public fields of a bean will be ignored.
* Default value is true.
* [Java -> JSON] */ public boolean isIgnorePublicFields() { return ignorePublicFields; } /** * Returns true if Javascript compatibility is turned on.
* Default value is false.
* [Java -> JSON] */ public boolean isJavascriptCompliant() { return javascriptCompliant; } /** * Returns true if map keys will not be transformed.
* Default value is false.
* [JSON -> Java] */ public boolean isSkipJavaIdentifierTransformationInMapKeys() { return skipJavaIdentifierTransformationInMapKeys; } /** * Registers a DefaultValueProcessor.
* [Java -> JSON] * * @param target the class to use as key * @param defaultValueProcessor the processor to register */ public void registerDefaultValueProcessor( Class target, DefaultValueProcessor defaultValueProcessor ) { if( target != null && defaultValueProcessor != null ) { defaultValueMap.put( target, defaultValueProcessor ); } } /** * Registers a PropertyNameProcessor.
* [JSON -> Java] * * @param target the class to use as key * @param propertyNameProcessor the processor to register */ public void registerJavaPropertyNameProcessor( Class target, PropertyNameProcessor propertyNameProcessor ) { if( target != null && propertyNameProcessor != null ) { javaPropertyNameProcessorMap.put( target, propertyNameProcessor ); } } /** * Registers a JsonBeanProcessor.
* [Java -> JSON] * * @param target the class to use as key * @param jsonBeanProcessor the processor to register */ public void registerJsonBeanProcessor( Class target, JsonBeanProcessor jsonBeanProcessor ) { if( target != null && jsonBeanProcessor != null ) { beanProcessorMap.put( target, jsonBeanProcessor ); } } /** * Registers a PropertyNameProcessor.
* [Java -> JSON] * * @param target the class to use as key * @param propertyNameProcessor the processor to register */ public void registerJsonPropertyNameProcessor( Class target, PropertyNameProcessor propertyNameProcessor ) { if( target != null && propertyNameProcessor != null ) { jsonPropertyNameProcessorMap.put( target, propertyNameProcessor ); } } /** * Registers a JsonValueProcessor.
* [Java -> JSON] * * @param beanClass the class to use as key * @param propertyType the property type to use as key * @param jsonValueProcessor the processor to register */ public void registerJsonValueProcessor( Class beanClass, Class propertyType, JsonValueProcessor jsonValueProcessor ) { if( beanClass != null && propertyType != null && jsonValueProcessor != null ) { beanTypeMap.put( beanClass, propertyType, jsonValueProcessor ); } } /** * Registers a JsonValueProcessor.
* [Java -> JSON] * * @param propertyType the property type to use as key * @param jsonValueProcessor the processor to register */ public void registerJsonValueProcessor( Class propertyType, JsonValueProcessor jsonValueProcessor ) { if( propertyType != null && jsonValueProcessor != null ) { typeMap.put( propertyType, jsonValueProcessor ); } } /** * Registers a JsonValueProcessor.
* [Java -> JSON] * * @param beanClass the class to use as key * @param key the property name to use as key * @param jsonValueProcessor the processor to register */ public void registerJsonValueProcessor( Class beanClass, String key, JsonValueProcessor jsonValueProcessor ) { if( beanClass != null && key != null && jsonValueProcessor != null ) { beanKeyMap.put( beanClass, key, jsonValueProcessor ); } } /** * Registers a JsonValueProcessor.
* [Java -> JSON] * * @param key the property name to use as key * @param jsonValueProcessor the processor to register */ public void registerJsonValueProcessor( String key, JsonValueProcessor jsonValueProcessor ) { if( key != null && jsonValueProcessor != null ) { keyMap.put( key, jsonValueProcessor ); } } /** * Registers a exclusion for a target class.
* [Java -> JSON] * * @param target the class to use as key * @param propertyName the property to be excluded */ public void registerPropertyExclusion( Class target, String propertyName ) { if( target != null && propertyName != null ) { Set set = (Set) exclusionMap.get( target ); if( set == null ){ set = new HashSet(); exclusionMap.put( target, set ); } if( !set.contains( propertyName )){ set.add(propertyName ); } } } /** * Registers exclusions for a target class.
* [Java -> JSON] * * @param target the class to use as key * @param properties the properties to be excluded */ public void registerPropertyExclusions( Class target, String[] properties ) { if( target != null && properties != null && properties.length > 0 ) { Set set = (Set) exclusionMap.get( target ); if( set == null ) { set = new HashSet(); exclusionMap.put( target, set ); } for( int i = 0; i < properties.length; i++ ) { if( !set.contains( properties[i] ) ) { set.add( properties[i] ); } } } } /** * Registers a PropertyNameProcessor.
* [JSON -> Java] * * @param target the class to use as key * @param propertyNameProcessor the processor to register * * @deprecated use registerJavaPropertyNameProcessor() instead */ public void registerPropertyNameProcessor( Class target, PropertyNameProcessor propertyNameProcessor ) { registerJavaPropertyNameProcessor( target, propertyNameProcessor ); } /** * Removes a listener for JSON events.
* [Java -> JSON] * * @see #addJsonEventListener(JsonEventListener) * @param listener a listener for events */ public synchronized void removeJsonEventListener( JsonEventListener listener ) { eventListeners.remove( listener ); } /** * Resets all values to its default state. */ public void reset() { excludes = EMPTY_EXCLUDES; ignoreDefaultExcludes = false; ignoreTransientFields = false; ignorePublicFields = true; javascriptCompliant = false; javaIdentifierTransformer = DEFAULT_JAVA_IDENTIFIER_TRANSFORMER; cycleDetectionStrategy = DEFAULT_CYCLE_DETECTION_STRATEGY; skipJavaIdentifierTransformationInMapKeys = false; triggerEvents = false; handleJettisonEmptyElement = false; handleJettisonSingleElementArray = false; arrayMode = MODE_LIST; rootClass = null; classMap = null; keyMap.clear(); typeMap.clear(); beanKeyMap.clear(); beanTypeMap.clear(); jsonPropertyFilter = null; javaPropertyFilter = null; jsonBeanProcessorMatcher = DEFAULT_JSON_BEAN_PROCESSOR_MATCHER; newBeanInstanceStrategy = DEFAULT_NEW_BEAN_INSTANCE_STRATEGY; defaultValueProcessorMatcher = DEFAULT_DEFAULT_VALUE_PROCESSOR_MATCHER; defaultValueMap.clear(); propertySetStrategy = null/* DEFAULT_PROPERTY_SET_STRATEGY */; //ignoreJPATransient = false; collectionType = DEFAULT_COLLECTION_TYPE; enclosedType = null; jsonValueProcessorMatcher = DEFAULT_JSON_VALUE_PROCESSOR_MATCHER; javaPropertyNameProcessorMap.clear(); javaPropertyNameProcessorMatcher = DEFAULT_PROPERTY_NAME_PROCESSOR_MATCHER; jsonPropertyNameProcessorMap.clear(); jsonPropertyNameProcessorMatcher = DEFAULT_PROPERTY_NAME_PROCESSOR_MATCHER; beanProcessorMap.clear(); propertyExclusionClassMatcher = DEFAULT_PROPERTY_EXCLUSION_CLASS_MATCHER; exclusionMap.clear(); ignoreFieldAnnotations.clear(); allowNonStringKeys = false; } /** * Sets if non-String keys are allowed on JSONObject.
* [Java -> JSON] */ public void setAllowNonStringKeys( boolean allowNonStringKeys ) { this.allowNonStringKeys = allowNonStringKeys; } /** * Sets the current array mode for conversion.
* If the value is not MODE_LIST, MODE_OBJECT_ARRAY nor MODE_SET, then MODE_LIST will be used.
* [JSON -> Java] * * @param arrayMode array mode for conversion */ public void setArrayMode( int arrayMode ) { if( arrayMode == MODE_OBJECT_ARRAY ) { this.arrayMode = arrayMode; } else if( arrayMode == MODE_SET ) { this.arrayMode = arrayMode; this.collectionType = Set.class; } else { this.arrayMode = MODE_LIST; this.enclosedType = DEFAULT_COLLECTION_TYPE; } } /** * Sets the current attribute/Class Map
* [JSON -> Java] * * @param classMap a Map of classes, every key identifies a property or a regexp */ public void setClassMap( Map classMap ) { this.classMap = classMap; } /** * Sets the current collection type used for collection transformations.
* [JSON -> Java] * * @param collectionType the target collection class for conversion */ public void setCollectionType( Class collectionType ) { if( collectionType != null ) { if( !Collection.class.isAssignableFrom( collectionType ) ) { throw new JSONException( "The configured collectionType is not a Collection: " + collectionType.getName() ); } this.collectionType = collectionType; } else { collectionType = DEFAULT_COLLECTION_TYPE; } } /** * Sets a CycleDetectionStrategy to use.
* Will set default value (CycleDetectionStrategy.STRICT) if null.
* [Java -> JSON] */ public void setCycleDetectionStrategy( CycleDetectionStrategy cycleDetectionStrategy ) { this.cycleDetectionStrategy = cycleDetectionStrategy == null ? DEFAULT_CYCLE_DETECTION_STRATEGY : cycleDetectionStrategy; } /** * Sets a DefaultValueProcessorMatcher to use.
* Will set default value (DefaultValueProcessorMatcher.DEFAULT) if null.
* [Java -> JSON] */ public void setDefaultValueProcessorMatcher( DefaultValueProcessorMatcher defaultValueProcessorMatcher ) { this.defaultValueProcessorMatcher = defaultValueProcessorMatcher == null ? DEFAULT_DEFAULT_VALUE_PROCESSOR_MATCHER : defaultValueProcessorMatcher; } /** * Sets the current enclosed type for generic collection transformations.
* [JSON -> Java] * * @param enclosedType the target type for conversion */ public void setEnclosedType( Class enclosedType ) { this.enclosedType = enclosedType; } /** * Sets the excludes to use.
* Will set default value ([]) if null.
* [Java -> JSON] */ public void setExcludes( String[] excludes ) { this.excludes = excludes == null ? EMPTY_EXCLUDES : excludes; } /** * Activate/Deactivate handling this jettison convention when converting to Java.
* Jettison states that "" (empty string) can be assigned to empty elements (objects), which * clearly violates the JSON spec.
* [JSON -> Java] */ public void setHandleJettisonEmptyElement( boolean handleJettisonEmptyElement ) { this.handleJettisonEmptyElement = handleJettisonEmptyElement; } /** * Activate/Deactivate handling this jettison convention when converting to Java.
* Jettison * states the following JSON {'media':{'title':'hello'}} can be set as a single element JSONArray * (media is the array).
* [JSON -> Java] */ public void setHandleJettisonSingleElementArray( boolean handleJettisonSingleElementArray ) { this.handleJettisonSingleElementArray = handleJettisonSingleElementArray; } /** * Sets if default excludes would be skipped when building.
* [Java -> JSON] */ public void setIgnoreDefaultExcludes( boolean ignoreDefaultExcludes ) { this.ignoreDefaultExcludes = ignoreDefaultExcludes; } /** * Sets if JPA Transient annotated methods would be skipped when building.
* [Java -> JSON] */ public void setIgnoreJPATransient( boolean ignoreJPATransient ) { if(ignoreJPATransient) { addIgnoreFieldAnnotation("javax.persistence.Transient"); } else { removeIgnoreFieldAnnotation("javax.persistence.Transient"); } } /** * Adds an annotation that marks a field to be skipped when building.
* [Java -> JSON] */ public void addIgnoreFieldAnnotation( String annotationClassName ) { if( annotationClassName != null && !ignoreFieldAnnotations.contains( annotationClassName )) { ignoreFieldAnnotations.add(annotationClassName); } } /** * Adds an annotation that marks a field to be skipped when building.
* [Java -> JSON] */ public void removeIgnoreFieldAnnotation( String annotationClassName ) { if( annotationClassName != null ) ignoreFieldAnnotations.remove(annotationClassName); } /** * Removes an annotation that marks a field to be skipped when building.
* [Java -> JSON] */ public void addIgnoreFieldAnnotation( Class annotationClass ) { if( annotationClass != null && !ignoreFieldAnnotations.contains( annotationClass.getName() )) { ignoreFieldAnnotations.add(annotationClass.getName()); } } /** * Removes an annotation that marks a field to be skipped when building.
* [Java -> JSON] */ public void removeIgnoreFieldAnnotation( Class annotationClass ) { if( annotationClass != null ) ignoreFieldAnnotations.remove(annotationClass.getName()); } /** * Returns a List of all annotations that mark a field to be skipped when building.
* [Java -> JSON] */ public List getIgnoreFieldAnnotations() { return Collections.unmodifiableList(ignoreFieldAnnotations); } /** * Sets if transient fields would be skipped when building.
* [Java -> JSON] */ public void setIgnoreTransientFields( boolean ignoreTransientFields ) { this.ignoreTransientFields = ignoreTransientFields; } /** * Sets if public fields would be skipped when building.
* [Java -> JSON] */ public void setIgnorePublicFields( boolean ignorePublicFields ) { this.ignorePublicFields = ignorePublicFields; } /** * Sets if Javascript compatibility is enabled when building.
* [Java -> JSON] */ public void setJavascriptCompliant( boolean javascriptCompliant ) { this.javascriptCompliant = javascriptCompliant; } /** * Sets the JavaIdentifierTransformer to use.
* Will set default value (JavaIdentifierTransformer.NOOP) if null.
* [JSON -> Java] */ public void setJavaIdentifierTransformer( JavaIdentifierTransformer javaIdentifierTransformer ) { this.javaIdentifierTransformer = javaIdentifierTransformer == null ? DEFAULT_JAVA_IDENTIFIER_TRANSFORMER : javaIdentifierTransformer; } /** * Sets a property filter used when serializing to Java.
* [JSON -> Java] * * @param javaPropertyFilter the property filter */ public void setJavaPropertyFilter( PropertyFilter javaPropertyFilter ) { this.javaPropertyFilter = javaPropertyFilter; } /** * Sets a PropertyNameProcessorMatcher to use.
* Will set default value (PropertyNameProcessorMatcher.DEFAULT) if null.
* [JSON -> Java] */ public void setJavaPropertyNameProcessorMatcher( PropertyNameProcessorMatcher propertyNameProcessorMatcher ) { this.javaPropertyNameProcessorMatcher = propertyNameProcessorMatcher == null ? DEFAULT_PROPERTY_NAME_PROCESSOR_MATCHER : propertyNameProcessorMatcher; } /** * Sets a JsonBeanProcessorMatcher to use.
* Will set default value (JsonBeanProcessorMatcher.DEFAULT) if null.
* [Java -> JSON] */ public void setJsonBeanProcessorMatcher( JsonBeanProcessorMatcher jsonBeanProcessorMatcher ) { this.jsonBeanProcessorMatcher = jsonBeanProcessorMatcher == null ? DEFAULT_JSON_BEAN_PROCESSOR_MATCHER : jsonBeanProcessorMatcher; } /** * Sets a property filter used when serializing to JSON.
* [Java -> JSON] * * @param jsonPropertyFilter the property filter */ public void setJsonPropertyFilter( PropertyFilter jsonPropertyFilter ) { this.jsonPropertyFilter = jsonPropertyFilter; } /** * Sets a PropertyNameProcessorMatcher to use.
* Will set default value (PropertyNameProcessorMatcher.DEFAULT) if null.
* [Java -> JSON] */ public void setJsonPropertyNameProcessorMatcher( PropertyNameProcessorMatcher propertyNameProcessorMatcher ) { this.jsonPropertyNameProcessorMatcher = propertyNameProcessorMatcher == null ? DEFAULT_PROPERTY_NAME_PROCESSOR_MATCHER : propertyNameProcessorMatcher; } /** * Sets a JsonValueProcessorMatcher to use.
* Will set default value (JsonValueProcessorMatcher.DEFAULT) if null.
* [Java -> JSON] */ public void setJsonValueProcessorMatcher( JsonValueProcessorMatcher jsonValueProcessorMatcher ) { this.jsonValueProcessorMatcher = jsonValueProcessorMatcher == null ? DEFAULT_JSON_VALUE_PROCESSOR_MATCHER : jsonValueProcessorMatcher; } /** * Sets the NewBeanInstanceStrategy to use.
* Will set default value (NewBeanInstanceStrategy.DEFAULT) if null.
* [JSON -> Java] */ public void setNewBeanInstanceStrategy( NewBeanInstanceStrategy newBeanInstanceStrategy ) { this.newBeanInstanceStrategy = newBeanInstanceStrategy == null ? DEFAULT_NEW_BEAN_INSTANCE_STRATEGY : newBeanInstanceStrategy; } /** * Sets a PropertyExclusionClassMatcher to use.
* Will set default value (PropertyExclusionClassMatcher.DEFAULT) if null.
* [Java -> JSON] */ public void setPropertyExclusionClassMatcher( PropertyExclusionClassMatcher propertyExclusionClassMatcher ) { this.propertyExclusionClassMatcher = propertyExclusionClassMatcher == null ? DEFAULT_PROPERTY_EXCLUSION_CLASS_MATCHER : propertyExclusionClassMatcher; } /** * Sets a PropertyNameProcessorMatcher to use.
* Will set default value (PropertyNameProcessorMatcher.DEFAULT) if null.
* [JSON -> Java] * * @deprecated use setJavaPropertyNameProcessorMatcher() instead */ public void setPropertyNameProcessorMatcher( PropertyNameProcessorMatcher propertyNameProcessorMatcher ) { setJavaPropertyNameProcessorMatcher( propertyNameProcessorMatcher ); } /** * Sets a PropertySetStrategy to use.
* Will set default value (PropertySetStrategy.DEFAULT) if null.
* [JSON -> Java] */ public void setPropertySetStrategy( PropertySetStrategy propertySetStrategy ) { this.propertySetStrategy = propertySetStrategy; } /** * Sets the current root Class.
* [JSON -> Java] * * @param rootClass the target class for conversion */ public void setRootClass( Class rootClass ) { this.rootClass = rootClass; } /** * Sets if property name as JavaIndetifier transformations would be skipped.
* [JSON -> Java] */ public void setSkipJavaIdentifierTransformationInMapKeys( boolean skipJavaIdentifierTransformationInMapKeys ) { this.skipJavaIdentifierTransformationInMapKeys = skipJavaIdentifierTransformationInMapKeys; } /** * Removes a DefaultValueProcessor.
* [Java -> JSON] * * @param target a class used for searching a DefaultValueProcessor. */ public void unregisterDefaultValueProcessor( Class target ) { if( target != null ) { defaultValueMap.remove( target ); } } /** * Removes a PropertyNameProcessor.
* [JSON -> Java] * * @param target a class used for searching a PropertyNameProcessor. */ public void unregisterJavaPropertyNameProcessor( Class target ) { if( target != null ) { javaPropertyNameProcessorMap.remove( target ); } } /** * Removes a JsonBeanProcessor.
* [Java -> JSON] * * @param target a class used for searching a JsonBeanProcessor. */ public void unregisterJsonBeanProcessor( Class target ) { if( target != null ) { beanProcessorMap.remove( target ); } } /** * Removes a PropertyNameProcessor.
* [Java -> JSON] * * @param target a class used for searching a PropertyNameProcessor. */ public void unregisterJsonPropertyNameProcessor( Class target ) { if( target != null ) { jsonPropertyNameProcessorMap.remove( target ); } } /** * Removes a JsonValueProcessor.
* [Java -> JSON] * * @param propertyType a class used for searching a JsonValueProcessor. */ public void unregisterJsonValueProcessor( Class propertyType ) { if( propertyType != null ) { typeMap.remove( propertyType ); } } /** * Removes a JsonValueProcessor.
* [Java -> JSON] * * @param beanClass the class to which the property may belong * @param propertyType the type of the property */ public void unregisterJsonValueProcessor( Class beanClass, Class propertyType ) { if( beanClass != null && propertyType != null ) { beanTypeMap.remove( beanClass, propertyType ); } } /** * Removes a JsonValueProcessor.
* [Java -> JSON] * * @param beanClass the class to which the property may belong * @param key the name of the property which may belong to the target class */ public void unregisterJsonValueProcessor( Class beanClass, String key ) { if( beanClass != null && key != null ) { beanKeyMap.remove( beanClass, key ); } } /** * Removes a JsonValueProcessor.
* [Java -> JSON] * * @param key the name of the property which may belong to the target class */ public void unregisterJsonValueProcessor( String key ) { if( key != null ) { keyMap.remove( key ); } } /** * Removes a property exclusion assigned to the target class.
* [Java -> JSON] * * @param target a class used for searching property exclusions. * @param propertyName the name of the property to be removed from the exclusion list. */ public void unregisterPropertyExclusion( Class target, String propertyName ) { if( target != null && propertyName != null ) { Set set = (Set) exclusionMap.get( target ); if( set == null ) { set = new HashSet(); exclusionMap.put( target, set ); } set.remove( propertyName ); } } /** * Removes all property exclusions assigned to the target class.
* [Java -> JSON] * * @param target a class used for searching property exclusions. */ public void unregisterPropertyExclusions( Class target ) { if( target != null ) { Set set = (Set) exclusionMap.get( target ); if( set != null ) { set.clear(); } } } /** * Removes a PropertyNameProcessor.
* [JSON -> Java] * * @param target a class used for searching a PropertyNameProcessor. * * @deprecated use unregisterJavaPropertyNameProcessor() instead */ public void unregisterPropertyNameProcessor( Class target ) { unregisterJavaPropertyNameProcessor( target ); } }json-lib-2.3/META-INF/0000755000175000017500000000000011226107170013214 5ustar mkochmkochjson-lib-2.3/META-INF/MANIFEST.MF0000644000175000017500000000014611226107166014654 0ustar mkochmkochManifest-Version: 1.0 Ant-Version: Apache Ant 1.7.1 Created-By: 14.0-b16 (Sun Microsystems Inc.)