/*! ******************************************************************************
*
* 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.validator;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.pentaho.di.core.Const;
import org.pentaho.di.core.util.Utils;
import org.pentaho.di.core.RowSet;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.core.exception.KettlePluginException;
import org.pentaho.di.core.exception.KettleStepException;
import org.pentaho.di.core.exception.KettleValueException;
import org.pentaho.di.core.row.RowMetaInterface;
import org.pentaho.di.core.row.ValueMetaInterface;
import org.pentaho.di.core.row.value.ValueMetaFactory;
import org.pentaho.di.i18n.BaseMessages;
import org.pentaho.di.trans.Trans;
import org.pentaho.di.trans.TransMeta;
import org.pentaho.di.trans.step.BaseStep;
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.StepMetaDataCombi;
import org.pentaho.di.trans.step.StepMetaInterface;
import org.pentaho.di.trans.step.errorhandling.StreamInterface;
/**
* Calculate new field values using pre-defined functions.
*
* @author Matt
* @since 8-sep-2005
*/
public class Validator extends BaseStep implements StepInterface {
private static Class<?> PKG = ValidatorMeta.class; // for i18n purposes, needed by Translator2!!
public class FieldIndexes {
public int indexName;
public int indexA;
public int indexB;
public int indexC;
}
private ValidatorMeta meta;
private ValidatorData data;
public Validator( StepMeta stepMeta, StepDataInterface stepDataInterface, int copyNr, TransMeta transMeta,
Trans trans ) {
super( stepMeta, stepDataInterface, copyNr, transMeta, trans );
}
public boolean processRow( StepMetaInterface smi, StepDataInterface sdi ) throws KettleException {
meta = (ValidatorMeta) smi;
data = (ValidatorData) sdi;
Object[] r;
if ( first ) {
first = false;
readSourceValuesFromInfoSteps();
// Read the row AFTER the info rows
// That way the info-rowsets are out of the way
//
r = getRow(); // get row, set busy!
if ( r == null ) { // no more input to be expected...
setOutputDone();
return false;
}
data.fieldIndexes = new int[meta.getValidations().size()];
// Calculate the indexes of the values and arguments in the target data or temporary data
// We do this in advance to save time later on.
//
for ( int i = 0; i < meta.getValidations().size(); i++ ) {
Validation field = meta.getValidations().get( i );
if ( !Utils.isEmpty( field.getFieldName() ) ) {
data.fieldIndexes[i] = getInputRowMeta().indexOfValue( field.getFieldName() );
if ( data.fieldIndexes[i] < 0 ) {
// Nope: throw an exception
throw new KettleStepException( "Unable to find the specified fieldname '"
+ field.getFieldName() + "' for validation#" + ( i + 1 ) );
}
} else {
throw new KettleStepException( "There is no name specified for validator field #" + ( i + 1 ) );
}
}
} else {
// Read the row AFTER the info rows
// That way the info-rowsets are out of the way
//
r = getRow(); // get row, set busy!
if ( r == null ) { // no more input to be expected...
setOutputDone();
return false;
}
}
if ( log.isRowLevel() ) {
logRowlevel( "Read row #" + getLinesRead() + " : " + getInputRowMeta().getString( r ) );
}
try {
List<KettleValidatorException> exceptions = validateFields( getInputRowMeta(), r );
if ( exceptions.size() > 0 ) {
if ( getStepMeta().isDoingErrorHandling() ) {
if ( meta.isConcatenatingErrors() ) {
StringBuilder messages = new StringBuilder();
StringBuilder fields = new StringBuilder();
StringBuilder codes = new StringBuilder();
boolean notFirst = false;
for ( KettleValidatorException e : exceptions ) {
if ( notFirst ) {
messages.append( meta.getConcatenationSeparator() );
fields.append( meta.getConcatenationSeparator() );
codes.append( meta.getConcatenationSeparator() );
} else {
notFirst = true;
}
messages.append( e.getMessage() );
fields.append( e.getFieldname() );
codes.append( e.getCodeDesc() );
}
putError( getInputRowMeta(), r, exceptions.size(), messages.toString(), fields.toString(), codes
.toString() );
} else {
for ( KettleValidatorException e : exceptions ) {
putError( getInputRowMeta(), r, 1, e.getMessage(), e.getFieldname(), e.getCodeDesc() );
}
}
} else {
KettleValidatorException e = exceptions.get( 0 );
throw new KettleException( e.getMessage(), e );
}
} else {
putRow( getInputRowMeta(), r ); // copy row to possible alternate rowset(s).
}
} catch ( KettleValidatorException e ) {
if ( getStepMeta().isDoingErrorHandling() ) {
putError( getInputRowMeta(), r, 1, e.getMessage(), e.getFieldname(), e.getCodeDesc() );
} else {
throw new KettleException( e.getMessage(), e );
}
}
if ( log.isRowLevel() ) {
logRowlevel( "Wrote row #" + getLinesWritten() + " : " + getInputRowMeta().getString( r ) );
}
if ( checkFeedback( getLinesRead() ) ) {
logBasic( "Linenr " + getLinesRead() );
}
return true;
}
private void readSourceValuesFromInfoSteps() throws KettleStepException {
for ( int i = 0; i < meta.getValidations().size(); i++ ) {
Validation field = meta.getValidations().get( i );
List<StreamInterface> streams = meta.getStepIOMeta().getInfoStreams();
// If we need to source the allowed values data from a different step, we do this here as well
//
if ( field.isSourcingValues() ) {
if ( streams.get( i ).getStepMeta() == null ) {
throw new KettleStepException(
"There is no valid source step specified for the allowed values of validation ["
+ field.getName() + "]" );
}
if ( Utils.isEmpty( field.getSourcingField() ) ) {
throw new KettleStepException(
"There is no valid source field specified for the allowed values of validation ["
+ field.getName() + "]" );
}
// Still here : OK, read the data from the specified step...
// The data is stored in data.listValues[i] and data.constantsMeta
//
RowSet allowedRowSet = findInputRowSet( streams.get( i ).getStepname() );
int fieldIndex = -1;
List<Object> allowedValues = new ArrayList<Object>();
Object[] allowedRowData = getRowFrom( allowedRowSet );
while ( allowedRowData != null ) {
RowMetaInterface allowedRowMeta = allowedRowSet.getRowMeta();
if ( fieldIndex < 0 ) {
fieldIndex = allowedRowMeta.indexOfValue( field.getSourcingField() );
if ( fieldIndex < 0 ) {
throw new KettleStepException( "Source field ["
+ field.getSourcingField() + "] is not found in the source row data" );
}
data.constantsMeta[i] = allowedRowMeta.getValueMeta( fieldIndex );
}
Object allowedValue = allowedRowData[fieldIndex];
if ( allowedValue != null ) {
allowedValues.add( allowedValue );
}
// Grab another row too...
//
allowedRowData = getRowFrom( allowedRowSet );
}
// Set the list values in the data block...
//
data.listValues[i] = allowedValues.toArray( new Object[allowedValues.size()] );
}
}
}
/**
* @param inputRowMeta the input row metadata
* @param r the input row (data)
* @throws KettleValidatorException in case there is a validation error, details are stored in the exception.
*/
private List<KettleValidatorException> validateFields( RowMetaInterface inputRowMeta, Object[] r ) throws KettleValueException {
List<KettleValidatorException> exceptions = new ArrayList<KettleValidatorException>();
for ( int i = 0; i < meta.getValidations().size(); i++ ) {
Validation field = meta.getValidations().get( i );
int valueIndex = data.fieldIndexes[i];
ValueMetaInterface validatorMeta = data.constantsMeta[i];
ValueMetaInterface valueMeta = inputRowMeta.getValueMeta( valueIndex );
Object valueData = r[valueIndex];
// Check for null
//
boolean isNull = valueMeta.isNull( valueData );
if ( !field.isNullAllowed() && isNull ) {
KettleValidatorException exception =
new KettleValidatorException(
this,
field,
KettleValidatorException.ERROR_NULL_VALUE_NOT_ALLOWED,
BaseMessages.getString(
PKG, "Validator.Exception.NullNotAllowed", field.getFieldName(), inputRowMeta.getString( r ) ),
field.getFieldName() );
exceptions.add( exception );
if ( !meta.isValidatingAll() ) {
return exceptions;
}
}
if ( field.isOnlyNullAllowed() && !isNull ) {
KettleValidatorException exception =
new KettleValidatorException(
this,
field,
KettleValidatorException.ERROR_ONLY_NULL_VALUE_ALLOWED,
BaseMessages.getString(
PKG, "Validator.Exception.OnlyNullAllowed", field.getFieldName(), inputRowMeta.getString( r ) ),
field.getFieldName() );
exceptions.add( exception );
if ( !meta.isValidatingAll() ) {
return exceptions;
}
}
// Check the data type!
//
if ( field.isDataTypeVerified() && field.getDataType() != ValueMetaInterface.TYPE_NONE ) {
// Same data type?
//
if ( field.getDataType() != valueMeta.getType() ) {
KettleValidatorException exception =
new KettleValidatorException(
this, field, KettleValidatorException.ERROR_UNEXPECTED_DATA_TYPE, BaseMessages.getString(
PKG, "Validator.Exception.UnexpectedDataType", field.getFieldName(), valueMeta
.toStringMeta(), validatorMeta.toStringMeta() ), field.getFieldName() );
exceptions.add( exception );
if ( !meta.isValidatingAll() ) {
return exceptions;
}
}
}
// Check various things if the value is not null..
//
if ( !isNull ) {
if ( data.fieldsMinimumLengthAsInt[i] >= 0
|| data.fieldsMaximumLengthAsInt[i] >= 0 || data.minimumValue[i] != null
|| data.maximumValue[i] != null || data.listValues[i].length > 0 || field.isSourcingValues()
|| !Utils.isEmpty( data.startString[i] ) || !Utils.isEmpty( data.endString[i] )
|| !Utils.isEmpty( data.startStringNotAllowed[i] ) || !Utils.isEmpty( data.endStringNotAllowed[i] )
|| field.isOnlyNumericAllowed() || data.patternExpected[i] != null
|| data.patternDisallowed[i] != null ) {
String stringValue = valueMeta.getString( valueData );
int stringLength = stringValue.length();
// Minimum length
//
// if (field.getMinimumLength()>=0 && stringValue.length()<field.getMinimumLength() ) {
if ( data.fieldsMinimumLengthAsInt[i] >= 0 && stringLength < data.fieldsMinimumLengthAsInt[i] ) {
KettleValidatorException exception =
new KettleValidatorException(
this, field, KettleValidatorException.ERROR_SHORTER_THAN_MINIMUM_LENGTH, BaseMessages
.getString(
PKG, "Validator.Exception.ShorterThanMininumLength", field.getFieldName(), valueMeta
.getString( valueData ), Integer.toString( stringValue.length() ), field
.getMinimumLength() ), field.getFieldName() );
exceptions.add( exception );
if ( !meta.isValidatingAll() ) {
return exceptions;
}
}
// Maximum length
//
// if (field.getMaximumLength()>=0 && stringValue.length()>field.getMaximumLength() ) {
if ( data.fieldsMaximumLengthAsInt[i] >= 0 && stringLength > data.fieldsMaximumLengthAsInt[i] ) {
KettleValidatorException exception =
new KettleValidatorException(
this, field, KettleValidatorException.ERROR_LONGER_THAN_MAXIMUM_LENGTH, BaseMessages
.getString(
PKG, "Validator.Exception.LongerThanMaximumLength", field.getFieldName(), valueMeta
.getString( valueData ), Integer.toString( stringValue.length() ), field
.getMaximumLength() ), field.getFieldName() );
exceptions.add( exception );
if ( !meta.isValidatingAll() ) {
return exceptions;
}
}
// Minimal value
//
if ( data.minimumValue[i] != null
&& valueMeta.compare( valueData, validatorMeta, data.minimumValue[i] ) < 0 ) {
KettleValidatorException exception =
new KettleValidatorException(
this, field, KettleValidatorException.ERROR_LOWER_THAN_ALLOWED_MINIMUM,
BaseMessages.getString(
PKG, "Validator.Exception.LowerThanMinimumValue", field.getFieldName(), valueMeta
.getString( valueData ), data.constantsMeta[i].getString( data.minimumValue[i] ) ),
field.getFieldName() );
exceptions.add( exception );
if ( !meta.isValidatingAll() ) {
return exceptions;
}
}
// Maximum value
//
if ( data.maximumValue[i] != null
&& valueMeta.compare( valueData, validatorMeta, data.maximumValue[i] ) > 0 ) {
KettleValidatorException exception =
new KettleValidatorException(
this, field, KettleValidatorException.ERROR_HIGHER_THAN_ALLOWED_MAXIMUM,
BaseMessages.getString( PKG, "Validator.Exception.HigherThanMaximumValue", field
.getFieldName(), valueMeta.getString( valueData ), data.constantsMeta[i]
.getString( data.maximumValue[i] ) ), field.getFieldName() );
exceptions.add( exception );
if ( !meta.isValidatingAll() ) {
return exceptions;
}
}
// In list?
//
if ( field.isSourcingValues() || data.listValues[i].length > 0 ) {
boolean found = false;
for ( Object object : data.listValues[i] ) {
if ( object != null
&& data.listValues[i] != null && valueMeta.compare( valueData, validatorMeta, object ) == 0 ) {
found = true;
}
}
if ( !found ) {
KettleValidatorException exception =
new KettleValidatorException(
this, field, KettleValidatorException.ERROR_VALUE_NOT_IN_LIST, BaseMessages.getString(
PKG, "Validator.Exception.NotInList", field.getFieldName(), valueMeta
.getString( valueData ) ), field.getFieldName() );
exceptions.add( exception );
if ( !meta.isValidatingAll() ) {
return exceptions;
}
}
}
// Numeric data or strings with only
if ( field.isOnlyNumericAllowed() ) {
KettleValidatorException exception = assertNumeric( valueMeta, valueData, field );
if ( exception != null ) {
exceptions.add( exception );
if ( !meta.isValidatingAll() ) {
return exceptions;
}
}
}
// Does not start with string value
//
if ( !Utils.isEmpty( data.startString[i] ) && !stringValue.startsWith( data.startString[i] ) ) {
KettleValidatorException exception =
new KettleValidatorException(
this, field, KettleValidatorException.ERROR_DOES_NOT_START_WITH_STRING, BaseMessages
.getString(
PKG, "Validator.Exception.DoesNotStartWithString", field.getFieldName(), valueMeta
.getString( valueData ), field.getStartString() ), field.getFieldName() );
exceptions.add( exception );
if ( !meta.isValidatingAll() ) {
return exceptions;
}
}
// Ends with string value
//
if ( !Utils.isEmpty( data.endString[i] ) && !stringValue.endsWith( data.endString[i] ) ) {
KettleValidatorException exception =
new KettleValidatorException(
this, field, KettleValidatorException.ERROR_DOES_NOT_END_WITH_STRING, BaseMessages.getString(
PKG, "Validator.Exception.DoesNotStartWithString", field.getFieldName(), valueMeta
.getString( valueData ), field.getEndString() ), field.getFieldName() );
exceptions.add( exception );
if ( !meta.isValidatingAll() ) {
return exceptions;
}
}
// Starts with string value
//
if ( !Utils.isEmpty( data.startStringNotAllowed[i] )
&& stringValue.startsWith( data.startStringNotAllowed[i] ) ) {
KettleValidatorException exception =
new KettleValidatorException(
this, field, KettleValidatorException.ERROR_STARTS_WITH_STRING, BaseMessages.getString(
PKG, "Validator.Exception.StartsWithString", field.getFieldName(), valueMeta
.getString( valueData ), field.getStartStringNotAllowed() ), field.getFieldName() );
exceptions.add( exception );
if ( !meta.isValidatingAll() ) {
return exceptions;
}
}
// Ends with string value
//
if ( !Utils.isEmpty( data.endStringNotAllowed[i] ) && stringValue.endsWith( data.endStringNotAllowed[i] ) ) {
KettleValidatorException exception =
new KettleValidatorException(
this, field, KettleValidatorException.ERROR_ENDS_WITH_STRING, BaseMessages.getString(
PKG, "Validator.Exception.EndsWithString", field.getFieldName(), valueMeta
.getString( valueData ), field.getEndStringNotAllowed() ), field.getFieldName() );
exceptions.add( exception );
if ( !meta.isValidatingAll() ) {
return exceptions;
}
}
// Matching regular expression allowed?
//
if ( data.patternExpected[i] != null ) {
Matcher matcher = data.patternExpected[i].matcher( stringValue );
if ( !matcher.matches() ) {
KettleValidatorException exception =
new KettleValidatorException(
this, field, KettleValidatorException.ERROR_MATCHING_REGULAR_EXPRESSION_EXPECTED,
BaseMessages.getString( PKG, "Validator.Exception.MatchingRegExpExpected", field
.getFieldName(), valueMeta.getString( valueData ), data.regularExpression[i] ), field
.getFieldName() );
exceptions.add( exception );
if ( !meta.isValidatingAll() ) {
return exceptions;
}
}
}
// Matching regular expression NOT allowed?
//
if ( data.patternDisallowed[i] != null ) {
Matcher matcher = data.patternDisallowed[i].matcher( stringValue );
if ( matcher.matches() ) {
KettleValidatorException exception =
new KettleValidatorException(
this,
field,
KettleValidatorException.ERROR_MATCHING_REGULAR_EXPRESSION_NOT_ALLOWED,
BaseMessages.getString( PKG, "Validator.Exception.MatchingRegExpNotAllowed", field
.getFieldName(), valueMeta.getString( valueData ), data.regularExpressionNotAllowed[i] ),
field.getFieldName() );
exceptions.add( exception );
if ( !meta.isValidatingAll() ) {
return exceptions;
}
}
}
}
}
}
return exceptions;
}
// package-local visibility for testing purposes
KettleValidatorException assertNumeric( ValueMetaInterface valueMeta,
Object valueData,
Validation field ) throws KettleValueException {
if ( valueMeta.isNumeric() || containsOnlyDigits( valueMeta.getString( valueData ) ) ) {
return null;
}
return new KettleValidatorException( this, field, KettleValidatorException.ERROR_NON_NUMERIC_DATA,
BaseMessages.getString( PKG, "Validator.Exception.NonNumericDataNotAllowed", field.getFieldName(),
valueMeta.toStringMeta() ), field.getFieldName() );
}
private boolean containsOnlyDigits( String string ) {
for ( char c : string.toCharArray() ) {
if ( c < '0' || c > '9' ) {
return false;
}
}
return true;
}
public boolean init( StepMetaInterface smi, StepDataInterface sdi ) {
meta = (ValidatorMeta) smi;
data = (ValidatorData) sdi;
if ( super.init( smi, sdi ) ) {
// initialize steps by names
List<StepMeta> steps = new ArrayList<>();
for ( StepMetaDataCombi s : getTrans().getSteps() ) {
steps.add( s.stepMeta );
}
meta.searchInfoAndTargetSteps( steps );
// initialize arrays of validation data
data.constantsMeta = new ValueMetaInterface[meta.getValidations().size()];
data.minimumValueAsString = new String[meta.getValidations().size()];
data.maximumValueAsString = new String[meta.getValidations().size()];
data.fieldsMinimumLengthAsInt = new int[meta.getValidations().size()];
data.fieldsMaximumLengthAsInt = new int[meta.getValidations().size()];
data.minimumValue = new Object[meta.getValidations().size()];
data.maximumValue = new Object[meta.getValidations().size()];
data.listValues = new Object[meta.getValidations().size()][];
data.errorCode = new String[meta.getValidations().size()];
data.errorDescription = new String[meta.getValidations().size()];
data.conversionMask = new String[meta.getValidations().size()];
data.decimalSymbol = new String[meta.getValidations().size()];
data.groupingSymbol = new String[meta.getValidations().size()];
data.maximumLength = new String[meta.getValidations().size()];
data.minimumLength = new String[meta.getValidations().size()];
data.startString = new String[meta.getValidations().size()];
data.endString = new String[meta.getValidations().size()];
data.startStringNotAllowed = new String[meta.getValidations().size()];
data.endStringNotAllowed = new String[meta.getValidations().size()];
data.regularExpression = new String[meta.getValidations().size()];
data.regularExpressionNotAllowed = new String[meta.getValidations().size()];
data.patternExpected = new Pattern[meta.getValidations().size()];
data.patternDisallowed = new Pattern[meta.getValidations().size()];
for ( int i = 0; i < meta.getValidations().size(); i++ ) {
Validation field = meta.getValidations().get( i );
try {
data.constantsMeta[i] = createValueMeta( field.getFieldName(), field.getDataType() );
data.constantsMeta[i].setConversionMask( field.getConversionMask() );
data.constantsMeta[i].setDecimalSymbol( field.getDecimalSymbol() );
data.constantsMeta[i].setGroupingSymbol( field.getGroupingSymbol() );
data.errorCode[i] = environmentSubstitute( Const.NVL( field.getErrorCode(), "" ) );
data.errorDescription[i] = environmentSubstitute( Const.NVL( field.getErrorDescription(), "" ) );
data.conversionMask[i] = environmentSubstitute( Const.NVL( field.getConversionMask(), "" ) );
data.decimalSymbol[i] = environmentSubstitute( Const.NVL( field.getDecimalSymbol(), "" ) );
data.groupingSymbol[i] = environmentSubstitute( Const.NVL( field.getGroupingSymbol(), "" ) );
data.maximumLength[i] = environmentSubstitute( Const.NVL( field.getMaximumLength(), "" ) );
data.minimumLength[i] = environmentSubstitute( Const.NVL( field.getMinimumLength(), "" ) );
data.maximumValueAsString[i] = environmentSubstitute( Const.NVL( field.getMaximumValue(), "" ) );
data.minimumValueAsString[i] = environmentSubstitute( Const.NVL( field.getMinimumValue(), "" ) );
data.startString[i] = environmentSubstitute( Const.NVL( field.getStartString(), "" ) );
data.endString[i] = environmentSubstitute( Const.NVL( field.getEndString(), "" ) );
data.startStringNotAllowed[i] =
environmentSubstitute( Const.NVL( field.getStartStringNotAllowed(), "" ) );
data.endStringNotAllowed[i] = environmentSubstitute( Const.NVL( field.getEndStringNotAllowed(), "" ) );
data.regularExpression[i] = environmentSubstitute( Const.NVL( field.getRegularExpression(), "" ) );
data.regularExpressionNotAllowed[i] =
environmentSubstitute( Const.NVL( field.getRegularExpressionNotAllowed(), "" ) );
ValueMetaInterface stringMeta = cloneValueMeta( data.constantsMeta[i], ValueMetaInterface.TYPE_STRING );
data.minimumValue[i] =
Utils.isEmpty( data.minimumValueAsString[i] ) ? null : data.constantsMeta[i].convertData(
stringMeta, data.minimumValueAsString[i] );
data.maximumValue[i] =
Utils.isEmpty( data.maximumValueAsString[i] ) ? null : data.constantsMeta[i].convertData(
stringMeta, data.maximumValueAsString[i] );
try {
data.fieldsMinimumLengthAsInt[i] = Integer.valueOf( Const.NVL( data.minimumLength[i], "-1" ) );
} catch ( NumberFormatException nfe ) {
throw new KettleValueException(
"Caught a number format exception converting minimum length with value "
+ data.minimumLength[i] + " to an int.", nfe );
}
try {
data.fieldsMaximumLengthAsInt[i] = Integer.valueOf( Const.NVL( data.maximumLength[i], "-1" ) );
} catch ( NumberFormatException nfe ) {
throw new KettleValueException(
"Caught a number format exception converting minimum length with value "
+ data.maximumLength[i] + " to an int.", nfe );
}
int listSize = field.getAllowedValues() != null ? field.getAllowedValues().length : 0;
data.listValues[i] = new Object[listSize];
for ( int s = 0; s < listSize; s++ ) {
data.listValues[i][s] =
Utils.isEmpty( field.getAllowedValues()[s] ) ? null : data.constantsMeta[i].convertData(
stringMeta, environmentSubstitute( field.getAllowedValues()[s] ) );
}
} catch ( KettleException e ) {
if ( field.getDataType() == ValueMetaInterface.TYPE_NONE ) {
logError( BaseMessages.getString( PKG, "Validator.Exception.SpecifyDataType" ), e );
} else {
logError( BaseMessages.getString( PKG, "Validator.Exception.DataConversionErrorEncountered" ), e );
}
return false;
}
if ( !Utils.isEmpty( data.regularExpression[i] ) ) {
data.patternExpected[i] = Pattern.compile( data.regularExpression[i] );
}
if ( !Utils.isEmpty( data.regularExpressionNotAllowed[i] ) ) {
data.patternDisallowed[i] = Pattern.compile( data.regularExpressionNotAllowed[i] );
}
}
return true;
}
return false;
}
protected ValueMetaInterface createValueMeta( String name, int type ) throws KettlePluginException {
return ValueMetaFactory.createValueMeta( name, type );
}
protected ValueMetaInterface cloneValueMeta( ValueMetaInterface valueMeta, int type ) throws KettlePluginException {
return ValueMetaFactory.cloneValueMeta( valueMeta, type );
}
}