Package org.jberet.support.io

Source Code of org.jberet.support.io.MappingJsonFactoryObjectFactory

/*
* Copyright (c) 2014 Red Hat, Inc. and/or its affiliates.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Cheng Fang - Initial API and implementation
*/

package org.jberet.support.io;

import java.util.Hashtable;
import java.util.StringTokenizer;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.spi.ObjectFactory;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.MappingJsonFactory;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.deser.DeserializationProblemHandler;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.jberet.support._private.SupportMessages;

/**
* An implementation of {@code javax.naming.spi.ObjectFactory} that produces instance of
* {@code com.fasterxml.jackson.databind.MappingJsonFactory}. This class can be used to create a custom JNDI resource
* in an application server. See wildfly.home/docs/schema/jboss-as-naming_2_0.xsd for more details.
*
* @see     "javax.naming.spi.ObjectFactory"
* @see     "wildfly.home/docs/schema/jboss-as-naming_2_0.xsd"
* @since   1.0.2
*/
public final class MappingJsonFactoryObjectFactory implements ObjectFactory {
    private volatile MappingJsonFactory jsonFactoryCached;

    /**
     * Gets an instance of {@code com.fasterxml.jackson.databind.MappingJsonFactory} based on the resource configuration
     * in the application server. The parameter {@code environment} contains MappingJsonFactory configuration properties,
     * and accepts the following properties:
     * <ul>
     * <li>jsonFactoryFeatures: JsonFactory features as defined in com.fasterxml.jackson.core.JsonFactory.Feature
     * <li>mapperFeatures: ObjectMapper features as defined in com.fasterxml.jackson.databind.MapperFeature
     * <li>deserializationFeatures:
     * <li>serializationFeatures:
     * <li>customDeserializers:
     * <li>customSerializers:
     * <li>deserializationProblemHandlers:
     * <li>inputDecorator: fully-qualified name of a class that extends {@code com.fasterxml.jackson.core.io.InputDecorator}
     * <li>outputDecorator: fully-qualified name of a class that extends {@code com.fasterxml.jackson.core.io.OutputDecorator}
     * </ul>
     *
     * @param obj         the JNDI name of {@code com.fasterxml.jackson.databind.MappingJsonFactory} resource
     * @param name        always null
     * @param nameCtx     always null
     * @param environment a {@code Hashtable} of configuration properties
     * @return an instance of {@code com.fasterxml.jackson.databind.MappingJsonFactory}
     * @throws Exception any exception occurred
     */
    @Override
    public Object getObjectInstance(final Object obj,
                                    final Name name,
                                    final Context nameCtx,
                                    final Hashtable<?, ?> environment) throws Exception {
        MappingJsonFactory jsonFactory = jsonFactoryCached;
        if (jsonFactory == null) {
            synchronized (this) {
                jsonFactory = jsonFactoryCached;
                if (jsonFactory == null) {
                    jsonFactoryCached = jsonFactory = new MappingJsonFactory();
                }

                final ClassLoader classLoader = MappingJsonFactoryObjectFactory.class.getClassLoader();
                final ObjectMapper objectMapper = jsonFactory.getCodec();

                final Object jsonFactoryFeatures = environment.get("jsonFactoryFeatures");
                if (jsonFactoryFeatures != null) {
                    NoMappingJsonFactoryObjectFactory.configureJsonFactoryFeatures(jsonFactory, (String) jsonFactoryFeatures);
                }

                final Object mapperFeatures = environment.get("mapperFeatures");
                if (mapperFeatures != null) {
                    configureMapperFeatures(objectMapper, (String) mapperFeatures);
                }

                final Object deserializationFeatures = environment.get("deserializationFeatures");
                if (deserializationFeatures != null) {
                    configureDeserializationFeatures(objectMapper, (String) deserializationFeatures);
                }

                final Object serializationFeatures = environment.get("serializationFeatures");
                if (serializationFeatures != null) {
                    configureSerializationFeatures(objectMapper, (String) serializationFeatures);
                }

                final Object deserializationProblemHandlers = environment.get("deserializationProblemHandlers");
                if (deserializationProblemHandlers != null) {
                    configureDeserializationProblemHandlers(objectMapper, (String) deserializationProblemHandlers, classLoader);
                }

                configureCustomSerializersAndDeserializers(objectMapper, (String) environment.get("customSerializers"),
                        (String) environment.get("customDeserializers"), classLoader);
                NoMappingJsonFactoryObjectFactory.configureInputDecoratorAndOutputDecorator(jsonFactory, environment);
            }
        }
        return jsonFactory;
    }

    static void configureDeserializationProblemHandlers(final ObjectMapper objectMapper,
                                                        final String deserializationProblemHandlers,
                                                        final ClassLoader classLoader) throws Exception {
        final StringTokenizer st = new StringTokenizer(deserializationProblemHandlers, ", ");
        while (st.hasMoreTokens()) {
            final Class<?> c = classLoader.loadClass(st.nextToken());
            objectMapper.addHandler((DeserializationProblemHandler) c.newInstance());
        }
    }

    static void configureCustomSerializersAndDeserializers(final ObjectMapper objectMapper,
                                                           final String customSerializers,
                                                           final String customDeserializers,
                                                           final ClassLoader classLoader) throws Exception {
        if (customDeserializers == null && customSerializers == null) {
            return;
        }

        final SimpleModule simpleModule = new SimpleModule("custom-serializer-deserializer-module");
        if (customSerializers != null) {
            final StringTokenizer st = new StringTokenizer(customSerializers, ", ");
            while (st.hasMoreTokens()) {
                final Class<?> aClass = classLoader.loadClass(st.nextToken());
                simpleModule.addSerializer(aClass, (JsonSerializer) aClass.newInstance());
            }
        }
        if (customDeserializers != null) {
            final StringTokenizer st = new StringTokenizer(customDeserializers, ", ");
            while (st.hasMoreTokens()) {
                final Class<?> aClass = classLoader.loadClass(st.nextToken());
                simpleModule.addDeserializer(aClass, (JsonDeserializer) aClass.newInstance());
            }
        }
        objectMapper.registerModule(simpleModule);
    }

    static void configureMapperFeatures(final ObjectMapper objectMapper, final String features) {
        final StringTokenizer st = new StringTokenizer(features, ",");
        while (st.hasMoreTokens()) {
            final String[] pair = NoMappingJsonFactoryObjectFactory.parseSingleFeatureValue(st.nextToken().trim());
            final String key = pair[0];
            final String value = pair[1];

            final MapperFeature feature;
            try {
                feature = MapperFeature.valueOf(key);
            } catch (final Exception e1) {
                throw SupportMessages.MESSAGES.unrecognizedReaderWriterProperty(key, value);
            }
            if ("true".equals(value)) {
                if (!feature.enabledByDefault()) {
                    objectMapper.configure(feature, true);
                }
            } else if ("false".equals(value)) {
                if (feature.enabledByDefault()) {
                    objectMapper.configure(feature, false);
                }
            } else {
                throw SupportMessages.MESSAGES.invalidReaderWriterProperty(null, value, key);
            }
        }
    }

    static void configureSerializationFeatures(final ObjectMapper objectMapper, final String features) {
        final StringTokenizer st = new StringTokenizer(features, ",");
        while (st.hasMoreTokens()) {
            final String[] pair = NoMappingJsonFactoryObjectFactory.parseSingleFeatureValue(st.nextToken().trim());
            final String key = pair[0];
            final String value = pair[1];

            final SerializationFeature feature;
            try {
                feature = SerializationFeature.valueOf(key);
            } catch (final Exception e1) {
                throw SupportMessages.MESSAGES.unrecognizedReaderWriterProperty(key, value);
            }
            if ("true".equals(value)) {
                if (!feature.enabledByDefault()) {
                    objectMapper.configure(feature, true);
                }
            } else if ("false".equals(value)) {
                if (feature.enabledByDefault()) {
                    objectMapper.configure(feature, false);
                }
            } else {
                throw SupportMessages.MESSAGES.invalidReaderWriterProperty(null, value, key);
            }
        }
    }

    static void configureDeserializationFeatures(final ObjectMapper objectMapper, final String features) {
        final StringTokenizer st = new StringTokenizer(features, ",");
        while (st.hasMoreTokens()) {
            final String[] pair = NoMappingJsonFactoryObjectFactory.parseSingleFeatureValue(st.nextToken().trim());
            final String key = pair[0];
            final String value = pair[1];

            final DeserializationFeature feature;
            try {
                feature = DeserializationFeature.valueOf(key);
            } catch (final Exception e1) {
                throw SupportMessages.MESSAGES.unrecognizedReaderWriterProperty(key, value);
            }
            if ("true".equals(value)) {
                if (!feature.enabledByDefault()) {
                    objectMapper.configure(feature, true);
                }
            } else if ("false".equals(value)) {
                if (feature.enabledByDefault()) {
                    objectMapper.configure(feature, false);
                }
            } else {
                throw SupportMessages.MESSAGES.invalidReaderWriterProperty(null, value, key);
            }
        }
    }
}
TOP

Related Classes of org.jberet.support.io.MappingJsonFactoryObjectFactory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.