datax(19):源码解读内置Transformer「建议收藏」

datax(19):源码解读内置Transformer「建议收藏」通过datax(18)已经对transformer有了初步了解,继续撸代码,看datax已经内置的5种简单类型transformer;一、概述目前datax内置了5种常用的transformer,分别如下截取SubstrTransformer填充PadTransformer替换ReplaceTransformer过滤FilterTransformerGroovy类型GroovyTransformer二、SubstrTransformer主要是对record中的column的值进.

大家好,又见面了,我是你们的朋友全栈君。

通过datax(18)已经对transformer有了初步了解,继续撸代码,看datax已经内置的5种简单类型transformer;


一、概述

目前datax内置了5种常用的transformer,分别如下

  1. 截取SubstrTransformer
  2. 填充PadTransformer
  3. 替换ReplaceTransformer
  4. 过滤FilterTransformer
  5. Groovy类型GroovyTransformer

二、SubstrTransformer

主要是对record中的column的值进行按照长度截取;

  • 参数:3个
    • 第一个参数:字段编号,对应record中第几个字段。
    • 第二个参数:字段值的开始位置。
    • 第三个参数:目标字段长度。
  • 返回: 从字符串的指定位置(包含)截取指定长度的字符串。如果开始位置非法抛出异常。如果字段为空值,直接返回(即不参与本transformer)
  • 举例:
dx_substr(1,"2","5")  column 1的value为“dataxTest”=>"taxTe"
dx_substr(1,"5","10")  column 1的value为“dataxTest”=>"Test"

里面第一个方法是给该transformer一个唯一的标识符name(后续几个transformer的子类类似,不在赘述)

 /** * 给该transform起一个唯一标识符 */
  public SubstrTransformer() { 
   
    setTransformerName("dx_substr");
  }

第二个方法是实现父类的evaluate

  /** * 参数:3个 <br> * 第一个参数:字段编号,对应record中第几个字段。 <br> * 第二个参数:字段值的开始位置。 <br> * 第三个参数:目标字段长度。 <br> * 举例: <br> * dx_substr(1,"2","5") column 1的value为“dataxTest”=>"taxTe" * dx_substr(1,"5","10") column 1的value为“dataxTest”=>"Test" * * @param record Record 行记录,UDF进行record的处理后,更新相应的record * @param paras Object transformer函数参数 * @return Record从字符串的指定位置(包含)截取指定长度的字符串。如果开始位置非法抛出异常。如果字段为空值,直接返回 * (即不参与本transformer) */
@Override
public Record evaluate(Record record, Object... paras) { 

int columnIndex;
int startIndex;
int targetLen;
try { 

// 参数异常检测
if (paras.length != 3) { 

throw new RuntimeException("dx_substr paras must be 3");
}
//获取对应参数值
columnIndex = (Integer) paras[0];
startIndex = Integer.valueOf((String) paras[1]);
targetLen = Integer.valueOf((String) paras[2]);
} catch (Exception e) { 

throw DataXException.asDataXException(TransformerErrorCode.TRANSFORMER_ILLEGAL_PARAMETER,
"paras:" + Arrays.asList(paras).toString() + " => " + e.getMessage());
}
// 根据index从record中获取 column
Column column = record.getColumn(columnIndex);
try { 

String oriValue = column.asString();
//如果字段为空,跳过subStr处理
if (oriValue == null) { 

return record;
}
String newValue;
int oriLen = oriValue.length();
if (startIndex > oriLen) { 

throw new RuntimeException(String
.format("dx_substr startIndex(%s) out of range(%s)", startIndex, oriLen));
}
if (startIndex + targetLen >= oriLen) { 

newValue = oriValue.substring(startIndex);
} else { 

newValue = oriValue.substring(startIndex, startIndex + targetLen);
}
record.setColumn(columnIndex, new StringColumn(newValue));
} catch (Exception e) { 

throw DataXException.asDataXException(TRANSFORMER_RUN_EXCEPTION, e.getMessage(), e);
}
return record;
}

三、PadTransformer

  • 参数:4个
    • 第一个参数:字段编号,对应record中第几个字段。
    • 第二个参数:“l”,“r”, 指示是在头进行pad,还是尾进行pad。
    • 第三个参数:目标字段长度。
    • 第四个参数:需要pad的字符。
  • 返回: 如果源字符串长度小于目标字段长度,按照位置添加pad字符后返回。如果长于,直接截断(都截右边)。如果字段为空值,转换为空字符串进行pad,即最后的字符串全是需要pad的字符
  • 举例:
         dx_pad(1,"l","4","A"), 如果column 1 的值为 xyz=> Axyz, 值为 xyzzzzz => xyzz
dx_pad(1,"r","4","A"), 如果column 1 的值为 xyz=> xyzA, 值为 xyzzzzz => xyzz
public PadTransformer() { 

setTransformerName("dx_pad");
}
/** * 参数:4个 <br/> * 第一个参数:字段编号,对应record中第几个字段。 <br/> * 第二个参数:"l","r", 指示是在头进行pad,还是尾进行pad。 <br/> * 第三个参数:目标字段长度。 <br/> * 第四个参数:需要pad的字符。 <br/> * 举例: <br/> * dx_pad(1,"l","4","A"), 如果column 1 的值为 xyz=> Axyz, 值为 xyzzzzz => xyzz <br/> * dx_pad(1,"r","4","A"), 如果column 1 的值为 xyz=> xyzA, 值为 xyzzzzz => xyzz <br/> * * @param record Record 行记录,UDF进行record的处理后,更新相应的record * @param paras Object transformer函数参数 * @return Record 如果源字符串长度小于目标字段长度,按照位置添加pad字符后返回。如果长于,直接截断(都截右边)。 * 如果字段为空值,转换为空字符串进行pad,即最后的字符串全是需要pad的字符 */
@Override
public Record evaluate(Record record, Object... paras) { 

int columnIndex;
String padType;
int length;
String padString;
try { 

if (paras.length != 4) { 

throw new RuntimeException("dx_pad paras must be 4");
}
columnIndex = (Integer) paras[0];
padType = (String) paras[1];
length = Integer.valueOf((String) paras[2]);
padString = (String) paras[3];
} catch (Exception e) { 

throw DataXException.asDataXException(TransformerErrorCode.TRANSFORMER_ILLEGAL_PARAMETER,
"paras:" + Arrays.asList(paras).toString() + " => " + e.getMessage());
}
Column column = record.getColumn(columnIndex);
try { 

String oriValue = column.asString();
//如果字段为空,作为空字符串处理
if (oriValue == null) { 

oriValue = "";
}
String newValue;
//"l","r", 指示是在头进行pad,还是尾进行pad
if (!padType.equalsIgnoreCase("r") && !padType.equalsIgnoreCase("l")) { 

throw new RuntimeException(String.format("dx_pad first para(%s) support l or r", padType));
}
if (length <= oriValue.length()) { 

// 如果目标长度len 小于 真实原数数据长度oriValue.length,则使用截取,截取原来数据0到len
newValue = oriValue.substring(0, length);
} else { 

newValue = doPad(padType, oriValue, length, padString);
}
record.setColumn(columnIndex, new StringColumn(newValue));
} catch (Exception e) { 

throw DataXException.asDataXException(TRANSFORMER_RUN_EXCEPTION, e.getMessage(), e);
}
return record;
}
/** * 真正实现填充的逻辑 * * @param padType String 需要填充的类型 * @param oriValue String 原始数据 * @param length int 需要填充后的长度 * @param padString String 需要填充的字符串 * @return String */
private String doPad(String padType, String oriValue, int length, String padString) { 

String finalPad = "";
int needLen = length - oriValue.length();
while (needLen > 0) { 

if (needLen >= padString.length()) { 

finalPad += padString;
needLen -= padString.length();
} else { 

finalPad += padString.substring(0, needLen);
needLen = 0;
}
}
//"l","r", 指示是在头进行pad,还是尾进行pad
if (padType.equalsIgnoreCase("l")) { 

return finalPad + oriValue;
} else { 

return oriValue + finalPad;
}
}

四、ReplaceTransformer

  • 参数:4个
    • 第一个参数:字段编号,对应record中第几个字段。
    • 第二个参数:字段值的开始位置。
    • 第三个参数:需要替换的字段长度。
    • 第四个参数:需要替换的字符串。
  • 返回: 从字符串的指定位置(包含)替换指定长度的字符串。如果开始位置非法抛出异常。如果字段为空值,直接返回(即不参与本transformer)
  • 举例:
dx_replace(1,"2","4","****")  column 1的value为“dataxTest”=>"da****est"
dx_replace(1,"5","10","****")  column 1的value为“dataxTest”=>"data****"
/** * 参数:4个 * 第一个参数:字段编号,对应record中第几个字段。 * 第二个参数:字段值的开始位置。 * 第三个参数:需要替换的字段长度。 * 第四个参数:需要替换的字符串。 * 举例: * dx_replace(1,"2","4","****") column 1的value为“dataxTest”=>"da****est" * dx_replace(1,"5","10","****") column 1的value为“dataxTest”=>"data****" * * @param record Record 行记录,UDF进行record的处理后,更新相应的record * @param paras Object transformer函数参数 * @return 从字符串的指定位置(包含)替换指定长度的字符串。如果开始位置非法抛出异常。如果字段为空值,直接返回(即不参与本transformer) */
@Override
public Record evaluate(Record record, Object... paras) { 

int columnIndex;
int startIndex;
int targetLen;
String replaceStr;
try { 

if (paras.length != 4) { 

throw new RuntimeException("dx_replace paras must be 4");
}
columnIndex = (Integer) paras[0];
startIndex = Integer.valueOf((String) paras[1]);
targetLen = Integer.valueOf((String) paras[2]);
replaceStr = (String) paras[3];
} catch (Exception e) { 

throw DataXException.asDataXException(TransformerErrorCode.TRANSFORMER_ILLEGAL_PARAMETER,
"paras:" + Arrays.asList(paras).toString() + " => " + e.getMessage());
}
Column column = record.getColumn(columnIndex);
try { 

String oriValue = column.asString();
//如果字段为空,跳过replace处理
if (oriValue == null) { 

return record;
}
String newValue;
int oriLen = oriValue.length();
if (startIndex > oriLen) { 

throw new RuntimeException(String
.format("dx_replace startIndex(%s) out of range(%s)", startIndex, oriLen));
}
newValue = oriValue.substring(0, startIndex) + replaceStr;
if (startIndex + targetLen < oriLen) { 

newValue = newValue + oriValue.substring(startIndex + targetLen);
}
record.setColumn(columnIndex, new StringColumn(newValue));
} catch (Exception e) { 

throw DataXException
.asDataXException(TransformerErrorCode.TRANSFORMER_RUN_EXCEPTION, e.getMessage(), e);
}
return record;
}

五、FilterTransformer

  • 参数:
    • 第一个参数:字段编号,对应record中第几个字段。
    • 第二个参数:运算符,支持一下运算符:like, not like, >, =, <, >=, !=, <=
    • 第三个参数:正则表达式(java正则表达式)、值。
  • 返回:
    • 如果匹配正则表达式,返回Null,表示过滤该行。不匹配表达式时,表示保留该行。(注意是该行)。对于>=<都是对字段直接compare的结果.
    • like , not like是将字段转换成String,然后和目标正则表达式进行全匹配。
    • , =, <, >=, !=, <= 对于DoubleColumn比较double值,对于LongColumn和DateColumn比较long值,其他StringColumn,BooleanColumn以及ByteColumn均比较的是StringColumn值。

    • 如果目标column为空(null),对于 = null的过滤条件,将满足条件,被过滤。!=null的过滤条件,null不满足过滤条件,不被过滤。 like,字段为null不满足条件,不被过滤,和not like,字段为null满足条件,被过滤。
  • 举例:
dx_filter(1,"like","dataTest")  
dx_filter(1,">=","10")  
/** * 过滤transformer类 * Created by liqiang on 16/3/4. */
public class FilterTransformer extends Transformer { 

public FilterTransformer() { 

setTransformerName("dx_filter");
}
/** * 参数: <br> * 第一个参数:字段编号,对应record中第几个字段。 <br> * 第二个参数:运算符,支持一下运算符:like, not like, >, =, <, >=, !=, <= <br> * 第三个参数:正则表达式(java正则表达式)、值。 <br> * 返回: * 如果匹配正则表达式,返回Null,表示过滤该行。不匹配表达式时,表示保留该行。(注意是该行)。对于>=<都是对字段直接compare的结果. <br> * like , not like是将字段转换成String,然后和目标正则表达式进行全匹配。 <br> * , =, <, >=, !=, <= 对于DoubleColumn比较double值,对于LongColumn和DateColumn比较long值, <br> * 其他StringColumn,BooleanColumn以及ByteColumn均比较的是StringColumn值。 <br> * <p> * 如果目标column为空(null),对于 = null的过滤条件,将满足条件,被过滤。!=null的过滤条件,null不满足过滤条件,不被过滤。 <br> * like,字段为null不满足条件,不被过滤,和not like,字段为null满足条件,被过滤。 <br> * 举例: <br> * dx_filter(1,"like","dataTest") <br> * dx_filter(1,">=","10") <br> * * @param record Record 行记录,UDF进行record的处理后,更新相应的record * @param paras Object transformer函数参数 * @return Record */
@Override
public Record evaluate(Record record, Object... paras) { 

int columnIndex;
String code;
String value;
try { 

if (paras.length != 3) { 

throw new RuntimeException("dx_filter paras must be 3");
}
columnIndex = (Integer) paras[0];
code = (String) paras[1];
value = (String) paras[2];
if (StringUtils.isEmpty(value)) { 

throw new RuntimeException("dx_filter para 2 can't be null");
}
} catch (Exception e) { 

throw DataXException.asDataXException(TransformerErrorCode.TRANSFORMER_ILLEGAL_PARAMETER,
"paras:" + Arrays.asList(paras).toString() + " => " + e.getMessage());
}
Column column = record.getColumn(columnIndex);
try { 

if ("like".equalsIgnoreCase(code)) { 

return doLike(record, value, column);
} else if ("not like".equalsIgnoreCase(code)) { 

return doNotLike(record, value, column);
} else if (">".equalsIgnoreCase(code)) { 

return doGreat(record, value, column, false);
} else if ("<".equalsIgnoreCase(code)) { 

return doLess(record, value, column, false);
} else if ("=".equalsIgnoreCase(code) || "==".equalsIgnoreCase(code)) { 

return doEqual(record, value, column);
} else if ("!=".equalsIgnoreCase(code)) { 

return doNotEqual(record, value, column);
} else if (">=".equalsIgnoreCase(code)) { 

return doGreat(record, value, column, true);
} else if ("<=".equalsIgnoreCase(code)) { 

return doLess(record, value, column, true);
} else { 

throw new RuntimeException("dx_filter can't support code:" + code);
}
} catch (Exception e) { 

throw DataXException.asDataXException(TRANSFORMER_RUN_EXCEPTION, e.getMessage(), e);
}
}
private Record doGreat(Record record, String value, Column column, boolean hasEqual) { 

//如果字段为空,直接不参与比较。即空也属于无穷小
if (column.getRawData() == null) { 

return record;
}
if (column instanceof DoubleColumn) { 

Double ori = column.asDouble();
double val = Double.parseDouble(value);
if (hasEqual) { 

return ori >= val ? null : record;
} else { 

return ori > val ? null : record;
}
} else if (column instanceof LongColumn || column instanceof DateColumn) { 

Long ori = column.asLong();
long val = Long.parseLong(value);
if (hasEqual) { 

return ori >= val ? null : record;
} else { 

return ori > val ? null : record;
}
} else if (column instanceof StringColumn || column instanceof BytesColumn
|| column instanceof BoolColumn) { 

String ori = column.asString();
if (hasEqual) { 

return ori.compareTo(value) >= 0 ? null : record;
} else { 

return ori.compareTo(value) > 0 ? null : record;
}
} else { 

throw new RuntimeException(
">=,> can't support this columnType:" + column.getClass().getSimpleName());
}
}
private Record doLess(Record record, String value, Column col, boolean hasEqual) { 

//如果字段为空,直接不参与比较。即空也属于无穷大
if (col.getRawData() == null) { 

return record;
}
if (col instanceof DoubleColumn) { 

Double ori = col.asDouble();
double val = Double.parseDouble(value);
if (hasEqual) { 

return ori <= val ? null : record;
} else { 

return ori < val ? null : record;
}
} else if (col instanceof LongColumn || col instanceof DateColumn) { 

Long ori = col.asLong();
long val = Long.parseLong(value);
if (hasEqual) { 

return ori <= val ? null : record;
} else { 

return ori < val ? null : record;
}
} else if (col instanceof StringColumn || col instanceof BytesColumn
|| col instanceof BoolColumn) { 

String ori = col.asString();
if (hasEqual) { 

return ori.compareTo(value) <= 0 ? null : record;
} else { 

return ori.compareTo(value) < 0 ? null : record;
}
} else { 

throw new RuntimeException(
"<=,< can't support this columnType:" + col.getClass().getSimpleName());
}
}
/** * DateColumn将比较long值,StringColumn,ByteColumn以及BooleanColumn比较其String值 * * @param record Record * @param value String * @param col Column * @return Record 如果相等,则过滤。 */
private Record doEqual(Record record, String value, Column col) { 

//如果字段为空,只比较目标字段为"null",否则null字段均不过滤
if (col.getRawData() == null) { 

return "null".equalsIgnoreCase(value) ? null : record;
}
if (col instanceof DoubleColumn) { 

Double ori = col.asDouble();
double val = Double.parseDouble(value);
return ori == val ? null : record;
} else if (col instanceof LongColumn || col instanceof DateColumn) { 

Long ori = col.asLong();
long val = Long.parseLong(value);
return ori == val ? null : record;
} else if (col instanceof StringColumn || col instanceof BytesColumn
|| col instanceof BoolColumn) { 

String ori = col.asString();
return ori.compareTo(value) == 0 ? null : record;
} else { 

throw new RuntimeException("can't support this columnType:" + col.getClass().getSimpleName());
}
}
/** * DateColumn将比较long值,StringColumn,ByteColumn以及BooleanColumn比较其String值 * * @param record Record * @param value String * @param col Column * @return Record 如果不相等,则过滤。 */
private Record doNotEqual(Record record, String value, Column col) { 

//如果字段为空,只比较目标字段为"null", 否则null字段均过滤。
if (col.getRawData() == null) { 

return "null".equalsIgnoreCase(value) ? record : null;
}
if (col instanceof DoubleColumn) { 

Double ori = col.asDouble();
double val = Double.parseDouble(value);
return ori != val ? null : record;
} else if (col instanceof LongColumn || col instanceof DateColumn) { 

Long ori = col.asLong();
long val = Long.parseLong(value);
return ori != val ? null : record;
} else if (col instanceof StringColumn || col instanceof BytesColumn
|| col instanceof BoolColumn) { 

String ori = col.asString();
return ori.compareTo(value) != 0 ? null : record;
} else { 

throw new RuntimeException("can't support this columnType:" + col.getClass().getSimpleName());
}
}
private Record doLike(Record record, String value, Column column) { 

String oriValue = column.asString();
return oriValue != null && oriValue.matches(value) ? null : record;
}
private Record doNotLike(Record record, String value, Column column) { 

String oriValue = column.asString();
return oriValue != null && oriValue.matches(value) ? record : null;
}
}

六、GroovyTransformer

首先需要知道groovy是什么:运行在jvm上,吸收Python、Ruby和Smalltalk等特性的一种脚本语言!!!可以和java代码库相互操作;
一句话概括就是:用户可以写一些groovy代码,使用GroovyTransformer加载运行实现transform的作用!!!

  • 参数。
    • 第一个参数: groovy code
    • 第二个参数(列表或者为空):extraPackage
  • 备注:
    • dx_groovy只能调用一次。不能多次调用。
    • groovy code中支持java.lang, java.util的包,可直接引用的对象有record,以及element下的各种column(BoolColumn.class,BytesColumn.class,DateColumn.class,DoubleColumn.class,LongColumn.class,StringColumn.class)。不支持其他包,如果用户有需要用到其他包,可设置extraPackage,注意extraPackage不支持第三方jar包。
    • groovy code中,返回更新过的Record(比如record.setColumn(columnIndex, new StringColumn(newValue));),或者null。返回null表示过滤此行。
    • 用户可以直接调用静态的Util方式(GroovyTransformerStaticUtil),目前GroovyTransformerStaticUtil的方法列表 (按需补充):
  • 举例:
groovy 实现的subStr:
String code = "Column column = record.getColumn(1);\n" +
" String oriValue = column.asString();\n" +
" String newValue = oriValue.substring(0, 3);\n" +
" record.setColumn(1, new StringColumn(newValue));\n" +
" return record;";
dx_groovy(record);
groovy 实现的Replace
String code2 = "Column column = record.getColumn(1);\n" +
" String oriValue = column.asString();\n" +
" String newValue = \"****\" + oriValue.substring(3, oriValue.length());\n" +
" record.setColumn(1, new StringColumn(newValue));\n" +
" return record;";
groovy 实现的Pad
String code3 = "Column column = record.getColumn(1);\n" +
" String oriValue = column.asString();\n" +
" String padString = \"12345\";\n" +
" String finalPad = \"\";\n" +
" int NeedLength = 8 - oriValue.length();\n" +
"        while (NeedLength > 0) {\n" +
"\n" +
"            if (NeedLength >= padString.length()) {\n" +
"                finalPad += padString;\n" +
"                NeedLength -= padString.length();\n" +
"            } else {\n" +
"                finalPad += padString.substring(0, NeedLength);\n" +
"                NeedLength = 0;\n" +
"            }\n" +
"        }\n" +
" String newValue= finalPad + oriValue;\n" +
" record.setColumn(1, new StringColumn(newValue));\n" +
" return record;";

/** * Groovy类的transformer * Created by liqiang on 16/3/4. */
public class GroovyTransformer extends Transformer { 

public GroovyTransformer() { 

setTransformerName("dx_groovy");
}
private Transformer groovyTransformer;
/** * 参数 <br> * 第一个参数: groovy code <br> * 第二个参数(列表或者为空):extraPackage <br> * 备注: <br> * dx_groovy只能调用一次。不能多次调用。 <br> * groovy code中支持java.lang, java.util的包,可直接引用的对象有record,以及element下的各种 <br> * column(BoolColumn.class,BytesColumn.class,DateColumn.class,DoubleColumn.class,LongColumn.class, * <br> * StringColumn.class)。不支持其他包,如果用户有需要用到其他包,可设置extraPackage,注意extraPackage不支持第三方jar包。 <br> * groovy code中,返回更新过的Record(比如record.setColumn(columnIndex, new StringColumn(newValue));), <br> * 或者null。返回null表示过滤此行。 <br> * 用户可以直接调用静态的Util方式(GroovyTransformerStaticUtil),目前GroovyTransformerStaticUtil的方法列表 (按需补充): <br> * * @param record Record 行记录,UDF进行record的处理后,更新相应的record * @param paras Object transformer函数参数 * @return Record */
@Override
public Record evaluate(Record record, Object... paras) { 

if (groovyTransformer == null) { 

//全局唯一
if (paras.length < 1 || paras.length > 2) { 

throw DataXException.asDataXException(TransformerErrorCode.TRANSFORMER_ILLEGAL_PARAMETER,
"dx_groovy paras must be 1 or 2. now paras is: " + Arrays.asList(paras).toString());
}
synchronized (this) { 

if (groovyTransformer == null) { 

String code = (String) paras[0];
@SuppressWarnings("unchecked")
List<String> extraPackage = paras.length == 2 ? (List<String>) paras[1] : null;
initGroovyTransformer(code, extraPackage);
}
}
}
return this.groovyTransformer.evaluate(record);
}
/** * 初始化 GroovyTransformer。<br> * 1 根据code和包列表,构造出完整的groovy代码段。<br> * 2 反射加载该groovy。<br> * 3 将2反射构造出的groovy对象强制类型转为,最后赋给groovyTransformer(Transformer类型)。<br> * * @param code String Groovy代码片段 * @param extraPackage List<String> 额外的import的包 */
private void initGroovyTransformer(String code, List<String> extraPackage) { 

GroovyClassLoader loader = new GroovyClassLoader(GroovyTransformer.class.getClassLoader());
String groovyRule = getGroovyRule(code, extraPackage);
Class groovyClass;
try { 

groovyClass = loader.parseClass(groovyRule);
} catch (CompilationFailedException cfe) { 

throw DataXException.asDataXException(TRANSFORMER_GROOVY_INIT_EXCEPTION, cfe);
}
try { 

Object t = groovyClass.newInstance();
if (!(t instanceof Transformer)) { 

throw DataXException
.asDataXException(TRANSFORMER_GROOVY_INIT_EXCEPTION, "datax bug! contact askdatax");
}
this.groovyTransformer = (Transformer) t;
} catch (Throwable ex) { 

throw DataXException.asDataXException(TRANSFORMER_GROOVY_INIT_EXCEPTION, ex);
}
}
/** * 根据code 和 引用的包,构建出groovy代码片段 * * @param code * @param extraPackagesStrList * @return */
private String getGroovyRule(String code, List<String> extraPackagesStrList) { 

StringBuffer sb = new StringBuffer();
if (extraPackagesStrList != null) { 

for (String extraPackagesStr : extraPackagesStrList) { 

if (StringUtils.isNotEmpty(extraPackagesStr)) { 

sb.append(extraPackagesStr);
}
}
}
sb.append(
"import static com.alibaba.datax.core.transport.transformer.GroovyTransformerStaticUtil.*;");
sb.append("import com.alibaba.datax.common.element.*;");
sb.append("import com.alibaba.datax.common.exception.DataXException;");
sb.append("import com.alibaba.datax.transformer.Transformer;");
sb.append("import java.util.*;");
sb.append("public class RULE extends Transformer").append("{");
sb.append("public Record evaluate(Record record, Object... paras) {");
sb.append(code);
sb.append("}}");
return sb.toString();
}
}

注:

  1. 对源码进行略微改动,主要修改为 1 阿里代码规约扫描出来的,2 clean code;

  2. 所有代码都已经上传到github(master分支和dev),可以免费白嫖

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/145297.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • ICMP 协议「建议收藏」

    ICMP 协议「建议收藏」一、什么是ICMP协议?ICMP(InternetControlMessageProtocol)Internet控制报文协议。它是TCP/IP协议簇的一个子协议,用于在IP主机、路由器之间传递控制消息。控制消息是指网络通不通、主机是否可达、路由是否可用等网络本身的消息。这些控制消息虽然并不传输用户数据,但是对于用户数据的传递起着重要的作用。ICMP使用IP的基本支持,就像它是一个更高级别…

    2022年10月23日
  • pycharm python interpreter_pycharm interpreter

    pycharm python interpreter_pycharm interpreter1,首先我们肯定要在Pycharm里建立一个新项目,有两个选项,一个建立新的虚拟的环境,一个基于已有的环境这里选择第一项。2,选择第一项之后会有两个解释器,一个虚拟的即location/venv/Scripts/python.exe,另一个需要基解释器即本地解释器/python.exe。关于第一项的解释我极力推荐此篇文章虚拟解释器的简单说明3,然后,如果在创建pycharm项目时项目解…

  • AArch64教程第一章

    AArch64教程第一章AArch64教程第一章AArch64是一个新的64位模式,它是ARMv8架构下的一部分,它于2011年随着ARM发布。它被逐步部署于智能手机和服务器。所以我认为现在学习一点关于此架构的知识是比较好的。硬件目前,有ARMv6/ARMv7的单板电脑是比较容易获得的,其中最流行的一个选择是树莓派。相反,支持64位ARMv8模式的单板电脑就没有那么多了,但是它们最近也慢慢变得流行了起来。例如,Pine64,ODROID-C2,Dragonboard410c,等等。它们中的任何一种都可以做64位开发,

    2022年10月16日
  • 机器学习之支持向量回归(SVR)

    机器学习之支持向量回归(SVR)简介支持向量机(SupportVectorMachine)是由Vapnik等人于1995年提出来的,之后随着统计理论的发展,支持向量机SVM也逐渐受到了各领域研究者的关注,在很短的时间就得到了很广泛的应用。支持向量机是被公认的比较优秀的分类模型。同时,在支持向量机的发展过程中,其理论方面的研究得到了同步的发展,为支持向量机的研究提供了强有力的理论支撑。本实训项目主要围绕支持向量机的原理和技术进行介绍,并基于实际案例进行实战实训。线性支持向量机#encoding=utf8fromsk

  • HttpSession详解「建议收藏」

    HttpSession详解「建议收藏」HttpSession服务端的技术服务器会为每一个用户创建一个独立的HttpSessionHttpSession原理当用户第一次访问Servlet时,服务器端会给用户创建一个独立的Sessi

  • java 卸载工具_java卸载工具下载

    java 卸载工具_java卸载工具下载java怎样完全卸载?怎么彻底删除java?有些用户的系统上会自带java程序,或者是因为安装了什么软件导致java一起安装了,那这个时候怎么将java卸载呢?不清楚的用户,看看小米小编为大家推荐的一款非常好用的java卸载工具。软件介绍java卸载器是一款java完全卸载工具,当你的java出现了故障需要卸载重装的话,就可以使用这个软件完全卸载掉java的所有文件,可以完美解决java卸载不了、…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号