在网上了解了kettle开发插件,查看模板,里面主要有四个java文件:界面显示java文件*dialog.java,*dialog.java主要使用的是swt的控件来使用和显示界面。元数据(属性)封装java文件*StepMeta.java,*StepMeta.java封装了要从dialog中接收、要使用的数据,当转换运行时,Kettle会重新生成一个Meta 对象并获取原对象的配置参数,在*StepMeta.java里面主要有两个方法,getXML()和loadXML(),这也是为什么界面关闭后数据也会保存下来的原因之一,还有一个方法getFields(),它用于设定输出的字段名,它与*Step.java中传入的数据个数要相同。*Step.java,它相当于main()方法,基本数据的处理逻辑都要在这里写。还有一个java文件,暂时没感觉有啥用。
下面是结合之前写的复制数据库代码而做的一个插件。
TemplateStepDialog源码:
package plugin.template;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.pentaho.di.core.Const;
import org.pentaho.di.i18n.BaseMessages;
import org.pentaho.di.trans.TransMeta;
import org.pentaho.di.ui.trans.step.BaseStepDialog;
import org.pentaho.di.trans.step.BaseStepMeta;
import org.pentaho.di.trans.step.StepDialogInterface;
/**
* @Title: 对话框类
* @Package plugin.template
* @Description: TODO(用一句话描述该文件做什么)
* @author http://www.ahuoo.com
* @date 2010-8-8 下午05:10:26
* @version V1.0
*/
public class TemplateStepDialog extends BaseStepDialog implements StepDialogInterface {
private static Class<?> PKG = TemplateStepMeta.class; // for i18n purposes
private TemplateStepMeta input;
public TemplateStepMeta getInput() {
return input;
}
public void setInput(TemplateStepMeta input) {
this.input = input;
}
// output field name
private Label wlValName;
private FormData fdlValName, fdValName;
private Label fromUrl,fromUserName,fromPassword,fromDatabase;
private Label toUrl,toUserName,toPassword,toDatabase;
private FormData fromUrlfd,fromUserNamefd,fromPasswordfd,fromDatabasefd;
private FormData toUrlfd,toUserNamefd,toPasswordfd,toDatabasefd;
private Text fromUrlTx,fromUserNameTx,fromPasswordTx,fromDatabaseTx;
private FormData fromUrlTxfd,fromUserNameTxfd,fromPasswordTxfd,fromDatabaseTxfd;
private Text toUrlTx,toUserNameTx,toPasswordTx,toDatabaseTx;
private FormData toUrlTxfd,toUserNameTxfd,toPasswordTxfd,toDatabaseTxfd;
/*-----------------其他标签---------------------------------------------------------------*/
private Label copyType;
private FormData copyTypefd;
private Button bt_struc, bt_table;
private Group group;
/*--------------------------------------------------------------------------------*/
/* FormData类型其实是在XMLHttpRequest 2级定义的,它是为序列化表以及创建与表单格式相同的数据(当然是用于XHR传输)提供便利。
<form id="myForm" action="" method="post">
<input type="text" name="name">名字
<input type="password" name="psw">密码
<input type="submit" value="提交">
</form>
我们可以使用这个表单元素作为初始化参数,来实例化一个formData对象
// 获取页面已有的一个form表单
var form = document.getElementById("myForm");
// 用表单来初始化
var formData = new FormData(form);
// 我们可以根据name来访问表单中的字段
var name = formData.get("name"); // 获取名字
var psw = formData.get("psw"); // 获取密码
// 当然也可以在此基础上,添加其他数据
formData.append("token","kshdfiwi3rh");*/
public TemplateStepDialog(Shell parent, Object in, TransMeta transMeta, String sname) {
super(parent, (BaseStepMeta) in, transMeta, sname);
input = (TemplateStepMeta) in;
}
public String open() {
Shell parent = getParent();
Display display = parent.getDisplay();
shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.RESIZE | SWT.MIN | SWT.MAX);
props.setLook(shell);
setShellImage(shell, input);//设置框体左上角的图片
/* ----------------设置窗体-----------------------------*/
ModifyListener lsMod = new ModifyListener() {
public void modifyText(ModifyEvent e) {
input.setChanged();
}
};
/* 定义一个监听器lsMod,监听文本输入的校验*/
changed = input.hasChanged();
FormLayout formLayout = new FormLayout();
/*定义相对布局*/
formLayout.marginWidth = Const.FORM_MARGIN;
formLayout.marginHeight = Const.FORM_MARGIN;
/*设置宽高*/
shell.setLayout(formLayout);
/*为窗体设置布局格式*/
shell.setText(BaseMessages.getString(PKG, "Template.Shell.Title"));
/*标题的设置*/
//------------------------------------------------------------------------//
int middle = props.getMiddlePct();
int margin = Const.MARGIN;
// Stepname line
wlStepname = new Label(shell, SWT.RIGHT);
/*定义一个标签*/
wlStepname.setText(BaseMessages.getString(PKG, "System.Label.StepName"));
/*设置左边的标签名称*/
props.setLook(wlStepname);
/*添加进去*/
fdlStepname = new FormData();
fdlStepname.left = new FormAttachment(0, 0);
fdlStepname.right = new FormAttachment(middle, -margin);
fdlStepname.top = new FormAttachment(0, margin);
wlStepname.setLayoutData(fdlStepname);
/*设置wlStepname的子组件*/
wStepname = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
wStepname.setText(stepname);
/*定义一个text文本框*/
props.setLook(wStepname);
wStepname.addModifyListener(lsMod);
/*添加监听器*/
fdStepname = new FormData();
fdStepname.left = new FormAttachment(middle, 0);
fdStepname.top = new FormAttachment(0, margin);
fdStepname.right = new FormAttachment(100, 0);
/*定义文本框的内容格式*/
wStepname.setLayoutData(fdStepname);
/* --------------------标签:文本框---------------*/
// output dummy value
/* --------------------标签:文本框---------------*/
fromUrl = new Label(shell,SWT.RIGHT);
fromUrl.setText(BaseMessages.getString(PKG, "fromUrl"));
props.setLook(fromUrl);
fromUrlfd = new FormData();
fromUrlfd.left = new FormAttachment(0,0);
fromUrlfd.top = new FormAttachment(wStepname,margin);
fromUrlfd.right = new FormAttachment(middle, -margin);
fromUrl.setLayoutData(fromUrlfd);
fromUrlTx = new Text(shell,SWT.SINGLE | SWT.LEFT | SWT.BORDER);
props.setLook(fromUrlTx);
fromUrlTx.addModifyListener(lsMod);
fromUrlTxfd = new FormData();
fromUrlTxfd.left = new FormAttachment(middle,0);
fromUrlTxfd.right = new FormAttachment(100,0);
fromUrlTxfd.top = new FormAttachment(wStepname,margin);
fromUrlTx.setLayoutData(fromUrlTxfd);
/*------------------------数据库地址结束------------------------------------- */
/*------------------------用户名开始------------------------------------- */
fromUserName = new Label(shell,SWT.RIGHT);
fromUserName.setText(BaseMessages.getString(PKG, "fromUserName"));
props.setLook(fromUserName);
fromUserNamefd = new FormData();
fromUserNamefd.left = new FormAttachment(0,0);
fromUserNamefd.top = new FormAttachment(fromUrlTx,margin);
fromUserNamefd.right = new FormAttachment(middle, -margin);
fromUserName.setLayoutData(fromUserNamefd);
fromUserNameTx = new Text(shell,SWT.SINGLE | SWT.LEFT | SWT.BORDER);
props.setLook(fromUserNameTx);
fromUserNameTx.addModifyListener(lsMod);
fromUserNameTxfd = new FormData();
fromUserNameTxfd.left = new FormAttachment(middle,0);
fromUserNameTxfd.right = new FormAttachment(100,0);
fromUserNameTxfd.top = new FormAttachment(fromUrlTx,margin);
fromUserNameTx.setLayoutData(fromUserNameTxfd);
/*------------------------用户名结束------------------------------------- */
/*-----------------------密码开始------------------------------------- */
fromPassword = new Label(shell,SWT.RIGHT);
fromPassword.setText(BaseMessages.getString(PKG, "fromPassword"));
props.setLook(fromPassword);
fromPasswordfd = new FormData();
fromPasswordfd.left = new FormAttachment(0,0);
fromPasswordfd.top = new FormAttachment(fromUserNameTx,margin);
fromPasswordfd.right = new FormAttachment(middle, -margin);
fromPassword.setLayoutData(fromPasswordfd);
fromPasswordTx = new Text(shell,SWT.PASSWORD | SWT.SINGLE | SWT.LEFT | SWT.BORDER);
props.setLook(fromPasswordTx);
fromPasswordTx.addModifyListener(lsMod);
fromPasswordTxfd = new FormData();
fromPasswordTxfd.left = new FormAttachment(middle,0);
fromPasswordTxfd.right = new FormAttachment(100,0);
fromPasswordTxfd.top = new FormAttachment(fromUserNameTx,margin);
fromPasswordTx.setLayoutData(fromPasswordTxfd);
/*------------------------密码结束------------------------------------- */
/*-----------------------数据库开始------------------------------------- */
fromDatabase= new Label(shell,SWT.RIGHT);
fromDatabase.setText(BaseMessages.getString(PKG, "fromDatabase"));
props.setLook(fromDatabase);
fromDatabasefd = new FormData();
fromDatabasefd.left = new FormAttachment(0,0);
fromDatabasefd.top = new FormAttachment(fromPasswordTx,margin);
fromDatabasefd.right = new FormAttachment(middle, -margin);
fromDatabase.setLayoutData(fromDatabasefd);
fromDatabaseTx = new Text(shell,SWT.SINGLE | SWT.LEFT | SWT.BORDER);
props.setLook(fromDatabaseTx);
fromDatabaseTx.addModifyListener(lsMod);
fromDatabaseTxfd = new FormData();
fromDatabaseTxfd.left = new FormAttachment(middle,0);
fromDatabaseTxfd.right = new FormAttachment(100,0);
fromDatabaseTxfd.top = new FormAttachment(fromPasswordTx,margin);
fromDatabaseTx.setLayoutData(fromDatabaseTxfd);
/*------------------------数据库结束------------------------------------- */
/*------------------------------目标数据库部分-------------------------------*/
toUrl = new Label(shell,SWT.RIGHT);
toUrl.setText(BaseMessages.getString(PKG, "toUrl"));
props.setLook(toUrl);
toUrlfd = new FormData();
toUrlfd.left = new FormAttachment(0,0);
toUrlfd.top = new FormAttachment(fromDatabaseTx,margin);
toUrlfd.right = new FormAttachment(middle, -margin);
toUrl.setLayoutData(toUrlfd);
toUrlTx = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
props.setLook(toUrlTx);
toUrlTx.addModifyListener(lsMod);
toUrlTxfd = new FormData();
toUrlTxfd.left = new FormAttachment(middle,0);
toUrlTxfd.right = new FormAttachment(100,0);
toUrlTxfd.top = new FormAttachment(fromDatabaseTx,margin);
toUrlTx.setLayoutData(toUrlTxfd);
//--------------------
toUserName = new Label(shell,SWT.RIGHT);
toUserName.setText(BaseMessages.getString(PKG, "toUserName"));
props.setLook(toUserName);
toUserNamefd = new FormData();
toUserNamefd.left = new FormAttachment(0,0);
toUserNamefd.top = new FormAttachment(toUrlTx,margin);
toUserNamefd.right = new FormAttachment(middle, -margin);
toUserName.setLayoutData(toUserNamefd);
toUserNameTx = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
props.setLook(toUserNameTx);
toUserNameTx.addModifyListener(lsMod);
toUserNameTxfd = new FormData();
toUserNameTxfd.left = new FormAttachment(middle,0);
toUserNameTxfd.right = new FormAttachment(100,0);
toUserNameTxfd.top = new FormAttachment(toUrlTx,margin);
toUserNameTx.setLayoutData(toUserNameTxfd);
//-----------------
toPassword = new Label(shell,SWT.RIGHT);
toPassword.setText(BaseMessages.getString(PKG, "toPassword"));
props.setLook(toPassword);
toPasswordfd = new FormData();
toPasswordfd.left = new FormAttachment(0,0);
toPasswordfd.top = new FormAttachment(toUserNameTx,margin);
toPasswordfd.right = new FormAttachment(middle, -margin);
toPassword.setLayoutData(toPasswordfd);
toPasswordTx = new Text(shell, SWT.PASSWORD | SWT.SINGLE | SWT.LEFT | SWT.BORDER);
props.setLook(toPasswordTx);
toPasswordTx.addModifyListener(lsMod);
toPasswordTxfd = new FormData();
toPasswordTxfd.left = new FormAttachment(middle,0);
toPasswordTxfd.right = new FormAttachment(100,0);
toPasswordTxfd.top = new FormAttachment(toUserNameTx,margin);
toPasswordTx.setLayoutData(toPasswordTxfd);
//-----------------
toDatabase = new Label(shell,SWT.RIGHT);
toDatabase.setText(BaseMessages.getString(PKG, "toDatabase"));
props.setLook(toDatabase);
toDatabasefd = new FormData();
toDatabasefd.left = new FormAttachment(0,0);
toDatabasefd.top = new FormAttachment(toPasswordTx,margin);
toDatabasefd.right = new FormAttachment(middle, -margin);
toDatabase.setLayoutData(toDatabasefd);
toDatabaseTx = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
props.setLook(toDatabaseTx);
toDatabaseTx.addModifyListener(lsMod);
toDatabaseTxfd = new FormData();
toDatabaseTxfd.left = new FormAttachment(middle,0);
toDatabaseTxfd.right = new FormAttachment(100,0);
toDatabaseTxfd.top = new FormAttachment(toPasswordTx,margin);
toDatabaseTx.setLayoutData(toDatabaseTxfd);
//----------------------
/*------------------------------目标数据库部分结束-------------------------------*/
group=new Group(shell,SWT.None);
group.setText("复制选择");
//copyType = new Label(shell,SWT.RIGHT);
//copyType.setText("复制------------------------------------------------------------");
props.setLook(group);
copyTypefd = new FormData();
copyTypefd.left = new FormAttachment(20,margin);
copyTypefd.top = new FormAttachment(toDatabaseTx,margin);
copyTypefd.right = new FormAttachment(100, 0);
group.setLayoutData(copyTypefd);
/* ---------------------*/
GridLayout gridLayout = new GridLayout();
gridLayout.numColumns = 2;
gridLayout.marginLeft = 30;
gridLayout.makeColumnsEqualWidth = true;
GridData g1 = new GridData(SWT.FILL, SWT.CENTER, false, false);
group.setLayout(gridLayout);
bt_struc = new Button(group, SWT.RADIO | SWT.LEFT);
bt_struc.setText("表结构");
bt_struc.setLayoutData(g1);
bt_table = new Button(group, SWT.RADIO | SWT.LEFT_TO_RIGHT);
bt_table.setText("表结构及数据");
GridData g2 = new GridData(SWT.FILL, SWT.CENTER, false, false);
bt_table.setLayoutData(g2);
if(input.getSelect_result().equals("true")|input.getSelect_result()==null){
bt_struc.setSelection(true);
}else{
bt_table.setSelection(true);
}
/* ---------------------*/
/*-------------------------------------------------------------------------*/
wOK = new Button(shell, SWT.PUSH);
wOK.setText(BaseMessages.getString(PKG, "System.Button.OK"));
wCancel = new Button(shell, SWT.PUSH);
wCancel.setText(BaseMessages.getString(PKG, "System.Button.Cancel"));
/* ---------------------确定 和 取消-------------------------*/
BaseStepDialog.positionBottomButtons(shell, new Button[] { wOK, wCancel }, margin, group);
SelectionListener lsSelect = new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
// TODO Auto-generated method stub
input.setSelect_result(bt_struc.getSelection()+"");
/*MessageBox mb = new MessageBox( shell, SWT.OK | SWT.ICON_ERROR );
mb.setMessage(b+"");
mb.setText( BaseMessages.getString( PKG, "System.Dialog.Error.Title" ) );
mb.open();*/
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
// TODO Auto-generated method stub
}
};
bt_struc.addSelectionListener( lsSelect);
bt_table.addSelectionListener(lsSelect);
// Add listeners
lsCancel = new Listener() {
public void handleEvent(Event e) {
cancel();
}
};
lsOK = new Listener() {
public void handleEvent(Event e) {
ok();
}
};
wCancel.addListener(SWT.Selection, lsCancel);
wOK.addListener(SWT.Selection, lsOK);
lsDef = new SelectionAdapter() {
public void widgetDefaultSelected(SelectionEvent e) {
input.setFromUrl(fromUrlTx.getText());
input.setToUrl(toUrlTx.getText());
input.setFromUserName(fromUserNameTx.getText());
input.setToUserName(toUserNameTx.getText());
input.setFromPassword(fromPasswordTx.getText());
input.setToPassword(toPasswordTx.getText());
input.setFromDatabase(fromDatabaseTx.getText());
input.setToDatabase(toDatabaseTx.getText());
/*String s = "--"+input.getFromUrl()+"--"+input.getToUrl()+"--"+input.getFromUserName()+"--"+input.getToUserName()
+"--"+input.getFromPassword()+"--"+input.getToPassword() ;
MessageBox mb = new MessageBox( shell, SWT.OK | SWT.ICON_ERROR );
mb.setMessage(s);
mb.setText( BaseMessages.getString( PKG, "System.Dialog.Error.Title" ) );
mb.open();*/
}
};
wStepname.addSelectionListener(lsDef);
toUrlTx.addSelectionListener(lsDef);
fromUrlTx.addSelectionListener(lsDef);
fromUserNameTx.addSelectionListener(lsDef);
toUserNameTx.addSelectionListener(lsDef);
fromPasswordTx.addSelectionListener(lsDef);
toPasswordTx.addSelectionListener(lsDef);
fromDatabaseTx.addSelectionListener(lsDef);
toDatabaseTx.addSelectionListener(lsDef);
//addSelectionListener单击事件
// Detect X or ALT-F4 or something that kills this window...
shell.addShellListener(new ShellAdapter() {
public void shellClosed(ShellEvent e) {
cancel();
}
});
// Set the shell size, based upon previous time...
setSize();
getData();
input.setChanged(changed);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
return stepname;
}
// Read data and place it in the dialog
public void getData() {
wStepname.selectAll();
toUrlTx.setText(input.getToUrl());
fromUrlTx.setText(input.getFromUrl());
fromUserNameTx.setText(input.getFromUserName());
toUserNameTx.setText(input.getToUserName());
fromPasswordTx.setText(input.getFromPassword());
toPasswordTx.setText(input.getToPassword());
fromDatabaseTx.setText(input.getFromDatabase());
toDatabaseTx.setText(input.getToDatabase());
}
private void cancel() {
stepname = null;
input.setChanged(changed);
dispose();
}
// let the plugin know about the entered data
private void ok() {
if ( Const.isEmpty( wStepname.getText() ) ) {
return;
}
stepname = wStepname.getText(); // return value
input.setFromUrl(fromUrlTx.getText());
input.setToUrl(toUrlTx.getText());
input.setFromUserName(fromUserNameTx.getText());
input.setToUserName(toUserNameTx.getText());
input.setFromPassword(fromPasswordTx.getText());
input.setToPassword(toPasswordTx.getText());
input.setFromDatabase(fromDatabaseTx.getText());
input.setToDatabase(toDatabaseTx.getText());
input.setSelect_result(bt_struc.getSelection()+"");
if(input.getSelect_result().equals("false")){
bt_table.setSelection(true);
}else{
bt_struc.setSelection(true);
}
/* String s ="input.getSelect_result():" + input.getSelect_result()+ group.getData(key)(); ;
MessageBox mb = new MessageBox( shell, SWT.OK | SWT.ICON_ERROR );
mb.setMessage(s);
mb.setText( BaseMessages.getString( PKG, "System.Dialog.Error.Title" ) );
mb.open();*/
dispose();
}
}
TemplateStepMeta源码:
package plugin.template;
import java.util.List;
import java.util.Map;
import org.eclipse.swt.widgets.Shell;
import org.pentaho.di.core.*;
import org.pentaho.di.core.database.DatabaseMeta;
import org.pentaho.di.core.exception.*;
import org.pentaho.di.core.row.*;
import org.pentaho.di.core.variables.VariableSpace;
import org.pentaho.di.core.xml.XMLHandler;
import org.pentaho.di.i18n.BaseMessages;
import org.pentaho.di.repository.*;
import org.pentaho.di.trans.*;
import org.pentaho.di.trans.step.*;
import org.w3c.dom.Node;
/**
* @Title: 元数据类
* @Package plugin.template
* @Description: TODO(用一句话描述该文件做什么)
* @author http://www.ahuoo.com
* @date 2010-8-8 下午05:10:26
* @version V1.0
*/
public class TemplateStepMeta extends BaseStepMeta implements StepMetaInterface {
private static Class<?> PKG = TemplateStepMeta.class; // for i18n purposes
private String fromUrl = new String() ;//127.0.0.1
private String toUrl = new String();//127.0.0.1
private String fromUserName = new String();
private String toUserName = new String();
private String fromPassword = new String();
private String toPassword = new String();
private String fromDatabase = new String();
private String toDatabase = new String();
//需要为属性初始化,不初始化会在新建步骤时出错,也不能用=“ ”或“”的方式初始化“”在text中显示null “ ” 显示空格
private String select_result = "true";
public String getSelect_result() {
return select_result;
}
public void setSelect_result(String select_result) {
this.select_result = select_result;
}
public String getFromDatabase() {
return fromDatabase;
}
public void setFromDatabase(String fromDatabase) {
this.fromDatabase = fromDatabase;
}
public String getToDatabase() {
return toDatabase;
}
public void setToDatabase(String toDatabase) {
this.toDatabase = toDatabase;
}
public String getFromUrl() {
return fromUrl;
}
public void setFromUrl(String fromUrl) {
this.fromUrl = fromUrl;
}
public String getToUrl() {
return toUrl;
}
public void setToUrl(String toUrl) {
this.toUrl = toUrl;
}
public String getFromUserName() {
return fromUserName;
}
public void setFromUserName(String fromUserName) {
this.fromUserName = fromUserName;
}
public String getToUserName() {
return toUserName;
}
public void setToUserName(String toUserName) {
this.toUserName = toUserName;
}
public String getFromPassword() {
return fromPassword;
}
public void setFromPassword(String fromPassword) {
this.fromPassword = fromPassword;
}
public String getToPassword() {
return toPassword;
}
public void setToPassword(String toPassword) {
this.toPassword = toPassword;
}
public TemplateStepMeta() {
super();
}
/*-----------------------------------------属性封装----------------------------------------------------------*/
public String getXML() throws KettleValueException {
String retval = "";
retval += " <fromUrl>" + getFromUrl() + "</fromUrl>" + Const.CR;
retval += " <toUrl>" + getToUrl() + "</toUrl>" + Const.CR;
retval += " <fromUserName>" + getFromUserName() + "</fromUserName>" + Const.CR;
retval += " <toUserName>" + getToUserName() + "</toUserName>" + Const.CR;
retval += " <fromPassword>" + getFromPassword() + "</fromPassword>" + Const.CR;
retval += " <toPassword>" + getToPassword() + "</toPassword>" + Const.CR;
retval += " <fromDatabase>" + getFromDatabase() + "</fromDatabase>" + Const.CR;
retval += " <toDatabase>" + getToDatabase() + "</toDatabase>" + Const.CR;
retval += " <select_result>" + getSelect_result() + "</select_result>" + Const.CR;
return retval;
}
public void getFields(RowMetaInterface r, String origin, RowMetaInterface[] info, StepMeta nextStep, VariableSpace space) {
// append the outputField to the output
/*ValueMetaInterface v = new ValueMeta();
v.setName(outputField);
//v.setType(ValueMeta.TYPE_STRING);
v.setTrimType(ValueMeta.TRIM_TYPE_BOTH);
v.setOrigin(origin);
r.addValueMeta(v);*/
int valtype = ValueMeta.getType("String");
/*ValueMetaInterface valueMeta = new ValueMeta( “FiledName1”, valtype);
valueMeta.setLength(-1);
r.addValueMeta(valueMeta);*/
ValueMetaInterface v_fromUrl = new ValueMeta( "结果", valtype);
//v_fromUrl.setName("源数据库地址");
v_fromUrl.setTrimType(ValueMeta.TRIM_TYPE_BOTH);
v_fromUrl.setOrigin(origin);
r.addValueMeta(v_fromUrl);
}
public Object clone() {
Object retval = super.clone();
return retval;
}
public void loadXML(Node stepnode, List<DatabaseMeta> databases, Map<String, Counter> counters) throws KettleXMLException {
/*readData( stepnode, databases );*/
try {
Node valnode = XMLHandler.getSubNode(stepnode, "fromUrl");
if(null!=valnode){
fromUrl = valnode.getTextContent();
}
valnode = XMLHandler.getSubNode(stepnode, "toUrl");
if(null!=valnode){
toUrl = valnode.getTextContent();
}
valnode = XMLHandler.getSubNode(stepnode, "fromUserName");
if(null!=valnode){
fromUserName = valnode.getTextContent();
}
valnode = XMLHandler.getSubNode(stepnode, "toUserName");
if(null!=valnode){
toUserName = valnode.getTextContent();
}
valnode = XMLHandler.getSubNode(stepnode, "fromPassword");
if(null!=valnode){
fromPassword = valnode.getTextContent();
}
valnode = XMLHandler.getSubNode(stepnode, "toPassword");
if(null!=valnode){
toPassword = valnode.getTextContent();
}
valnode = XMLHandler.getSubNode(stepnode, "fromDatabase");
if(null!=valnode){
fromDatabase = valnode.getTextContent();
}
valnode = XMLHandler.getSubNode(stepnode, "toDatabase");
if(null!=valnode){
toDatabase = valnode.getTextContent();
}
valnode = XMLHandler.getSubNode(stepnode, "select_result");
if(null!=valnode){
select_result = valnode.getTextContent();
}
} catch (Exception e) {
throw new KettleXMLException("Template Plugin Unable to read step info from XML node", e);
}
//readData( stepnode, databases );
}
public void setDefault() {
select_result = "true";
}
public void check(List<CheckResultInterface> remarks, TransMeta transmeta, StepMeta stepMeta, RowMetaInterface prev, String input[], String output[], RowMetaInterface info) {
CheckResult cr;
// See if we have input streams leading to this step!
if (input.length > 0) {
cr = new CheckResult(CheckResult.TYPE_RESULT_OK, "Step is receiving info from other steps.", stepMeta);
remarks.add(cr);
} else {
cr = new CheckResult(CheckResult.TYPE_RESULT_ERROR, "No input received from other steps!", stepMeta);
remarks.add(cr);
}
}
public StepDialogInterface getDialog(Shell shell, StepMetaInterface meta, TransMeta transMeta, String name) {
return new TemplateStepDialog(shell, meta, transMeta, name);
}
public StepInterface getStep(StepMeta stepMeta, StepDataInterface stepDataInterface, int cnr, TransMeta transMeta, Trans disp) {
return new TemplateStep(stepMeta, stepDataInterface, cnr, transMeta, disp);
}
public StepDataInterface getStepData() {
return new TemplateStepData();
}
public void readRep(Repository rep, ObjectId id_step, List<DatabaseMeta> databases, Map<String, Counter> counters) throws KettleException {
try
{
fromUrl = rep.getStepAttributeString(id_step, "fromUrl");
toUrl = rep.getStepAttributeString(id_step, "toUrl");
fromUserName = rep.getStepAttributeString(id_step, "fromUserName");
toUserName = rep.getStepAttributeString(id_step, "toUserName");
fromPassword = rep.getStepAttributeString(id_step, "fromPassword");
toPassword = rep.getStepAttributeString(id_step, "toPassword");
fromDatabase = rep.getStepAttributeString(id_step, "fromDatabase");
toDatabase = rep.getStepAttributeString(id_step, "toDatabase");
select_result = rep.getStepAttributeString(id_step, "select_result");
}
catch(Exception e)
{
throw new KettleException(BaseMessages.getString(PKG, "TemplateStep.Exception.UnexpectedErrorInReadingStepInfo"), e);
}
}
public void saveRep(Repository rep, ObjectId id_transformation, ObjectId id_step) throws KettleException
{
try
{
rep.saveStepAttribute(id_transformation, id_step, "fromUrl", fromUrl);
rep.saveStepAttribute(id_transformation, id_step, "toUrl", toUrl);
rep.saveStepAttribute(id_transformation, id_step, "fromUserName", fromUserName);
rep.saveStepAttribute(id_transformation, id_step, "toUserName", toUserName);
rep.saveStepAttribute(id_transformation, id_step, "fromPassword", fromPassword);
rep.saveStepAttribute(id_transformation, id_step, "toPassword", toPassword);
rep.saveStepAttribute(id_transformation, id_step, "fromDatabase", fromDatabase);
rep.saveStepAttribute(id_transformation, id_step, "toDatabase", toDatabase);
rep.saveStepAttribute(id_transformation, id_step, "select_result", select_result);
}
catch(Exception e)
{
throw new KettleException(BaseMessages.getString(PKG, "TemplateStep.Exception.UnableToSaveStepInfoToRepository")+id_step, e);
}
}
}
TemplateStep源码:
package plugin.template;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.pentaho.di.core.Const;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.core.row.RowDataUtil;
import org.pentaho.di.core.row.RowMetaInterface;
import org.pentaho.di.core.row.ValueMeta;
import org.pentaho.di.core.row.ValueMetaInterface;
import org.pentaho.di.i18n.BaseMessages;
import org.pentaho.di.trans.Trans;
import org.pentaho.di.trans.TransMeta;
import org.pentaho.di.trans.step.*;
import org.pentaho.di.trans.steps.userdefinedjavaclass.TransformClassBase.Fields;
/**
* @Title: 步骤类
* @Package plugin.template
* @Description: TODO(用一句话描述该文件做什么)
* @author http://www.ahuoo.com
* @date 2010-8-8 下午05:10:26
* @version V1.0
*/
public class TemplateStep extends BaseStep implements StepInterface {
private TemplateStepData data;
private TemplateStepMeta meta;
private String fromUrl,toUrl,fromUserName,toUserName,fromPassword,toPassword,fromDatabse,toDatabase,select_resu;
private CopyTable copyTable;
private String resu;
public TemplateStep(StepMeta s, StepDataInterface stepDataInterface, int c, TransMeta t, Trans dis) {
super(s, stepDataInterface, c, t, dis);
}
public boolean processRow(StepMetaInterface smi, StepDataInterface sdi) throws KettleException {
meta = (TemplateStepMeta) smi;
data = (TemplateStepData) sdi;
Object[] r = getRow(); // get row, blocks when needed!
if (r == null) // no more input to be expected...
{
logBasic("无输入数据");
setOutputDone();
return false;
}
if (first) {
first = false;
fromUrl = meta.getFromUrl();
toUrl = meta.getToUrl();
data.outputRowMeta = (RowMetaInterface) getInputRowMeta().clone();
meta.getFields(data.outputRowMeta, getStepname(), null, null, this);
//获取输入字段名集合
}
String s ="--"+meta.getFromUrl()+"--"+meta.getToUrl()+"--"+meta.getFromUserName()+"--"+meta.getToUserName()
+"--"+meta.getFromPassword()+"--"+meta.getToPassword() + meta.getSelect_result();
logBasic(s);
fromUrl = meta.getFromUrl();
fromUserName = meta.getFromUserName();
fromPassword = meta.getFromPassword();
fromDatabse = meta.getFromDatabase();
toUrl = meta.getToUrl();
toUserName = meta.getToUserName();
toPassword = meta.getToPassword();
toDatabase = meta.getToDatabase();
select_resu = meta.getSelect_result();
// logBasic(fromUrl+fromUserName+fromPassword+"-----start-"+fromDatabse+"------end"+toUrl+toUserName+toPassword+"-------"+toDatabase);
copyTable = new CopyTable();
copyTable.Init(fromUrl, fromDatabse, fromUserName, fromPassword, toUrl,toDatabase, toUserName,toPassword);
if(select_resu.equals("true")){
resu = copyTable.copyAllTableStructure();
}else{
resu = copyTable.copyAllTable();
}
Object[] outputRow = RowDataUtil.addValueData(r, data.outputRowMeta.size() - 1, resu);//输出的个数与设置的字段数必须一致
putRow(data.outputRowMeta, outputRow); // copy row to possible alternate rowset(s)
if (checkFeedback(getLinesRead())) {
logBasic("Linenr " + getLinesRead()); // Some basic logging
}
return true;
}
public boolean init(StepMetaInterface smi, StepDataInterface sdi) {
meta = (TemplateStepMeta) smi;
data = (TemplateStepData) sdi;
return super.init(smi, sdi);
}
public void dispose(StepMetaInterface smi, StepDataInterface sdi) {
meta = (TemplateStepMeta) smi;
data = (TemplateStepData) sdi;
super.dispose(smi, sdi);
}
//
// Run is were the action happens!
public void run() {
logBasic("Starting to run...");
try {
while (processRow(meta, data) && !isStopped())
;
} catch (Exception e) {
logError("Unexpected error : " + e.toString());
logError(Const.getStackTracker(e));
setErrors(1);
stopAll();
} finally {
dispose(meta, data);
logBasic("Finished, processing " + getLinesRead() + " rows");
markStop();
}
}
}
TemplateStepData源码:
package plugin.template;
/**
* @Title: 数据类
* @Package plugin.template
* @Description: TODO(用一句话描述该文件做什么)
* @author http://www.ahuoo.com
* @date 2010-8-8 下午05:10:26
* @version V1.0
*/
import org.pentaho.di.core.row.RowMetaInterface;
import org.pentaho.di.trans.step.BaseStepData;
import org.pentaho.di.trans.step.StepDataInterface;
public class TemplateStepData extends BaseStepData implements StepDataInterface {
public RowMetaInterface outputRowMeta;
public TemplateStepData()
{
super();
}
}
之前写的复制数据库代码copyTable:
package plugin.template;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
public class CopyTable {
String driverName = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
String copyFromUrl;
String copyFromDatabase;
String copyFromUserName;
String copyFromPassword;
String copyToUrl;
String copyToDatabase;
String copyToUserName;
String copyToPassword;
/**
* 构造方法接收两个数据库的连接信息
* @param copyFromUrl 示例:localhost
* @param copyFromDatabase
* @param copyFromUserName
* @param copyFromPassword
* @param copyToUrl 示例:127.0.0.1
* @param copyToDatabase
* @param copyToUserName
* @param copyToPassword
*/
/* CopyTable(String copyFromUrl,String copyFromDatabase,String copyFromUserName,String copyFromPassword,
String copyToUrl,String copyToDatabase,String copyToUserName,String copyToPassword
){
this.copyFromUrl = copyFromUrl;
this.copyFromDatabase = copyFromDatabase;
this.copyFromUserName = copyFromUserName;
this.copyFromPassword = copyFromPassword;
this.copyToUrl = copyToUrl;
this.copyToDatabase = copyToDatabase;
this.copyToUserName = copyToUserName;
this.copyToPassword = copyToPassword;
}*/
/**
* 初始化
* @param copyFromUrl 示例:127.0.0.1
* @param copyFromDatabase
* @param copyFromUserName
* @param copyFromPassword
* @param copyToUrl 示例:127.0.0.1
* @param copyToDatabase
* @param copyToUserName
* @param copyToPassword
*/
public void Init(String copyFromUrl,String copyFromDatabase,String copyFromUserName,String copyFromPassword,
String copyToUrl,String copyToDatabase,String copyToUserName,String copyToPassword){
this.copyFromUrl = copyFromUrl;
this.copyFromDatabase = copyFromDatabase;
this.copyFromUserName = copyFromUserName;
this.copyFromPassword = copyFromPassword;
this.copyToUrl = copyToUrl;
this.copyToDatabase = copyToDatabase;
this.copyToUserName = copyToUserName;
this.copyToPassword = copyToPassword;
}
/**
* 获得源数据库的连接
* @return Connection
* @throws ClassNotFoundException
* @throws SQLException
*/
public Connection getConFrom() throws ClassNotFoundException, SQLException{
Class.forName(this.driverName);
String copyFromUrls = "jdbc:sqlserver://"+this.copyFromUrl+":1433;Database="+this.copyFromDatabase;
Connection fromConnection = DriverManager.getConnection(copyFromUrls,this.copyFromUserName,this.copyFromPassword);
return fromConnection;
}
/**
* 获得目标数据库的连接,并打开Ad Hoc服务
* @return Connection
* @throws ClassNotFoundException
* @throws SQLException
*/
public Connection getConTo() throws ClassNotFoundException, SQLException{
Class.forName(this.driverName);
String copyToUrls = "jdbc:sqlserver://"+this.copyToUrl+":1433;Database="+this.copyToDatabase;
Connection ToConnection = DriverManager.getConnection(copyToUrls,this.copyToUserName,this.copyToPassword);
String s1 =
"EXEC sp_configure 'show advanced options',1 "+
"RECONFIGURE "+
"EXEC sp_configure 'Ad Hoc Distributed Queries',1 "+
"RECONFIGURE";
PreparedStatement stat = ToConnection.prepareCall(s1);
stat.execute();
return ToConnection;
}
/**
* 获得源数据库的表名
* @return List
*/
public List getTableName(){
try {
Class.forName(this.driverName);
this.copyFromUrl = this.copyFromUrl+";Database="+this.copyFromDatabase;
Connection fromConnection = getConFrom();
List TableNameList = new ArrayList();
String sql = "SELECT Name FROM SysObjects Where XType='U' ORDER BY Name";
ResultSet rSet = fromConnection.createStatement().executeQuery(sql);
while(rSet.next()){
TableNameList.add(rSet.getString("Name"));
}
rSet.close();
fromConnection.close();
return TableNameList;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/**
* 复制表结构
* @return String
*/
public String copyAllTableStructure(){
List list = getTableName();
String resultString = "";
try {
Connection conTo = getConTo();
Statement statement = conTo.createStatement();
String sql = "SELECT Name FROM SysObjects Where XType='U' ORDER BY Name";
for(int i = 0 ; i < list.size() ; i++){
String tableNameString = (String) list.get(i);
String s =
"SELECT * INTO "+this.copyToDatabase+".dbo."+tableNameString
+" FROM opendatasource( 'SQLOLEDB', 'Data Source="+this.copyFromUrl
+";User ID="+this.copyFromUserName+";Password="+this.copyFromPassword+"')."
+this.copyFromDatabase+".dbo."+tableNameString+" WHERE 1=2";
ResultSet rs = null;
rs = statement.executeQuery(sql);
boolean b = true;
while(rs!=null&&rs.next()){
String nameString = rs.getString("Name");
if(nameString.equals(tableNameString)){
b = false;
}
}
if(b){
statement.execute(s);
resultString = resultString + " 已创建"+tableNameString+"表";
}else{
resultString = resultString + " 表" +tableNameString +"已存在";
}
}
statement.close();
conTo.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(resultString);
return resultString;
}
/**
* 复制表结构及其数据
* @return String
*/
public String copyAllTable(){
List list = getTableName();
String resultString = "";
try {
Connection conTo = getConTo();
Statement statement = conTo.createStatement();
String sql = "SELECT Name FROM SysObjects Where XType='U' ORDER BY Name";
for(int i = 0 ; i < list.size() ; i++){
String tableNameString = (String) list.get(i);
String s =
"SELECT * INTO "+this.copyToDatabase+".dbo."+tableNameString
+" FROM opendatasource( 'SQLOLEDB', 'Data Source="+this.copyFromUrl
+";User ID="+this.copyFromUserName+";Password="+this.copyFromPassword+"')."
+this.copyFromDatabase+".dbo."+tableNameString;
ResultSet rs = null;
rs = statement.executeQuery(sql);
boolean b = true;
while(rs!=null&&rs.next()){
String nameString = rs.getString("Name");
if(nameString.equals(tableNameString)){
b = false;
}
}
if(b){
statement.execute(s);
resultString = resultString + " 已复制"+tableNameString+"表";
}else{
resultString = resultString + " 表" +tableNameString +"已存在";
}
}
statement.close();
conTo.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(resultString);
return resultString;
}
/**
* 复制指定的表的结构
* @param tableName
* @return
*/
public String copyTableStructureFromTableName(String tableName){
String resultString = "";
try {
Connection conTo = getConTo();
Statement statement = conTo.createStatement();
String sql = "SELECT Name FROM SysObjects Where XType='U' ORDER BY Name";
String s =
"SELECT * INTO "+this.copyToDatabase+".dbo."+tableName
+" FROM opendatasource( 'SQLOLEDB', 'Data Source="+this.copyFromUrl
+";User ID="+this.copyFromUserName+";Password="+this.copyFromPassword+"')."
+this.copyFromDatabase+".dbo."+tableName+" where 1=2";
ResultSet rs = null;
rs = statement.executeQuery(sql);
boolean b = true;
while(rs!=null&&rs.next()){
String nameString = rs.getString("Name");
if(nameString.equals(tableName)){
b = false;
}
}
if(b){
statement.execute(s);
resultString = resultString + " 已复制"+tableName+"表";
}else{
resultString = resultString + " 表" +tableName +"已存在";
}
statement.close();
conTo.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(resultString);
return resultString;
}
/**
* 复制指定的表的结构及数据
* @param tableName
* @return
*/
public String copyTableFromTableName(String tableName){
String resultString = "";
try {
Connection conTo = getConTo();
Statement statement = conTo.createStatement();
String sql = "SELECT Name FROM SysObjects Where XType='U' ORDER BY Name";
String s =
"SELECT * INTO "+this.copyToDatabase+".dbo."+tableName
+" FROM opendatasource( 'SQLOLEDB', 'Data Source="+this.copyFromUrl
+";User ID="+this.copyFromUserName+";Password="+this.copyFromPassword+"')."
+this.copyFromDatabase+".dbo."+tableName;
ResultSet rs = null;
rs = statement.executeQuery(sql);
boolean b = true;
while(rs!=null&&rs.next()){
String nameString = rs.getString("Name");
if(nameString.equals(tableName)){
b = false;
}
}
if(b){
statement.execute(s);
resultString = resultString + " 已复制"+tableName+"表";
}else{
resultString = resultString + " 表" +tableName +"已存在";
}
statement.close();
conTo.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(resultString);
return resultString;
}
public void close(){
String s2 =
"EXEC sp_configure 'Ad Hoc Distributed Queries',0 "+
"RECONFIGURE "+
"EXEC sp_configure 'show advanced options',0 "+
"RECONFIGURE";
Connection toConn;
try {
toConn = this.getConTo();
PreparedStatement stat = toConn.prepareCall(s2);
stat.execute();
stat.close();
toConn.close();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}