Java tutorial
/* * 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 com.xwtec.xwserver.util.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 org.apache.commons.collections.map.MultiKeyMap; import org.apache.commons.lang.StringUtils; import com.xwtec.xwserver.util.json.processors.DefaultDefaultValueProcessor; import com.xwtec.xwserver.util.json.processors.DefaultValueProcessor; import com.xwtec.xwserver.util.json.processors.DefaultValueProcessorMatcher; import com.xwtec.xwserver.util.json.processors.JsonBeanProcessor; import com.xwtec.xwserver.util.json.processors.JsonBeanProcessorMatcher; import com.xwtec.xwserver.util.json.processors.JsonValueProcessor; import com.xwtec.xwserver.util.json.processors.JsonValueProcessorMatcher; import com.xwtec.xwserver.util.json.processors.PropertyNameProcessor; import com.xwtec.xwserver.util.json.processors.PropertyNameProcessorMatcher; import com.xwtec.xwserver.util.json.util.CycleDetectionStrategy; import com.xwtec.xwserver.util.json.util.JavaIdentifierTransformer; import com.xwtec.xwserver.util.json.util.JsonEventListener; import com.xwtec.xwserver.util.json.util.NewBeanInstanceStrategy; import com.xwtec.xwserver.util.json.util.PropertyExclusionClassMatcher; import com.xwtec.xwserver.util.json.util.PropertyFilter; import com.xwtec.xwserver.util.json.util.PropertySetStrategy; /** * Utility class that helps configuring the serialization process. * * @author Andres Almiray <aalmiray@users.sourceforge.net> */ @SuppressWarnings("unchecked") 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.<br> * The events will be triggered only when using the static builders and if event triggering is * enabled.<br> * [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.<br> * [JSON -> Java] */ public void clearJavaPropertyNameProcessors() { javaPropertyNameProcessorMap.clear(); } /** * Removes all registered JsonBeanProcessors.<br> * [Java -> JSON] */ public void clearJsonBeanProcessors() { beanProcessorMap.clear(); } /** * Removes all registered listener for JSON Events.<br> * [Java -> JSON] */ public synchronized void clearJsonEventListeners() { eventListeners.clear(); } /** * Removes all registered PropertyNameProcessors.<br> * [Java -> JSON] */ public void clearJsonPropertyNameProcessors() { jsonPropertyNameProcessorMap.clear(); } /** * Removes all registered JsonValueProcessors.<br> * [Java -> JSON] */ public void clearJsonValueProcessors() { beanKeyMap.clear(); beanTypeMap.clear(); keyMap.clear(); typeMap.clear(); } /** * Removes all property exclusions registered per class.<br> * [Java -> JSON] */ public void clearPropertyExclusions() { exclusionMap.clear(); } /** * Removes all registered PropertyNameProcessors.<br> * [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.<br> * [Java -> JSON] */ public void disableEventTriggering() { triggerEvents = false; } /** * Enables event triggering when building.<br> * [Java -> JSON] */ public void enableEventTriggering() { triggerEvents = true; } /** * Finds a DefaultValueProcessor registered to the target class.<br> * Returns null if none is registered.<br> * [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.<br> * Returns null if none is registered.<br> * [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.<br> * Returns null if none is registered.<br> * [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.<br> * Returns null if none is registered.<br> * [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.<br> * Returns null if none is registered.<br> * [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.<br> * It will search the registered JsonValueProcessors in the following order: * <ol> * <li>beanClass, key</li> * <li>beanClass, type</li> * <li>key</li> * <li>type</li> * </ol> * Returns null if none is registered.<br> * [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.<br> * It will search the registered JsonValueProcessors in the following order: * <ol> * <li>key</li> * <li>type</li> * </ol> * Returns null if none is registered.<br> * [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.<br> * Returns null if none is registered. <br> * [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.<br> * [JSON -> Java] * * @return MODE_OBJECT_ARRAY, MODE_LIST or MODE_SET */ public int getArrayMode() { return arrayMode; } /** * Returns the current attribute/class Map.<br> * [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.<br> * [JSON -> Java] * * @return the target collection class for conversion */ public Class getCollectionType() { return collectionType; } /** * Returns the configured CycleDetectionStrategy.<br> * Default value is CycleDetectionStrategy.STRICT<br> * [Java -> JSON] */ public CycleDetectionStrategy getCycleDetectionStrategy() { return cycleDetectionStrategy; } /** * Returns the configured DefaultValueProcessorMatcher.<br> * Default value is DefaultValueProcessorMatcher.DEFAULT<br> * [Java -> JSON] */ public DefaultValueProcessorMatcher getDefaultValueProcessorMatcher() { return defaultValueProcessorMatcher; } /** * Returns the current enclosed type for generic collection transformations.<br> * [JSON -> Java] * * @return the target type for conversion */ public Class getEnclosedType() { return enclosedType; } /** * Returns the configured properties for exclusion. <br> * [Java -> JSON] */ public String[] getExcludes() { return excludes; } /** * Returns the configured JavaIdentifierTransformer. <br> * Default value is JavaIdentifierTransformer.NOOP<br> * [JSON -> Java] */ public JavaIdentifierTransformer getJavaIdentifierTransformer() { return javaIdentifierTransformer; } /** * Returns the configured property filter when serializing to Java.<br> * [JSON -> Java] */ public PropertyFilter getJavaPropertyFilter() { return javaPropertyFilter; } /** * Returns the configured PropertyNameProcessorMatcher.<br> * Default value is PropertyNameProcessorMatcher.DEFAULT<br> * [JSON -> Java] */ public PropertyNameProcessorMatcher getJavaPropertyNameProcessorMatcher() { return javaPropertyNameProcessorMatcher; } /** * Returns the configured JsonBeanProcessorMatcher.<br> * Default value is JsonBeanProcessorMatcher.DEFAULT<br> * [JSON -> Java] */ public JsonBeanProcessorMatcher getJsonBeanProcessorMatcher() { return jsonBeanProcessorMatcher; } /** * Returns a list of registered listeners for JSON events.<br> * [JSON -> Java] */ public synchronized List getJsonEventListeners() { return eventListeners; } /** * Returns the configured property filter when serializing to JSON.<br> * [Java -> JSON] */ public PropertyFilter getJsonPropertyFilter() { return jsonPropertyFilter; } /** * Returns the configured PropertyNameProcessorMatcher.<br> * Default value is PropertyNameProcessorMatcher.DEFAULT<br> * [Java -> JSON] */ public PropertyNameProcessorMatcher getJsonPropertyNameProcessorMatcher() { return javaPropertyNameProcessorMatcher; } /** * Returns the configured JsonValueProcessorMatcher.<br> * Default value is JsonValueProcessorMatcher.DEFAULT<br> * [Java -> JSON] */ public JsonValueProcessorMatcher getJsonValueProcessorMatcher() { return jsonValueProcessorMatcher; } /** * Returns a set of default excludes with user-defined excludes.<br> * [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.<br> * 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.<br> * Default value is NewBeanInstanceStrategy.DEFAULT<br> * [JSON -> Java] */ public NewBeanInstanceStrategy getNewBeanInstanceStrategy() { return newBeanInstanceStrategy; } /** * Returns the configured PropertyExclusionClassMatcher.<br> * Default value is PropertyExclusionClassMatcher.DEFAULT<br> * [JSON -> Java] */ public PropertyExclusionClassMatcher getPropertyExclusionClassMatcher() { return propertyExclusionClassMatcher; } /** * Returns the configured PropertyNameProcessorMatcher.<br> * Default value is PropertyNameProcessorMatcher.DEFAULT<br> * [JSON -> Java] * * @deprecated use getJavaPropertyNameProcessorMatcher() instead */ public PropertyNameProcessorMatcher getPropertyNameProcessorMatcher() { return getJavaPropertyNameProcessorMatcher(); } /** * Returns the configured PropertySetStrategy.<br> * Default value is PropertySetStrategy.DEFAULT<br> * [JSON -> Java] */ public PropertySetStrategy getPropertySetStrategy() { return propertySetStrategy; } /** * Returns the current root Class.<br> * [JSON -> Java] * * @return the target class for conversion */ public Class getRootClass() { return rootClass; } /** * Returns true if non-String keys are allowed on JSONObject.<br> * Default value is false<br> * [Java -> JSON] */ public boolean isAllowNonStringKeys() { return allowNonStringKeys; } /** * Returns true if event triggering is enabled during building.<br> * Default value is false<br> * [Java -> JSON] */ public boolean isEventTriggeringEnabled() { return triggerEvents; } /** * Returns true if this Jettison convention will be handled when converting to Java.<br> * Jettison assumes that "" (empty string) can be assigned to empty elements (objects), which * clearly violates the JSON spec.<br> * [JSON -> Java] */ public boolean isHandleJettisonEmptyElement() { return handleJettisonEmptyElement; } /** * Returns true if this jettison convention will be handled when converting to Java.<br> * Jettison states the following JSON {'media':{'title':'hello'}} can be set as a single element * JSONArray (media is the array).<br> * [JSON -> Java] */ public boolean isHandleJettisonSingleElementArray() { return handleJettisonSingleElementArray; } /** * Returns true if default excludes will not be used.<br> * Default value is false.<br> * [Java -> JSON] */ public boolean isIgnoreDefaultExcludes() { return ignoreDefaultExcludes; } /** * Returns true if JPA Transient annotated methods should be ignored.<br> * Default value is false.<br> * [Java -> JSON] */ public boolean isIgnoreJPATransient() { return ignoreFieldAnnotations.contains("javax.persistence.Transient"); } /** * Returns true if transient fields of a bean will be ignored.<br> * Default value is false.<br> * [Java -> JSON] */ public boolean isIgnoreTransientFields() { return ignoreTransientFields; } /** * Returns true if public fields of a bean will be ignored.<br> * Default value is true.<br> * [Java -> JSON] */ public boolean isIgnorePublicFields() { return ignorePublicFields; } /** * Returns true if Javascript compatibility is turned on.<br> * Default value is false.<br> * [Java -> JSON] */ public boolean isJavascriptCompliant() { return javascriptCompliant; } /** * Returns true if map keys will not be transformed.<br> * Default value is false.<br> * [JSON -> Java] */ public boolean isSkipJavaIdentifierTransformationInMapKeys() { return skipJavaIdentifierTransformationInMapKeys; } /** * Registers a DefaultValueProcessor.<br> * [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.<br> * [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.<br> * [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.<br> * [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.<br> * [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.<br> * [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.<br> * [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.<br> * [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.<br> * [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.<br> * [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.<br> * [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.<br> * [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.<br> * [Java -> JSON] */ public void setAllowNonStringKeys(boolean allowNonStringKeys) { this.allowNonStringKeys = allowNonStringKeys; } /** * Sets the current array mode for conversion.<br> * If the value is not MODE_LIST, MODE_OBJECT_ARRAY nor MODE_SET, then MODE_LIST will be used.<br> * [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<br> * [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.<br> * [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.<br> * Will set default value (CycleDetectionStrategy.STRICT) if null.<br> * [Java -> JSON] */ public void setCycleDetectionStrategy(CycleDetectionStrategy cycleDetectionStrategy) { this.cycleDetectionStrategy = cycleDetectionStrategy == null ? DEFAULT_CYCLE_DETECTION_STRATEGY : cycleDetectionStrategy; } /** * Sets a DefaultValueProcessorMatcher to use.<br> * Will set default value (DefaultValueProcessorMatcher.DEFAULT) if null.<br> * [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.<br> * [JSON -> Java] * * @param enclosedType the target type for conversion */ public void setEnclosedType(Class enclosedType) { this.enclosedType = enclosedType; } /** * Sets the excludes to use.<br> * Will set default value ([]) if null.<br> * [Java -> JSON] */ public void setExcludes(String[] excludes) { this.excludes = excludes == null ? EMPTY_EXCLUDES : excludes; } /** * Activate/Deactivate handling this jettison convention when converting to Java.<br> * Jettison states that "" (empty string) can be assigned to empty elements (objects), which * clearly violates the JSON spec.<br> * [JSON -> Java] */ public void setHandleJettisonEmptyElement(boolean handleJettisonEmptyElement) { this.handleJettisonEmptyElement = handleJettisonEmptyElement; } /** * Activate/Deactivate handling this jettison convention when converting to Java.<br> * Jettison * states the following JSON {'media':{'title':'hello'}} can be set as a single element JSONArray * (media is the array).<br> * [JSON -> Java] */ public void setHandleJettisonSingleElementArray(boolean handleJettisonSingleElementArray) { this.handleJettisonSingleElementArray = handleJettisonSingleElementArray; } /** * Sets if default excludes would be skipped when building.<br> * [Java -> JSON] */ public void setIgnoreDefaultExcludes(boolean ignoreDefaultExcludes) { this.ignoreDefaultExcludes = ignoreDefaultExcludes; } /** * Sets if JPA Transient annotated methods would be skipped when building.<br> * [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.<br> * [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.<br> * [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.<br> * [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.<br> * [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.<br> * [Java -> JSON] */ public List getIgnoreFieldAnnotations() { return Collections.unmodifiableList(ignoreFieldAnnotations); } /** * Sets if transient fields would be skipped when building.<br> * [Java -> JSON] */ public void setIgnoreTransientFields(boolean ignoreTransientFields) { this.ignoreTransientFields = ignoreTransientFields; } /** * Sets if public fields would be skipped when building.<br> * [Java -> JSON] */ public void setIgnorePublicFields(boolean ignorePublicFields) { this.ignorePublicFields = ignorePublicFields; } /** * Sets if Javascript compatibility is enabled when building.<br> * [Java -> JSON] */ public void setJavascriptCompliant(boolean javascriptCompliant) { this.javascriptCompliant = javascriptCompliant; } /** * Sets the JavaIdentifierTransformer to use.<br> * Will set default value (JavaIdentifierTransformer.NOOP) if null.<br> * [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.<br> * [JSON -> Java] * * @param javaPropertyFilter the property filter */ public void setJavaPropertyFilter(PropertyFilter javaPropertyFilter) { this.javaPropertyFilter = javaPropertyFilter; } /** * Sets a PropertyNameProcessorMatcher to use.<br> * Will set default value (PropertyNameProcessorMatcher.DEFAULT) if null.<br> * [JSON -> Java] */ public void setJavaPropertyNameProcessorMatcher(PropertyNameProcessorMatcher propertyNameProcessorMatcher) { this.javaPropertyNameProcessorMatcher = propertyNameProcessorMatcher == null ? DEFAULT_PROPERTY_NAME_PROCESSOR_MATCHER : propertyNameProcessorMatcher; } /** * Sets a JsonBeanProcessorMatcher to use.<br> * Will set default value (JsonBeanProcessorMatcher.DEFAULT) if null.<br> * [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.<br> * [Java -> JSON] * * @param jsonPropertyFilter the property filter */ public void setJsonPropertyFilter(PropertyFilter jsonPropertyFilter) { this.jsonPropertyFilter = jsonPropertyFilter; } /** * Sets a PropertyNameProcessorMatcher to use.<br> * Will set default value (PropertyNameProcessorMatcher.DEFAULT) if null.<br> * [Java -> JSON] */ public void setJsonPropertyNameProcessorMatcher(PropertyNameProcessorMatcher propertyNameProcessorMatcher) { this.jsonPropertyNameProcessorMatcher = propertyNameProcessorMatcher == null ? DEFAULT_PROPERTY_NAME_PROCESSOR_MATCHER : propertyNameProcessorMatcher; } /** * Sets a JsonValueProcessorMatcher to use.<br> * Will set default value (JsonValueProcessorMatcher.DEFAULT) if null.<br> * [Java -> JSON] */ public void setJsonValueProcessorMatcher(JsonValueProcessorMatcher jsonValueProcessorMatcher) { this.jsonValueProcessorMatcher = jsonValueProcessorMatcher == null ? DEFAULT_JSON_VALUE_PROCESSOR_MATCHER : jsonValueProcessorMatcher; } /** * Sets the NewBeanInstanceStrategy to use.<br> * Will set default value (NewBeanInstanceStrategy.DEFAULT) if null.<br> * [JSON -> Java] */ public void setNewBeanInstanceStrategy(NewBeanInstanceStrategy newBeanInstanceStrategy) { this.newBeanInstanceStrategy = newBeanInstanceStrategy == null ? DEFAULT_NEW_BEAN_INSTANCE_STRATEGY : newBeanInstanceStrategy; } /** * Sets a PropertyExclusionClassMatcher to use.<br> * Will set default value (PropertyExclusionClassMatcher.DEFAULT) if null.<br> * [Java -> JSON] */ public void setPropertyExclusionClassMatcher(PropertyExclusionClassMatcher propertyExclusionClassMatcher) { this.propertyExclusionClassMatcher = propertyExclusionClassMatcher == null ? DEFAULT_PROPERTY_EXCLUSION_CLASS_MATCHER : propertyExclusionClassMatcher; } /** * Sets a PropertyNameProcessorMatcher to use.<br> * Will set default value (PropertyNameProcessorMatcher.DEFAULT) if null.<br> * [JSON -> Java] * * @deprecated use setJavaPropertyNameProcessorMatcher() instead */ public void setPropertyNameProcessorMatcher(PropertyNameProcessorMatcher propertyNameProcessorMatcher) { setJavaPropertyNameProcessorMatcher(propertyNameProcessorMatcher); } /** * Sets a PropertySetStrategy to use.<br> * Will set default value (PropertySetStrategy.DEFAULT) if null.<br> * [JSON -> Java] */ public void setPropertySetStrategy(PropertySetStrategy propertySetStrategy) { this.propertySetStrategy = propertySetStrategy; } /** * Sets the current root Class.<br> * [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.<br> * [JSON -> Java] */ public void setSkipJavaIdentifierTransformationInMapKeys(boolean skipJavaIdentifierTransformationInMapKeys) { this.skipJavaIdentifierTransformationInMapKeys = skipJavaIdentifierTransformationInMapKeys; } /** * Removes a DefaultValueProcessor.<br> * [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.<br> * [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.<br> * [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.<br> * [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.<br> * [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.<br> * [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.<br> * [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.<br> * [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.<br> * [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.<br> * [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.<br> * [JSON -> Java] * * @param target a class used for searching a PropertyNameProcessor. * * @deprecated use unregisterJavaPropertyNameProcessor() instead */ public void unregisterPropertyNameProcessor(Class target) { unregisterJavaPropertyNameProcessor(target); } }