Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.spincast.plugins.jacksonjson.SpincastJsonManager Maven / Gradle / Ivy
package org.spincast.plugins.jacksonjson;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import javax.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spincast.core.config.SpincastConfig;
import org.spincast.core.json.JsonArray;
import org.spincast.core.json.JsonManager;
import org.spincast.core.json.JsonObject;
import org.spincast.core.json.JsonObjectFactory;
import org.spincast.core.json.JsonObjectOrArray;
import org.spincast.core.json.JsonPathUtils;
import org.spincast.core.request.Form;
import org.spincast.core.request.FormFactory;
import org.spincast.core.utils.SpincastStatics;
import org.spincast.core.utils.SpincastUtils;
import org.spincast.shaded.org.apache.commons.lang3.StringUtils;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.core.util.DefaultIndenter;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter.Indenter;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Provider;
/**
* Spincast Jackson Json manager
*/
public class SpincastJsonManager implements JsonManager {
protected static final Logger logger = LoggerFactory.getLogger(SpincastJsonManager.class);
public static final String ENUM_SERIALIZER_FIELD_NAME_NAME = "name";
public static final String ENUM_SERIALIZER_FIELD_NAME_LABEL = "label";
private final JsonObjectFactory jsonObjectFactory;
private final Provider guiceProvider;
private final Set jsonMixinInfos;
private final SpincastConfig spincastConfig;
private final SpincastJsonManagerConfig spincastJsonManagerConfig;
private final JsonPathUtils jsonPathUtils;
private final SpincastUtils spincastUtils;
private final FormFactory formFactory;
private ObjectMapper objectMapper;
private JsonSerializer jsonObjectSerializer;
private JsonDeserializer jsonObjectDeserializer;
private JsonSerializer jsonArraySerializer;
private JsonDeserializer jsonArrayDeserializer;
private JsonSerializer dateSerializer;
private JsonSerializer instantSerializer;
private JsonSerializer bigDecimalSerializer;
private DefaultPrettyPrinter jacksonPrettyPrinter;
private JsonSerializer> enumSerializer;
@Inject
public SpincastJsonManager(Provider guiceProvider,
JsonObjectFactory jsonObjectFactory,
@Nullable Set jsonMixinInfos,
SpincastJsonManagerConfig spincastJsonManagerConfig,
SpincastConfig spincastConfig,
JsonPathUtils jsonPathUtils,
SpincastUtils spincastUtils,
FormFactory formFactory) {
this.guiceProvider = guiceProvider;
this.jsonObjectFactory = jsonObjectFactory;
if (jsonMixinInfos == null) {
jsonMixinInfos = new HashSet();
}
this.jsonMixinInfos = jsonMixinInfos;
this.spincastJsonManagerConfig = spincastJsonManagerConfig;
this.spincastConfig = spincastConfig;
this.jsonPathUtils = jsonPathUtils;
this.spincastUtils = spincastUtils;
this.formFactory = formFactory;
}
protected Injector getGuice() {
return this.guiceProvider.get();
}
protected JsonObjectFactory getJsonObjectFactory() {
return this.jsonObjectFactory;
}
protected Set getJsonMixinInfos() {
return this.jsonMixinInfos;
}
protected SpincastJsonManagerConfig getSpincastJsonManagerConfig() {
return this.spincastJsonManagerConfig;
}
protected SpincastConfig getSpincastConfig() {
return this.spincastConfig;
}
protected JsonPathUtils getJsonPathUtils() {
return this.jsonPathUtils;
}
protected SpincastUtils getSpincastUtils() {
return this.spincastUtils;
}
protected FormFactory getFormFactory() {
return this.formFactory;
}
protected DefaultPrettyPrinter getJacksonPrettyPrinter() {
if (this.jacksonPrettyPrinter == null) {
this.jacksonPrettyPrinter = new DefaultPrettyPrinter();
Indenter indenter = new DefaultIndenter(getJacksonPrettyPrinterIndentation(), getJacksonPrettyPrinterNewline());
this.jacksonPrettyPrinter.indentObjectsWith(indenter);
this.jacksonPrettyPrinter.indentArraysWith(indenter);
}
return this.jacksonPrettyPrinter;
}
protected String getJacksonPrettyPrinterNewline() {
return getSpincastJsonManagerConfig().getPrettyPrinterNewlineChars();
}
protected String getJacksonPrettyPrinterIndentation() {
return StringUtils.repeat(" ", getSpincastJsonManagerConfig().getPrettyPrinterIndentationSpaceNumber());
}
protected ObjectMapper getObjectMapper() {
if (this.objectMapper == null) {
ObjectMapper objectMapper = createObjectManager();
registerCustomModules(objectMapper);
this.objectMapper = objectMapper;
}
return this.objectMapper;
}
/**
* Creates the ObjectMapper
*/
protected ObjectMapper createObjectManager() {
ObjectMapper objectMapper = new ObjectMapper();
configureObjectMapper(objectMapper);
return objectMapper;
}
/**
* Configuration of the ObjectMapper.
*/
protected void configureObjectMapper(ObjectMapper objectMapper) {
objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, isAllowCommentsInJson());
//==========================================
// To allow serialization of "empty" POJOs (no properties to serialize)
// (without this setting, an exception is thrown in those cases)
//==========================================
configureEmptyBeans(objectMapper);
//==========================================
// Add the mixins, if any.
//==========================================
configureMixins(objectMapper);
}
/**
* Should comments be accepted in Json?
* @see https://github.com/FasterXML/jackson-core/wiki/JsonParser-Features#support-for-non-standard-data-format-constructs
*/
protected boolean isAllowCommentsInJson() {
//==========================================
// Accepted by default
//==========================================
return true;
}
protected void configureEmptyBeans(ObjectMapper objectMapper) {
objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
}
protected void configureMixins(ObjectMapper objectMapper) {
for (JsonMixinInfo jsonMixinInfo : getJsonMixinInfos()) {
objectMapper.addMixIn(jsonMixinInfo.getTargetClass(), jsonMixinInfo.getMixinClass());
}
}
protected JsonSerializer getJsonObjectSerializer() {
if (this.jsonObjectSerializer == null) {
this.jsonObjectSerializer = new JsonSerializer() {
@Override
public void serialize(JsonObject jsonObject,
JsonGenerator gen,
SerializerProvider serializers)
throws IOException, JsonProcessingException {
if (jsonObject == null) {
return;
}
Map asMap = jsonObject.convertToPlainMap();
gen.writeObject(asMap);
}
};
}
return this.jsonObjectSerializer;
}
protected JsonSerializer> getEnumSerializer() {
if (this.enumSerializer == null) {
this.enumSerializer = new JsonSerializer>() {
@Override
public void serialize(Enum> enumValue,
JsonGenerator gen,
SerializerProvider serializers)
throws IOException, JsonProcessingException {
if (enumValue == null) {
return;
}
Map enumObj = new HashMap();
enumObj.put(ENUM_SERIALIZER_FIELD_NAME_NAME, enumValue.name());
enumObj.put(ENUM_SERIALIZER_FIELD_NAME_LABEL, enumValue.toString());
gen.writeObject(enumObj);
}
};
}
return this.enumSerializer;
}
protected JsonSerializer getJsonArraySerializer() {
if (this.jsonArraySerializer == null) {
this.jsonArraySerializer = new JsonSerializer() {
@Override
public void serialize(JsonArray jsonArray,
JsonGenerator gen,
SerializerProvider serializers)
throws IOException, JsonProcessingException {
if (jsonArray == null) {
return;
}
List asList = jsonArray.convertToPlainList();
gen.writeObject(asList);
}
};
}
return this.jsonArraySerializer;
}
protected JsonSerializer getDateSerializer() {
if (this.dateSerializer == null) {
this.dateSerializer = new JsonSerializer() {
@Override
public void serialize(Date date,
JsonGenerator gen,
SerializerProvider serializers)
throws IOException, JsonProcessingException {
if (date == null) {
return;
}
String dateStr = SpincastStatics.getIso8601DateParserDefault().format(date);
gen.writeObject(dateStr);
}
};
}
return this.dateSerializer;
}
protected JsonSerializer getInstantSerializer() {
if (this.instantSerializer == null) {
this.instantSerializer = new JsonSerializer() {
@Override
public void serialize(Instant instant,
JsonGenerator gen,
SerializerProvider serializers)
throws IOException, JsonProcessingException {
if (instant == null) {
return;
}
getDateSerializer().serialize(Date.from(instant), gen, serializers);
}
};
}
return this.instantSerializer;
}
protected JsonSerializer getBigDecimalSerializer() {
if (this.bigDecimalSerializer == null) {
this.bigDecimalSerializer = new JsonSerializer() {
@Override
public void serialize(BigDecimal bigDecimal,
JsonGenerator gen,
SerializerProvider serializers)
throws IOException, JsonProcessingException {
if (bigDecimal == null) {
return;
}
gen.writeObject(bigDecimal.toPlainString());
}
};
}
return this.bigDecimalSerializer;
}
protected JsonDeserializer getJsonObjectDeserializer() {
if (this.jsonObjectDeserializer == null) {
this.jsonObjectDeserializer = new JsonDeserializer() {
@Override
public JsonObject deserialize(JsonParser jsonParser,
DeserializationContext context)
throws IOException,
JsonProcessingException {
JsonObject jsonObject = getJsonObjectFactory().create();
JsonToken jsonToken = jsonParser.getCurrentToken();
if (jsonToken == JsonToken.START_OBJECT) {
jsonToken = jsonParser.nextToken();
} else {
throw new RuntimeException("Invalid json object");
}
while (jsonToken != null) {
if (jsonToken != JsonToken.FIELD_NAME) {
break;
}
String name = jsonParser.getCurrentName();
jsonToken = jsonParser.nextToken();
if (jsonToken == JsonToken.START_OBJECT) {
jsonObject.set(name, deserialize(jsonParser, context));
} else if (jsonToken == JsonToken.START_ARRAY) {
jsonObject.set(name, getJsonArrayDeserializer().deserialize(jsonParser, context));
} else if (jsonToken == JsonToken.VALUE_EMBEDDED_OBJECT) {
jsonObject.set(name, jsonParser.getEmbeddedObject());
} else if (jsonToken == JsonToken.VALUE_NULL) {
jsonObject.set(name, null);
} else if (jsonToken == JsonToken.VALUE_STRING) {
jsonObject.set(name, jsonParser.getText());
} else if (jsonToken == JsonToken.VALUE_TRUE) {
jsonObject.set(name, true);
} else if (jsonToken == JsonToken.VALUE_FALSE) {
jsonObject.set(name, false);
} else if (jsonToken == JsonToken.VALUE_NUMBER_INT ||
jsonToken == JsonToken.VALUE_NUMBER_FLOAT) {
jsonObject.set(name, jsonParser.getNumberValue());
} else {
throw new RuntimeException("Unmanaged json token type : " + jsonToken);
}
jsonToken = jsonParser.nextToken();
}
return jsonObject;
}
};
}
return this.jsonObjectDeserializer;
}
protected JsonDeserializer getJsonArrayDeserializer() {
if (this.jsonArrayDeserializer == null) {
this.jsonArrayDeserializer = new JsonDeserializer() {
@Override
public JsonArray deserialize(JsonParser jsonParser,
DeserializationContext context)
throws IOException,
JsonProcessingException {
JsonArray jsonArray = getJsonObjectFactory().createArray();
JsonToken jsonToken = jsonParser.getCurrentToken();
if (jsonToken == JsonToken.START_ARRAY) {
jsonToken = jsonParser.nextToken();
} else {
throw new RuntimeException("Invalid json array");
}
while (jsonToken != null) {
if (jsonToken == JsonToken.END_ARRAY) {
break;
}
if (jsonToken == JsonToken.START_OBJECT) {
jsonArray.add(getJsonObjectDeserializer().deserialize(jsonParser, context));
} else if (jsonToken == JsonToken.START_ARRAY) {
jsonArray.add(deserialize(jsonParser, context));
} else if (jsonToken == JsonToken.VALUE_EMBEDDED_OBJECT) {
jsonArray.add(jsonParser.getEmbeddedObject());
} else if (jsonToken == JsonToken.VALUE_NULL) {
jsonArray.add(null);
} else if (jsonToken == JsonToken.VALUE_STRING) {
jsonArray.add(jsonParser.getText());
} else if (jsonToken == JsonToken.VALUE_TRUE) {
jsonArray.add(true);
} else if (jsonToken == JsonToken.VALUE_FALSE) {
jsonArray.add(false);
} else if (jsonToken == JsonToken.VALUE_NUMBER_INT ||
jsonToken == JsonToken.VALUE_NUMBER_FLOAT) {
jsonArray.add(jsonParser.getNumberValue());
} else {
throw new RuntimeException("Unmanaged json token type : " + jsonToken);
}
jsonToken = jsonParser.nextToken();
}
return jsonArray;
}
};
}
return this.jsonArrayDeserializer;
}
protected void registerCustomModules(ObjectMapper objectMapper) {
registerJsonObjectModule(objectMapper);
registerCustomTypeSerializerModule(objectMapper);
registerJava8DatatypesModule(objectMapper);
}
/**
* Register our custom (de)serializers for JsonObject
*/
@SuppressWarnings({"unchecked", "rawtypes"})
protected void registerJsonObjectModule(ObjectMapper objectMapper) {
SimpleModule module = new SimpleModule();
module.addSerializer(JsonObject.class, getJsonObjectSerializer());
module.addDeserializer(JsonObject.class, getJsonObjectDeserializer());
module.addSerializer(JsonArray.class, getJsonArraySerializer());
module.addDeserializer(JsonArray.class, getJsonArrayDeserializer());
if (getSpincastJsonManagerConfig().isSerializeEnumsToNameAndLabelObjects()) {
module.addSerializer((Class)Enum.class, getEnumSerializer());
}
objectMapper.registerModule(module);
}
/**
* Register our custom serializers for some types.
*/
protected void registerCustomTypeSerializerModule(ObjectMapper objectMapper) {
SimpleModule module = new SimpleModule();
module.addSerializer(Date.class, getDateSerializer());
module.addSerializer(Instant.class, getInstantSerializer());
module.addSerializer(BigDecimal.class, getBigDecimalSerializer());
objectMapper.registerModule(module);
}
protected void registerJava8DatatypesModule(ObjectMapper objectMapper) {
objectMapper.registerModule(new Jdk8Module());
}
@Override
public String toJsonString(Object obj) {
return toJsonString(obj, false);
}
@Override
public String toJsonString(Object obj, boolean pretty) {
try {
if (pretty) {
return getObjectMapper().writer(getJacksonPrettyPrinter()).writeValueAsString(obj);
} else {
return getObjectMapper().writeValueAsString(obj);
}
} catch (Exception ex) {
throw SpincastStatics.runtimize(ex);
}
}
/**
* Once the deserialization of an Object is done,
* we inject dependencies using Guice.
*/
protected void injectDependencies(Object obj) {
if (obj != null) {
getGuice().injectMembers(obj);
}
}
@Override
public JsonObject create() {
return getJsonObjectFactory().create();
}
@Override
public JsonArray createArray() {
return getJsonObjectFactory().createArray();
}
@Override
public JsonObject fromObject(Object object) {
JsonObject jsonObj = getObjectMapper().convertValue(object, JsonObject.class);
return jsonObj;
}
@Override
public T fromString(String jsonString, Class clazz) {
if (jsonString == null) {
return null;
}
try {
T jsonObj = getObjectMapper().readValue(jsonString, clazz);
injectDependencies(jsonObj);
return jsonObj;
} catch (Exception ex) {
throw SpincastStatics.runtimize(ex);
}
}
@Override
public T fromInputStream(InputStream inputStream, Class clazz) {
if (inputStream == null) {
return null;
}
try {
T jsonObj = getObjectMapper().readValue(inputStream, clazz);
injectDependencies(jsonObj);
return jsonObj;
} catch (Exception ex) {
throw SpincastStatics.runtimize(ex);
}
}
@Override
public Map fromStringToMap(String jsonString) {
if (jsonString == null) {
return null;
}
try {
Map map = getObjectMapper().readValue(jsonString, new TypeReference>() {});
return map;
} catch (Exception ex) {
throw SpincastStatics.runtimize(ex);
}
}
@Override
public Map fromInputStreamToMap(InputStream inputStream) {
if (inputStream == null) {
return null;
}
try {
Map map = getObjectMapper().readValue(inputStream,
new TypeReference>() {});
return map;
} catch (Exception ex) {
throw SpincastStatics.runtimize(ex);
}
}
@Override
public JsonObject fromString(String jsonString) {
if (jsonString == null) {
return null;
}
try {
JsonObject obj = getObjectMapper().readValue(jsonString, JsonObject.class);
return obj;
} catch (Exception ex) {
throw SpincastStatics.runtimize(ex);
}
}
@Override
public JsonObject fromMap(Map params) {
if (params == null) {
return null;
}
return fromMap(params, false);
}
@Override
public JsonObject fromMap(Map params, boolean parseKeysAsJsonPaths) {
if (params == null) {
return null;
}
JsonObject root = getJsonObjectFactory().create();
if (parseKeysAsJsonPaths && params.size() > getMaxNumberOfKeysWhenConvertingMapToJsonObject()) {
throw new RuntimeException("Too many keys to parse : " + params.size() + " as JsonPaths. " +
"The maximum is currently set to " + getMaxNumberOfKeysWhenConvertingMapToJsonObject());
}
for (Entry entry : params.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
if (parseKeysAsJsonPaths) {
putElementAtJsonPath(root, key, value, true);
} else {
root.setNoKeyParsing(key, value);
}
}
return root;
}
@Override
public JsonObject fromInputStream(InputStream inputStream) {
if (inputStream == null) {
return null;
}
try {
JsonObject obj = getObjectMapper().readValue(inputStream, JsonObject.class);
return obj;
} catch (Exception ex) {
throw SpincastStatics.runtimize(ex);
}
}
@Override
public JsonObject fromFile(File jsonFile) {
if (jsonFile == null || !jsonFile.exists()) {
return null;
}
try {
JsonObject obj = getObjectMapper().readValue(jsonFile, JsonObject.class);
return obj;
} catch (Exception ex) {
throw SpincastStatics.runtimize(ex);
}
}
@Override
public JsonObject fromFile(String path) {
Objects.requireNonNull(path, "The path can't be NULL");
File file = new File(path);
return fromFile(file);
}
@Override
public JsonObject fromClasspathFile(String path) {
Objects.requireNonNull(path, "The path can't be NULL");
String content = getSpincastUtils().readClasspathFile(path);
return fromString(content);
}
@Override
public JsonArray fromCollectionToJsonArray(Collection> collection) {
JsonArray jsonArray = getObjectMapper().convertValue(collection, JsonArray.class);
return jsonArray;
}
@Override
public JsonArray fromStringArray(String jsonString) {
if (jsonString == null) {
return null;
}
try {
JsonArray obj = getObjectMapper().readValue(jsonString, JsonArray.class);
return obj;
} catch (Exception ex) {
throw SpincastStatics.runtimize(ex);
}
}
@Override
public JsonArray fromListArray(List> elements) {
if (elements == null) {
return null;
}
JsonArray array = createArray();
if (elements != null) {
for (Object element : elements) {
array.add(element);
}
}
return array;
}
@Override
public JsonArray fromInputStreamArray(InputStream inputStream) {
if (inputStream == null) {
return null;
}
try {
JsonArray obj = getObjectMapper().readValue(inputStream, JsonArray.class);
return obj;
} catch (Exception ex) {
throw SpincastStatics.runtimize(ex);
}
}
protected int getMaxNumberOfKeysWhenConvertingMapToJsonObject() {
return getSpincastConfig().getMaxNumberOfKeysWhenConvertingMapToJsonObject();
}
@Override
public Object getElementAtJsonPath(JsonObject obj, String jsonPath) {
return getJsonPathUtils().getElementAtJsonPath(obj, jsonPath);
}
@Override
public Object getElementAtJsonPath(JsonObject obj, String jsonPath, Object defaultValue) {
return getJsonPathUtils().getElementAtJsonPath(obj, jsonPath, defaultValue);
}
@Override
public Object getElementAtJsonPath(JsonArray array, String jsonPath) {
return getJsonPathUtils().getElementAtJsonPath(array, jsonPath);
}
@Override
public Object getElementAtJsonPath(JsonArray array, String jsonPath, Object defaultValue) {
return getJsonPathUtils().getElementAtJsonPath(array, jsonPath, defaultValue);
}
@Override
public void putElementAtJsonPath(JsonObjectOrArray objOrArray, String jsonPath, Object value) {
putElementAtJsonPath(objOrArray, jsonPath, value, false);
}
@Override
public void putElementAtJsonPath(JsonObjectOrArray objOrArray, String jsonPath, Object value, boolean clone) {
if (clone) {
value = clone(value);
}
getJsonPathUtils().putElementAtJsonPath(objOrArray, jsonPath, value);
}
@Override
public Form createForm(String formName) {
return getFormFactory().createForm(formName, null);
}
@Override
public String convertToJsonDate(Date date) {
return SpincastStatics.getIso8601DateParserDefault().format(date);
}
/**
* Currently support ISO 8601 encoded dates.
*/
@Override
public Date parseDateFromJson(String str) {
return SpincastStatics.parseISO8601date(str);
}
@Override
public Object convertToNativeType(Object originalObject) {
if (originalObject == null) {
return null;
}
//==========================================
// Already a native type
//==========================================
if ((originalObject instanceof String) ||
(originalObject instanceof Integer) ||
(originalObject instanceof Long) ||
(originalObject instanceof Float) ||
(originalObject instanceof Double) ||
(originalObject instanceof Boolean) ||
(originalObject instanceof BigDecimal) ||
(originalObject instanceof byte[]) ||
(originalObject instanceof Date) ||
(originalObject instanceof Instant) ||
(originalObject instanceof JsonObject) ||
(originalObject instanceof JsonArray)) {
return originalObject;
}
//==========================================
// Array or Collection
//==========================================
if (originalObject instanceof Collection>) {
JsonArray array = createArray();
for (Object element : (Collection>)originalObject) {
array.add(element);
}
return array;
} else if (originalObject instanceof Object[]) {
JsonArray array = createArray();
for (Object element : (Object[])originalObject) {
array.add(element);
}
return array;
} else if (originalObject instanceof Map) {
JsonObject obj = create();
Map, ?> map = (Map, ?>)originalObject;
for (Entry, ?> entry : map.entrySet()) {
if (entry.getKey() == null) {
throw new RuntimeException("Cannot convert a Map to a JsonObject when a key is NULL.");
}
obj.setNoKeyParsing(String.valueOf(entry.getKey()),
entry.getValue());
}
return obj;
}
//==========================================
// Why this? Don't we want ".name" and ".label" to be generated?
// We would have that using the "Converts to a JsonObject"
// code below because of our custom Json serializer.
//
// But only using the *names* of the enum values
// is very useful since it is then possible to use
// the serialized data as is in some filters. For
// example :
//
// {{something | checked(menuItemForm.availabilityTypes)}}
//
// Here, if "menuItemForm.availabilityTypes" was an object with
// ".name" and ".label" properties, the filter wouldn't work.
//
// To convert an enum to a "friendly" JsonObject, one can
// use the "enumToFriendlyJsonObject(...)" and
// "enumsToFriendlyJsonArray(...)" methods.
//==========================================
else if (originalObject instanceof Enum>) {
return ((Enum>)originalObject).name();
}
//==========================================
// Converts to a JsonObject or returns as
// a string
//==========================================
String jsonStr = toJsonString(originalObject);
if (jsonStr.startsWith("\"") && jsonStr.endsWith("\"") && jsonStr.length() > 1) {
jsonStr = jsonStr.substring(1, jsonStr.length() - 1);
return jsonStr;
}
JsonObject jsonObject = fromString(jsonStr);
return jsonObject;
}
@Override
public JsonObject cloneJsonObject(JsonObject jsonObject, boolean mutable) {
return (JsonObject)clone(jsonObject, mutable);
}
@Override
public JsonArray cloneJsonArray(JsonArray jsonArray, boolean mutable) {
return (JsonArray)clone(jsonArray, mutable);
}
@Override
public Object clone(Object originalObject) {
return clone(originalObject, true);
}
@Override
public Object clone(Object originalObject, boolean mutable) {
if (originalObject == null) {
return null;
}
if ((originalObject instanceof String) ||
(originalObject instanceof Integer) ||
(originalObject instanceof Long) ||
(originalObject instanceof Float) ||
(originalObject instanceof Double) ||
(originalObject instanceof Boolean) ||
(originalObject instanceof BigDecimal) ||
(originalObject instanceof byte[]) ||
(originalObject instanceof Date)) {
return originalObject;
} else if (originalObject instanceof JsonObject) {
JsonObject jsonObj = (JsonObject)originalObject;
//==========================================
// Already immutable, no need to clone!
//==========================================
if (!mutable && !jsonObj.isMutable()) {
return jsonObj;
}
Map map = new HashMap();
for (Entry entry : jsonObj) {
Object elementClone = clone(entry.getValue(), mutable);
map.put(entry.getKey(), elementClone);
}
return getJsonObjectFactory().create(map, mutable);
} else if (originalObject instanceof JsonArray) {
JsonArray array = (JsonArray)originalObject;
//==========================================
// Already immutable, no need to clone!
//==========================================
if (!mutable && !array.isMutable()) {
return array;
}
List elements = new ArrayList();
for (Object element : array) {
Object elementClone = clone(element, mutable);
elements.add(elementClone);
}
return getJsonObjectFactory().createArray(elements, mutable);
} else {
return convertToNativeType(originalObject);
}
}
@Override
public void removeElementAtJsonPath(JsonObject obj, String jsonPath) {
getJsonPathUtils().removeElementAtJsonPath(obj, jsonPath);
}
@Override
public void removeElementAtJsonPath(JsonArray array, String jsonPath) {
getJsonPathUtils().removeElementAtJsonPath(array, jsonPath);
}
@Override
public boolean isElementExists(JsonObject obj, String jsonPath) {
return getJsonPathUtils().isElementExists(obj, jsonPath);
}
@Override
public boolean isElementExists(JsonArray array, String jsonPath) {
return getJsonPathUtils().isElementExists(array, jsonPath);
}
@Override
public JsonObject enumToFriendlyJsonObject(Enum> enumValue) {
if (enumValue == null) {
return null;
}
JsonObject obj = create();
obj.set(ENUM_SERIALIZER_FIELD_NAME_NAME, enumValue.name());
obj.set(ENUM_SERIALIZER_FIELD_NAME_LABEL, enumValue.toString());
return obj;
}
@Override
public JsonArray enumsToFriendlyJsonArray(Enum>[] enumValues) {
JsonArray arr = createArray();
if (enumValues == null || enumValues.length == 0) {
return arr;
}
for (Enum> enumValue : enumValues) {
arr.add(enumToFriendlyJsonObject(enumValue));
}
return arr;
}
}