/*! ******************************************************************************
*
* Pentaho Data Integration
*
* Copyright (C) 2002-2016 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 org.pentaho.di.trans.steps.stringcut;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.junit.Test;
import org.pentaho.di.core.KettleEnvironment;
import org.pentaho.di.core.RowMetaAndData;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.core.plugins.PluginRegistry;
import org.pentaho.di.core.plugins.StepPluginType;
import org.pentaho.di.core.row.RowMeta;
import org.pentaho.di.core.row.RowMetaInterface;
import org.pentaho.di.core.row.ValueMetaInterface;
import org.pentaho.di.core.row.value.ValueMetaString;
import org.pentaho.di.trans.RowProducer;
import org.pentaho.di.trans.RowStepCollector;
import org.pentaho.di.trans.Trans;
import org.pentaho.di.trans.TransHopMeta;
import org.pentaho.di.trans.TransMeta;
import org.pentaho.di.trans.TransformationTestCase;
import org.pentaho.di.trans.step.StepInterface;
import org.pentaho.di.trans.step.StepMeta;
import org.pentaho.di.trans.steps.dummytrans.DummyTransMeta;
import org.pentaho.di.trans.steps.injector.InjectorMeta;
/**
* Test class for the StringCut step.
*
* @author Matt Burgess
*/
public class StringCutTest extends TransformationTestCase {
public StringCutTest() throws KettleException {
super();
}
public RowMetaInterface createRowMetaInterface() {
RowMetaInterface rm = new RowMeta();
ValueMetaInterface[] valuesMeta =
{ new ValueMetaString( "field1" ), new ValueMetaString( "field2" ),
};
for ( int i = 0; i < valuesMeta.length; i++ ) {
rm.addValueMeta( valuesMeta[i] );
}
return rm;
}
public RowMetaInterface createResultRowMetaInterface1() {
RowMetaInterface rm = new RowMeta();
ValueMetaInterface[] valuesMeta =
{
new ValueMetaString( "field1" ), new ValueMetaString( "field2" ),
new ValueMetaString( "outf3" ),
};
for ( int i = 0; i < valuesMeta.length; i++ ) {
rm.addValueMeta( valuesMeta[i] );
}
return rm;
}
public RowMetaInterface createResultRowMetaInterface2() {
RowMetaInterface rm = new RowMeta();
ValueMetaInterface[] valuesMeta =
{
new ValueMetaString( "field1" ), new ValueMetaString( "field2" ),
new ValueMetaString( "outf3" ), new ValueMetaString( "outf4" ),
};
for ( int i = 0; i < valuesMeta.length; i++ ) {
rm.addValueMeta( valuesMeta[i] );
}
return rm;
}
/**
* Create data rows.
*
* @return List of row and meta data
*/
public List<RowMetaAndData> createData1() {
List<RowMetaAndData> list = new ArrayList<RowMetaAndData>();
RowMetaInterface rm = createRowMetaInterface();
Object[] r1 = new Object[] { "abcdef", "ghijkl" };
list.add( new RowMetaAndData( rm, r1 ) );
return list.subList( 0, 1 );
}
public List<RowMetaAndData> createResultData1() {
List<RowMetaAndData> list = new ArrayList<RowMetaAndData>();
RowMetaInterface rm = createResultRowMetaInterface1();
Object[] r1 = new Object[] { "abcdef", "ghijkl", "hi" };
list.add( new RowMetaAndData( rm, r1 ) );
return list.subList( 0, 1 );
}
public List<RowMetaAndData> createResultData2() {
List<RowMetaAndData> list = new ArrayList<RowMetaAndData>();
RowMetaInterface rm = createResultRowMetaInterface2();
Object[] r1 = new Object[] { "abcdef", "ghijkl", "a", "hi" };
list.add( new RowMetaAndData( rm, r1 ) );
return list.subList( 0, 1 );
}
/**
* This is a test for PDI-8042, where the first row of meta has no output field but the second does.
*/
@Test
public void testStringCut1() throws KettleException {
KettleEnvironment.init();
//
// Create a new transformation...
//
TransMeta transMeta = new TransMeta();
transMeta.setName( "stringcuttest1" );
PluginRegistry registry = PluginRegistry.getInstance();
//
// create an injector step...
//
String injectorStepname = "injector step";
InjectorMeta im = new InjectorMeta();
// Set the information of the injector.
String injectorPid = registry.getPluginId( StepPluginType.class, im );
StepMeta injectorStep = new StepMeta( injectorPid, injectorStepname, im );
transMeta.addStep( injectorStep );
//
// Create a dummy step 1
//
String dummyStepname1 = "dummy step 1";
DummyTransMeta dm1 = new DummyTransMeta();
String dummyPid1 = registry.getPluginId( StepPluginType.class, dm1 );
StepMeta dummyStep1 = new StepMeta( dummyPid1, dummyStepname1, dm1 );
transMeta.addStep( dummyStep1 );
TransHopMeta hi = new TransHopMeta( injectorStep, dummyStep1 );
transMeta.addTransHop( hi );
//
// Create a String Cut step
//
String stringcutStepname = "string cut step";
StringCutMeta scm = new StringCutMeta();
scm.setFieldInStream( new String[] { "field1", "field2" } );
scm.setFieldOutStream( new String[] { null, "outf3" } );
scm.setCutFrom( new String[] { null, "1" } );
scm.setCutTo( new String[] { null, "3" } );
String stringCutStepPid = registry.getPluginId( StepPluginType.class, scm );
StepMeta stringCutStep = new StepMeta( stringCutStepPid, stringcutStepname, scm );
transMeta.addStep( stringCutStep );
TransHopMeta hi2 = new TransHopMeta( dummyStep1, stringCutStep );
transMeta.addTransHop( hi2 );
//
// Create a dummy step 2
//
String dummyStepname2 = "dummy step 2";
DummyTransMeta dm2 = new DummyTransMeta();
String dummyPid2 = registry.getPluginId( StepPluginType.class, dm2 );
StepMeta dummyStep2 = new StepMeta( dummyPid2, dummyStepname2, dm2 );
transMeta.addStep( dummyStep2 );
TransHopMeta hi3 = new TransHopMeta( stringCutStep, dummyStep2 );
transMeta.addTransHop( hi3 );
// Now execute the transformation...
Trans trans = new Trans( transMeta );
trans.prepareExecution( null );
StepInterface si = trans.getStepInterface( dummyStepname1, 0 );
RowStepCollector dummyRc1 = new RowStepCollector();
si.addRowListener( dummyRc1 );
si = trans.getStepInterface( stringcutStepname, 0 );
RowStepCollector stringCutRc = new RowStepCollector();
si.addRowListener( stringCutRc );
RowProducer rp = trans.addRowProducer( injectorStepname, 0 );
trans.startThreads();
// add rows
List<RowMetaAndData> inputList = createData1();
Iterator<RowMetaAndData> it = inputList.iterator();
while ( it.hasNext() ) {
RowMetaAndData rm = it.next();
rp.putRow( rm.getRowMeta(), rm.getData() );
}
rp.finished();
trans.waitUntilFinished();
List<RowMetaAndData> resultRows1 = dummyRc1.getRowsRead();
checkRows( resultRows1, inputList );
List<RowMetaAndData> goldRows = createResultData1();
List<RowMetaAndData> resultRows2 = stringCutRc.getRowsWritten();
checkRows( resultRows2, goldRows );
}
/**
* This is a generic test using two input fields and different cuts for each
*/
@Test
public void testStringCut2() throws KettleException {
KettleEnvironment.init();
//
// Create a new transformation...
//
TransMeta transMeta = new TransMeta();
transMeta.setName( "stringcuttest1" );
PluginRegistry registry = PluginRegistry.getInstance();
//
// create an injector step...
//
String injectorStepname = "injector step";
InjectorMeta im = new InjectorMeta();
// Set the information of the injector.
String injectorPid = registry.getPluginId( StepPluginType.class, im );
StepMeta injectorStep = new StepMeta( injectorPid, injectorStepname, im );
transMeta.addStep( injectorStep );
//
// Create a dummy step 1
//
String dummyStepname1 = "dummy step 1";
DummyTransMeta dm1 = new DummyTransMeta();
String dummyPid1 = registry.getPluginId( StepPluginType.class, dm1 );
StepMeta dummyStep1 = new StepMeta( dummyPid1, dummyStepname1, dm1 );
transMeta.addStep( dummyStep1 );
TransHopMeta hi = new TransHopMeta( injectorStep, dummyStep1 );
transMeta.addTransHop( hi );
//
// Create a String Cut step
//
String stringcutStepname = "string cut step";
StringCutMeta scm = new StringCutMeta();
scm.setFieldInStream( new String[] { "field1", "field2" } );
scm.setFieldOutStream( new String[] { "outf3", "outf4" } );
scm.setCutFrom( new String[] { "0", "1" } );
scm.setCutTo( new String[] { "1", "3" } );
String stringCutStepPid = registry.getPluginId( StepPluginType.class, scm );
StepMeta stringCutStep = new StepMeta( stringCutStepPid, stringcutStepname, scm );
transMeta.addStep( stringCutStep );
TransHopMeta hi2 = new TransHopMeta( dummyStep1, stringCutStep );
transMeta.addTransHop( hi2 );
//
// Create a dummy step 2
//
String dummyStepname2 = "dummy step 2";
DummyTransMeta dm2 = new DummyTransMeta();
String dummyPid2 = registry.getPluginId( StepPluginType.class, dm2 );
StepMeta dummyStep2 = new StepMeta( dummyPid2, dummyStepname2, dm2 );
transMeta.addStep( dummyStep2 );
TransHopMeta hi3 = new TransHopMeta( stringCutStep, dummyStep2 );
transMeta.addTransHop( hi3 );
// Now execute the transformation...
Trans trans = new Trans( transMeta );
trans.prepareExecution( null );
StepInterface si = trans.getStepInterface( dummyStepname1, 0 );
RowStepCollector dummyRc1 = new RowStepCollector();
si.addRowListener( dummyRc1 );
si = trans.getStepInterface( stringcutStepname, 0 );
RowStepCollector stringCutRc = new RowStepCollector();
si.addRowListener( stringCutRc );
RowProducer rp = trans.addRowProducer( injectorStepname, 0 );
trans.startThreads();
// add rows
List<RowMetaAndData> inputList = createData1();
Iterator<RowMetaAndData> it = inputList.iterator();
while ( it.hasNext() ) {
RowMetaAndData rm = it.next();
rp.putRow( rm.getRowMeta(), rm.getData() );
}
rp.finished();
trans.waitUntilFinished();
List<RowMetaAndData> resultRows1 = dummyRc1.getRowsRead();
checkRows( resultRows1, inputList );
List<RowMetaAndData> goldRows = createResultData2();
List<RowMetaAndData> resultRows2 = stringCutRc.getRowsWritten();
checkRows( resultRows2, goldRows );
}
/**
* This is a generic test using two input fields and different cuts for each
*/
public void testPDI11236() throws KettleException {
KettleEnvironment.init();
//
// Create a new transformation...
//
TransMeta transMeta = new TransMeta();
transMeta.setName( "stringcuttest3" );
PluginRegistry registry = PluginRegistry.getInstance();
//
// create an injector step...
//
String injectorStepname = "injector step";
InjectorMeta im = new InjectorMeta();
// Set the information of the injector.
String injectorPid = registry.getPluginId( StepPluginType.class, im );
StepMeta injectorStep = new StepMeta( injectorPid, injectorStepname, im );
transMeta.addStep( injectorStep );
//
// Create a dummy step 1
//
String dummyStepname1 = "dummy step 1";
DummyTransMeta dm1 = new DummyTransMeta();
String dummyPid1 = registry.getPluginId( StepPluginType.class, dm1 );
StepMeta dummyStep1 = new StepMeta( dummyPid1, dummyStepname1, dm1 );
transMeta.addStep( dummyStep1 );
TransHopMeta hi = new TransHopMeta( injectorStep, dummyStep1 );
transMeta.addTransHop( hi );
//
// Create a String Cut step
//
String stringcutStepname = "string cut step";
StringCutMeta scm = new StringCutMeta();
scm.setFieldInStream( new String[] { "field1", "field1" } );
scm.setFieldOutStream( new String[] { "", "field1" } );
scm.setCutFrom( new String[] { "1", "0" } );
scm.setCutTo( new String[] { "3", "1" } );
String stringCutStepPid = registry.getPluginId( StepPluginType.class, scm );
StepMeta stringCutStep = new StepMeta( stringCutStepPid, stringcutStepname, scm );
transMeta.addStep( stringCutStep );
TransHopMeta hi2 = new TransHopMeta( dummyStep1, stringCutStep );
transMeta.addTransHop( hi2 );
//
// Create a dummy step 2
//
String dummyStepname2 = "dummy step 2";
DummyTransMeta dm2 = new DummyTransMeta();
String dummyPid2 = registry.getPluginId( StepPluginType.class, dm2 );
StepMeta dummyStep2 = new StepMeta( dummyPid2, dummyStepname2, dm2 );
transMeta.addStep( dummyStep2 );
TransHopMeta hi3 = new TransHopMeta( stringCutStep, dummyStep2 );
transMeta.addTransHop( hi3 );
// Now execute the transformation...
Trans trans = new Trans( transMeta );
trans.prepareExecution( null );
StepInterface si = trans.getStepInterface( dummyStepname1, 0 );
RowStepCollector dummyRc1 = new RowStepCollector();
si.addRowListener( dummyRc1 );
si = trans.getStepInterface( stringcutStepname, 0 );
RowStepCollector stringCutRc = new RowStepCollector();
si.addRowListener( stringCutRc );
RowProducer rp = trans.addRowProducer( injectorStepname, 0 );
trans.startThreads();
// add rows
List<RowMetaAndData> inputList = createDataBinary();
Iterator<RowMetaAndData> it = inputList.iterator();
while ( it.hasNext() ) {
RowMetaAndData rm = it.next();
rp.putRow( rm.getRowMeta(), rm.getData() );
}
rp.finished();
trans.waitUntilFinished();
List<RowMetaAndData> resultRows1 = dummyRc1.getRowsRead();
checkRows( resultRows1, inputList );
List<RowMetaAndData> goldRows = createBinaryResultData();
List<RowMetaAndData> resultRows2 = stringCutRc.getRowsWritten();
checkRows( resultRows2, goldRows );
}
private List<RowMetaAndData> createDataBinary() {
List<RowMetaAndData> list = new ArrayList<RowMetaAndData>();
RowMetaInterface rm = createBinaryRowMetaInterface();
Object[] r1 = new Object[] { "abcdef".getBytes(), "ghijkl".getBytes() };
list.add( new RowMetaAndData( rm, r1 ) );
return list.subList( 0, 1 );
}
private RowMetaInterface createBinaryRowMetaInterface() {
RowMetaInterface rm = new RowMeta();
ValueMetaInterface[] valuesMeta =
{ new ValueMetaString( "field1" ), new ValueMetaString( "field2" ), };
for ( int i = 0; i < valuesMeta.length; i++ ) {
valuesMeta[i].setStorageMetadata( createRowMetaInterface().getValueMeta( i ) );
valuesMeta[i].setStorageType( ValueMetaInterface.STORAGE_TYPE_BINARY_STRING );
rm.addValueMeta( valuesMeta[i] );
}
return rm;
}
private RowMetaInterface createBinaryResultRowMetaInterface() {
RowMetaInterface rm = new RowMeta();
ValueMetaInterface[] valuesMeta =
{ new ValueMetaString( "field1" ), new ValueMetaString( "field2" ),
new ValueMetaString( "field1_1" ), };
valuesMeta[1].setStorageMetadata( createRowMetaInterface().getValueMeta( 1 ) );
valuesMeta[1].setStorageType( ValueMetaInterface.STORAGE_TYPE_BINARY_STRING );
for ( ValueMetaInterface aValuesMeta : valuesMeta ) {
rm.addValueMeta( aValuesMeta );
}
return rm;
}
public List<RowMetaAndData> createBinaryResultData() {
List<RowMetaAndData> list = new ArrayList<RowMetaAndData>();
RowMetaInterface rm = createBinaryResultRowMetaInterface();
Object[] r1 = new Object[] { "bc", "ghijkl".getBytes(), "a" };
// Now not used row but it seems to be such result in
// conversion work with ReplaceString and StringOperations
// Object[] r2 = new Object[] { "bc", "ghijkl".getBytes(), "b" };
list.add( new RowMetaAndData( rm, r1 ) );
return list.subList( 0, 1 );
}
}