/*! ****************************************************************************** * * 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.symmetriccrypto.symmetriccryptotrans; import java.util.List; import org.pentaho.di.core.CheckResult; import org.pentaho.di.core.CheckResultInterface; import org.pentaho.di.core.Const; import org.pentaho.di.core.util.Utils; import org.pentaho.di.core.database.DatabaseMeta; import org.pentaho.di.core.encryption.Encr; 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.RowMetaInterface; import org.pentaho.di.core.row.ValueMetaInterface; import org.pentaho.di.core.row.value.ValueMetaFactory; 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.ObjectId; import org.pentaho.di.repository.Repository; 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.pentaho.di.trans.steps.symmetriccrypto.symmetricalgorithm.SymmetricCryptoMeta; import org.pentaho.metastore.api.IMetaStore; import org.w3c.dom.Node; /** * Symmetric algorithm Executes a SymmetricCryptoTrans on the values in the input stream. Selected calculated values can * then be put on the output stream. * * @author Samatar * @since 5-apr-2003 * */ public class SymmetricCryptoTransMeta extends BaseStepMeta implements StepMetaInterface { private static Class<?> PKG = SymmetricCryptoTransMeta.class; // for i18n purposes, needed by Translator2!! /** Operations type */ private int operationType; /** * The operations description */ public static final String[] operationTypeDesc = { BaseMessages.getString( PKG, "SymmetricCryptoTransMeta.operationType.Encrypt" ), BaseMessages.getString( PKG, "SymmetricCryptoTransMeta.operationType.Decrypt" ) }; /** * The operations type codes */ public static final String[] operationTypeCode = { "encrypt", "decrypt" }; public static final int OPERATION_TYPE_ENCRYPT = 0; public static final int OPERATION_TYPE_DECRYPT = 1; private String algorithm; private String schema; private String messageField; private String secretKey; private boolean secretKeyInField; private String secretKeyField; private String resultfieldname; private boolean readKeyAsBinary; private boolean outputResultAsBinary; public SymmetricCryptoTransMeta() { super(); // allocate BaseStepMeta } private static int getOperationTypeByCode( String tt ) { if ( tt == null ) { return 0; } for ( int i = 0; i < operationTypeCode.length; i++ ) { if ( operationTypeCode[i].equalsIgnoreCase( tt ) ) { return i; } } return 0; } public int getOperationType() { return operationType; } public static int getOperationTypeByDesc( String tt ) { if ( tt == null ) { return 0; } for ( int i = 0; i < operationTypeDesc.length; i++ ) { if ( operationTypeDesc[i].equalsIgnoreCase( tt ) ) { return i; } } // If this fails, try to match using the code. return getOperationTypeByCode( tt ); } public void setOperationType( int operationType ) { this.operationType = operationType; } public static String getOperationTypeDesc( int i ) { if ( i < 0 || i >= operationTypeDesc.length ) { return operationTypeDesc[0]; } return operationTypeDesc[i]; } /** * @return Returns the XSL filename. */ public String getSecretKeyField() { return secretKeyField; } public void setSecretKey( String secretKeyin ) { this.secretKey = secretKeyin; } public String getSecretKey() { return secretKey; } public String getResultfieldname() { return resultfieldname; } /* * Get the Message Field name * * @deprecated use {@link #getMessageField()} instead. */ @Deprecated public String getMessageFied() { return getMessageField(); } /* * Get the Message Field name */ public String getMessageField() { return messageField; } public String getAlgorithm() { return algorithm; } /** * @param algorithm * The algorithm to set. */ public void setAlgorithm( String algorithm ) { this.algorithm = algorithm; } public boolean isReadKeyAsBinary() { return readKeyAsBinary; } /** * @param readKeyAsBinary * The readKeyAsBinary to set. */ public void setReadKeyAsBinary( boolean readKeyAsBinary ) { this.readKeyAsBinary = readKeyAsBinary; } public boolean isOutputResultAsBinary() { return outputResultAsBinary; } /** * @param outputResultAsBinary * The outputResultAsBinary to set. */ public void setOutputResultAsBinary( boolean outputResultAsBinary ) { this.outputResultAsBinary = outputResultAsBinary; } public String getSchema() { return schema; } /** * @param schema * The schema to set. */ public void setSchema( String schema ) { this.schema = schema; } /** * @param secretKeyField * The secretKeyField to set. */ public void setsecretKeyField( String secretKeyField ) { this.secretKeyField = secretKeyField; } public void setResultfieldname( String resultfield ) { this.resultfieldname = resultfield; } public void setMessageField( String fieldnamein ) { this.messageField = fieldnamein; } public void loadXML( Node stepnode, List<DatabaseMeta> databases, IMetaStore metaStore ) throws KettleXMLException { readData( stepnode ); } public Object clone() { SymmetricCryptoTransMeta retval = (SymmetricCryptoTransMeta) super.clone(); return retval; } public boolean isSecretKeyInField() { return secretKeyInField; } public void setSecretKeyInField( boolean secretKeyInField ) { this.secretKeyInField = secretKeyInField; } private void readData( Node stepnode ) throws KettleXMLException { try { operationType = getOperationTypeByCode( Const.NVL( XMLHandler.getTagValue( stepnode, "operation_type" ), "" ) ); algorithm = XMLHandler.getTagValue( stepnode, "algorithm" ); schema = XMLHandler.getTagValue( stepnode, "schema" ); secretKeyField = XMLHandler.getTagValue( stepnode, "secretKeyField" ); messageField = XMLHandler.getTagValue( stepnode, "messageField" ); resultfieldname = XMLHandler.getTagValue( stepnode, "resultfieldname" ); setSecretKey( Encr.decryptPasswordOptionallyEncrypted( XMLHandler.getTagValue( stepnode, "secretKey" ) ) ); secretKeyInField = "Y".equalsIgnoreCase( XMLHandler.getTagValue( stepnode, "secretKeyInField" ) ); readKeyAsBinary = "Y".equalsIgnoreCase( XMLHandler.getTagValue( stepnode, "readKeyAsBinary" ) ); outputResultAsBinary = "Y".equalsIgnoreCase( XMLHandler.getTagValue( stepnode, "outputResultAsBinary" ) ); } catch ( Exception e ) { throw new KettleXMLException( BaseMessages.getString( PKG, "SymmetricCryptoTransMeta.Exception.UnableToLoadStepInfoFromXML" ), e ); } } public void setDefault() { secretKeyField = null; messageField = null; resultfieldname = "result"; secretKey = null; secretKeyInField = false; operationType = OPERATION_TYPE_ENCRYPT; algorithm = SymmetricCryptoMeta.TYPE_ALGORYTHM_CODE[0]; schema = algorithm; readKeyAsBinary = false; outputResultAsBinary = false; } public void getFields( RowMetaInterface rowMeta, String origin, RowMetaInterface[] info, StepMeta nextStep, VariableSpace space, Repository repository, IMetaStore metaStore ) throws KettleStepException { if ( !Utils.isEmpty( getResultfieldname() ) ) { int type = ValueMetaInterface.TYPE_STRING; if ( isOutputResultAsBinary() ) { type = ValueMetaInterface.TYPE_BINARY; } try { ValueMetaInterface v = ValueMetaFactory.createValueMeta( getResultfieldname(), type ); v.setOrigin( origin ); rowMeta.addValueMeta( v ); } catch ( Exception e ) { throw new KettleStepException( e ); } } } public String getXML() { StringBuilder retval = new StringBuilder(); retval.append( " " + XMLHandler.addTagValue( "operation_type", getOperationTypeCode( operationType ) ) ); retval.append( " " + XMLHandler.addTagValue( "algorithm", algorithm ) ); retval.append( " " + XMLHandler.addTagValue( "schema", schema ) ); retval.append( " " + XMLHandler.addTagValue( "secretKeyField", secretKeyField ) ); retval.append( " " + XMLHandler.addTagValue( "messageField", messageField ) ); retval.append( " " + XMLHandler.addTagValue( "resultfieldname", resultfieldname ) ); retval.append( " " ).append( XMLHandler.addTagValue( "secretKey", Encr.encryptPasswordIfNotUsingVariables( secretKey ) ) ); retval.append( " " + XMLHandler.addTagValue( "secretKeyInField", secretKeyInField ) ); retval.append( " " + XMLHandler.addTagValue( "readKeyAsBinary", readKeyAsBinary ) ); retval.append( " " + XMLHandler.addTagValue( "outputResultAsBinary", outputResultAsBinary ) ); return retval.toString(); } public void readRep( Repository rep, IMetaStore metaStore, ObjectId id_step, List<DatabaseMeta> databases ) throws KettleException { try { operationType = getOperationTypeByCode( Const.NVL( rep.getStepAttributeString( id_step, "operation_type" ), "" ) ); algorithm = rep.getStepAttributeString( id_step, "algorithm" ); schema = rep.getStepAttributeString( id_step, "schema" ); secretKeyField = rep.getStepAttributeString( id_step, "secretKeyField" ); messageField = rep.getStepAttributeString( id_step, "messageField" ); resultfieldname = rep.getStepAttributeString( id_step, "resultfieldname" ); secretKey = Encr.decryptPasswordOptionallyEncrypted( rep.getStepAttributeString( id_step, "secretKey" ) ); secretKeyInField = rep.getStepAttributeBoolean( id_step, "secretKeyInField" ); readKeyAsBinary = rep.getStepAttributeBoolean( id_step, "readKeyAsBinary" ); outputResultAsBinary = rep.getStepAttributeBoolean( id_step, "outputResultAsBinary" ); } catch ( Exception e ) { throw new KettleException( BaseMessages.getString( PKG, "SymmetricCryptoTransMeta.Exception.UnexpectedErrorInReadingStepInfo" ), e ); } } private static String getOperationTypeCode( int i ) { if ( i < 0 || i >= operationTypeCode.length ) { return operationTypeCode[0]; } return operationTypeCode[i]; } public void saveRep( Repository rep, IMetaStore metaStore, ObjectId id_transformation, ObjectId id_step ) throws KettleException { try { rep.saveStepAttribute( id_transformation, id_step, "operation_type", getOperationTypeCode( operationType ) ); rep.saveStepAttribute( id_transformation, id_step, "algorithm", algorithm ); rep.saveStepAttribute( id_transformation, id_step, "schema", schema ); rep.saveStepAttribute( id_transformation, id_step, "secretKeyField", secretKeyField ); rep.saveStepAttribute( id_transformation, id_step, "messageField", messageField ); rep.saveStepAttribute( id_transformation, id_step, "resultfieldname", resultfieldname ); rep.saveStepAttribute( id_transformation, id_step, "secretKey", Encr .encryptPasswordIfNotUsingVariables( secretKey ) ); rep.saveStepAttribute( id_transformation, id_step, "secretKeyInField", secretKeyInField ); rep.saveStepAttribute( id_transformation, id_step, "readKeyAsBinary", readKeyAsBinary ); rep.saveStepAttribute( id_transformation, id_step, "outputResultAsBinary", outputResultAsBinary ); } catch ( Exception e ) { throw new KettleException( BaseMessages.getString( PKG, "SymmetricCryptoTransMeta.Exception.UnableToSaveStepInfo" ) + id_step, e ); } } public void check( List<CheckResultInterface> remarks, TransMeta transMeta, StepMeta stepinfo, RowMetaInterface prev, String[] input, String[] output, RowMetaInterface info, VariableSpace space, Repository repository, IMetaStore metaStore ) { CheckResult cr; if ( prev != null && prev.size() > 0 ) { cr = new CheckResult( CheckResult.TYPE_RESULT_OK, BaseMessages.getString( PKG, "SymmetricCryptoTransMeta.CheckResult.ConnectedStepOK", String.valueOf( prev.size() ) ), stepinfo ); } else { cr = new CheckResult( CheckResult.TYPE_RESULT_ERROR, BaseMessages.getString( PKG, "SymmetricCryptoTransMeta.CheckResult.NoInputReceived" ), stepinfo ); } remarks.add( cr ); // Check if The result field is given if ( getResultfieldname() == null ) { // Result Field is missing ! cr = new CheckResult( CheckResult.TYPE_RESULT_ERROR, BaseMessages.getString( PKG, "SymmetricCryptoTransMeta.CheckResult.ErrorResultFieldNameMissing" ), stepinfo ); remarks.add( cr ); } } public StepInterface getStep( StepMeta stepMeta, StepDataInterface stepDataInterface, int cnr, TransMeta transMeta, Trans trans ) { return new SymmetricCryptoTrans( stepMeta, stepDataInterface, cnr, transMeta, trans ); } public StepDataInterface getStepData() { return new SymmetricCryptoTransData(); } public boolean supportsErrorHandling() { return true; } }