org.grails.web.converters.configuration.ConvertersConfigurationInitializer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of grace-plugin-converters Show documentation
Show all versions of grace-plugin-converters Show documentation
Grace Framework : Grace Plugin Converters
/*
* Copyright 2004-2022 the original author or authors.
*
* 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
*
* https://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.
*/
package org.grails.web.converters.configuration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.Assert;
import grails.config.Config;
import grails.converters.JSON;
import grails.converters.XML;
import grails.core.GrailsApplication;
import grails.core.support.GrailsApplicationAware;
import grails.core.support.proxy.DefaultProxyHandler;
import grails.core.support.proxy.ProxyHandler;
import org.grails.config.PropertySourcesConfig;
import org.grails.web.converters.Converter;
import org.grails.web.converters.marshaller.ObjectMarshaller;
import org.grails.web.converters.marshaller.ProxyUnwrappingMarshaller;
/**
* @author Siegfried Puchbauer
* @author Michael Yan
* @since 1.1
*/
public class ConvertersConfigurationInitializer implements ApplicationContextAware, GrailsApplicationAware,
InitializingBean, SmartInitializingSingleton {
public static final Log logger = LogFactory.getLog(ConvertersConfigurationInitializer.class);
public static final String SETTING_CONVERTERS_JSON_DATE = "grails.converters.json.date";
public static final String SETTING_CONVERTERS_JSON_DEFAULT_DEEP = "grails.converters.json.default.deep";
public static final String SETTING_CONVERTERS_ENCODING = "grails.converters.encoding";
public static final String SETTING_CONVERTERS_CIRCULAR_REFERENCE_BEHAVIOUR = "grails.converters.default.circular.reference.behaviour";
public static final String SETTING_CONVERTERS_JSON_CIRCULAR_REFERENCE_BEHAVIOUR = "grails.converters.json.circular.reference.behaviour";
public static final String SETTING_CONVERTERS_PRETTY_PRINT = "grails.converters.default.pretty.print";
public static final String SETTING_CONVERTERS_JSON_PRETTY_PRINT = "grails.converters.json.pretty.print";
public static final String SETTING_CONVERTERS_JSON_CACHE_OBJECTS = "grails.converters.json.cacheObjectMarshallerSelectionByClass";
public static final String SETTING_CONVERTERS_XML_DEEP = "grails.converters.xml.default.deep";
private ApplicationContext applicationContext;
private GrailsApplication grailsApplication;
public ApplicationContext getApplicationContext() {
return this.applicationContext;
}
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
@Override
public void afterPropertiesSet() throws Exception {
Assert.notNull(this.applicationContext, "ApplicationContext must be set");
}
@Override
public void afterSingletonsInstantiated() {
initialize();
}
public void initialize() {
if (logger.isDebugEnabled()) {
logger.debug("Initializing Converters Default Configurations...");
}
initJSONConfiguration();
initXMLConfiguration();
initDeepJSONConfiguration();
initDeepXMLConfiguration();
}
private void initJSONConfiguration() {
if (logger.isDebugEnabled()) {
logger.debug("Initializing default JSON Converters Configuration...");
}
List> marshallers = new ArrayList<>();
marshallers.addAll(getPreviouslyConfiguredMarshallers(JSON.class));
marshallers.add(new org.grails.web.converters.marshaller.json.ArrayMarshaller());
marshallers.add(new org.grails.web.converters.marshaller.json.ByteArrayMarshaller());
marshallers.add(new org.grails.web.converters.marshaller.json.CollectionMarshaller());
marshallers.add(new org.grails.web.converters.marshaller.json.MapMarshaller());
marshallers.add(new org.grails.web.converters.marshaller.json.EnumMarshaller());
marshallers.add(new org.grails.web.converters.marshaller.ProxyUnwrappingMarshaller<>());
Config grailsConfig = getGrailsConfig();
if ("javascript".equals(grailsConfig.getProperty(SETTING_CONVERTERS_JSON_DATE,
String.class, "default", Arrays.asList("javascript", "default")))) {
if (logger.isDebugEnabled()) {
logger.debug("Using Javascript JSON Date Marshaller.");
}
marshallers.add(new org.grails.web.converters.marshaller.json.JavascriptDateMarshaller());
}
else {
if (logger.isDebugEnabled()) {
logger.debug("Using default JSON Date Marshaller");
}
marshallers.add(new org.grails.web.converters.marshaller.json.DateMarshaller());
}
marshallers.add(new org.grails.web.converters.marshaller.json.ToStringBeanMarshaller());
boolean includeDomainVersion = includeDomainVersionProperty(grailsConfig, "json");
boolean includeDomainClassName = includeDomainClassProperty(grailsConfig, "json");
ProxyHandler proxyHandler = getProxyHandler();
if (grailsConfig.getProperty(SETTING_CONVERTERS_JSON_DEFAULT_DEEP, Boolean.class, false)) {
logger.debug("Using DeepDomainClassMarshaller as default.");
marshallers.add(new org.grails.web.converters.marshaller.json.DeepDomainClassMarshaller(
includeDomainVersion, includeDomainClassName, proxyHandler, this.grailsApplication));
}
else {
marshallers.add(new org.grails.web.converters.marshaller.json.DomainClassMarshaller(
includeDomainVersion, includeDomainClassName, proxyHandler, this.grailsApplication));
}
marshallers.add(new org.grails.web.converters.marshaller.json.GroovyBeanMarshaller());
marshallers.add(new org.grails.web.converters.marshaller.json.GenericJavaBeanMarshaller());
DefaultConverterConfiguration cfg = new DefaultConverterConfiguration(marshallers, proxyHandler);
cfg.setEncoding(grailsConfig.getProperty(SETTING_CONVERTERS_ENCODING, "UTF-8"));
String defaultCirRefBehaviour = grailsConfig.getProperty(SETTING_CONVERTERS_CIRCULAR_REFERENCE_BEHAVIOUR, "DEFAULT");
cfg.setCircularReferenceBehaviour(Converter.CircularReferenceBehaviour.valueOf(
grailsConfig.getProperty(SETTING_CONVERTERS_JSON_CIRCULAR_REFERENCE_BEHAVIOUR, String.class,
defaultCirRefBehaviour, Converter.CircularReferenceBehaviour.allowedValues())));
Boolean defaultPrettyPrint = grailsConfig.getProperty(SETTING_CONVERTERS_PRETTY_PRINT, Boolean.class, false);
Boolean prettyPrint = grailsConfig.getProperty(SETTING_CONVERTERS_JSON_PRETTY_PRINT, Boolean.class, defaultPrettyPrint);
cfg.setPrettyPrint(prettyPrint);
cfg.setCacheObjectMarshallerByClass(grailsConfig.getProperty(SETTING_CONVERTERS_JSON_CACHE_OBJECTS, Boolean.class, true));
registerObjectMarshallersFromApplicationContext(cfg, JSON.class);
ConvertersConfigurationHolder.setDefaultConfiguration(JSON.class, new ChainedConverterConfiguration<>(cfg, proxyHandler));
}
private Config getGrailsConfig() {
Config grailsConfig;
if (this.grailsApplication != null) {
grailsConfig = this.grailsApplication.getConfig();
}
else {
// empty config, will trigger defaults
grailsConfig = new PropertySourcesConfig();
}
return grailsConfig;
}
private void initDeepJSONConfiguration() {
DefaultConverterConfiguration deepConfig = new DefaultConverterConfiguration<>(
ConvertersConfigurationHolder.getConverterConfiguration(JSON.class), getProxyHandler());
deepConfig.registerObjectMarshaller(new org.grails.web.converters.marshaller.json.DeepDomainClassMarshaller(
includeDomainVersionProperty(getGrailsConfig(), "json"),
includeDomainClassProperty(getGrailsConfig(), "json"),
getProxyHandler(), this.grailsApplication));
ConvertersConfigurationHolder.setNamedConverterConfiguration(JSON.class, "deep", deepConfig);
}
private void initXMLConfiguration() {
logger.debug("Initializing default XML Converters Configuration...");
List> marshallers = new ArrayList<>();
marshallers.addAll(getPreviouslyConfiguredMarshallers(XML.class));
marshallers.add(new org.grails.web.converters.marshaller.xml.Base64ByteArrayMarshaller());
marshallers.add(new org.grails.web.converters.marshaller.xml.ArrayMarshaller());
marshallers.add(new org.grails.web.converters.marshaller.xml.CollectionMarshaller());
marshallers.add(new org.grails.web.converters.marshaller.xml.MapMarshaller());
marshallers.add(new org.grails.web.converters.marshaller.xml.EnumMarshaller());
marshallers.add(new org.grails.web.converters.marshaller.xml.DateMarshaller());
marshallers.add(new ProxyUnwrappingMarshaller());
marshallers.add(new org.grails.web.converters.marshaller.xml.ToStringBeanMarshaller());
ProxyHandler proxyHandler = getProxyHandler();
Config grailsConfig = getGrailsConfig();
boolean includeDomainVersion = includeDomainVersionProperty(grailsConfig, "xml");
if (grailsConfig.getProperty(SETTING_CONVERTERS_XML_DEEP, Boolean.class, false)) {
marshallers.add(new org.grails.web.converters.marshaller.xml.DeepDomainClassMarshaller(
includeDomainVersion, proxyHandler, this.grailsApplication));
}
else {
marshallers.add(new org.grails.web.converters.marshaller.xml.DomainClassMarshaller(
includeDomainVersion, proxyHandler, this.grailsApplication));
}
marshallers.add(new org.grails.web.converters.marshaller.xml.GroovyBeanMarshaller());
marshallers.add(new org.grails.web.converters.marshaller.xml.GenericJavaBeanMarshaller());
DefaultConverterConfiguration cfg = new DefaultConverterConfiguration(marshallers, proxyHandler);
cfg.setEncoding(grailsConfig.getProperty(SETTING_CONVERTERS_ENCODING, "UTF-8"));
String defaultCirRefBehaviour = grailsConfig.getProperty(SETTING_CONVERTERS_CIRCULAR_REFERENCE_BEHAVIOUR, "DEFAULT");
cfg.setCircularReferenceBehaviour(Converter.CircularReferenceBehaviour.valueOf(
grailsConfig.getProperty("grails.converters.xml.circular.reference.behaviour", String.class,
defaultCirRefBehaviour, Converter.CircularReferenceBehaviour.allowedValues())));
Boolean defaultPrettyPrint = grailsConfig.getProperty(SETTING_CONVERTERS_PRETTY_PRINT, Boolean.class, false);
Boolean prettyPrint = grailsConfig.getProperty("grails.converters.xml.pretty.print", Boolean.class, defaultPrettyPrint);
cfg.setPrettyPrint(prettyPrint);
cfg.setCacheObjectMarshallerByClass(
grailsConfig.getProperty("grails.converters.xml.cacheObjectMarshallerSelectionByClass", Boolean.class, true));
registerObjectMarshallersFromApplicationContext(cfg, XML.class);
ConvertersConfigurationHolder.setDefaultConfiguration(XML.class, new ChainedConverterConfiguration(cfg, proxyHandler));
}
private ProxyHandler getProxyHandler() {
ProxyHandler proxyHandler;
if (this.applicationContext != null) {
proxyHandler = this.applicationContext.getBean(ProxyHandler.class);
}
else {
proxyHandler = new DefaultProxyHandler();
}
return proxyHandler;
}
private void initDeepXMLConfiguration() {
DefaultConverterConfiguration deepConfig = new DefaultConverterConfiguration<>(
ConvertersConfigurationHolder.getConverterConfiguration(XML.class), getProxyHandler());
deepConfig.registerObjectMarshaller(new org.grails.web.converters.marshaller.xml.DeepDomainClassMarshaller(
includeDomainVersionProperty(getGrailsConfig(), "xml"),
includeDomainClassProperty(getGrailsConfig(), "xml"), getProxyHandler(), this.grailsApplication));
ConvertersConfigurationHolder.setNamedConverterConfiguration(XML.class, "deep", deepConfig);
}
private boolean includeDomainVersionProperty(Config grailsConfig, String converterType) {
return grailsConfig.getProperty(String.format("grails.converters.%s.domain.include.version", converterType),
Boolean.class, grailsConfig.getProperty("grails.converters.domain.include.version", Boolean.class, false));
}
private boolean includeDomainClassProperty(Config grailsConfig, String converterType) {
return grailsConfig.getProperty(String.format("grails.converters.%s.domain.include.class", converterType),
Boolean.class, grailsConfig.getProperty("grails.converters.domain.include.class", Boolean.class, false));
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private void registerObjectMarshallersFromApplicationContext(
DefaultConverterConfiguration cfg, Class converterClass) {
if (this.applicationContext == null) {
return;
}
for (ObjectMarshallerRegisterer omr : this.applicationContext.getBeansOfType(ObjectMarshallerRegisterer.class).values()) {
if (omr.getConverterClass() == converterClass) {
cfg.registerObjectMarshaller(omr.getMarshaller(), omr.getPriority());
}
}
}
@Override
public void setGrailsApplication(GrailsApplication grailsApplication) {
this.grailsApplication = grailsApplication;
}
private List> getPreviouslyConfiguredMarshallers(Class converterClass) {
ConverterConfiguration previousConfiguration = ConvertersConfigurationHolder.getConverterConfiguration(converterClass);
return previousConfiguration.getOrderedObjectMarshallers();
}
}