/*
* chombo: Hadoop Map Reduce utility
* Author: Pranab Ghosh
*
* 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 org.chombo.transformer;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.chombo.util.ProcessorAttribute;
import com.typesafe.config.Config;
import com.typesafe.config.ConfigException;
/**
* @author pranab
*
*/
public class TransformerFactory {
public static final String LOWER_CASE_TRANSFORMER = "lowerCaseTrans";
public static final String UPPER_CASE_TRANSFORMER = "upperCaseTrans";
public static final String PATTERN_BASED_TRANSFORMER = "patternBasedTrans";
public static final String SEARCH_REPLACE_TRANSFORMER = "searchReplaceTrans";
public static final String KEY_VALUE_TRANSFORMER = "keyValueTrans";
public static final String DEFAULT_VALUE_TRANSFORMER = "defaultValueTrans";
public static final String ANOYNMIZER_TRANSFORMER = "anoynmizerTrans";
public static final String UNIQUE_KEY_GENERATOR = "uniqueKeyGen";
public static final String TRIM_TRANSFORMER = "trimTrans";
public static final String LONG_POLYNOMIAL_TRANSFORMER = "longPolynomialTrans";
public static final String DOUBLE_POLYNOMIAL_TRANSFORMER = "doublePolynomialTrans";
public static final String LONG_CUSTOM_TRANSFORMER = "longCustomTrans";
public static final String DOUBLE_CUSTOM_TRANSFORMER = "doubleCustomTrans";
public static final String EPOCH_TIME_GENERATOR = "epochTimeGen";
public static final String DATE_GENERATOR = "dateGen";
public static final String DATE_FORMAT_TRANSFORMER = "dateFormatTrans";
public static final String DATE_COMPONENT_TRANSFORMER = "dateComponentTrans";
public static final String ELAPSED_TIME_TRANSFORMER = "elapsedTimeTrans";
public static final String CONTEXTUAL_ELAPSED_TIME_TRANSFORMER = "contextualElapsedTimeTrans";
public static final String TIME_CYCLE_SHIFT_TRANSFORMER = "timeCycleShiftTrans";
public static final String CONTEXTUAL_TIME_CYCLE_SHIFT_TRANSFORMER = "contextualTimeCycleShiftTrans";
public static final String TIME_CYCLE_TRANSFORMER = "timeCycleTrans";
public static final String NUM_DATA_DISCRETIZER = "discretizerTrans";
public static final String NUM_BINARY_TRANSFORMER = "binaryTrans";
public static final String INT_ADD_TRANSFORMER = "intAddTrans";
public static final String INT_SUBTRACT_TRANSFORMER = "intSubtractTrans";
public static final String INT_MULTIPLY_TRANSFORMER = "intMultiplyTrans";
public static final String INT_DIVIDE_TRANSFORMER = "intDivideTrans";
public static final String DOUBLE_ADD_TRANSFORMER= "doubleAddTrans";
public static final String DOUBLE_SUBTRACT_TRANSFORMER = "doubleSubtractTrans";
public static final String DOUBLE_MULTIPLY_TRANSFORMER = "doubleMultiplyTrans";
public static final String DOUBLE_DIVIDE_TRANSFORMER = "doubleDivideTrans";
public static final String CONST_GENERATOR = "constGen";
public static final String GROUP_TRANFORMER = "groupTrans";
public static final String FORCED_REPLACE_TRANSFORMER = "forcedReplaceTrans";
public static final String STRING_CUSTOM_TRANSFORMER = "stringCustomTrans";
public static final String STRING_DELETE_TRANSFORMER = "stringDeleteTrans";
public static final String STRING_CONCATENATION_TRANSFORMER = "stringConcatenationTrans";
public static final String STRING_SPLIT_TRANSFORMER = "stringSplitTrans";
public static final String STRING_FIELD_MERGE_TRANSFORMER = "stringFieldMergeTrans";
public static final String STRING_WITHIN_FIELD_DELIM_TRANSFORMER = "stringWithinFieldDelimTrans";
public static final String STRING_BINARY_TRANSFORMER = "stringBinaryTrans";
private static Map<String,String> custTransformerClasses = new HashMap<String,String>();
private static Map<String,AttributeTransformer> custTransformers = new HashMap<String,AttributeTransformer>();
private static CustomTransformerFactory custTransFactory;
/**
* @param customTransFactoryClass
* @param transConfig
*/
public static void initialize(String customTransFactoryClass, Config transConfig) {
if (null != customTransFactoryClass) {
Class<?>factoryCls = null;
try {
factoryCls = Class.forName(customTransFactoryClass);
custTransFactory = (CustomTransformerFactory)factoryCls.newInstance();
} catch (ClassNotFoundException cne) {
throw new IllegalArgumentException("custom factory class could not be created " + cne.getMessage());
} catch (InstantiationException ie) {
throw new IllegalStateException("custom factory instance could not be created " + ie.getMessage());
} catch (IllegalAccessException iae) {
throw new IllegalStateException("custom factory instance could not be created with access issue " + iae.getMessage());
}
}
//custom transformer classes
if (null == custTransFactory && null != transConfig) {
if (transConfig.hasPath("transformers.customTransformers")) {
List <? extends Config> customTransConfigs = transConfig.getConfigList("transformers.customTransformers");
for (Config custTransConfig : customTransConfigs ) {
custTransformerClasses.put("custom.transformer.class." + custTransConfig.getString("tag"), custTransConfig.getString("class"));
}
}
}
}
/**
* @param tag
* @param config
* @return
*/
public static AttributeTransformer createTransformer(String transformerTag, ProcessorAttribute prAttr, Config config) {
AttributeTransformer transformer = null;
if (transformerTag.equals(LOWER_CASE_TRANSFORMER)) {
transformer = new StringTransformer.LowerCaseTransformer(prAttr);
} else if (transformerTag.equals(UPPER_CASE_TRANSFORMER)) {
transformer = new StringTransformer.UpperCaseTransformer(prAttr);
} else if (transformerTag.equals(PATTERN_BASED_TRANSFORMER)) {
transformer = new StringTransformer.PatternBasedTransformer(prAttr, getTransformerConfig(config , transformerTag, prAttr));
} else if (transformerTag.equals(SEARCH_REPLACE_TRANSFORMER)) {
transformer = new StringTransformer.PatternBasedTransformer(prAttr, getTransformerConfig(config , transformerTag, prAttr));
} else if (transformerTag.equals(KEY_VALUE_TRANSFORMER)) {
transformer = new StringTransformer.KeyValueTransformer(prAttr, getTransformerConfig(config , transformerTag, prAttr));
} else if (transformerTag.equals(DEFAULT_VALUE_TRANSFORMER)) {
transformer = new StringTransformer.DefaultValueTransformer(prAttr, getTransformerConfig(config , transformerTag, prAttr));
} else if (transformerTag.equals(ANOYNMIZER_TRANSFORMER)) {
transformer = new StringTransformer.AnoynmizerTransformer(prAttr, getTransformerConfig(config , transformerTag, prAttr));
} else if (transformerTag.equals(UNIQUE_KEY_GENERATOR)) {
transformer = new StringTransformer.UniqueKeyGenerator(prAttr, getTransformerConfig(config , transformerTag, prAttr));
} else if (transformerTag.equals(TRIM_TRANSFORMER)) {
transformer = new StringTransformer.TrimTransformer(prAttr);
} else if (transformerTag.equals(LONG_POLYNOMIAL_TRANSFORMER)) {
transformer = new NumericTransformer.LongPolynomial(prAttr, getTransformerConfig(config , transformerTag, prAttr));
} else if (transformerTag.equals(DOUBLE_POLYNOMIAL_TRANSFORMER)) {
transformer = new NumericTransformer.DoublePolynomial(prAttr, getTransformerConfig(config , transformerTag, prAttr));
} else if (transformerTag.equals(LONG_CUSTOM_TRANSFORMER)) {
transformer = new NumericTransformer.LongCustom(prAttr, getTransformerConfig(config , transformerTag, prAttr));
} else if (transformerTag.equals(DOUBLE_CUSTOM_TRANSFORMER)) {
transformer = new NumericTransformer.DoubleCustom(prAttr, getTransformerConfig(config , transformerTag, prAttr));
} else if (transformerTag.equals(EPOCH_TIME_GENERATOR)) {
transformer = new DateTransformer.EpochTimeGenerator(prAttr);
} else if (transformerTag.equals(DATE_GENERATOR)) {
transformer = new DateTransformer.DateGenerator(prAttr, getTransformerConfig(config , transformerTag, prAttr));
} else if (transformerTag.equals(DATE_FORMAT_TRANSFORMER)) {
transformer = new DateTransformer.DateFormatTransformer(prAttr, getTransformerConfig(config , transformerTag, prAttr));
} else if (transformerTag.equals(DATE_COMPONENT_TRANSFORMER)) {
transformer = new DateTransformer.DateComponentTransformer(prAttr, getTransformerConfig(config , transformerTag, prAttr));
} else if (transformerTag.equals(ELAPSED_TIME_TRANSFORMER)) {
transformer = new DateTransformer.ElapsedTimeTransformer(prAttr, getTransformerConfig(config , transformerTag, prAttr));
} else if (transformerTag.equals(CONTEXTUAL_ELAPSED_TIME_TRANSFORMER)) {
transformer = new DateTransformer.ContextualElapsedTimeTransformer(prAttr, getTransformerConfig(config , transformerTag, prAttr));
} else if (transformerTag.equals(TIME_CYCLE_SHIFT_TRANSFORMER)) {
transformer = new DateTransformer.TimeCyclicShiftTransformer(prAttr, getTransformerConfig(config , transformerTag, prAttr));
} else if (transformerTag.equals(CONTEXTUAL_TIME_CYCLE_SHIFT_TRANSFORMER)) {
transformer = new DateTransformer.ContextualTimeCyclicShiftTransformer(prAttr, getTransformerConfig(config , transformerTag, prAttr));
} else if (transformerTag.equals(TIME_CYCLE_TRANSFORMER)) {
transformer = new DateTransformer.TimeCycleTransformer(prAttr, getTransformerConfig(config , transformerTag, prAttr));
} else if (transformerTag.equals(NUM_DATA_DISCRETIZER)) {
transformer = new NumericTransformer.Discretizer(prAttr, getTransformerConfig(config , transformerTag, prAttr));
} else if (transformerTag.equals(NUM_BINARY_TRANSFORMER)) {
transformer = new NumericTransformer.BinaryCreator(prAttr, getTransformerConfig(config , transformerTag, prAttr));
} else if (transformerTag.equals(INT_ADD_TRANSFORMER) || transformerTag.equals(DOUBLE_ADD_TRANSFORMER)) {
transformer = new NumericTransformer.Adder(prAttr, getTransformerConfig(config , transformerTag, prAttr));
} else if (transformerTag.equals(INT_SUBTRACT_TRANSFORMER) || transformerTag.equals(DOUBLE_SUBTRACT_TRANSFORMER)) {
transformer = new NumericTransformer.Subtracter(prAttr, getTransformerConfig(config , transformerTag, prAttr));
} else if (transformerTag.equals(INT_MULTIPLY_TRANSFORMER) || transformerTag.equals(DOUBLE_MULTIPLY_TRANSFORMER)) {
transformer = new NumericTransformer.Multiplier(prAttr, getTransformerConfig(config , transformerTag, prAttr));
} else if (transformerTag.equals(INT_DIVIDE_TRANSFORMER) || transformerTag.equals(DOUBLE_DIVIDE_TRANSFORMER)) {
transformer = new NumericTransformer.Divider(prAttr, getTransformerConfig(config , transformerTag, prAttr));
} else if (transformerTag.equals(CONST_GENERATOR)) {
transformer = new StringTransformer.ConstantGenerator(prAttr, getTransformerConfig(config , transformerTag, prAttr));
} else if (transformerTag.equals(GROUP_TRANFORMER)) {
transformer = new StringTransformer.GroupTransformer(prAttr, getTransformerConfig(config , transformerTag, prAttr));
} else if (transformerTag.equals(FORCED_REPLACE_TRANSFORMER)) {
transformer = new StringTransformer.ForcedReplaceTransformer(prAttr, getTransformerConfig(config , transformerTag, prAttr));
} else if (transformerTag.equals(STRING_CUSTOM_TRANSFORMER)) {
transformer = new StringTransformer.StringCustomTransformer(prAttr, getTransformerConfig(config , transformerTag, prAttr));
} else if (transformerTag.equals(STRING_DELETE_TRANSFORMER)) {
transformer = new StringTransformer.DeleteTransformer(prAttr, getTransformerConfig(config , transformerTag, prAttr));
} else if (transformerTag.equals(STRING_CONCATENATION_TRANSFORMER)) {
transformer = new StringTransformer.ConcatenatorTransformer(prAttr, getTransformerConfig(config , transformerTag, prAttr));
} else if (transformerTag.equals(STRING_SPLIT_TRANSFORMER)) {
transformer = new StringTransformer.SplitterTransformer(prAttr, getTransformerConfig(config , transformerTag, prAttr));
} else if (transformerTag.equals(STRING_FIELD_MERGE_TRANSFORMER)) {
transformer = new StringTransformer.FieldMergeTransformer(prAttr, getTransformerConfig(config , transformerTag, prAttr));
} else if (transformerTag.equals(STRING_WITHIN_FIELD_DELIM_TRANSFORMER)) {
transformer = new StringTransformer.WithinFieldDelimiterTransformer(prAttr, getTransformerConfig(config , transformerTag, prAttr));
} else if (transformerTag.equals(STRING_BINARY_TRANSFORMER)) {
transformer = new StringTransformer.BinaryValueTransformer(prAttr, getTransformerConfig(config , transformerTag, prAttr));
} else {
//custom transformer with configured transformer class names
transformer = createCustomTransformer(transformerTag, prAttr, config);
//transformer factory
if (null == transformer && null != custTransFactory) {
//custom transformer factory
transformer = custTransFactory.createTransformer(transformerTag, prAttr, config);
}
//invalid transformer tag
if (null == transformer) {
throw new IllegalArgumentException("invalid transformer tag: " + transformerTag + " ordinal:" +
prAttr.getOrdinal() + " data type:" + prAttr.getDataType());
}
}
return transformer;
}
/**
* @param transformerTag
* @param prAttr
* @param config
* @param inStrm
* @return
* @throws IOException
*/
public static AttributeTransformer createTransformer(String transformerTag, ProcessorAttribute prAttr,
Config config, InputStream inStrm) throws IOException {
AttributeTransformer transformer = null;
if (transformerTag.equals(KEY_VALUE_TRANSFORMER)) {
transformer = new StringTransformer.KeyValueTransformer(prAttr,
getTransformerConfig(config , transformerTag, prAttr), inStrm);
} else {
throw new IllegalArgumentException("invalid transformer tag: " + transformerTag + " ordinal:" +
prAttr.getOrdinal() + " data type:" + prAttr.getDataType());
}
return transformer;
}
/**
* @param tranformerTag
* @param prAttr
* @return
*/
public static Config getTransformerConfig(Config transformerConfig ,String transformerTag, ProcessorAttribute prAttr) {
Config transConfig = transformerConfig.getConfig("transformers." + transformerTag);
Config config = null;
try {
//attribute specific config
config = transConfig.getConfig(prAttr.getName());
} catch ( ConfigException.Missing ex) {
}
return null != config ? config : transConfig;
}
/**
* @param transformerTag
* @param prAttr
* @param validatorConfig
* @return
*/
private static AttributeTransformer createCustomTransformer(String transformerTag, ProcessorAttribute prAttr, Config transConfig) {
AttributeTransformer transformer = custTransformers.get(transformerTag);
if (null == transformer) {
String transformerClass = custTransformerClasses.get("custom.transformer.class." + transformerTag);
if (null != transformerClass) {
try {
Class<?> clazz = Class.forName(transformerClass);
Constructor<?> ctor = clazz.getConstructor(String.class, prAttr.getClass(), Config.class);
transformer = (AttributeTransformer)(ctor.newInstance(new Object[] { transformerTag, prAttr, transConfig}));
custTransformers.put(transformerTag, transformer);
} catch (Exception ex) {
throw new IllegalArgumentException("could not create dynamic validator object for " + transformerTag + " " + ex.getMessage());
}
}
}
return transformer;
}
}