/* Copyright (c) 2007 Pentaho Corporation. All rights reserved.
* This software was developed by Pentaho Corporation and is provided under the terms
* of the GNU Lesser General Public License, Version 2.1. You may not use
* this file except in compliance with the license. If you need a copy of the license,
* please go to http://www.gnu.org/licenses/lgpl-2.1.txt. The Original Code is Pentaho
* Data Integration. The Initial Developer is Pentaho Corporation.
*
* Software distributed under the GNU Lesser Public License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. Please refer to
* the license for the specific language governing your rights and limitations.*/
/**********************************************************************
** **
** This Script has been modified for higher performance **
** and more functionality in December-2006, **
** by proconis GmbH / Germany **
** **
** http://www.proconis.de **
** info@proconis.de **
** **
**********************************************************************/
package com.akretion.kettle.steps.terminatooor;
import java.math.BigDecimal;
import java.net.URL;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.script.Bindings;
import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.script.ScriptContext;
import org.pentaho.di.compatibility.Row;
import org.pentaho.di.compatibility.Value;
import org.pentaho.di.core.CheckResult;
import org.pentaho.di.core.CheckResultInterface;
import org.pentaho.di.core.Const;
import org.pentaho.di.core.Counter;
import org.pentaho.di.core.database.DatabaseMeta;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.core.exception.KettleStepException;
import org.pentaho.di.core.exception.KettleXMLException;
import org.pentaho.di.core.row.RowMeta;
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.core.variables.VariableSpace;
import org.pentaho.di.core.xml.XMLHandler;
import org.pentaho.di.i18n.BaseMessages;
import org.pentaho.di.repository.Repository;
import org.pentaho.di.repository.ObjectId;
import org.pentaho.di.trans.KettleURLClassLoader;
import org.pentaho.di.trans.Trans;
import org.pentaho.di.trans.TransMeta;
import org.pentaho.di.trans.step.BaseStepMeta;
import org.pentaho.di.trans.step.StepDataInterface;
import org.pentaho.di.trans.step.StepInterface;
import org.pentaho.di.trans.step.StepMeta;
import org.pentaho.di.trans.step.StepMetaInterface;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
/*
* Created on 2-jun-2003
*
*/
public class ScriptValuesMetaMod extends BaseStepMeta implements StepMetaInterface
{
private static Class<?> PKG = ScriptValuesMetaMod.class; // for i18n purposes, needed by Translator2!! $NON-NLS-1$
private static final String JSSCRIPT_TAG_TYPE = "jsScript_type";
private static final String JSSCRIPT_TAG_NAME = "jsScript_name";
private static final String JSSCRIPT_TAG_SCRIPT= "jsScript_script";
private ScriptValuesAddClasses[] additionalClasses;
private ScriptValuesScript[] jsScripts;
private String fieldname[];
private String rename[];
private int type[];
private int length[];
private int precision[];
private boolean replace[]; // Replace the specified field.
private boolean compatible;
public ScriptValuesMetaMod(){
super(); // allocate BaseStepMeta
compatible=true;
try{
parseXmlForAdditionalClasses();
}catch(Exception e){};
}
/**
* @return Returns the length.
*/
public int[] getLength(){
return length;
}
/**
* @param length The length to set.
*/
public void setLength(int[] length){
this.length = length;
}
/**
* @return Returns the name.
*/
public String[] getFieldname(){
return fieldname;
}
/**
* @param fieldname The name to set.
*/
public void setFieldname(String[] fieldname){
this.fieldname = fieldname;
}
/**
* @return Returns the precision.
*/
public int[] getPrecision()
{
return precision;
}
/**
* @param precision The precision to set.
*/
public void setPrecision(int[] precision)
{
this.precision = precision;
}
/**
* @return Returns the rename.
*/
public String[] getRename()
{
return rename;
}
/**
* @param rename The rename to set.
*/
public void setRename(String[] rename)
{
this.rename = rename;
}
/**
* @return Returns the type.
*/
public int[] getType()
{
return type;
}
/**
* @param type The type to set.
*/
public void setType(int[] type)
{
this.type = type;
}
public int getNumberOfJSScripts(){
return jsScripts.length;
}
public String[] getJSScriptNames(){
String strJSNames[] = new String[jsScripts.length];
for(int i=0;i<jsScripts.length;i++) strJSNames[i] = jsScripts[i].getScriptName();
return strJSNames;
}
public ScriptValuesScript[] getJSScripts(){
return jsScripts;
}
public void setJSScripts(ScriptValuesScript[] jsScripts){
this.jsScripts = jsScripts;
}
public void loadXML(Node stepnode, List<DatabaseMeta> databases, Map<String, Counter> counters)
throws KettleXMLException
{
readData(stepnode);
}
public void allocate(int nrfields){
fieldname = new String [nrfields];
rename = new String [nrfields];
type = new int [nrfields];
length = new int [nrfields];
precision = new int [nrfields];
replace = new boolean[nrfields];
}
public Object clone()
{
ScriptValuesMetaMod retval = (ScriptValuesMetaMod)super.clone();
int nrfields = fieldname.length;
retval.allocate(nrfields);
for (int i=0;i<nrfields;i++)
{
retval.fieldname [i] = fieldname[i];
retval.rename [i] = rename[i];
retval.type [i] = type[i];
retval.length [i] = length[i];
retval.precision[i] = precision[i];
retval.replace [i] = replace[i];
}
return retval;
}
private void readData(Node stepnode) throws KettleXMLException{
try {
String script = XMLHandler.getTagValue(stepnode, "script");
String strCompatible = XMLHandler.getTagValue(stepnode, "compatible");
if (strCompatible==null) {
compatible=true;
}
else {
compatible = "Y".equalsIgnoreCase(strCompatible);
}
// When in compatibility mode, we load the script, not the other tabs...
//
if (!Const.isEmpty(script)) {
jsScripts = new ScriptValuesScript[1];
jsScripts[0] = new ScriptValuesScript(
ScriptValuesScript.TRANSFORM_SCRIPT,
"ScriptValue",
script
);
}
else {
Node scripts = XMLHandler.getSubNode(stepnode, "jsScripts");
int nrscripts = XMLHandler.countNodes(scripts, "jsScript");
jsScripts = new ScriptValuesScript[nrscripts];
for (int i=0;i<nrscripts;i++){
Node fnode = XMLHandler.getSubNodeByNr(scripts, "jsScript", i); //$NON-NLS-1$
jsScripts[i] = new ScriptValuesScript(
Integer.parseInt(XMLHandler.getTagValue(fnode, JSSCRIPT_TAG_TYPE)),
XMLHandler.getTagValue(fnode, JSSCRIPT_TAG_NAME),
XMLHandler.getTagValue(fnode, JSSCRIPT_TAG_SCRIPT)
);
}
}
Node fields = XMLHandler.getSubNode(stepnode, "fields"); //$NON-NLS-1$
int nrfields = XMLHandler.countNodes(fields, "field"); //$NON-NLS-1$
allocate(nrfields);
for (int i=0;i<nrfields;i++)
{
Node fnode = XMLHandler.getSubNodeByNr(fields, "field", i); //$NON-NLS-1$
fieldname [i] = XMLHandler.getTagValue(fnode, "name"); //$NON-NLS-1$
rename [i] = XMLHandler.getTagValue(fnode, "rename"); //$NON-NLS-1$
type [i] = ValueMeta.getType(XMLHandler.getTagValue(fnode, "type")); //$NON-NLS-1$
String slen = XMLHandler.getTagValue(fnode, "length"); //$NON-NLS-1$
String sprc = XMLHandler.getTagValue(fnode, "precision"); //$NON-NLS-1$
length [i]=Const.toInt(slen, -1);
precision[i]=Const.toInt(sprc, -1);
replace [i] = "Y".equalsIgnoreCase(XMLHandler.getTagValue(fnode, "replace")); //$NON-NLS-1$
}
}
catch(Exception e)
{
throw new KettleXMLException(BaseMessages.getString(PKG, "ScriptValuesMetaMod.Exception.UnableToLoadStepInfoFromXML"), e); //$NON-NLS-1$
}
}
public void setDefault(){
jsScripts = new ScriptValuesScript[1];
jsScripts[0] = new ScriptValuesScript(
ScriptValuesScript.TRANSFORM_SCRIPT,
BaseMessages.getString(PKG, "ScriptValuesMod.Script1"),
"//"+ BaseMessages.getString(PKG, "ScriptValuesMod.ScriptHere") +Const.CR+Const.CR
);
int nrfields=0;
allocate(nrfields);
for (int i=0;i<nrfields;i++){
fieldname [i] = "newvalue"; //$NON-NLS-1$
rename [i] = "newvalue"; //$NON-NLS-1$
type [i] = ValueMetaInterface.TYPE_NUMBER;
length [i] = -1;
precision[i] = -1;
replace [i] = false;
}
compatible=false;
}
public void getFields(RowMetaInterface row, String originStepname, RowMetaInterface[] info, StepMeta nextStep, VariableSpace space) throws KettleStepException
{
for (int i=0;i<fieldname.length;i++)
{
if (!Const.isEmpty(fieldname[i]))
{
ValueMetaInterface v;
if (replace[i]) {
// Look up the field to replace using the "name" field
v = row.searchValueMeta(fieldname[i]);
if (v==null) {
// The field was not found using the "name" field
if(Const.isEmpty(rename[i])) {
// There is no "rename" field to try; Therefore we cannot find the field to replace
throw new KettleStepException(BaseMessages.getString(PKG, "ScriptValuesMetaMod.Exception.FieldToReplaceNotFound", fieldname[i]));
} else {
// Lookup the field to replace using the "rename" field
v = row.searchValueMeta(rename[i]);
if(v == null) {
// The field was not found using the "rename" field"; Therefore we cannot find the field to replace
throw new KettleStepException(BaseMessages.getString(PKG, "ScriptValuesMetaMod.Exception.FieldToReplaceNotFound", rename[i]));
}
}
}
// Change the data type to match what's specified...
//
v.setType(type[i]);
} else {
if (rename[i]!=null && rename[i].length()!=0)
{
v = new ValueMeta(rename[i], type[i]);
}
else
{
v = new ValueMeta(this.fieldname[i], type[i]);
}
}
v.setLength(length[i]);
v.setPrecision(precision[i]);
v.setOrigin(originStepname);
if (!replace[i]) {
row.addValueMeta( v );
}
}
}
}
public String getXML()
{
StringBuffer retval = new StringBuffer(300);
retval.append(" ").append(XMLHandler.addTagValue("compatible", compatible)); //$NON-NLS-1$ //$NON-NLS-2$
retval.append(" <jsScripts>");
for (int i=0;i<jsScripts.length;i++){
retval.append(" <jsScript>"); //$NON-NLS-1$
retval.append(" ").append(XMLHandler.addTagValue(JSSCRIPT_TAG_TYPE, jsScripts[i].getScriptType()));
retval.append(" ").append(XMLHandler.addTagValue(JSSCRIPT_TAG_NAME, jsScripts[i].getScriptName()));
retval.append(" ").append(XMLHandler.addTagValue(JSSCRIPT_TAG_SCRIPT, jsScripts[i].getScript()));
retval.append(" </jsScript>"); //$NON-NLS-1$
}
retval.append(" </jsScripts>");
retval.append(" <fields>"); //$NON-NLS-1$
for (int i=0;i<fieldname.length;i++)
{
retval.append(" <field>"); //$NON-NLS-1$
retval.append(" ").append(XMLHandler.addTagValue("name", fieldname[i])); //$NON-NLS-1$ //$NON-NLS-2$
retval.append(" ").append(XMLHandler.addTagValue("rename", rename[i])); //$NON-NLS-1$ //$NON-NLS-2$
retval.append(" ").append(XMLHandler.addTagValue("type", ValueMeta.getTypeDesc(type[i]))); //$NON-NLS-1$ //$NON-NLS-2$
retval.append(" ").append(XMLHandler.addTagValue("length", length[i])); //$NON-NLS-1$ //$NON-NLS-2$
retval.append(" ").append(XMLHandler.addTagValue("precision", precision[i])); //$NON-NLS-1$ //$NON-NLS-2$
retval.append(" ").append(XMLHandler.addTagValue("replace", replace[i])); //$NON-NLS-1$ //$NON-NLS-2$
retval.append(" </field>"); //$NON-NLS-1$
}
retval.append(" </fields>"); //$NON-NLS-1$
return retval.toString();
}
public void readRep(Repository rep, ObjectId id_step, List<DatabaseMeta> databases, Map<String, Counter> counters) throws KettleException
{
try
{
String script = rep.getStepAttributeString(id_step, "script"); //$NON-NLS-1$
compatible = rep.getStepAttributeBoolean(id_step, 0, "compatible", true); //$NON-NLS-1$
// When in compatibility mode, we load the script, not the other tabs...
//
if (!Const.isEmpty(script)) {
jsScripts = new ScriptValuesScript[1];
jsScripts[0] = new ScriptValuesScript(
ScriptValuesScript.TRANSFORM_SCRIPT,
"ScriptValue",
script
);
}
else {
int nrScripts = rep.countNrStepAttributes(id_step, JSSCRIPT_TAG_NAME); //$NON-NLS-1$
jsScripts = new ScriptValuesScript[nrScripts];
for (int i = 0; i < nrScripts; i++)
{
jsScripts[i] = new ScriptValuesScript((int) rep.getStepAttributeInteger(id_step, i, JSSCRIPT_TAG_TYPE), rep.getStepAttributeString(
id_step, i, JSSCRIPT_TAG_NAME), rep.getStepAttributeString(id_step, i, JSSCRIPT_TAG_SCRIPT));
}
}
int nrfields = rep.countNrStepAttributes(id_step, "field_name"); //$NON-NLS-1$
allocate(nrfields);
for (int i=0;i<nrfields;i++)
{
fieldname[i] = rep.getStepAttributeString (id_step, i, "field_name"); //$NON-NLS-1$
rename[i] = rep.getStepAttributeString (id_step, i, "field_rename"); //$NON-NLS-1$
type[i] = ValueMeta.getType( rep.getStepAttributeString (id_step, i, "field_type") ); //$NON-NLS-1$
length[i] = (int)rep.getStepAttributeInteger(id_step, i, "field_length"); //$NON-NLS-1$
precision[i] = (int)rep.getStepAttributeInteger(id_step, i, "field_precision"); //$NON-NLS-1$
replace[i] = rep.getStepAttributeBoolean(id_step, i, "field_replace"); //$NON-NLS-1$
}
}
catch(Exception e)
{
throw new KettleException(BaseMessages.getString(PKG, "ScriptValuesMetaMod.Exception.UnexpectedErrorInReadingStepInfo"), e); //$NON-NLS-1$
}
}
public void saveRep(Repository rep, ObjectId id_transformation, ObjectId id_step) throws KettleException
{
try
{
rep.saveStepAttribute(id_transformation, id_step, "compatible", compatible); //$NON-NLS-1$
for (int i = 0; i < jsScripts.length; i++)
{
rep.saveStepAttribute(id_transformation, id_step, i, JSSCRIPT_TAG_NAME, jsScripts[i].getScriptName());
rep.saveStepAttribute(id_transformation, id_step, i, JSSCRIPT_TAG_SCRIPT, jsScripts[i].getScript());
rep.saveStepAttribute(id_transformation, id_step, i, JSSCRIPT_TAG_TYPE, jsScripts[i].getScriptType());
}
for (int i = 0; i < fieldname.length; i++)
{
rep.saveStepAttribute(id_transformation, id_step, i, "field_name", fieldname[i]); //$NON-NLS-1$
rep.saveStepAttribute(id_transformation, id_step, i, "field_rename", rename[i]); //$NON-NLS-1$
rep.saveStepAttribute(id_transformation, id_step, i, "field_type", ValueMeta.getTypeDesc(type[i])); //$NON-NLS-1$
rep.saveStepAttribute(id_transformation, id_step, i, "field_length", length[i]); //$NON-NLS-1$
rep.saveStepAttribute(id_transformation, id_step, i, "field_precision", precision[i]); //$NON-NLS-1$
rep.saveStepAttribute(id_transformation, id_step, i, "field_replace", replace[i]); //$NON-NLS-1$
}
}
catch (Exception e)
{
throw new KettleException(BaseMessages.getString(PKG, "ScriptValuesMetaMod.Exception.UnableToSaveStepInfo") + id_step, e); //$NON-NLS-1$
}
}
public void check(List<CheckResultInterface> remarks, TransMeta transMeta, StepMeta stepinfo, RowMetaInterface prev, String input[], String output[], RowMetaInterface info)
{
boolean error_found=false;
String error_message = ""; //$NON-NLS-1$
CheckResult cr;
ScriptEngine jscx;
Bindings jsscope;
CompiledScript jsscript;
jscx = createNewScriptEngine(stepinfo.getName());
jsscope = jscx.getBindings(ScriptContext.ENGINE_SCOPE);
// String strActiveScriptName="";
String strActiveStartScriptName="";
String strActiveEndScriptName="";
String strActiveScript="";
String strActiveStartScript="";
String strActiveEndScript="";
// Building the Scripts
if(jsScripts.length>0){
for(int i=0;i<jsScripts.length;i++){
if(jsScripts[i].isTransformScript()){
// strActiveScriptName =jsScripts[i].getScriptName();
strActiveScript =jsScripts[i].getScript();
}else if(jsScripts[i].isStartScript()) {
strActiveStartScriptName =jsScripts[i].getScriptName();
strActiveStartScript =jsScripts[i].getScript();
}else if(jsScripts[i].isEndScript()){
strActiveEndScriptName =jsScripts[i].getScriptName();
strActiveEndScript =jsScripts[i].getScript();
}
}
}
if (prev!=null && strActiveScript.length()>0) {
cr = new CheckResult(CheckResultInterface.TYPE_RESULT_OK, BaseMessages.getString(PKG, "ScriptValuesMetaMod.CheckResult.ConnectedStepOK",String.valueOf(prev.size())), stepinfo); //$NON-NLS-1$ //$NON-NLS-2$
remarks.add(cr);
// Adding the existing Scripts to the Context
for(int i=0;i<getNumberOfJSScripts();i++){
jsscope.put(jsScripts[i].getScriptName(), jsScripts[i].getScript());
}
// Modification for Additional Script parsing
try{
if (getAddClasses()!=null)
{
for(int i=0;i<getAddClasses().length;i++){
//TODO AKRETION ensure it works
jsscope.put(getAddClasses()[i].getJSName(), getAddClasses()[i].getAddObject());
//Object jsOut = Context.javaToJS(getAddClasses()[i].getAddObject(), jsscope);
//ScriptableObject.putProperty(jsscope, getAddClasses()[i].getJSName(), jsOut);
//ScriptableObject.putProperty(jsscope, getAddClasses()[i].getJSName(), jsOut);
}
}
}catch(Exception e){
error_message = ("Couldn't add JavaClasses to Context! Error:");
cr = new CheckResult(CheckResultInterface.TYPE_RESULT_ERROR, error_message, stepinfo);
remarks.add(cr);
}
// Adding some default JavaScriptFunctions to the System
//TODO AKRETION not implemented yet
// try {
// Context.javaToJS(ScriptValuesAddedFunctions.class, jsscope);
// ((ScriptableObject)jsscope).defineFunctionProperties(ScriptValuesAddedFunctions.jsFunctionList, ScriptValuesAddedFunctions.class, ScriptableObject.DONTENUM);
// } catch (Exception ex) {
// error_message="Couldn't add Default Functions! Error:"+Const.CR+ex.toString();
// cr = new CheckResult(CheckResultInterface.TYPE_RESULT_ERROR, error_message, stepinfo);
// remarks.add(cr);
// };
// Adding some Constants to the JavaScript
try {
jsscope.put("SKIP_TRANSFORMATION", Integer.valueOf(ScriptValuesMod.SKIP_TRANSFORMATION));
jsscope.put("ABORT_TRANSFORMATION", Integer.valueOf(ScriptValuesMod.ABORT_TRANSFORMATION));
jsscope.put("ERROR_TRANSFORMATION", Integer.valueOf(ScriptValuesMod.ERROR_TRANSFORMATION));
jsscope.put("CONTINUE_TRANSFORMATION", Integer.valueOf(ScriptValuesMod.CONTINUE_TRANSFORMATION));
} catch (Exception ex) {
error_message="Couldn't add Transformation Constants! Error:"+Const.CR+ex.toString(); //$NON-NLS-1$
cr = new CheckResult(CheckResultInterface.TYPE_RESULT_ERROR, error_message, stepinfo);
remarks.add(cr);
};
try{
ScriptValuesModDummy dummyStep = new ScriptValuesModDummy(prev, transMeta.getStepFields(stepinfo));
jsscope.put("_step_", dummyStep); //$NON-NLS-1$
Object[] row=new Object[prev.size()];
jsscope.put("rowMeta", prev); //$NON-NLS-1$
for (int i=0;i<prev.size();i++)
{
ValueMetaInterface valueMeta = prev.getValueMeta(i);
Object valueData = null;
// Set date and string values to something to simulate real thing
//
if (valueMeta.isDate()) valueData = new Date();
if (valueMeta.isString()) valueData = "test value test value test value test value test value test value test value test value test value test value"; //$NON-NLS-1$
if (valueMeta.isInteger()) valueData = Long.valueOf(0L);
if (valueMeta.isNumber()) valueData = new Double(0.0);
if (valueMeta.isBigNumber()) valueData = BigDecimal.ZERO;
if (valueMeta.isBoolean()) valueData = Boolean.TRUE;
if (valueMeta.isBinary()) valueData = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, };
row[i]=valueData;
if (isCompatible()) {
Value value = valueMeta.createOriginalValue(valueData);
jsscope.put(valueMeta.getName(), value);
}
else {
jsscope.put(valueMeta.getName(), valueData);
}
}
// Add support for Value class (new Value())
jsscope.put("Value", Value.class); //$NON-NLS-1$
// Add the old style row object for compatibility reasons...
//
if (isCompatible()) {
Row v2Row = RowMeta.createOriginalRow(prev, row);
jsscope.put("row", v2Row); //$NON-NLS-1$
}
else {
jsscope.put("row", row); //$NON-NLS-1$
}
} catch(Exception ev){
error_message="Couldn't add Input fields to Script! Error:"+Const.CR+ev.toString(); //$NON-NLS-1$
cr = new CheckResult(CheckResultInterface.TYPE_RESULT_ERROR, error_message, stepinfo);
remarks.add(cr);
}
try{
// Checking for StartScript
if(strActiveStartScript != null && strActiveStartScript.length()>0){
jscx.eval(strActiveStartScript, jsscope);
error_message = "Found Start Script. "+ strActiveStartScriptName+" Processing OK";
cr = new CheckResult(CheckResultInterface.TYPE_RESULT_OK, error_message, stepinfo); //$NON-NLS-1$
remarks.add(cr);
}
}catch(Exception e){
error_message="Couldn't process Start Script! Error:"+Const.CR+e.toString(); //$NON-NLS-1$
cr = new CheckResult(CheckResultInterface.TYPE_RESULT_ERROR, error_message, stepinfo);
remarks.add(cr);
};
try{
jsscript = ((Compilable) jscx).compile(strActiveScript);
//cr = new CheckResult(CheckResultInterface.TYPE_RESULT_OK, BaseMessages.getString(PKG, "ScriptValuesMetaMod.CheckResult.ScriptCompiledOK"), stepinfo); //$NON-NLS-1$
//remarks.add(cr);
try{
jsscript.eval(jsscope);
cr = new CheckResult(CheckResultInterface.TYPE_RESULT_OK, BaseMessages.getString(PKG, "ScriptValuesMetaMod.CheckResult.ScriptCompiledOK2"), stepinfo); //$NON-NLS-1$
remarks.add(cr);
if (fieldname.length>0){
StringBuffer message = new StringBuffer(BaseMessages.getString(PKG, "ScriptValuesMetaMod.CheckResult.FailedToGetValues",String.valueOf(fieldname.length))+Const.CR+Const.CR); //$NON-NLS-1$ //$NON-NLS-2$
if (error_found)
{
cr = new CheckResult(CheckResultInterface.TYPE_RESULT_ERROR, message.toString(), stepinfo);
}
else
{
cr = new CheckResult(CheckResultInterface.TYPE_RESULT_OK, message.toString(), stepinfo);
}
remarks.add(cr);
}
}catch(ScriptException jse){
//Context.exit(); TODO AKRETION NOT SURE
error_message=BaseMessages.getString(PKG, "ScriptValuesMetaMod.CheckResult.CouldNotExecuteScript")+Const.CR+jse.toString(); //$NON-NLS-1$
cr = new CheckResult(CheckResultInterface.TYPE_RESULT_ERROR, error_message, stepinfo);
remarks.add(cr);
}catch(Exception e){
//Context.exit(); TODO AKRETION NOT SURE
error_message=BaseMessages.getString(PKG, "ScriptValuesMetaMod.CheckResult.CouldNotExecuteScript2")+Const.CR+e.toString(); //$NON-NLS-1$
cr = new CheckResult(CheckResultInterface.TYPE_RESULT_ERROR, error_message, stepinfo);
remarks.add(cr);
}
// Checking End Script
try{
if(strActiveEndScript != null && strActiveEndScript.length()>0){
/* Object endScript = */ jscx.eval(strActiveEndScript, jsscope);
error_message = "Found End Script. "+ strActiveEndScriptName+" Processing OK";
cr = new CheckResult(CheckResultInterface.TYPE_RESULT_OK, error_message, stepinfo); //$NON-NLS-1$
remarks.add(cr);
}
}catch(Exception e){
error_message="Couldn't process End Script! Error:"+Const.CR+e.toString(); //$NON-NLS-1$
cr = new CheckResult(CheckResultInterface.TYPE_RESULT_ERROR, error_message, stepinfo);
remarks.add(cr);
};
}catch(Exception e){
//Context.exit(); TODO AKRETION NOT SURE
error_message = BaseMessages.getString(PKG, "ScriptValuesMetaMod.CheckResult.CouldNotCompileScript")+Const.CR+e.toString(); //$NON-NLS-1$
cr = new CheckResult(CheckResultInterface.TYPE_RESULT_ERROR, error_message, stepinfo);
remarks.add(cr);
}
}else{
//Context.exit(); TODO AKRETION NOT SURE
error_message = BaseMessages.getString(PKG, "ScriptValuesMetaMod.CheckResult.CouldNotGetFieldsFromPreviousStep"); //$NON-NLS-1$
cr = new CheckResult(CheckResultInterface.TYPE_RESULT_ERROR, error_message, stepinfo);
remarks.add(cr);
}
// See if we have input streams leading to this step!
if (input.length>0){
cr = new CheckResult(CheckResultInterface.TYPE_RESULT_OK, BaseMessages.getString(PKG, "ScriptValuesMetaMod.CheckResult.ConnectedStepOK2"), stepinfo); //$NON-NLS-1$
remarks.add(cr);
}else{
cr = new CheckResult(CheckResultInterface.TYPE_RESULT_ERROR, BaseMessages.getString(PKG, "ScriptValuesMetaMod.CheckResult.NoInputReceived"), stepinfo); //$NON-NLS-1$
remarks.add(cr);
}
}
public String getFunctionFromScript(String strFunction, String strScript){
String sRC = "";
int iStartPos=strScript.indexOf(strFunction);
if(iStartPos>0){
iStartPos = strScript.indexOf('{', iStartPos);
int iCounter = 1;
while(iCounter!=0){
if(strScript.charAt(iStartPos++)=='{') iCounter++;
else if(strScript.charAt(iStartPos++)=='}') iCounter--;
sRC = sRC + strScript.charAt(iStartPos);
}
}
return sRC;
}
public boolean getValue(Bindings scope, int i, Value res, StringBuffer message)
{
boolean error_found = false;
if (fieldname[i]!=null && fieldname[i].length()>0)
{
res.setName(rename[i]);
res.setType(type[i]);
try{
Object result = scope.get(fieldname[i]);
if (result!=null){
String classname = result.getClass().getName();
switch(type[i]){
case ValueMetaInterface.TYPE_NUMBER:
if (classname.equalsIgnoreCase("org.mozilla.javascript.Undefined")){
res.setNull();
}else if (classname.equalsIgnoreCase("org.mozilla.javascript.NativeJavaObject")){
// Is it a java Value class ?
Value v = (Value) result;
res.setValue( v.getNumber() );
}else{
res.setValue( ((Double)result).doubleValue() );
}
break;
case ValueMetaInterface.TYPE_INTEGER:
if (classname.equalsIgnoreCase("java.lang.Byte")){
res.setValue( ((java.lang.Byte)result).longValue() );
}else if (classname.equalsIgnoreCase("java.lang.Short")){
res.setValue( ((Short)result).longValue() );
}else if (classname.equalsIgnoreCase("java.lang.Integer")){
res.setValue( ((Integer)result).longValue() );
}else if (classname.equalsIgnoreCase("java.lang.Long")){
res.setValue( ((Long)result).longValue() );
}else if (classname.equalsIgnoreCase("org.mozilla.javascript.Undefined")){
res.setNull();
}else if (classname.equalsIgnoreCase("org.mozilla.javascript.NativeJavaObject")){
// Is it a java Value class ?
Value v = (Value) result;
res.setValue( v.getInteger() );
}else{
res.setValue( Math.round( ((Double)result).doubleValue() ) );
}
break;
case ValueMetaInterface.TYPE_STRING:
if (classname.equalsIgnoreCase("org.mozilla.javascript.NativeJavaObject") || //$NON-NLS-1$
classname.equalsIgnoreCase("org.mozilla.javascript.Undefined")) //$NON-NLS-1$
{
// Is it a java Value class ?
try
{
Value v = (Value) result;
res.setValue( v.getString() );
}
catch(Exception ev)
{
// A String perhaps?
String s = (String) result;
res.setValue( s );
}
}
else
{
res.setValue( ((String)result) );
}
break;
case ValueMetaInterface.TYPE_DATE:
double dbl=0;
if (classname.equalsIgnoreCase("org.mozilla.javascript.Undefined")) //$NON-NLS-1$
{
res.setNull();
}
else
{
if (classname.equalsIgnoreCase("org.mozilla.javascript.NativeDate")) //$NON-NLS-1$
{
dbl = (Double) result;//TODO AKRETION not sure!
}
else
if (classname.equalsIgnoreCase("org.mozilla.javascript.NativeJavaObject")) //$NON-NLS-1$
{
// Is it a java Date() class ?
try
{
Date dat = (Date) result;
dbl = dat.getTime();
}
catch(Exception e) // Nope, try a Value
{
Value v = (Value) result;
Date dat = v.getDate();
if (dat!=null) dbl = dat.getTime();
else res.setNull();
}
}
else // Finally, try a number conversion to time
{
dbl = ((Double)result).doubleValue();
}
long lng = Math.round(dbl);
Date dat = new Date(lng);
res.setValue( dat );
}
break;
case ValueMetaInterface.TYPE_BOOLEAN:
res.setValue( ((Boolean)result).booleanValue());
break;
default: res.setNull();
}
}
else
{
res.setNull();
}
}
catch(Exception e)
{
message.append(BaseMessages.getString(PKG, "ScriptValuesMetaMod.CheckResult.ErrorRetrievingValue",fieldname[i])+" : "+e.toString()); //$NON-NLS-1$ //$NON-NLS-2$
error_found=true;
}
res.setLength(length[i], precision[i]);
message.append(BaseMessages.getString(PKG, "ScriptValuesMetaMod.CheckResult.RetrievedValue",fieldname[i],res.toStringMeta())); //$NON-NLS-1$ //$NON-NLS-2$
}
else
{
message.append(BaseMessages.getString(PKG, "ScriptValuesMetaMod.CheckResult.ValueIsEmpty",String.valueOf(i))); //$NON-NLS-1$ //$NON-NLS-2$
error_found=true;
}
return error_found;
}
public StepInterface getStep(StepMeta stepMeta, StepDataInterface stepDataInterface, int cnr, TransMeta transMeta, Trans trans)
{
return new ScriptValuesMod(stepMeta, stepDataInterface, cnr, transMeta, trans);
}
public StepDataInterface getStepData()
{
return new ScriptValuesModData();
}
// This is for Additional Classloading
public void parseXmlForAdditionalClasses() throws KettleException{
try {
Properties sysprops = System.getProperties();
String strActPath = sysprops.getProperty("user.dir");
Document dom = XMLHandler.loadXMLFile(strActPath + "/plugins/steps/ScriptValues_mod/plugin.xml");
Node stepnode = dom.getDocumentElement();
Node libraries = XMLHandler.getSubNode(stepnode, "js_libraries");
int nbOfLibs = XMLHandler.countNodes(libraries, "js_lib");
additionalClasses = new ScriptValuesAddClasses[nbOfLibs];
for(int i=0;i<nbOfLibs;i++){
Node fnode = XMLHandler.getSubNodeByNr(libraries, "js_lib", i);
String strJarName = XMLHandler.getTagAttribute(fnode, "name");
String strClassName =XMLHandler.getTagAttribute(fnode, "classname");
String strJSName = XMLHandler.getTagAttribute(fnode, "js_name");
Class<?> addClass = LoadAdditionalClass(strActPath + "/plugins/steps/ScriptValues_mod/"+ strJarName,strClassName);
Object addObject = addClass.newInstance();
additionalClasses[i] = new ScriptValuesAddClasses(addClass, addObject, strJSName);
}
}catch(Exception e) {
throw new KettleException(BaseMessages.getString(PKG, "ScriptValuesMetaMod.Exception.UnableToParseXMLforAdditionalClasses"), e);
}
}
private static Class<?> LoadAdditionalClass(String strJar, String strClassName) throws KettleException{
try{
Thread t = Thread.currentThread();
ClassLoader cl = t.getContextClassLoader();
URL u = new URL("jar:file:"+strJar+"!/");
KettleURLClassLoader kl = new KettleURLClassLoader(new URL[]{u}, cl);
Class<?> toRun = kl.loadClass(strClassName);
return toRun;
}catch(Exception e){
throw new KettleException(BaseMessages.getString(PKG, "ScriptValuesMetaMod.Exception.UnableToLoadAdditionalClass"), e); //$NON-NLS-1$
}
}
public ScriptValuesAddClasses[] getAddClasses(){
return additionalClasses;
}
/**
* @return the compatible
*/
public boolean isCompatible() {
return compatible;
}
/**
* @param compatible the compatible to set
*/
public void setCompatible(boolean compatible) {
this.compatible = compatible;
}
public boolean supportsErrorHandling() {
return true;
}
public String getDialogClassName()
{
return "com.akretion.kettle.steps.terminatooor.ui.ScriptValuesModDialog";
}
/**
* @return the replace
*/
public boolean[] getReplace() {
return replace;
}
/**
* @param replace the replace to set
*/
public void setReplace(boolean[] replace) {
this.replace = replace;
}
/**
* Instanciates the right scripting language interpreter, falling back to Javascript for backward compat.
* Because Kettle GUI sucks for extensibility, we use the script name extension
* to determine the language rather than add a Combo box. Complain to Pentaho please.
* @param stepName
* @return
*/
public static ScriptEngine createNewScriptEngine(String stepName) {
System.setProperty("org.jruby.embed.localvariable.behavior", "persistent");//required for JRuby, transparent for others
System.setProperty("org.jruby.embed.localcontext.scope", "threadsafe");
ScriptEngineManager manager = new ScriptEngineManager();
String extension;
if(stepName.indexOf("jruby") > 0 || stepName.indexOf("ruby") > 0 || stepName.indexOf(".rb") > 0) {
extension = "jruby";
} else if(stepName.indexOf("jython") > 0 || stepName.indexOf("python") > 0 || stepName.indexOf(".py") > 0){
extension = "jython";
} else if(stepName.indexOf(".") > 0){
String[] strings = stepName.split("\\.");
extension = strings[strings.length > 0 ? 1 : 0];//skip the script number extension
} else {
extension = "jruby";
}
System.out.println("script name= " + stepName +"; extension name= " + extension);
ScriptEngine scriptEngine = manager.getEngineByName(extension);
if (scriptEngine == null) {//falls back to Javascript
System.out.println("FALLING BACK TO JAVASCRIPT INTERPRETER...");
scriptEngine = manager.getEngineByName("javascript");
}
return scriptEngine;
}
}