blob: d3b047aa8f88d47284a7fb6769b8c80515a491ba [file] [log] [blame]
/*
* Copyright (c) 2010, 2019 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
package org.glassfish.jersey.jettison;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* An immutable configuration of JSON notation and options. {@code JettisonConfig}
* instance can be used for configuring the JSON notation on {@link JettisonJaxbContext}.
*
* @author Jakub Podlesak
*/
public class JettisonConfig {
/**
* Enumeration of supported JSON notations.
*/
public enum Notation {
/**
* The mapped Jettison JSON notation.
* <p>Example JSON expression:<pre>
* {"userTable":{"columns":[{"id":"userid","label":"UserID"},{"id":"name","label":"User Name"}],"rows":{"userid":1621,"name":"Grotefend"}}}
* </pre>
*/
MAPPED_JETTISON,
/**
* The mapped Badgerfish JSON notation.
* <p>Example JSON expression:<pre>
* {"userTable":{"columns":[{"id":{"$":"userid"},"label":{"$":"UserID"}},{"id":{"$":"name"},"label":{"$":"User Name"}}],"rows":{"userid":{"$":"1621"},"name":{"$":"Grotefend"}}}}
* </pre>
*/
BADGERFISH
}
private final Notation notation;
private final Map<String, String> jsonXml2JsonNs;
private final List<String> serializeAsArray;
/**
* Builder class for constructing {@link JettisonConfig} options
*/
public static class Builder {
private final Notation notation;
protected Map<String, String> jsonXml2JsonNs = new HashMap<String, String>(0);
protected List<String> serializeAsArray = new LinkedList<String>();
private Builder(final Notation notation) {
this.notation = notation;
}
/**
* Constructs a new immutable {@link JettisonConfig} object based on options set on this Builder
*
* @return a non-null {@link JettisonConfig} instance
*/
public JettisonConfig build() {
return new JettisonConfig(this);
}
private void copyAttributes(final JettisonConfig jc) {
jsonXml2JsonNs.putAll(jc.getXml2JsonNs());
serializeAsArray.addAll(jc.getArrayElements());
}
}
/**
* Builder class for constructing {@link JettisonConfig} options
* for the {@link JettisonConfig.Notation#MAPPED_JETTISON} convention.
*/
public static class MappedJettisonBuilder extends Builder {
private MappedJettisonBuilder(final Notation notation) {
super(notation);
}
/**
* Setter for XML to JSON namespace mapping.
* This property is valid for the {@link JettisonConfig.Notation#MAPPED_JETTISON}
* notation only.
* <p>
* 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.
* <p>
* The default value is a map with zero key/value pairs.
*
* @param jsonXml2JsonNs XML to JSON namespace map.
* @return updated builder instance.
*/
public MappedJettisonBuilder xml2JsonNs(final Map<String, String> jsonXml2JsonNs) {
this.jsonXml2JsonNs = jsonXml2JsonNs;
return this;
}
/**
* Add element names to be treated as arrays.
* This property is valid for the {@link JettisonConfig.Notation#MAPPED_JETTISON}
* notation only.
* <p>
* Property value is a list of element names that should be treated
* as arrays even if only a single item is present.
* <p>
* The default value is an empty list.
*
* @param arrays names to be serialized as arrays.
* @return updated builder instance.
*/
public MappedJettisonBuilder serializeAsArray(final String... arrays) {
return serializeAsArray(Arrays.asList(arrays));
}
/**
* Add element names to be treated as arrays.
* This property is valid for the {@link JettisonConfig.Notation#MAPPED_JETTISON}
* notation only.
* <p>
* Property value is a list of element names that should be treated
* as arrays even if only a single item is present.
* <p>
* The default value is an empty list.
*
* @param arrays of element names to be serialized as arrays.
* @return updated builder instance.
*/
public MappedJettisonBuilder serializeAsArray(final List<String> arrays) {
this.serializeAsArray.addAll(arrays);
return this;
}
}
private JettisonConfig(final Builder b) {
notation = b.notation;
jsonXml2JsonNs = b.jsonXml2JsonNs;
serializeAsArray = b.serializeAsArray;
}
/**
* A static method for obtaining {@link JettisonConfig} instance with humanReadableFormatting
* set according to formatted parameter.
*
* @param c original instance of {@link JettisonConfig}, can't be null
* @return copy of provided {@link JettisonConfig} with humanReadableFormatting set to formatted.
* @throws IllegalArgumentException when provided {@code JettisonConfig} is null.
*/
public static JettisonConfig createJSONConfiguration(final JettisonConfig c) throws IllegalArgumentException {
if (c == null) {
throw new IllegalArgumentException("JettisonConfig can't be null");
}
final Builder b = copyBuilder(c);
return b.build();
}
/**
* The default {@code JettisonConfig} uses {@link JettisonConfig.Notation#MAPPED_JETTISON}
* notation with root unwrapping option set to true.
*/
public static final JettisonConfig DEFAULT = mappedJettison().build();
/**
* A static method for obtaining a builder of {@link JettisonConfig} instance, which will use {@link JettisonConfig.Notation#MAPPED_JETTISON} JSON notation.
* After getting the builder, you can set configuration options on it and finally get an immutable {@code JettisonConfig}
* instance using the {@link JettisonConfig.Builder#build() } method.
*
* @return a builder for {@code JettisonConfig} instance
*/
public static MappedJettisonBuilder mappedJettison() {
return new MappedJettisonBuilder(Notation.MAPPED_JETTISON);
}
/**
* A static method for obtaining a builder of {@link JettisonConfig} instance, which will use {@link JettisonConfig.Notation#BADGERFISH} JSON notation.
* After getting the builder, you can set configuration options on it and finally get an immutable {@code JettisonConfig}
* instance using the {@link JettisonConfig.Builder#build() } method.
*
* @return a builder for {@code JettisonConfig} instance
*/
public static Builder badgerFish() {
return new Builder(Notation.BADGERFISH);
}
public static Builder copyBuilder(final JettisonConfig jc) {
Builder result = new Builder(jc.getNotation());
switch (jc.notation) {
case BADGERFISH:
result = new Builder(jc.getNotation());
break;
case MAPPED_JETTISON:
result = new MappedJettisonBuilder(jc.getNotation());
break;
}
result.copyAttributes(jc);
return result;
}
/**
* Returns JSON notation selected for this configuration
* @return JSON notation
*/
public Notation getNotation() {
return notation;
}
/**
* Returns a map for XML to JSON namespace mapping
* This property is valid for the {@link JettisonConfig.Notation#MAPPED_JETTISON}
* notation only.
* @return a map for XML to JSON namespace mapping.
* @see JettisonConfig.MappedJettisonBuilder#xml2JsonNs(java.util.Map)
*/
public Map<String, String> getXml2JsonNs() {
return (jsonXml2JsonNs != null) ? Collections.unmodifiableMap(jsonXml2JsonNs) : null;
}
/**
* Returns a list of elements to be treated as arrays. I.e. these elements will be serialized
* as arrays even if only a single element is included.
* This property is valid for the {@link JettisonConfig.Notation#MAPPED_JETTISON}
* notation only.
* @return a list of elements representing arrays.
* @see JettisonConfig.MappedJettisonBuilder#serializeAsArray(java.util.List)
*/
public List<String> getArrayElements() {
return Collections.unmodifiableList(serializeAsArray);
}
@Override
public String toString() {
return String.format("{notation:%s}", notation);
}
}