org.jberet.support.io.NoMappingJsonFactoryObjectFactory.java Source code

Java tutorial

Introduction

Here is the source code for org.jberet.support.io.NoMappingJsonFactoryObjectFactory.java

Source

/*
 * 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.core.JsonFactory;
import com.fasterxml.jackson.core.io.InputDecorator;
import com.fasterxml.jackson.core.io.OutputDecorator;
import org.jberet.support._private.SupportMessages;

/**
 * An implementation of {@code javax.naming.spi.ObjectFactory} that produces instance of
 * {@code com.fasterxml.jackson.core.JsonFactory}. 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 NoMappingJsonFactoryObjectFactory implements ObjectFactory {
    private volatile JsonFactory jsonFactoryCached;

    /**
     * Gets an instance of {@code com.fasterxml.jackson.core.JsonFactory} based on the resource configuration in the
     * application server. The parameter {@code environment} contains JsonFactory configuration properties, and accepts
     * the following properties:
     * <ul>
     * <li>jsonFactoryFeatures: JsonFactory features as defined in com.fasterxml.jackson.core.JsonFactory.Feature
     * <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.core.JsonFactory} 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.core.JsonFactory}
     * @throws Exception any exception occurred
     */
    @Override
    public Object getObjectInstance(final Object obj, final Name name, final Context nameCtx,
            final Hashtable<?, ?> environment) throws Exception {
        JsonFactory jsonFactory = jsonFactoryCached;
        if (jsonFactory == null) {
            synchronized (this) {
                jsonFactory = jsonFactoryCached;
                if (jsonFactory == null) {
                    jsonFactoryCached = jsonFactory = new JsonFactory();
                }

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

    static void configureInputDecoratorAndOutputDecorator(final JsonFactory jsonFactory,
            final Hashtable<?, ?> environment) throws Exception {
        final Object inputDecorator = environment.get("inputDecorator");
        if (inputDecorator != null) {
            final Class<?> inputDecoratorClass = NoMappingJsonFactoryObjectFactory.class.getClassLoader()
                    .loadClass((String) inputDecorator);
            jsonFactory.setInputDecorator((InputDecorator) inputDecoratorClass.newInstance());
        }

        final Object outputDecorator = environment.get("outputDecorator");
        if (outputDecorator != null) {
            final Class<?> outputDecoratorClass = NoMappingJsonFactoryObjectFactory.class.getClassLoader()
                    .loadClass((String) outputDecorator);
            jsonFactory.setOutputDecorator((OutputDecorator) outputDecoratorClass.newInstance());
        }
    }

    static void configureJsonFactoryFeatures(final JsonFactory jsonFactory, final String jsonFactoryFeatures) {
        final StringTokenizer st = new StringTokenizer(jsonFactoryFeatures, ",");
        while (st.hasMoreTokens()) {
            final String[] pair = parseSingleFeatureValue(st.nextToken().trim());
            final String key = pair[0];
            final String value = pair[1];
            final JsonFactory.Feature feature;
            try {
                feature = JsonFactory.Feature.valueOf(key);
            } catch (final Exception e1) {
                throw SupportMessages.MESSAGES.unrecognizedReaderWriterProperty(key, value);
            }
            if ("true".equals(value)) {
                if (!feature.enabledByDefault()) {
                    jsonFactory.configure(feature, true);
                }
            } else if ("false".equals(value)) {
                if (feature.enabledByDefault()) {
                    jsonFactory.configure(feature, false);
                }
            } else {
                throw SupportMessages.MESSAGES.invalidReaderWriterProperty(null, value, key);
            }
        }
    }

    static String[] parseSingleFeatureValue(final String pair) {
        final int i = pair.indexOf('=');
        final String[] result = new String[2];
        if (i > 0) {
            result[0] = pair.substring(0, i).trim();
            result[1] = pair.substring(i + 1).trim();
        } else {
            result[0] = pair;
            result[1] = null;
        }
        return result;
    }
}