com.aol.advertising.qiao.util.ContextUtils.java Source code

Java tutorial

Introduction

Here is the source code for com.aol.advertising.qiao.util.ContextUtils.java

Source

/****************************************************************************
 * Copyright (c) 2015 AOL Inc.
 * @author:     ytung05
 *
 * 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.
 ****************************************************************************/

package com.aol.advertising.qiao.util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.FatalBeanException;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.ReflectionUtils;

import com.aol.advertising.qiao.config.PropertyValue;
import com.aol.advertising.qiao.config.PropertyValue.DataType;
import com.aol.advertising.qiao.config.PropertyValue.Type;
import com.aol.advertising.qiao.config.SingleSubnodeConfiguration;
import com.aol.advertising.qiao.exception.BeanNotFoundException;
import com.aol.advertising.qiao.exception.ConfigurationException;
import com.aol.advertising.qiao.exception.MethodNotFoundException;

/**
 * ContextUtil needs to be defined as a singleton.
 */
public class ContextUtils implements ApplicationContextAware {
    protected static Logger logger = LoggerFactory.getLogger(ContextUtils.class);
    protected ApplicationContext applicationContext;
    protected static ContextUtils _instance;

    protected static final String ERR_METHOD_NOTFOUND = "Unable to find method %s with param type %s in the class %s";

    public static Object createBean(String className) throws ClassNotFoundException {
        //logger.info("loading " + className + "...");
        Object o = null;

        logger.info("Instantiate the class " + className);
        Class<?> clz = Class.forName(className);
        try {
            o = clz.newInstance();
        } catch (Exception e) {
            logger.error("Failed to instantiate class " + className);
        }

        return o;
    }

    public static Object createBeanSilently(String className) throws ClassNotFoundException {
        Object o = null;

        Class<?> clz = Class.forName(className);
        try {
            o = clz.newInstance();
        } catch (Exception e) {
            logger.error("Failed to instantiate class " + className);
        }

        return o;
    }

    public static Object loadClass(ApplicationContext appContext, String className)
            throws BeansException, ClassNotFoundException {
        return appContext.getBean(Class.forName(className));
    }

    public static Object loadClass(String className) throws BeansException, ClassNotFoundException {
        if (_instance == null) {
            throw new FatalBeanException("Missing ContextUtil bean");
        }

        return _instance.applicationContext.getBean(Class.forName(className));
    }

    public static Object loadClassById(String id) throws BeansException, ClassNotFoundException {
        if (_instance == null) {
            throw new FatalBeanException("Missing ContextUtil bean");
        }

        return _instance.applicationContext.getBean(id);
    }

    public static <T> T getBean(Class<T> clz) {
        if (_instance == null) {
            throw new FatalBeanException("Missing ContextUtil bean");
        }

        return _instance.applicationContext.getBean(clz);
    }

    public static String[] getBeanNames(Class<?> clz) {
        if (_instance == null) {
            throw new FatalBeanException("Missing ContextUtil bean");
        }

        return BeanFactoryUtils.beanNamesForTypeIncludingAncestors(_instance.applicationContext, clz);

    }

    /**
     * Locate a Spring bean of the given class. If not found, instantiate a new
     * instance of the class.
     *
     * @param clzname
     *            class name
     * @return the object of the class
     * @throws ClassNotFoundException
     */
    public static Object getOrCreateBean(String clzname) throws ClassNotFoundException {
        Object o = null;
        Class<?> clz = Class.forName(clzname);
        try {
            o = ContextUtils.getBean(clz);
        } catch (NoSuchBeanDefinitionException e) {
            try {
                o = clz.newInstance();
            } catch (Exception e1) {
                logger.error("Failed to instantiate class " + clzname);
            }
        }

        return o;
    }

    public static void resolvePropertyReferences(SingleSubnodeConfiguration singleNode)
            throws BeansException, ClassNotFoundException {
        Map<String, PropertyValue> map = singleNode.getProperties();
        if (map == null || map.size() == 0)
            return;

        ContextUtils.resolvePropertyReferences(map);

    }

    public static void resolvePropertyReferences(Map<String, PropertyValue> propsMap)
            throws BeansException, ClassNotFoundException {
        if (propsMap == null || propsMap.size() == 0)
            return;

        for (Entry<String, PropertyValue> entry : propsMap.entrySet()) {
            PropertyValue pv = entry.getValue();
            if (pv.getType() == Type.IS_REF) {
                Object o = ContextUtils.loadClassById(pv.getValue());
                if (o == null) {
                    String err = "Unable to find bean id=" + pv.getValue();
                    logger.error(err);
                    throw new BeanNotFoundException(err);
                }

                pv.setRefObject(o);
            }
        }
    }

    protected static Object stringToValueByType(String str, DataType type) {

        switch (type) {
        case STRING:
            return str;
        case INTEGER:
            return Integer.parseInt(str);
        case CLZ_INTEGER:
            return Integer.valueOf(str);
        case SHORT:
            return Short.parseShort(str);
        case CLZ_SHORT:
            return Short.valueOf(str);
        case LONG:
            return Long.parseLong(str);
        case CLZ_LONG:
            return Long.valueOf(str);
        case FLOAT:
            return Float.parseFloat(str);
        case CLZ_FLOAT:
            return Float.valueOf(str);
        case DOUBLE:
            return Double.parseDouble(str);
        case CLZ_DOUBLE:
            return Double.valueOf(str);
        case BOOLEAN:
            return Boolean.parseBoolean(str);
        case CLZ_BOOLEAN:
            return Boolean.valueOf(str);
        default: // default to string
            return str;
        }

    }

    public static void injectMethods(Object object, SingleSubnodeConfiguration cfg)
            throws BeansException, ClassNotFoundException {
        Map<String, PropertyValue> props = cfg.getProperties();
        // <fieldname, fieldvalue>

        ContextUtils.injectMethods(object, props);

    }

    public static void injectMethods(Object object, Map<String, PropertyValue> props)
            throws BeansException, ClassNotFoundException {
        resolvePropertyReferences(props);

        if (props != null) {
            for (String key : props.keySet()) {
                String mth_name = "set" + StringUtils.capitalize(key);

                PropertyValue pv = props.get(key);
                if (pv.getType() == Type.IS_VALUE) {
                    String pv_value = pv.getValue();
                    if (!pv.isResolved()) {
                        if (pv.getDefaultValue() == null) // not resolved + no default
                            throw new ConfigurationException("value " + pv.getValue() + " not resolved");

                        pv_value = pv.getDefaultValue();
                    }

                    Method mth = findMethod(object.getClass(), mth_name, pv.getDataType().getJavaClass());
                    if (mth != null) {
                        ReflectionUtils.invokeMethod(mth, object,
                                ContextUtils.stringToValueByType(pv_value, pv.getDataType()));
                    } else {
                        String err = String.format(ERR_METHOD_NOTFOUND, mth_name, pv.getDataType(),
                                object.getClass().getSimpleName());
                        logger.error(err);
                        throw new MethodNotFoundException(err);

                    }
                } else {
                    Method mth = findMethod(object.getClass(), mth_name, pv.getRefObject().getClass());

                    if (mth != null) {
                        ReflectionUtils.invokeMethod(mth, object, pv.getRefObject());
                    } else {
                        String err = String.format(ERR_METHOD_NOTFOUND, mth_name,
                                pv.getRefObject().getClass().getSimpleName(), object.getClass().getSimpleName());
                        logger.error(err);
                        throw new MethodNotFoundException(err);
                    }
                }
            }
        }
    }

    /**
     * A simple call to invoke a class method.
     *
     * @param object
     *            the target object to invoke the method on
     * @param fieldName
     *            the field whose set method to be invoked
     * @param param
     *            the invocation argument
     * @throws BeansException
     * @throws ClassNotFoundException
     */
    public static void injectMethod(Object object, String fieldName, Object param)
            throws BeansException, ClassNotFoundException {
        String mth_name = "set" + StringUtils.capitalize(fieldName);

        Method mth = findMethod(object.getClass(), mth_name, param.getClass());

        if (mth != null) {
            ReflectionUtils.invokeMethod(mth, object, param);
        } else {
            String err = String.format(ERR_METHOD_NOTFOUND, mth_name, param.getClass().getSimpleName(),
                    object.getClass().getSimpleName());
            logger.error(err);
            throw new MethodNotFoundException(err);
        }
    }

    /**
     * Invoke a class method if exists.
     *
     * @param object
     * @param fieldName
     * @param param
     * @throws BeansException
     * @throws ClassNotFoundException
     */
    public static void injectMethodSilently(Object object, String fieldName, Object param)
            throws BeansException, ClassNotFoundException {
        String mth_name = "set" + StringUtils.capitalize(fieldName);

        Method mth = findMethod(object.getClass(), mth_name, param.getClass());

        if (mth != null) {
            ReflectionUtils.invokeMethod(mth, object, param);
        }
    }

    /**
     * Supporting one parameter only.
     *
     * @param clazz
     * @param methodName
     * @param paramType
     * @return
     */
    private static Method findMethod(Class<?> clazz, String methodName, Class<?> paramType) {
        // trace
        //System.out.println("findMethod> class=" + clazz.getSimpleName()
        //        + ",method=" + methodName + ",param="
        //        + paramType.getSimpleName());
        Method mth = ReflectionUtils.findMethod(clazz, methodName, paramType);
        if (mth == null) {

            // check param's interfaces
            Class<?>[] list = paramType.getInterfaces();
            if (list != null && list.length > 0) {
                for (Class<?> c : list) {
                    mth = findMethod(clazz, methodName, c);
                    if (mth != null)
                        return mth;
                }
            }

            // check param's super class
            Class<?> param_super = paramType.getSuperclass();
            if (param_super != null) {
                mth = findMethod(clazz, methodName, param_super);
                if (mth != null)
                    return mth;
            }

            if (mth == null) {
                // check object's super class
                Class<?> parent_clz = clazz.getSuperclass();
                if (parent_clz != null) {
                    mth = findMethod(parent_clz, methodName, paramType);
                }
            }
        }

        return mth;
    }

    public static <T> Map<String, T> getBeansOfType(Class<T> type, boolean includeNonSingletons,
            boolean allowEagerInit) throws BeansException {
        return _instance.applicationContext.getBeansOfType(type, includeNonSingletons, allowEagerInit);
    }

    // ----------------------------------------------------

    public static ContextUtils getInstance() {
        if (_instance == null)
            _instance = new ContextUtils();

        return _instance;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public ApplicationContext getApplicationContext() {
        return applicationContext;
    }

}