All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.jersey.api.json.JSONJAXBContext Maven / Gradle / Ivy

The newest version!
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2010-2011 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * http://glassfish.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */
package com.sun.jersey.api.json;

import com.sun.jersey.json.impl.BaseJSONMarshaller;
import com.sun.jersey.json.impl.BaseJSONUnmarshaller;
import com.sun.jersey.json.impl.JSONMarshallerImpl;
import com.sun.jersey.json.impl.JSONUnmarshallerImpl;
import com.sun.xml.bind.v2.runtime.JAXBContextImpl;

import javax.xml.bind.*;
import java.util.*;

/**
 * An adaption of {@link JAXBContext} that supports marshalling
 * and unmarshalling of JAXB beans using the JSON format.
 * 

* The JSON format may be configured by using a {@link JSONConfiguration} object * as a constructor parameter of this class. */ public final class JSONJAXBContext extends JAXBContext implements JSONConfigurated { /** * A namespace for JSONJAXBContext related properties names. */ @Deprecated public static final String NAMESPACE = "com.sun.jersey.impl.json."; /** * Enumeration of supported JSON notations. */ @Deprecated public enum JSONNotation { /** * The mapped (default) JSON notation. */ @Deprecated MAPPED, /** * The mapped Jettison JSON notation. */ @Deprecated MAPPED_JETTISON, /** * The mapped Badgerfish JSON notation. */ @Deprecated BADGERFISH, /** * The natural JSON notation, leveraging tight JAXB RI integration. */ @Deprecated NATURAL }; /** * JSON notation property is now deprecated. See {@link JSONConfiguration}. *

* The type of this property is enum type {@link JSONNotation}. *

* The value may be one of the following that are the currently supported JSON * notations: JSONNotation.MAPPED, * JSONNotation.MAPPED_JETTISON and JSONNotation.BADGERFISH *

* The default value is JSONNotation.MAPPED. */ @Deprecated public static final String JSON_NOTATION = NAMESPACE + "notation"; /** * JSON enabled property is now deprecated. See {@link JSONConfiguration}. *

* The type of this property is {@link Boolean} *

* If set to true, JSON will be serialized/deserialized instead of XML *

* The default value is false. */ @Deprecated public static final String JSON_ENABLED = NAMESPACE + "enabled"; /** * XML root element unwrapping property is now deprecated. See {@link JSONConfiguration}. *

* The type of this property is {@link Boolean} *

* If set to true, JSON code corresponding to the XML root element will be stripped out * for JSONNotation.MAPPED (default) notation. *

* The default value is false. */ @Deprecated public static final String JSON_ROOT_UNWRAPPING = NAMESPACE + "root.unwrapping"; /** * JSON arrays property is now deprecated. See {@link JSONConfiguration}. * This property is valid for the JSONNotation.MAPPED notation only. *

* The type of this property is java.util.Collection<String>. *

* The value is a collection of string values that are * object names. * The value of an object name in the JSON document that exists in the collection * of object names will be declared as an array, even if only one * element is present. *

* For example, consider that the property value is not set and the * JSON document is { ..., "arr1":"single element", ... }. * If the property value is set to contain "arr1" then * the JSON document would be { ..., "arr1":["single element"], ... }. *

* The default value is an empty collection. */ @Deprecated public static final String JSON_ARRAYS = NAMESPACE + "arrays"; /** * JSON non-string values property is now deprecated. See {@link JSONConfiguration}. * This property is valid for the JSONNotation.MAPPED notation only. *

* The type of this property is Collection<String>. *

* The value is collection of string values that are * object names. * The value of an object name in the JSON document that exists in the collection * of object names will be declared as non-string value, which is not surrounded * by double quotes. *

* For example, consider that the property value is not set and the * JSON document is { ..., "anumber":"12", ... }. * If the property value is set to contain "anumber" * then the JSON document would be { ..., "anumber":12, ... }. *

* The default value is an empty collection. */ @Deprecated public static final String JSON_NON_STRINGS = NAMESPACE + "non.strings"; /** * JSON attributes as elements property is now deprecated. See {@link JSONConfiguration}. * This property is valid for the JSONNotation.MAPPED notation only. *

* The type of this property is Collection<String>. *

* The value is a collection of string values that are * object names that correspond to XML attribute information items. * The value of an object name in the JSON document that exists in the collection * of object names will be declared as an element as not as an attribute if * the object corresponds to an XML attribute information item. *

* For example, consider that the property value is not set and the * JSON document is { ..., "@number":"12", ... }. * If the property value is set contain "number" * then the JSON document would be { ..., "number":"12", ... }. *

* The default value is an empty collection. */ @Deprecated public static final String JSON_ATTRS_AS_ELEMS = NAMESPACE + "attrs.as.elems"; /** * XML to JSON namespace mapping property is now deprecated. See {@link JSONConfiguration}. * This property is valid for the MAPPED_JETTISON notation only. *

*

* The type of this property is Map<String,String>. *

* The value is a map with zero or more * key/value pairs, where the key is an XML namespace and the value * is the prefix to use as the replacement for the XML namespace. *

* The default value is a map with zero key/value pairs. */ @Deprecated public static final String JSON_XML2JSON_NS = NAMESPACE + "xml.to.json.ns"; private static final Map defaultJsonProperties = new HashMap(); static { defaultJsonProperties.put(JSON_NOTATION, JSONNotation.MAPPED); defaultJsonProperties.put(JSON_ROOT_UNWRAPPING, Boolean.TRUE); } private JSONConfiguration jsonConfiguration; private final JAXBContext jaxbContext; /** * Constructs a new instance with default {@link JSONConfiguration}. * * @param classesToBeBound list of java classes to be recognized by the * new JSONJAXBContext. Can be empty, in which case a JSONJAXBContext * that only knows about spec-defined classes will be returned. * @throws JAXBException if an error was encountered while creating the * underlying JAXBContext. */ public JSONJAXBContext(Class... classesToBeBound) throws JAXBException { this(JSONConfiguration.DEFAULT, classesToBeBound); } /** * Constructs a new instance with given {@link JSONConfiguration}. * * @param config {@link JSONConfiguration}, can not be null * @param classesToBeBound list of java classes to be recognized by the * new JSONJAXBContext. Can be empty, in which case a JSONJAXBContext * that only knows about spec-defined classes will be returned. * @throws JAXBException if an error was encountered while creating the * underlying JAXBContext. */ public JSONJAXBContext(final JSONConfiguration config, final Class... classesToBeBound) throws JAXBException { if (config == null) { throw new IllegalArgumentException("JSONConfiguration MUST not be null"); } jsonConfiguration = config; if (config.getNotation() == JSONConfiguration.Notation.NATURAL) { jaxbContext = JAXBContext.newInstance(classesToBeBound, Collections.singletonMap(JAXBContextImpl.RETAIN_REFERENCE_TO_INFO, true)); } else { jaxbContext = JAXBContext.newInstance(classesToBeBound); } } /** * Constructs a new instance with a custom set of properties. * The default {@link JSONConfiguration} is used if no (now deprecated) * JSON related properties are specified * * @param classesToBeBound list of java classes to be recognized by the * new JSONJAXBContext. Can be empty, in which case a JSONJAXBContext * that only knows about spec-defined classes will be returned. * @param properties the custom set of properties. If it contains(now deprecated) JSON related properties, * then a non-default {@link JSONConfiguration} is used reflecting the JSON properties * @throws JAXBException if an error was encountered while creating the * underlying JAXBContext. */ public JSONJAXBContext(Class[] classesToBeBound, Map properties) throws JAXBException { jaxbContext = JAXBContext.newInstance(classesToBeBound, createProperties(properties)); if (jsonConfiguration == null) { jsonConfiguration = JSONConfiguration.DEFAULT; } } /** * Constructs a new instance with a custom set of properties. * If no (now deprecated) JSON related properties are specified, * the {@link JSONConfiguration#DEFAULT} is used as {@link JSONConfiguration} * * @param config {@link JSONConfiguration}, can not be null * @param classesToBeBound list of java classes to be recognized by the * new JSONJAXBContext. Can be empty, in which case a JSONJAXBContext * that only knows about spec-defined classes will be returned. * @param properties the custom set of properties. * @throws JAXBException if an error was encountered while creating the * underlying JAXBContext. */ public JSONJAXBContext(final JSONConfiguration config, final Class[] classesToBeBound, final Map properties) throws JAXBException { if (config == null) { throw new IllegalArgumentException("JSONConfiguration MUST not be null"); } jsonConfiguration = config; if (config.getNotation() == JSONConfiguration.Notation.NATURAL) { Map myProps = new HashMap(properties.size() + 1); myProps.putAll(properties); myProps.put(JAXBContextImpl.RETAIN_REFERENCE_TO_INFO, Boolean.TRUE); jaxbContext = JAXBContext.newInstance(classesToBeBound, myProps); } else { jaxbContext = JAXBContext.newInstance(classesToBeBound, properties); } } /** * Construct a new instance of using context class loader of the thread * with default {@link JSONConfiguration}. * * @param contextPath list of java package names that contain schema * derived class and/or java to schema (JAXB-annotated) mapped * classes * @throws JAXBException if an error was encountered while creating the * underlying JAXBContext. */ public JSONJAXBContext(String contextPath) throws JAXBException { this(JSONConfiguration.DEFAULT, contextPath); } /** * Construct a new instance of using context class loader of the thread * with given {@link JSONConfiguration}. * * @param config {@link JSONConfiguration}, can not be null * @param contextPath list of java package names that contain schema * derived class and/or java to schema (JAXB-annotated) mapped * classes * @throws JAXBException if an error was encountered while creating the * underlying JAXBContext. */ public JSONJAXBContext(JSONConfiguration config, String contextPath) throws JAXBException { if (config == null) { throw new IllegalArgumentException("JSONConfiguration MUST not be null"); } if (config.getNotation() == JSONConfiguration.Notation.NATURAL) { jaxbContext = JAXBContext.newInstance(contextPath, Thread.currentThread().getContextClassLoader(), Collections.singletonMap(JAXBContextImpl.RETAIN_REFERENCE_TO_INFO, true)); } else { jaxbContext = JAXBContext.newInstance(contextPath, Thread.currentThread().getContextClassLoader()); } jsonConfiguration = config; } /** * Construct a new instance using a specified class loader with * default {@link JSONConfiguration}. * * @param contextPath list of java package names that contain schema * derived class and/or java to schema (JAXB-annotated) mapped * classes * @param classLoader * @throws JAXBException if an error was encountered while creating the * underlying JAXBContext. */ public JSONJAXBContext(String contextPath, ClassLoader classLoader) throws JAXBException { jaxbContext = JAXBContext.newInstance(contextPath, classLoader); jsonConfiguration = JSONConfiguration.DEFAULT; } /** * Construct a new instance using a specified class loader and * a custom set of properties. {@link JSONConfiguration} is set to default, * if user does not specify any (now deprecated) JSON related properties * * @param contextPath list of java package names that contain schema * derived class and/or java to schema (JAXB-annotated) mapped * classes * @param classLoader * @param properties the custom set of properties. * @throws JAXBException if an error was encountered while creating the * underlying JAXBContext. */ public JSONJAXBContext(String contextPath, ClassLoader classLoader, Map properties) throws JAXBException { jaxbContext = JAXBContext.newInstance(contextPath, classLoader, createProperties(properties)); if (jsonConfiguration == null) { jsonConfiguration = JSONConfiguration.DEFAULT; } } /** * Construct a new instance using a specified class loader, * set of properties and {@link JSONConfiguration} . * * @param config {@link JSONConfiguration}, can not be null * @param contextPath list of java package names that contain schema * derived class and/or java to schema (JAXB-annotated) mapped * classes * @param classLoader * @param properties the custom set of properties. * @throws JAXBException if an error was encountered while creating the * underlying JAXBContext. */ public JSONJAXBContext(JSONConfiguration config, String contextPath, ClassLoader classLoader, Map properties) throws JAXBException { if (config == null) { throw new IllegalArgumentException("JSONConfiguration MUST not be null"); } if (config.getNotation() == JSONConfiguration.Notation.NATURAL) { Map myProps = new HashMap(properties.size() + 1); myProps.putAll(properties); myProps.put(JAXBContextImpl.RETAIN_REFERENCE_TO_INFO, Boolean.TRUE); jaxbContext = JAXBContext.newInstance(contextPath, classLoader, myProps); } else { jaxbContext = JAXBContext.newInstance(contextPath, classLoader, properties); } jsonConfiguration = config; } /** * Get a {@link JSONMarshaller} from a {@link Marshaller}. * * @param marshaller the JAXB marshaller. * @return the JSON marshaller. */ public static JSONMarshaller getJSONMarshaller(Marshaller marshaller) { if (marshaller instanceof JSONMarshaller) { return (JSONMarshaller) marshaller; } else { return new BaseJSONMarshaller(marshaller, JSONConfiguration.DEFAULT); } } /** * Get a {@link JSONUnmarshaller} from a {@link Unmarshaller}. * * @param unmarshaller the JAXB unmarshaller. * @return the JSON unmarshaller. */ public static JSONUnmarshaller getJSONUnmarshaller(Unmarshaller unmarshaller) { if (unmarshaller instanceof JSONUnmarshaller) { return (JSONUnmarshaller) unmarshaller; } else { return new BaseJSONUnmarshaller(unmarshaller, JSONConfiguration.DEFAULT); } } /** * Get the JSON configuration. * * @return the JSON configuration. */ public JSONConfiguration getJSONConfiguration() { return jsonConfiguration; } /** * Create a JSON unmarshaller. * * @return the JSON unmarshaller * * @throws JAXBException if there is an error creating the unmarshaller. */ public JSONUnmarshaller createJSONUnmarshaller() throws JAXBException { return new JSONUnmarshallerImpl(this, getJSONConfiguration()); } /** * Create a JSON marshaller. * * @return the JSON marshaller. * * @throws JAXBException if there is an error creating the marshaller. */ public JSONMarshaller createJSONMarshaller() throws JAXBException { return new JSONMarshallerImpl(this, getJSONConfiguration()); } /** * Overrides underlaying createUnmarshaller method and returns * an unmarshaller which is capable of JSON deserialization. * * @return unmarshaller instance with JSON capabilities * @throws javax.xml.bind.JAXBException */ @Override public Unmarshaller createUnmarshaller() throws JAXBException { return new JSONUnmarshallerImpl(jaxbContext, getJSONConfiguration()); } /** * Overrides underlaying createMarshaller method and returns * a marshaller which is capable of JSON serialization. * * @return marshaller instance with JSON capabilities * @throws javax.xml.bind.JAXBException */ @Override public Marshaller createMarshaller() throws JAXBException { return new JSONMarshallerImpl(jaxbContext, getJSONConfiguration()); } /** * Simply delegates to underlying JAXBContext implementation. * * @return what underlying JAXBContext returns * @throws javax.xml.bind.JAXBException */ @Override public Validator createValidator() throws JAXBException { return jaxbContext.createValidator(); } static final Map _notationMap = new HashMap() { { put(JSONJAXBContext.JSONNotation.BADGERFISH.toString(), JSONConfiguration.Notation.BADGERFISH); put(JSONJAXBContext.JSONNotation.MAPPED.toString(), JSONConfiguration.Notation.MAPPED); put(JSONJAXBContext.JSONNotation.MAPPED_JETTISON.toString(), JSONConfiguration.Notation.MAPPED_JETTISON); put(JSONJAXBContext.JSONNotation.NATURAL.toString(), JSONConfiguration.Notation.NATURAL); } }; private Map createProperties(Map properties) { Map workProperties = new HashMap(); workProperties.putAll(defaultJsonProperties); workProperties.putAll(properties); if (JSONJAXBContext.JSONNotation.NATURAL == workProperties.get(JSONJAXBContext.JSON_NOTATION)) { workProperties.put(JAXBContextImpl.RETAIN_REFERENCE_TO_INFO, Boolean.TRUE); } processProperties(workProperties); return workProperties; } private final void processProperties(Map properties) { final Collection jsonKeys = new HashSet(); for (String k : Collections.unmodifiableSet(properties.keySet())) { if (k.startsWith(NAMESPACE)) { jsonKeys.add(k); } } if (!jsonKeys.isEmpty()) { if (jsonConfiguration == null) { JSONConfiguration.Notation pNotation = JSONConfiguration.Notation.MAPPED; if (properties.containsKey(JSONJAXBContext.JSON_NOTATION)) { Object nO = properties.get(JSONJAXBContext.JSON_NOTATION); if ((nO instanceof JSONJAXBContext.JSONNotation) || (nO instanceof String)) { pNotation = _notationMap.get(nO.toString()); } } jsonConfiguration = getConfiguration(pNotation, properties); } } for (String k : jsonKeys) { properties.remove(k); } } private JSONConfiguration getConfiguration(JSONConfiguration.Notation pNotation, Map properties) { String[] a = new String[0]; switch (pNotation) { case BADGERFISH: return JSONConfiguration.badgerFish().build(); case MAPPED_JETTISON: JSONConfiguration.MappedJettisonBuilder mappedJettisonBuilder = JSONConfiguration.mappedJettison(); if (properties.containsKey(JSONJAXBContext.JSON_XML2JSON_NS)) { mappedJettisonBuilder.xml2JsonNs((Map) properties.get(JSONJAXBContext.JSON_XML2JSON_NS)); } return mappedJettisonBuilder.build(); case NATURAL: return JSONConfiguration.natural().build(); case MAPPED: default: { JSONConfiguration.MappedBuilder mappedBuilder = JSONConfiguration.mapped(); if (properties.containsKey(JSONJAXBContext.JSON_ARRAYS)) { mappedBuilder.arrays(((Collection) properties.get(JSONJAXBContext.JSON_ARRAYS)).toArray(a)); } if (properties.containsKey(JSONJAXBContext.JSON_ATTRS_AS_ELEMS)) { mappedBuilder.attributeAsElement(((Collection) properties.get(JSONJAXBContext.JSON_ATTRS_AS_ELEMS)).toArray(a)); } if (properties.containsKey(JSONJAXBContext.JSON_NON_STRINGS)) { mappedBuilder.nonStrings(((Collection) properties.get(JSONJAXBContext.JSON_NON_STRINGS)).toArray(a)); } if (properties.containsKey(JSONJAXBContext.JSON_ROOT_UNWRAPPING)) { mappedBuilder.rootUnwrapping((Boolean) properties.get(JSONJAXBContext.JSON_ROOT_UNWRAPPING)); } return mappedBuilder.build(); } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy