org.apache.fulcrum.json.gson.GSONBuilderService Maven / Gradle / Ivy
The newest version!
package org.apache.fulcrum.json.gson;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
import java.lang.reflect.Type;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.EnumSet;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Set;
import java.util.concurrent.Callable;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.fulcrum.json.JsonService;
import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.jayway.jsonpath.Option;
import com.jayway.jsonpath.spi.json.GsonJsonProvider;
import com.jayway.jsonpath.spi.json.JsonProvider;
import com.jayway.jsonpath.spi.mapper.GsonMappingProvider;
import com.jayway.jsonpath.spi.mapper.MappingProvider;
/**
*
* By default multiple serialization of the same object in a single thread is
* not support (e.g adapter + default for the same bean / object).
*
*
* @author gk
* @version $Id: GSONBuilderService.java 1890800 2021-06-15 08:33:26Z gk $
*
*/
public class GSONBuilderService extends AbstractLogEnabled implements
JsonService, Initializable, Configurable {
private static final String GLOBAL_ADAPTERS = "globalAdapters";
private static final String DATE_FORMAT = "dateFormat";
private static final String USEJSONPATH = "useJsonPath";
private String dateFormat;
private Hashtable adapters = null;
private boolean useJsonPath = false;
GsonBuilder gson;
@Override
public String ser(Object src) throws Exception {
getLogger().debug("ser" + src);
return gson.create().toJson(src);
}
@Override
public String ser(Object src, Class type) throws Exception {
getLogger().debug("ser::" + src + " with type" + type);
Type collectionType = new TypeToken() {
}.getType();
return gson.create().toJson(src, collectionType);
}
@Override
public T deSer(String json, Class type) throws Exception {
// TODO Auto-generated method stub
getLogger().debug("deser:" + json);
return gson.create().fromJson(json, type);
}
@Override
public Collection deSerCollection(String json, Object collectionType,
Class elementType) throws Exception {
getLogger().debug("deser:" + json);
getLogger().debug("collectionType:" + collectionType);
return gson.create().fromJson(json, (Type)collectionType);
}
@Override
public String serializeOnlyFilter(Object src, String... filterAttr)
throws Exception {
return gson
.addSerializationExclusionStrategy(
include(null,filterAttr)).create().toJson(src);
}
@Override
public String serializeOnlyFilter(Object src, Boolean notused,
String... filterAttr) throws Exception {
return gson
.addSerializationExclusionStrategy(
include(null,filterAttr)).create().toJson(src);
}
@Override
public String serializeOnlyFilter(Object src, Class filterClass,
String... filterAttr) throws Exception {
return gson
.addSerializationExclusionStrategy(
include(filterClass, filterAttr)).create().toJson(src);
}
@Override
public String serializeOnlyFilter(Object arg0, Class arg1,
Boolean arg2, String... arg3) throws Exception {
throw new Exception("Not yet implemented!");
}
/**
* registering an adapter
*
* @see GsonBuilder#registerTypeAdapter(Type, Object)
*/
@Override
public JsonService addAdapter(String name, Class target, Object adapter)
throws Exception {
gson.registerTypeAdapter(target, adapter);
return this;
}
/**
* registering an adapter. Unregistering could be only done by reinitialize {@link GsonBuilder}
* using @link {@link GSONBuilderService#initialize()}, although a new Adapter with the same target overwrites the previously defined.
*
* @see GsonBuilder#registerTypeAdapter(Type, Object)
*/
@Override
public JsonService addAdapter(String name, Class target, Class adapter)
throws Exception {
gson.registerTypeAdapter(target, adapter.getConstructor().newInstance());
return null;
}
@Override
public String serializeAllExceptFilter(Object src,
Class filterClass, String... filterAttr) throws Exception {
return gson
.addSerializationExclusionStrategy(
exclude(filterClass, filterAttr)).create().toJson(src);
}
@Override
public String serializeAllExceptFilter(Object src, Class filterClass,
Boolean clearCache, String... filterAttr) throws Exception {
throw new Exception("Not yet implemented!");
}
@Override
public String serializeAllExceptFilter(Object src, String... filterAttr)
throws Exception {
return gson
.addSerializationExclusionStrategy(
exclude(null, filterAttr)).create().toJson(src);
}
@Override
public String serializeAllExceptFilter(Object src, Boolean notused,
String... filterAttr) throws Exception {
return gson
.addSerializationExclusionStrategy(
exclude(null, filterAttr)).create().toJson(src);
}
@Override
public String ser(Object src, Boolean refreshCache) throws Exception {
throw new Exception("Not implemented!");
}
@Override
public String ser(Object src, Class type, Boolean refreshCache)
throws Exception {
throw new Exception("Not implemented!");
}
public JsonService registerTypeAdapter(Object serdeser, Type type) {
gson.registerTypeAdapter(type, serdeser);
return this;
}
/**
* Alternative method to calling {@link #registerTypeAdapter(Object, Type)}
* Note: Always use either this direct format call or the other adapter register call,
* otherwise inconsistencies may occur!
*
* @param dfStr date format string
*/
public void setDateFormat(final String dfStr) {
gson.setDateFormat(dfStr);
}
/* (non-Javadoc)
* @see org.apache.fulcrum.json.JsonService#setDateFormat(java.text.DateFormat)
*/
@Override
public void setDateFormat(final DateFormat df) {
DateTypeAdapter dateTypeAdapter = new DateTypeAdapter();
dateTypeAdapter.setCustomDateFormat(df);
gson.registerTypeAdapter(Date.class,dateTypeAdapter);
}
public void getJsonService() throws InstantiationException {
// gson.registerTypeAdapter(Date.class, ser).
// addSerializationExclusionStrategy( exclude(ObjectKey.class) ).
// addSerializationExclusionStrategy( exclude(ComboKey.class) );
// return gson.create().toJson( src );
}
/* (non-Javadoc)
* @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
*/
@Override
public void configure(Configuration conf) throws ConfigurationException {
getLogger().debug("conf.getName()" + conf.getName());
final Configuration configuredDateFormat = conf.getChild(DATE_FORMAT,
false);
if (configuredDateFormat != null) {
this.dateFormat = configuredDateFormat.getValue();// DEFAULTDATEFORMAT);
}
final Configuration configuredAdapters = conf.getChild(GLOBAL_ADAPTERS,
true);
if (configuredAdapters != null) {
Configuration[] nameVal = configuredAdapters.getChildren();
for (int i = 0; i < nameVal.length; i++) {
String key = nameVal[i].getName();
getLogger().debug("configured key: " + key);
if (key.equals("adapter")) {
String forClass = nameVal[i].getAttribute("forClass");
this.adapters = new Hashtable();
this.adapters.put(forClass, nameVal[i].getValue());
}
}
}
// TODO provide configurable Type Adapters
final Configuration configuredjsonPath = conf.getChild(
USEJSONPATH, false);
if (configuredjsonPath != null) {
this.useJsonPath = configuredjsonPath.getValueAsBoolean();
}
}
/* (non-Javadoc)
* @see org.apache.avalon.framework.activity.Initializable#initialize()
*/
@Override
public void initialize() throws Exception {
gson = new GsonBuilder();
getLogger().debug("initialized: gson:" + gson);
if (dateFormat != null) {
getLogger().info("setting date format to: " + dateFormat);
setDateFormat(new SimpleDateFormat(dateFormat));
//setDateFormat(dateFormat);
}
if (adapters != null) {
Enumeration enumKey = adapters.keys();
while (enumKey.hasMoreElements()) {
String forClass = enumKey.nextElement();
String avClass = adapters.get(forClass);
if (avClass != null) {
try {
getLogger().debug(
"initializing: adapters " + avClass
+ " forClass:" + forClass);
Class adapterForClass = Class.forName(forClass);
Class adapterClass = Class.forName(avClass);
addAdapter("Test Adapter", adapterForClass,
adapterClass);
} catch (Exception e) {
throw new InstantiationException(
"JsonMapperService: Error instantiating one of the adapters: "
+ avClass + " for " + forClass);
}
}
}
}
if (useJsonPath) {
// set it before runtime
com.jayway.jsonpath.Configuration.setDefaults(new com.jayway.jsonpath.Configuration.Defaults() {
private Callable gsonFuture = new Callable() {
@Override
public Gson call() {
return GSONBuilderService.this.gson.create();
}
};
private final JsonProvider jsonProvider = new GsonJsonProvider(GSONBuilderService.this.gson.create());
private final MappingProvider mappingProvider = new GsonMappingProvider(gsonFuture);
@Override
public JsonProvider jsonProvider() {
return jsonProvider;
}
@Override
public MappingProvider mappingProvider() {
return mappingProvider;
}
@Override
public Set