![JAR search and dependency download from the Maven repository](/logo.png)
yakworks.json.groovy.JsonEngine.groovy Maven / Gradle / Ivy
/*
* Copyright 2021 original authors
* SPDX-License-Identifier: Apache-2.0
*/
package yakworks.json.groovy
import groovy.json.JsonGenerator
import groovy.json.JsonSlurper
import groovy.transform.CompileStatic
import groovy.transform.builder.Builder
import groovy.transform.builder.SimpleStrategy
import yakworks.json.groovy.converters.CurrencyConverter
import yakworks.json.groovy.converters.InstantJsonConverter
import yakworks.json.groovy.converters.LocalDateJsonConverter
import yakworks.json.groovy.converters.LocalDateTimeJsonConverter
import yakworks.json.groovy.converters.LocalTimeJsonConverter
import yakworks.json.groovy.converters.OffsetDateTimeJsonConverter
import yakworks.json.groovy.converters.OffsetTimeJsonConverter
import yakworks.json.groovy.converters.PeriodJsonConverter
import yakworks.json.groovy.converters.URIConverter
import yakworks.json.groovy.converters.ZonedDateTimeJsonConverter
/**
* Wrapper for groovy Json slurper and generator
*
* @author Joshua Burnett (@basejump)
*/
@SuppressWarnings('FieldName')
@Builder(builderStrategy= SimpleStrategy, prefix="")
@CompileStatic
class JsonEngine {
String dateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'"
String timeZone = "GMT"
String locale = "en/US"
Boolean escapeUnicode = false
JsonGenerator jsonGenerator
JsonSlurper jsonSlurper
// JsonEngine(){ }
// default build options
JsonGenerator.Options buildOptions() {
JsonGenerator.Options options = new JsonGenerator.Options()
if (!escapeUnicode) {
options.disableUnicodeEscaping()
}
Locale loc
String[] localeData = locale.split('/')
if (localeData.length > 1) {
loc = new Locale(localeData[0], localeData[1])
} else {
loc = new Locale(localeData[0])
}
options.dateFormat(dateFormat, loc)
options.timezone(timeZone)
options.excludeNulls()
getConverters().each {
options.addConverter(it)
}
return options
}
JsonEngine build() {
def opts = buildOptions()
jsonGenerator = new EnhancedJsonGenerator(opts)
// jsonGenerator = buildOptions().build()
jsonSlurper = buildSlurper()
return this
}
JsonSlurper buildSlurper(){
//TODO make this configurable
return new JsonSlurper() //.setType(JsonParserType.LAX).setLazyChop(false).setChop(true)
}
List getConverters(){
ServiceLoader loader = ServiceLoader.load(JsonGenerator.Converter);
List converters = []
for (JsonGenerator.Converter converter : loader) {
converters.add(converter)
}
converters = converters.sort {
it.hasProperty('order') ? it['order'] : 0
}
converters.add(new InstantJsonConverter())
converters.add(new LocalDateJsonConverter())
converters.add(new LocalDateTimeJsonConverter())
converters.add(new LocalTimeJsonConverter())
converters.add(new OffsetDateTimeJsonConverter())
converters.add(new OffsetTimeJsonConverter())
converters.add(new PeriodJsonConverter())
converters.add(new ZonedDateTimeJsonConverter())
converters.add(new CurrencyConverter())
converters.add(new URIConverter())
// OrderComparator.sort(converters)
return converters
}
static String toJson(Object object){
stringify(object)
}
static String stringify(Object object, Map arguments = [:]){
getGenerator().toJson(object)
}
// see good explanation of thread safe static instance stratgey https://stackoverflow.com/a/16106598/6500859
@SuppressWarnings('UnusedPrivateField')
private static class Holder {
private static final JsonEngine INSTANCE = new JsonEngine().build();
}
static JsonEngine getInstance() {
return Holder.INSTANCE
}
static JsonGenerator getGenerator(){
getInstance().jsonGenerator
}
static JsonSlurper getSlurper(){
getInstance().jsonSlurper
}
/**
* Parse a JSON data structure from request body input stream.
* if no content then returns an empty map
*/
static Object parseJson(String text) {
return getSlurper().parseText(text)
}
/**
* parse string and expect the class type back.
* usually would call this with parseJson(text, Map) or parseJson(text, List)
*/
static T parseJson(String text, Class clazz) {
Object parsedObj = parseJson(text)
validateExpectedClass(clazz, parsedObj)
return (T)parsedObj
}
/**
* throw IllegalArgumentException if clazz is not a super of object
*/
static void validateExpectedClass(Class clazz, Object parsedObj){
if(!clazz.isAssignableFrom(parsedObj.class))
throw new IllegalArgumentException("Json parsing expected a ${clazz.simpleName} but got a ${parsedObj.class.simpleName}")
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy