Java tutorial
/** * 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; } }