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.
act.util.JsonUtilConfig Maven / Gradle / Ivy
package act.util;
/*-
* #%L
* ACT Framework
* %%
* Copyright (C) 2014 - 2017 ActFramework
* %%
* 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.
* #L%
*/
import static act.app.event.SysEventId.CLASS_LOADER_INITIALIZED;
import static com.alibaba.fastjson.JSON.DEFAULT_GENERATE_FEATURE;
import act.Act;
import act.app.ActionContext;
import act.app.App;
import act.app.event.AppClassLoaderInitialized;
import act.cli.util.MappedFastJsonNameFilter;
import act.conf.AppConfig;
import act.data.DataPropertyRepository;
import act.event.SysEventListenerBase;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.PropertyNamingStrategy;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.serializer.*;
import com.alibaba.fastjson.util.TypeUtils;
import org.joda.time.*;
import org.osgl.$;
import org.osgl.OsglConfig;
import org.osgl.exception.NotAppliedException;
import org.osgl.mvc.MvcConfig;
import org.osgl.storage.ISObject;
import org.osgl.storage.impl.SObject;
import org.osgl.util.*;
import java.io.StringWriter;
import java.io.Writer;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
public class JsonUtilConfig {
public static class JsonWriter extends $.Visitor {
private final Object v;
private SerializerFeature[] features;
private SerializeFilter[] filters;
private SerializeConfig config;
private DateFormat dateFormat;
private boolean disableCircularReferenceDetect = true;
private boolean isLargeResponse;
private String sv;
public JsonWriter(Object v, PropertySpec.MetaInfo spec, boolean format, ActContext context) {
if (null == v) {
this.v = "{}";
this.isLargeResponse = false;
this.sv = (String)v;
} else if (v instanceof String) {
String s = S.string(v).trim();
int len = s.length();
if (0 == len) {
this.v = "{}";
} else {
char a = s.charAt(0);
char z = s.charAt(len - 1);
if (('{' == a && '}' == z) || ('[' == a && ']' == z)) {
this.v = s;
} else {
this.v = "{\"result\":" + s + "}";
}
}
this.isLargeResponse = ((String) v).length() > OsglConfig.getThreadLocalCharBufferLimit();
this.sv = (String) v;
} else {
this.v = v;
AppConfig config = Act.appConfig();
Locale locale = null == context ? config.locale() : context.locale(true);
String dateFormatPattern = null == context ? null : context.dateFormatPattern();
if (S.blank(dateFormatPattern)) {
if (context instanceof ActionContext && ((ActionContext) context).shouldSuppressJsonDateFormat()) {
this.dateFormat = null;
} else {
if (!config.i18nEnabled() || locale.equals(config.locale())) {
this.dateFormat = config.dateTimeFormat();
} else {
dateFormatPattern = config.localizedDateTimePattern(locale);
this.dateFormat = new SimpleDateFormat(dateFormatPattern, locale);
}
}
} else {
this.dateFormat = new SimpleDateFormat(dateFormatPattern, locale);
}
this.disableCircularReferenceDetect = null == spec && context.isDisableCircularReferenceDetect();
this.filters = initFilters(v, spec, context);
this.features = initFeatures(format, context);
this.config = initConfig(context);
this.isLargeResponse = context instanceof ActionContext && ((ActionContext) context).isLargeResponse();
}
}
private SerializeFilter[] initFilters(Object v, PropertySpec.MetaInfo spec, ActContext context) {
Set filterSet = new LinkedHashSet<>();
FastJsonPropertyPreFilter propertyFilter = initPropertyPreFilter(v, spec, context);
if (null != spec && null != context) {
MappedFastJsonNameFilter nameFilter = new MappedFastJsonNameFilter(spec.labelMapping(context));
filterSet.add(nameFilter);
}
if (null != context) {
SerializeFilter[] filters = context.fastjsonFilters();
if (null != filters) {
for (SerializeFilter f : filters) {
filterSet.add(f);
}
}
}
if (null != propertyFilter) {
filterSet.add(propertyFilter);
}
return filterSet.toArray(new SerializeFilter[filterSet.size()]);
}
private SerializeConfig initConfig(ActContext context) {
SerializeConfig config = SerializeConfig.getGlobalInstance();
PropertyNamingStrategy propertyNamingStrategy = context.fastjsonPropertyNamingStrategy();
if (null == propertyNamingStrategy) {
return config;
}
config = new SerializeConfig();
config.propertyNamingStrategy = propertyNamingStrategy;
return config;
}
private SerializerFeature[] initFeatures(boolean format, ActContext context) {
Set featureSet = new HashSet<>();
if (format) {
featureSet.add(SerializerFeature.PrettyFormat);
}
if (null != context) {
SerializerFeature[] features = context.fastjsonFeatures();
if (null != features) {
for (SerializerFeature f : features) {
featureSet.add(f);
}
}
}
if (disableCircularReferenceDetect) {
featureSet.add(SerializerFeature.DisableCircularReferenceDetect);
}
featureSet.add(SerializerFeature.WriteDateUseDateFormat);
return featureSet.toArray(new SerializerFeature[featureSet.size()]);
}
private FastJsonPropertyPreFilter initPropertyPreFilter(Object v, PropertySpec.MetaInfo spec, ActContext context) {
if (null != context) {
PropertySpec.MetaInfo withCurrent = PropertySpec.MetaInfo.withCurrent(spec, context);
spec = null == withCurrent ? spec : withCurrent;
}
if (null == spec) {
return null;
}
List outputs = spec.outputFields(context);
Set excluded = spec.excludedFields(context);
if (outputs.isEmpty() && excluded.isEmpty()) {
return null;
}
return new FastJsonPropertyPreFilter(v.getClass(), outputs, excluded, context.app().service(DataPropertyRepository.class));
}
@Override
public void visit(Writer writer) throws $.Break {
if (v instanceof CharSequence) {
IO.write((CharSequence) v, writer);
return;
}
writeJson(writer, v, config, filters, dateFormat, DEFAULT_GENERATE_FEATURE, features);
}
public $.Func0 asContentProducer() {
final JsonWriter me = this;
return new $.Func0() {
@Override
public String apply() throws NotAppliedException, $.Break {
if (null != me.sv) {
return sv;
}
Writer w = me.isLargeResponse ? new StringWriter() : S.buffer();
me.visit(w);
return w.toString();
}
};
}
}
public static void configure(final App app) {
SerializeConfig config = SerializeConfig.getGlobalInstance();
// patch https://github.com/alibaba/fastjson/issues/478
config.put(FastJsonIterable.class, FastJsonIterableSerializer.instance);
FastJsonJodaDateCodec jodaDateCodec = new FastJsonJodaDateCodec(app);
app.registerSingleton(FastJsonJodaDateCodec.class, jodaDateCodec);
FastJsonValueObjectSerializer valueObjectSerializer = new FastJsonValueObjectSerializer();
app.registerSingleton(FastJsonValueObjectSerializer.class, valueObjectSerializer);
FastJsonKeywordCodec keywordCodec = new FastJsonKeywordCodec();
FastJsonSObjectCodec sObjectCodec = new FastJsonSObjectCodec();
config.put(DateTime.class, jodaDateCodec);
config.put(LocalDate.class, jodaDateCodec);
config.put(LocalTime.class, jodaDateCodec);
config.put(LocalDateTime.class, jodaDateCodec);
config.put(ValueObject.class, valueObjectSerializer);
config.put(Keyword.class, keywordCodec);
config.put(KV.class, FastJsonKvCodec.INSTANCE);
config.put(KVStore.class, FastJsonKvCodec.INSTANCE);
final ParserConfig parserConfig = ParserConfig.getGlobalInstance();
parserConfig.putDeserializer(DateTime.class, jodaDateCodec);
parserConfig.putDeserializer(LocalDate.class, jodaDateCodec);
parserConfig.putDeserializer(LocalTime.class, jodaDateCodec);
parserConfig.putDeserializer(LocalDateTime.class, jodaDateCodec);
parserConfig.putDeserializer(Keyword.class, keywordCodec);
parserConfig.putDeserializer(KV.class, FastJsonKvCodec.INSTANCE);
parserConfig.putDeserializer(KVStore.class, FastJsonKvCodec.INSTANCE);
parserConfig.putDeserializer(ISObject.class, sObjectCodec);
parserConfig.putDeserializer(SObject.class, sObjectCodec);
MvcConfig.jsonSerializer(new $.Func2() {
@Override
public Void apply(Writer writer, Object v) throws NotAppliedException, $.Break {
ActContext ctx = ActContext.Base.currentContext();
new JsonWriter(v, null, false, ctx).apply(writer);
return null;
}
});
app.eventBus().bind(CLASS_LOADER_INITIALIZED, new SysEventListenerBase() {
@Override
public void on(AppClassLoaderInitialized event) {
parserConfig.setDefaultClassLoader(app.classLoader());
TypeUtils.clearClassMapping();
}
});
}
// FastJSON does not provide the API so we have to create our own
private static final void writeJson(Writer os, //
Object object, //
SerializeConfig config, //
SerializeFilter[] filters, //
DateFormat dateFormat, //
int defaultFeatures, //
SerializerFeature... features) {
SerializeWriter writer = new SerializeWriter(os, defaultFeatures, features);
try {
JSONSerializer serializer = new JSONSerializer(writer, config);
if (dateFormat != null) {
serializer.setDateFormat(dateFormat);
serializer.config(SerializerFeature.WriteDateUseDateFormat, true);
}
if (filters != null) {
for (SerializeFilter filter : filters) {
serializer.addFilter(filter);
}
}
serializer.write(object);
} finally {
writer.close();
}
}
private static class Bean {
public String fooBar = "foo_bar";
}
}