org.openflamingo.uploader.el.ELService.java Source code

Java tutorial

Introduction

Here is the source code for org.openflamingo.uploader.el.ELService.java

Source

/**
 * Flamingo HDFS File Uploader - a tool to upload from datasource to datasource and schedule jobs
 *
 * Copyright (C) 2011-2012 Cloudine.
 *
 * This file is part of Flamingo HDFS File Uploader.
 *
 * Flamingo HDFS File Uploader is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Flamingo HDFS File Uploader is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.openflamingo.uploader.el;

import org.apache.commons.lang.StringUtils;
import org.openflamingo.uploader.exception.SystemException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ELService implements InitializingBean, DisposableBean {

    /**
     * SLF4J Logging
     */
    private static Logger logger = LoggerFactory.getLogger(ELService.class);

    /**
     * Flamingo Site XML? ? EL? Prefix
     */
    public static final String CONF_PREFIX = "EL.";

    /**
     * Flamingo Site XML? ? Constant EL? Key
     */
    public static final String CONF_CONSTANTS = CONF_PREFIX + "constants";

    /**
     * Flamingo Site XML? ? Function EL? Key
     */
    public static final String CONF_FUNCTIONS = CONF_PREFIX + "functions";

    /**
     * EL Function ?. Key ?.
     */
    private HashMap<String, List<ELConstant>> constants;

    /**
     * EL Function ?. Key ?.
     */
    private HashMap<String, List<ELFunction>> functions;

    /**
     * EL Definition(Functions and Constants) Map.
     */
    private Map<String, String> definitions;

    @Override
    public void afterPropertiesSet() throws Exception {
        constants = new HashMap<String, List<ELConstant>>();
        functions = new HashMap<String, List<ELFunction>>();

        // EL Constants
        List<ELConstant> tmpConstants = new ArrayList<ELConstant>();
        tmpConstants.addAll(extractConstants(definitions, CONF_CONSTANTS));
        constants.put(CONF_CONSTANTS, tmpConstants);

        // EL Functions
        List<ELFunction> tmpFunctions = new ArrayList<ELFunction>();
        tmpFunctions.addAll(extractFunctions(definitions, CONF_FUNCTIONS));
        functions.put(CONF_FUNCTIONS, tmpFunctions);

        logger.info("Expression Language   ? ?  ?.");
    }

    /**
     * Comma Separated String?  .
     *   Trim  .
     *
     * @param commaSeparatedList Comma Separated String
     * @return ? 
     */
    private String[] split(String commaSeparatedList) {
        List<String> params = new ArrayList<String>();
        String[] values = StringUtils.splitPreserveAllTokens(commaSeparatedList.trim(), ",");
        for (String value : values) {
            params.add(value.trim());
        }
        return org.openflamingo.uploader.util.StringUtils.collectionToStringArray(params);
    }

    /**
     * EL    ?  ? ?.
     *  ? <tt>PREFIX:NAME</tt> .
     */
    private static class ELConstant {

        private String name;

        private Object value;

        private ELConstant(String prefix, String name, Object value) {
            if (prefix.length() > 0) {
                name = prefix + ":" + name;
            }
            this.name = name;
            this.value = value;
        }
    }

    /**
     * EL      ? ?.
     */
    private static class ELFunction {
        private String prefix;
        private String name;
        private Method method;

        private ELFunction(String prefix, String name, Method method) {
            this.prefix = prefix;
            this.name = name;
            this.method = method;
        }
    }

    private List<ELConstant> extractConstants(Map<String, String> props, String key) throws SystemException {
        List<ELConstant> list = new ArrayList<ELConstant>();
        if (props.get(key) != null && props.get(key).trim().length() > 0) {
            for (String function : split(props.get(key))) {
                if (!StringUtils.isEmpty(function)) {
                    String[] parts = parseDefinition(function);
                    list.add(new ELConstant(parts[0], parts[1], findConstant(parts[2], parts[3])));
                    logger.debug("Registered prefix:constant[{}:{}] for class#field[{}#{}]", (Object[]) parts);
                }
            }
        }
        return list;
    }

    private List<ELFunction> extractFunctions(Map<String, String> props, String key) throws SystemException {
        List<ELFunction> list = new ArrayList<ELFunction>();
        if (props.get(key) != null && props.get(key).trim().length() > 0) {
            for (String function : split(props.get(key))) {
                if (!StringUtils.isEmpty(function)) {
                    String[] parts = parseDefinition(function);
                    list.add(new ELFunction(parts[0], parts[1], findMethod(parts[2], parts[3])));
                    logger.debug("Registered prefix:constant[{}:{}] for class#field[{}#{}]", (Object[]) parts);
                }
            }
        }
        return list;
    }

    /**
     * Destroy the EL service.
     */
    @Override
    public void destroy() {
        constants = null;
        functions = null;
    }

    /**
     * Return an {@link ELEvaluator} pre-configured with the constants and functions for the specific group of
     * EL-functions and variables defined in the configuration. If the group name doesn't exist,
     * IllegalArgumentException is thrown
     *
     * @return a preconfigured {@link ELEvaluator}.
     */
    public ELEvaluator createEvaluator() {
        ELEvaluator.Context context = new ELEvaluator.Context();
        for (ELConstant constant : constants.get(ELService.CONF_CONSTANTS)) {
            context.setVariable(constant.name, constant.value);
        }
        for (ELFunction function : functions.get(ELService.CONF_FUNCTIONS)) {
            context.addFunction(function.prefix, function.name, function.method);
        }
        return new ELEvaluator(context);
    }

    private static String[] parseDefinition(String str) throws SystemException {
        logger.trace(" '{}'", str);
        try {
            str = str.trim();
            if (!str.contains(":")) {
                str = ":" + str;
            }
            String[] parts = str.split(":");
            String prefix = parts[0];
            parts = parts[1].split("=");
            String name = parts[0];
            parts = parts[1].split("#");
            String klass = parts[0];
            String method = parts[1];
            return new String[] { prefix, name, klass, method };
        } catch (Exception ex) {
            // throw new SystemException(ErrorCode.E0110, str, ex.getMessage(), ex);
            throw new SystemException(ex);
        }
    }

    public static Method findMethod(String className, String methodName) throws SystemException {
        Method method = null;
        try {
            Class clazz = Thread.currentThread().getContextClassLoader().loadClass(className);
            for (Method m : clazz.getMethods()) {
                if (m.getName().equals(methodName)) {
                    method = m;
                    break;
                }
            }
            if (method == null) {
                // throw new SystemException(ErrorCode.E0111, className, methodName);
            }
            if ((method.getModifiers() & (Modifier.PUBLIC | Modifier.STATIC)) != (Modifier.PUBLIC
                    | Modifier.STATIC)) {
                // throw new SystemException(ErrorCode.E0112, className, methodName);
            }
        } catch (ClassNotFoundException ex) {
            // throw new SystemException(ErrorCode.E0113, className);
        }
        return method;
    }

    public static Object findConstant(String className, String constantName) throws SystemException {
        try {
            Class clazz = Thread.currentThread().getContextClassLoader().loadClass(className);
            Field field = clazz.getField(constantName);
            if ((field.getModifiers() & (Modifier.PUBLIC | Modifier.STATIC)) != (Modifier.PUBLIC
                    | Modifier.STATIC)) {
                // throw new SystemException(ErrorCode.E0114, className, constantName);
            }
            return field.get(null);
        } catch (IllegalAccessException ex) {
            throw new SystemException(ex);
        } catch (NoSuchFieldException ex) {
            throw new SystemException(ex);
        } catch (ClassNotFoundException ex) {
            throw new SystemException(ex);
        }
    }

    ////////////////////////////////////////////////////
    // Spring Framework Setter Injection
    ////////////////////////////////////////////////////

    /**
     * EL Definition? .
     *
     * @param definitions EL Definition
     */
    public void setDefinitions(Map<String, String> definitions) {
        this.definitions = definitions;
    }
}