/** * Copyright 2015 StreamSets Inc. * * Licensed under the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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.streamsets.datacollector.util; import com.streamsets.datacollector.config.ConfigDefinition; import com.streamsets.datacollector.config.PipelineConfiguration; import com.streamsets.datacollector.config.StageDefinition; import com.streamsets.datacollector.el.ELEvaluator; import com.streamsets.datacollector.el.ELVariables; import com.streamsets.datacollector.el.RuntimeEL; import com.streamsets.pipeline.api.ConfigDef; import com.streamsets.pipeline.api.el.ELEvalException; import com.streamsets.pipeline.lib.el.StringEL; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.List; import java.util.Map; public class ElUtil { private static final String EL_PREFIX = "${"; private static final String CONSTANTS = "constants"; private ElUtil() {} public static Object evaluate(Object value, StageDefinition stageDefinition, ConfigDefinition configDefinition, Map<String, Object> constants) throws ELEvalException { if(configDefinition.getEvaluation() == ConfigDef.Evaluation.IMPLICIT) { if(isElString(value)) { //its an EL expression, try to evaluate it. ELEvaluator elEvaluator = createElEval(configDefinition.getName(), constants, getElDefs(stageDefinition, configDefinition)); Type genericType = configDefinition.getConfigField().getGenericType(); Class<?> klass; if(genericType instanceof ParameterizedType) { //As of today the only supported parameterized types are //1. List<String> //2. Map<String, String> //3. List<Map<String, String>> //In all cases we want to return String.class klass = String.class; } else if (genericType instanceof Enum) { klass = String.class; } else { klass = (Class<?>) genericType; } return elEvaluator.evaluate(new ELVariables(constants), (String)value, klass); } } return value; } public static boolean isElString(Object value) { if(value instanceof String && ((String) value).contains(EL_PREFIX)) { return true; } return false; } public static Class<?>[] getElDefs(StageDefinition stageDef, ConfigDefinition configDefinition) { List<Class> elDefs = configDefinition.getElDefs(); if(elDefs != null && elDefs.size() > 0) { return elDefs.toArray(new Class[elDefs.size()]); } Class<?>[] elDefClasses = new Class[2]; //inject RuntimeEL.class & StringEL.class into the evaluator elDefClasses[0] = RuntimeEL.class; elDefClasses[1] = StringEL.class; return elDefClasses; } public static Class<?>[] getElDefClassArray(List<Class> elDefs) { Class[] elDefClasses = new Class[elDefs.size() + 2]; int i = 0; for(; i < elDefs.size(); i++) { elDefClasses[i] = elDefs.get(i); } elDefClasses[i++] = RuntimeEL.class; elDefClasses[i] = StringEL.class; return elDefClasses; } public static ELEvaluator createElEval(String name, Map<String, Object> constants, Class<?>... elDefs) { return new ELEvaluator(name, constants, elDefs); } public static Map<String, Object> getConstants(PipelineConfiguration pipelineConf) { return PipelineConfigurationUtil.getFlattenedMap(CONSTANTS, pipelineConf); } }