kettle系列-4.kettle定制化开发工具类

要说的话这个工具类还是比较简单的,每个方法体都比较小,但用起来还是可以的,把开发中一些常用的步骤封装了下,不用去kettle源码中找相关操作的具体实现了。

算了废话不多了,直接上重点,代码如下:

import java.util.List;

import org.apache.log4j.Logger;
import org.pentaho.di.core.KettleEnvironment;
import org.pentaho.di.core.database.DatabaseMeta;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.core.exception.KettleSecurityException;
import org.pentaho.di.job.JobMeta;
import org.pentaho.di.job.entries.job.JobEntryJob;
import org.pentaho.di.job.entries.trans.JobEntryTrans;
import org.pentaho.di.job.entry.JobEntryBase;
import org.pentaho.di.job.entry.JobEntryCopy;
import org.pentaho.di.repository.AbstractRepository;
import org.pentaho.di.repository.LongObjectId;
import org.pentaho.di.repository.RepositoryDirectoryInterface;
import org.pentaho.di.repository.StringObjectId;
import org.pentaho.di.repository.filerep.KettleFileRepository;
import org.pentaho.di.repository.filerep.KettleFileRepositoryMeta;
import org.pentaho.di.repository.kdr.KettleDatabaseRepository;
import org.pentaho.di.repository.kdr.KettleDatabaseRepositoryMeta;
import org.pentaho.di.trans.TransMeta;
import org.pentaho.di.trans.TransPreviewFactory;
import org.pentaho.di.trans.step.BaseStepMeta;
import org.pentaho.di.trans.step.StepMeta;
import org.pentaho.di.trans.step.StepMetaInterface;
import org.pentaho.di.trans.steps.jobexecutor.JobExecutorMeta;
import org.pentaho.di.trans.steps.transexecutor.TransExecutorMeta; /**
* ClassName: KettleUtils <br/>
* Function: kettle定制化开发工具集. <br/>
* date: 2015年4月29日 上午8:56:24 <br/>
* @author jingma
* @version 0.0.1
* @since JDK 1.6
*/
public class KettleUtils {
/**
* LOG:日志
*/
public static Logger log = Logger.getLogger(KettleUtils.class);
/**
* repository:kettle资源库
*/
private static AbstractRepository repository;
/**
* 转换模板
*/
private static TransMeta transMetaTemplate;
/**
* 作业模板
*/
private static JobMeta jobMetaTemplate; /**
* getInstance:获取的单例资源库. <br/>
* @author jingma
* @return 已经初始化的资源库
* @throws KettleException 若没有初始化则抛出异常
* @since JDK 1.6
*/
public static AbstractRepository getInstanceRep() throws KettleException{
if(repository!=null){
return repository;
// }else if(1==1){
// //TODO jingma:这里以后添加读取配置初始化连接资源库
}else{
throw new KettleException("没有初始化资源库");
}
} /**
* createFileRep:创建文件资源库. <br/>
* @author jingma
* @param id 资源库id
* @param name 资源库名称
* @param description 资源库描述
* @param baseDirectory 资源库目录
* @return 已经初始化的资源库
* @throws KettleException
* @since JDK 1.6
*/
public static AbstractRepository createFileRep(String id, String name, String description, String baseDirectory) throws KettleException{
destroy();
//初始化kettle环境
if(!KettleEnvironment.isInitialized()){
KettleEnvironment.init();
}
repository = new KettleFileRepository();
KettleFileRepositoryMeta fileRepMeta = new KettleFileRepositoryMeta( id, name, description, baseDirectory);
repository.init(fileRepMeta);
log.info(repository.getName()+"资源库初始化成功");
return repository;
} /**
* createDBRep:创建数据库资源库. <br/>
* @author jingma
* @param name 数据库连接名称
* @param type 数据库类型
* @param access 访问类型
* @param host ip地址
* @param db 数据库名称
* @param port 端口
* @param user 数据库用户名
* @param pass 数据库密码
* @return 初始化的资源库
* @throws KettleException
* @since JDK 1.6
*/
public static AbstractRepository createDBRep(String name, String type, String access, String host,
String db, String port, String user, String pass) throws KettleException{
return createDBRep( name, type, access, host,
db, port, user, pass, "DBRep", "DBRep", "数据库资源库");
} /**
* createDBRep:创建数据库资源库. <br/>
* @author jingma
* @param name 数据库连接名称
* @param type 数据库类型
* @param access 访问类型
* @param host ip地址
* @param db 数据库名称
* @param port 端口
* @param user 数据库用户名
* @param pass 数据库密码
* @param id 资源库id
* @param repName 资源库名称
* @param description 资源库描述
* @return 已经初始化的资源库
* @throws KettleException
* @since JDK 1.6
*/
public static AbstractRepository createDBRep(String name, String type, String access, String host,
String db, String port, String user, String pass,String id, String repName, String description) throws KettleException{
destroy();
//初始化kettle环境
if(!KettleEnvironment.isInitialized()){
KettleEnvironment.init();
}
//创建资源库对象
repository = new KettleDatabaseRepository();
//创建资源库数据库对象,类似我们在spoon里面创建资源库
DatabaseMeta dataMeta = new DatabaseMeta(name, type, access, host, db, port, user, pass);
//资源库元对象
KettleDatabaseRepositoryMeta kettleDatabaseMeta =
new KettleDatabaseRepositoryMeta(id, repName, description, dataMeta);
//给资源库赋值
repository.init(kettleDatabaseMeta);
log.info(repository.getName()+"资源库初始化成功");
return repository;
} /**
* connect:连接资源库. <br/>
* @author jingma
* @return 连接后的资源库
* @throws KettleSecurityException
* @throws KettleException
* @since JDK 1.6
*/
public static AbstractRepository connect() throws KettleSecurityException, KettleException{
return connect(null,null);
} /**
* connect:连接资源库. <br/>
* @author jingma
* @param username 资源库用户名
* @param password 资源库密码
* @return 连接后的资源库
* @throws KettleSecurityException
* @throws KettleException
* @since JDK 1.6
*/
public static AbstractRepository connect(String username,String password) throws KettleSecurityException, KettleException{
repository.connect(username, password);
log.info(repository.getName()+"资源库连接成功");
return repository;
} /**
* setRepository:设置资源库. <br/>
* @author jingma
* @param repository 外部注入资源库
* @since JDK 1.6
*/
public static void setRepository(AbstractRepository repository){
KettleUtils.repository = repository;
} /**
* destroy:释放资源库. <br/>
* @author jingma
* @since JDK 1.6
*/
public static void destroy(){
if(repository!=null){
repository.disconnect();
log.info(repository.getName()+"资源库释放成功");
}
} /**
* loadJob:通过id加载job. <br/>
* @author jingma
* @param jobId 数字型job的id,数据库资源库时用此方法
* @return job元数据
* @throws KettleException
* @since JDK 1.6
*/
public static JobMeta loadJob(long jobId) throws KettleException {
return repository.loadJob(new LongObjectId(jobId), null);
} /**
* loadJob:通过id加载job. <br/>
* @author jingma
* @param jobId 字符串job的id,文件资源库时用此方法
* @return job元数据
* @throws KettleException
* @since JDK 1.6
*/
public static JobMeta loadJob(String jobId) throws KettleException {
return repository.loadJob(new StringObjectId(jobId), null);
} /**
* loadTrans:加载作业. <br/>
* @author jingma
* @param jobname 作业名称
* @param directory 作业路径
* @return 作业元数据
* @since JDK 1.6
*/
public static JobMeta loadJob(String jobname, String directory) {
return loadJob(jobname, directory, repository);
}
/**
* loadTrans:加载作业. <br/>
* @author jingma
* @param jobname 作业名称
* @param directory 作业路径
* @param repository 资源库
* @return 作业元数据
* @since JDK 1.6
*/
public static JobMeta loadJob(String jobname, String directory,AbstractRepository repository) {
try {
RepositoryDirectoryInterface dir = repository.findDirectory(directory);
return repository.loadJob(jobname,dir,null, null);
} catch (KettleException e) {
log.error("获取作业失败,jobname:"+jobname+",directory:"+directory, e);
}
return null;
} /**
* loadTrans:加载转换. <br/>
* @author jingma
* @param transname 转换名称
* @param directory 转换路径
* @return 转换元数据
* @since JDK 1.6
*/
public static TransMeta loadTrans(String transname, String directory) {
return loadTrans(transname, directory, repository);
} /**
* loadTrans:加载转换. <br/>
* @author jingma
* @param transname 转换名称
* @param directory 转换路径
* @param repository 资源库
* @return 转换元数据
* @since JDK 1.6
*/
public static TransMeta loadTrans(String transname, String directory,AbstractRepository repository) {
try {
RepositoryDirectoryInterface dir = repository.findDirectory(directory);
return repository.loadTransformation( transname, dir, null, true, null);
} catch (KettleException e) {
log.error("获取转换失败,transname:"+transname+",directory:"+directory, e);
}
return null;
} /**
* loadTrans:根据job元数据获取指定转换元数据. <br/>
* @author jingma
* @param jobMeta job元数据
* @param teansName 转换名称
* @return 转换元数据
* @since JDK 1.6
*/
public static TransMeta loadTrans(JobMeta jobMeta, String teansName) {
JobEntryTrans trans = (JobEntryTrans)(jobMeta.findJobEntry(teansName).getEntry());
TransMeta transMeta = KettleUtils.loadTrans(trans.getTransname(), trans.getDirectory());
return transMeta;
} /**
* 根据转换元数据和步骤名称获取具体的步骤元数据的复制. <br/>
* 一般是不需要这用这个方法的,该方法获取的实体不属于该转换,相当于一个复制 ,修改了直接保存transMeta是没有保存到修改的。<br/>
* 若需要修改转换,可以使用:(T)transMeta.findStep(stepName).getStepMetaInterface(),
* 这个方法获取的步骤是属于该转换的,修改后,直接保存transMeta就能实现转换修改<br/>
* @author jingma
* @param transMeta 转换元数据
* @param stepName 步骤名称
* @param stepMeta 具体的步骤元数据对象
* @return 从资源库获取具体数据的步骤元数据
* @since JDK 1.6
*/
public static <T extends BaseStepMeta> T loadStep(TransMeta transMeta, String stepName,
T stepMeta) {
StepMeta step = transMeta.findStep(stepName);
try {
stepMeta.readRep(KettleUtils.getInstanceRep(), null, step.getObjectId(), KettleUtils.getInstanceRep().readDatabases());
} catch (KettleException e) {
log.error("获取步骤失败", e);
}
return stepMeta;
}
/**
* 根据作业元数据和作业实体名称获取具体的作业实体元数据的复制。<br/>
* 一般是不需要这用这个方法的,该方法获取的实体不属于该job了,相当于一个复制 ,修改了直接保存jobMeta是没有保存到修改的。<br/>
* 若需要修改job,可以使用:(T)jobMeta.findJobEntry(jobEntryName).getEntry(),
* 这个方法获取的实体是属于job,修改后,直接保存jobMeta就能实现job修改<br/>
* @author jingma
* @param jobMeta 作业元数据
* @param jobEntryName 作业实体名称
* @param jobEntryMeta 要获取的作业实体对象
* @return 加载了数据的作业实体对象
*/
public static <T extends JobEntryBase> T loadJobEntry(JobMeta jobMeta, String jobEntryName,
T jobEntryMeta) {
try {
jobEntryMeta.loadRep(KettleUtils.getInstanceRep(), null,
jobMeta.findJobEntry(jobEntryName).getEntry().getObjectId(),
KettleUtils.getInstanceRep().readDatabases(),null);
} catch (KettleException e) {
log.error("获取作业控件失败", e);
}
return jobEntryMeta;
} /**
* saveTrans:保存转换. <br/>
* @author jingma
* @param transMeta 转换元数据
* @throws KettleException
* @since JDK 1.6
*/
public static void saveTrans(TransMeta transMeta) throws KettleException {
// repository.save(transMeta, null, new RepositoryImporter(repository), true );
repository.save(transMeta, null, null, true );
} /**
* saveJob:保存job. <br/>
* @author jingma
* @param jobMeta job元数据
* @throws KettleException
* @since JDK 1.6
*/
public static void saveJob(JobMeta jobMeta) throws KettleException {
// repository.save(jobMeta, null, new RepositoryImporter(repository), true );
repository.save(jobMeta, null, null, true );
} /**
* isDirectoryExist:判断指定的job目录是否存在. <br/>
* @author jingma
* @param directoryName
* @return
* @since JDK 1.6
*/
public static boolean isDirectoryExist(String directoryName) {
try {
RepositoryDirectoryInterface dir = repository.findDirectory(directoryName);
if(dir==null){
return false;
}else{
return true;
}
} catch (KettleException e) {
log.error("判断job目录是否存在失败!",e);
}
return false;
} /**
* 将步骤smi设置到转换trans中<br/>
* @author jingma
* @param teans 转换元数据
* @param stepName 步骤名称
* @param smi 步骤
*/
public static void setStepToTrans(TransMeta teans, String stepName, StepMetaInterface smi) {
try {
StepMeta step = teans.findStep(stepName);
step.setStepMetaInterface(smi);
} catch (Exception e) {
log.error("将步骤smi设置到转换trans中-失败",e);
}
} /**
* 将步骤smi设置到转换trans中并保存到资源库 <br/>
* @author jingma
* @param teans 转换元数据
* @param stepName 步骤名称
* @param smi 步骤
*/
public static void setStepToTransAndSave(TransMeta teans, String stepName, StepMetaInterface smi) {
setStepToTrans( teans, stepName, smi);
try {
KettleUtils.saveTrans(teans);
} catch (KettleException e) {
log.error("将步骤smi设置到转换trans中并保存到资源库-失败",e);
}
} /**
* 步骤数据预览 <br/>
* @author jingma
* @param teans 转换
* @param testStep 步骤名称
* @param smi 步骤实体
* @param previewSize 预览的条数
* @return 预览结果
*/
public static List<List<Object>> stepPreview(TransMeta teans,
String testStep, StepMetaInterface smi, int previewSize) {
TransMeta previewMeta = TransPreviewFactory.generatePreviewTransformation(
teans,
smi,
testStep);
TransPreviewUtil tpu = new TransPreviewUtil(
previewMeta,
new String[] { testStep },
new int[] { previewSize } );
tpu.doPreview();
return TransPreviewUtil.getData(tpu.getPreviewRowsMeta(testStep),tpu.getPreviewRows(testStep));
} /**
* 将指定job复制到KettleUtils中的资源库 <br/>
* @author jingma
* @param jobName job名称
* @param jobPath job路径
* @param repository 来源资源库
* @throws KettleException
*/
public static void jobCopy(String jobName,String jobPath,AbstractRepository repository) throws KettleException {
JobMeta jobMeta = KettleUtils.loadJob(jobName,jobPath,repository);
for(JobEntryCopy jec:jobMeta.getJobCopies()){
if(jec.isTransformation()){
JobEntryTrans jet = (JobEntryTrans)jec.getEntry();
transCopy(jet.getObjectName(), jet.getDirectory(),repository);
}else if(jec.isJob()){
JobEntryJob jej = (JobEntryJob)jec.getEntry();
jobCopy(jej.getObjectName(),jej.getDirectory(),repository);
}
}
jobMeta.setRepository(KettleUtils.getInstanceRep());
jobMeta.setMetaStore(KettleUtils.getInstanceRep().getMetaStore());
if(!isDirectoryExist(jobPath)){
//所在目录不存在则创建
KettleUtils.repository.createRepositoryDirectory(KettleUtils.repository.findDirectory("/"), jobPath);
}
KettleUtils.saveJob(jobMeta);
} /**
* 将指定转换复制到KettleUtils中的资源库 <br/>
* @author jingma
* @param jobName 转换名称
* @param jobPath 转换路径
* @param repository 来源资源库
* @throws KettleException
*/
public static void transCopy(String transName,String transPath,AbstractRepository repository) throws KettleException {
TransMeta tm = KettleUtils.loadTrans(transName, transPath, repository);
for(StepMeta sm:tm.getSteps()){
if(sm.isJobExecutor()){
JobExecutorMeta jem = (JobExecutorMeta)sm.getStepMetaInterface();
jobCopy(jem.getJobName(),jem.getDirectoryPath(),repository);
}
else if(sm.getStepMetaInterface() instanceof TransExecutorMeta){
TransExecutorMeta te = (TransExecutorMeta)sm.getStepMetaInterface();
transCopy(te.getTransName(), te.getDirectoryPath(),repository);
}
}
if(!isDirectoryExist(transPath)){
//所在目录不存在则创建
KettleUtils.repository.createRepositoryDirectory(KettleUtils.repository.findDirectory("/"), transPath);
}
tm.setRepository(KettleUtils.getInstanceRep());
tm.setMetaStore(KettleUtils.getInstanceRep().getMetaStore());
KettleUtils.saveTrans(tm);
} /**
* @return transMetaTemplate
*/
public static TransMeta getTransMetaTemplate() {
// if(transMetaTemplate==null){
// setTransMetaTemplate(KettleUtils.loadTrans(SysCode.TRANS_TEMPLATE_NAME, SysCode.TEMPLATE_DIR));
// }
return transMetaTemplate;
} /**
* @param transMetaTemplate the transMetaTemplate to set
*/
public static void setTransMetaTemplate(TransMeta transMetaTemplate) {
KettleUtils.transMetaTemplate = transMetaTemplate;
} /**
* @return jobMetaTemplate
*/
public static JobMeta getJobMetaTemplate() {
// if(jobMetaTemplate==null){
// setJobMetaTemplate(KettleUtils.loadJob(SysCode.JOB_TEMPLATE_NAME, SysCode.TEMPLATE_DIR));
// }
return jobMetaTemplate;
} /**
* @param jobMetaTemplate the jobMetaTemplate to set
*/
public static void setJobMetaTemplate(JobMeta jobMetaTemplate) {
KettleUtils.jobMetaTemplate = jobMetaTemplate;
} }

上面就是我定制化开发中编写的工具类,基本是一个独立可用的类,里面的模版jobMetaTemplate、transMetaTemplate可用删除,也可以根据需要使用。其中的步骤预览功能需要依赖另外一个类,这个类是我从kettleUI层提取出来并做了修改的,这里贴出代码吧:

/*! ******************************************************************************
*
* Pentaho Data Integration
*
* Copyright (C) 2002-2013 by Pentaho : http://www.pentaho.com
*
*******************************************************************************
*
* 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 com.iflytek.kettle.utils; import java.util.ArrayList;
import java.util.List; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.di.core.Const;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.core.exception.KettleValueException;
import org.pentaho.di.core.logging.KettleLogStore;
import org.pentaho.di.core.row.RowMetaInterface;
import org.pentaho.di.core.row.ValueMetaInterface;
import org.pentaho.di.trans.Trans;
import org.pentaho.di.trans.TransMeta;
import org.pentaho.di.trans.debug.BreakPointListener;
import org.pentaho.di.trans.debug.StepDebugMeta;
import org.pentaho.di.trans.debug.TransDebugMeta;
import org.pentaho.di.trans.step.StepMeta; /**
* Takes care of displaying a dialog that will handle the wait while previewing a transformation...
*
* @author Matt
* @since 13-jan-2006
*/
public class TransPreviewUtil {
public static final int MAX_BINARY_STRING_PREVIEW_SIZE = 1000000;
private static Log log = LogFactory.getLog(TransPreviewUtil.class);
private TransMeta transMeta;
private String[] previewStepNames;
private int[] previewSize;
private Trans trans; private boolean cancelled;
private String loggingText;
private TransDebugMeta transDebugMeta; /**
* Creates a new dialog that will handle the wait while previewing a transformation...
*/
public TransPreviewUtil( TransMeta transMeta, String[] previewStepNames, int[] previewSize ) {
this.transMeta = transMeta;
this.previewStepNames = previewStepNames;
this.previewSize = previewSize; cancelled = false;
} public void doPreview() {
// This transformation is ready to run in preview!
trans = new Trans( transMeta ); // Prepare the execution...
//
try {
trans.prepareExecution( null );
} catch ( final KettleException e ) {
log.error("", e);
return;
} // Add the preview / debugging information...
//
transDebugMeta = new TransDebugMeta( transMeta );
for ( int i = 0; i < previewStepNames.length; i++ ) {
StepMeta stepMeta = transMeta.findStep( previewStepNames[i] );
StepDebugMeta stepDebugMeta = new StepDebugMeta( stepMeta );
stepDebugMeta.setReadingFirstRows( true );
stepDebugMeta.setRowCount( previewSize[i] );
transDebugMeta.getStepDebugMetaMap().put( stepMeta, stepDebugMeta );
} // set the appropriate listeners on the transformation...
//
transDebugMeta.addRowListenersToTransformation( trans ); // Fire off the step threads... start running!
//
try {
trans.startThreads();
} catch ( final KettleException e ) {
log.error("", e);
// It makes no sense to continue, so just stop running...
//
return;
} final List<String> previewComplete = new ArrayList<String>(); while ( previewComplete.size() < previewStepNames.length
&& !trans.isFinished() ) {
// We add a break-point that is called every time we have a step with a full preview row buffer
// That makes it easy and fast to see if we have all the rows we need
//
transDebugMeta.addBreakPointListers( new BreakPointListener() {
public void breakPointHit( TransDebugMeta transDebugMeta, StepDebugMeta stepDebugMeta,
RowMetaInterface rowBufferMeta, List<Object[]> rowBuffer ) {
String stepName = stepDebugMeta.getStepMeta().getName();
previewComplete.add( stepName );
}
} ); // Change the percentage...
try {
Thread.sleep( 500 );
} catch ( InterruptedException e ) {
log.error("", e);
// Ignore errors
} } trans.stopAll(); // Capture preview activity to a String:
loggingText =
KettleLogStore.getAppender().getBuffer( trans.getLogChannel().getLogChannelId(), true ).toString(); } /**
* @param stepname
* the name of the step to get the preview rows for
* @return A list of rows as the result of the preview run.
*/
public List<Object[]> getPreviewRows( String stepname ) {
if ( transDebugMeta == null ) {
return null;
} for ( StepMeta stepMeta : transDebugMeta.getStepDebugMetaMap().keySet() ) {
if ( stepMeta.getName().equals( stepname ) ) {
StepDebugMeta stepDebugMeta = transDebugMeta.getStepDebugMetaMap().get( stepMeta );
return stepDebugMeta.getRowBuffer();
}
}
return null;
} /**
* @param stepname
* the name of the step to get the preview rows for
* @return A description of the row (metadata)
*/
public RowMetaInterface getPreviewRowsMeta( String stepname ) {
if ( transDebugMeta == null ) {
return null;
} for ( StepMeta stepMeta : transDebugMeta.getStepDebugMetaMap().keySet() ) {
if ( stepMeta.getName().equals( stepname ) ) {
StepDebugMeta stepDebugMeta = transDebugMeta.getStepDebugMetaMap().get( stepMeta );
return stepDebugMeta.getRowBufferMeta();
}
}
return null;
} /**
* @return true is the preview was canceled by the user
*/
public boolean isCancelled() {
return cancelled;
} /**
* @return The logging text from the latest preview run
*/
public String getLoggingText() {
return loggingText;
} /**
*
* @return The transformation object that executed the preview TransMeta
*/
public Trans getTrans() {
return trans;
} /**
* @return the transDebugMeta
*/
public TransDebugMeta getTransDebugMeta() {
return transDebugMeta;
} /**
* Copy information from the meta-data input to the dialog fields.
* @param rowMetaInterface
*/
public static List<List<Object>> getData(RowMetaInterface rowMeta, List<Object[]> buffer) {
List<List<Object>> result = new ArrayList<List<Object>>();
List<Object> row1 = new ArrayList<Object>();
for ( int i = 0; i < buffer.size(); i++ ) {
row1 = new ArrayList<Object>();
Object[] row = buffer.get( i );
getDataForRow( rowMeta, row1, row );
result.add(row1);
}
return result;
} public static int getDataForRow( RowMetaInterface rowMeta, List<Object> row1, Object[] row ) {
int nrErrors = 0; // Display the correct line item...
//
for ( int c = 0; c < rowMeta.size(); c++ ) {
ValueMetaInterface v = rowMeta.getValueMeta( c );
String show;
try {
show = v.getString( row[c] );
if ( v.isBinary() && show != null && show.length() > MAX_BINARY_STRING_PREVIEW_SIZE ) {
// We want to limit the size of the strings during preview to keep all SWT widgets happy.
//
show = show.substring( 0, MAX_BINARY_STRING_PREVIEW_SIZE );
}
} catch ( KettleValueException e ) {
nrErrors++;
if ( nrErrors < 25 ) {
log.error( Const.getStackTracker( e ) );
}
show = null;
} catch ( ArrayIndexOutOfBoundsException e ) {
nrErrors++;
if ( nrErrors < 25 ) {
log.error( Const.getStackTracker( e ) );
}
show = null;
} if ( show != null ) {
row1.add(show);
} else {
// Set null value
row1.add("<null>");
}
} return nrErrors; }
}

以上两个类复制到自己项目中就可以用了,这个工具类是根据我自己需求编写的,根据使用场景不同,你也可以添加其他方法,丰富该类的功能。

关于使用示例,本来也想贴出来的,但相关代码依赖较多,同时工具类本身注释很详细,方法体很小,自己看一遍就能了解个大概,所以这里就不提供使用示例代码,希望对有需要的人有所帮助。

上一篇:<<< 将一个rar格式的文件变成一张jpg图片,按照后缀来选择打开他的模式


下一篇:针对移动端开发的响应式 Jekyll 主题