/*! ******************************************************************************
*
* Pentaho Data Integration
*
* Copyright (C) 2002-2015 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.ui.spoon;
import java.util.Locale;
import org.eclipse.jface.dialogs.MessageDialogWithToggle;
import org.pentaho.di.core.Const;
import org.pentaho.di.core.EngineMetaInterface;
import org.pentaho.di.core.LastUsedFile;
import org.pentaho.di.core.ObjectLocationSpecificationMethod;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.core.exception.KettleMissingPluginsException;
import org.pentaho.di.core.extension.ExtensionPointHandler;
import org.pentaho.di.core.extension.KettleExtensionPoint;
import org.pentaho.di.core.gui.OverwritePrompter;
import org.pentaho.di.core.variables.Variables;
import org.pentaho.di.i18n.BaseMessages;
import org.pentaho.di.trans.TransMeta;
import org.pentaho.di.trans.step.StepMeta;
import org.pentaho.di.trans.steps.jobexecutor.JobExecutorMeta;
import org.pentaho.di.trans.steps.transexecutor.TransExecutorMeta;
import org.pentaho.di.ui.core.PropsUI;
import org.pentaho.di.ui.core.dialog.ErrorDialog;
import org.pentaho.di.ui.core.gui.GUIResource;
import org.pentaho.di.ui.trans.steps.missing.MissingTransDialog;
import org.w3c.dom.Node;
public class TransFileListener implements FileListener {
private static Class<?> PKG = Spoon.class; // for i18n purposes, needed by Translator2!!
public boolean open( Node transNode, String fname, boolean importfile ) throws KettleMissingPluginsException {
final Spoon spoon = Spoon.getInstance();
final PropsUI props = PropsUI.getInstance();
try {
// Call extension point(s) before the file has been opened
ExtensionPointHandler.callExtensionPoint( spoon.getLog(), KettleExtensionPoint.TransBeforeOpen.id, fname );
TransMeta transMeta = new TransMeta();
transMeta.loadXML(
transNode, fname, spoon.getMetaStore(), spoon.getRepository(), true, new Variables(),
new OverwritePrompter() {
public boolean overwritePrompt( String message, String rememberText, String rememberPropertyName ) {
MessageDialogWithToggle.setDefaultImage( GUIResource.getInstance().getImageSpoon() );
Object[] res =
spoon.messageDialogWithToggle(
BaseMessages.getString( PKG, "System.Button.Yes" ), null, message, Const.WARNING,
new String[]{
BaseMessages.getString( PKG, "System.Button.Yes" ),
BaseMessages.getString( PKG, "System.Button.No" ) }, 1, rememberText, !props
.askAboutReplacingDatabaseConnections() );
int idx = ( (Integer) res[0] ).intValue();
boolean toggleState = ( (Boolean) res[1] ).booleanValue();
props.setAskAboutReplacingDatabaseConnections( !toggleState );
return ( ( idx & 0xFF ) == 0 ); // Yes means: overwrite
}
} );
if ( transMeta.hasMissingPlugins() ) {
StepMeta stepMeta = transMeta.getStep( 0 );
MissingTransDialog missingDialog =
new MissingTransDialog( spoon.getShell(), transMeta.getMissingTrans(), stepMeta.getStepMetaInterface(),
transMeta, stepMeta.getName() );
if ( missingDialog.open() == null ) {
return true;
}
}
transMeta.setRepositoryDirectory( spoon.getDefaultSaveLocation( transMeta ) );
transMeta.setRepository( spoon.getRepository() );
transMeta.setMetaStore( spoon.getMetaStore() );
spoon.setTransMetaVariables( transMeta );
spoon.getProperties().addLastFile( LastUsedFile.FILE_TYPE_TRANSFORMATION, fname, null, false, null );
spoon.addMenuLast();
// If we are importing into a repository we need to fix
// up the references to other jobs and transformations
// if any exist.
if ( importfile ) {
if ( spoon.getRepository() != null ) {
transMeta = fixLinks( transMeta );
}
} else {
transMeta.clearChanged();
}
transMeta.setFilename( fname );
spoon.addTransGraph( transMeta );
spoon.sharedObjectsFileMap.put( transMeta.getSharedObjects().getFilename(), transMeta.getSharedObjects() );
// Call extension point(s) now that the file has been opened
ExtensionPointHandler.callExtensionPoint( spoon.getLog(), KettleExtensionPoint.TransAfterOpen.id, transMeta );
SpoonPerspectiveManager.getInstance().activatePerspective( MainSpoonPerspective.class );
spoon.refreshTree();
return true;
} catch ( KettleMissingPluginsException e ) {
throw e;
} catch ( KettleException e ) {
new ErrorDialog(
spoon.getShell(), BaseMessages.getString( PKG, "Spoon.Dialog.ErrorOpening.Title" ), BaseMessages
.getString( PKG, "Spoon.Dialog.ErrorOpening.Message" )
+ fname, e );
}
return false;
}
private TransMeta fixLinks( TransMeta transMeta ) {
transMeta = processLinkedJobs( transMeta );
transMeta = processLinkedTrans( transMeta );
return transMeta;
}
protected TransMeta processLinkedJobs( TransMeta transMeta ) {
for ( StepMeta stepMeta : transMeta.getSteps() ) {
if ( stepMeta.getStepID().equalsIgnoreCase( "JobExecutor" ) ) {
JobExecutorMeta jem = (JobExecutorMeta) stepMeta.getStepMetaInterface();
ObjectLocationSpecificationMethod specMethod = jem.getSpecificationMethod();
// If the reference is by filename, change it to Repository By Name. Otherwise it's fine so leave it alone
if ( specMethod == ObjectLocationSpecificationMethod.FILENAME ) {
jem.setSpecificationMethod( ObjectLocationSpecificationMethod.REPOSITORY_BY_NAME );
String filename = jem.getFileName();
String jobname = filename.substring( filename.lastIndexOf( "/" ) + 1, filename.lastIndexOf( '.' ) );
String directory = filename.substring( 0, filename.lastIndexOf( "/" ) );
jem.setJobName( jobname );
jem.setDirectoryPath( directory );
}
}
}
return transMeta;
}
protected TransMeta processLinkedTrans( TransMeta transMeta ) {
for ( StepMeta stepMeta : transMeta.getSteps() ) {
if ( stepMeta.getStepID().equalsIgnoreCase( "TransExecutor" ) ) {
TransExecutorMeta tem = (TransExecutorMeta) stepMeta.getStepMetaInterface();
ObjectLocationSpecificationMethod specMethod = tem.getSpecificationMethod();
// If the reference is by filename, change it to Repository By Name. Otherwise it's fine so leave it alone
if ( specMethod == ObjectLocationSpecificationMethod.FILENAME ) {
tem.setSpecificationMethod( ObjectLocationSpecificationMethod.REPOSITORY_BY_NAME );
String filename = tem.getFileName();
String jobname = filename.substring( filename.lastIndexOf( "/" ) + 1, filename.lastIndexOf( '.' ) );
String directory = filename.substring( 0, filename.lastIndexOf( "/" ) );
tem.setTransName( jobname );
tem.setDirectoryPath( directory );
}
}
}
return transMeta;
}
public boolean save( EngineMetaInterface meta, String fname, boolean export ) {
Spoon spoon = Spoon.getInstance();
EngineMetaInterface lmeta;
if ( export ) {
lmeta = (TransMeta) ( (TransMeta) meta ).realClone( false );
} else {
lmeta = meta;
}
try {
ExtensionPointHandler.callExtensionPoint( spoon.getLog(), KettleExtensionPoint.TransBeforeSave.id, lmeta );
} catch ( KettleException e ) {
// fails gracefully
}
boolean saveStatus = spoon.saveMeta( lmeta, fname );
if ( saveStatus ) {
try {
ExtensionPointHandler.callExtensionPoint( spoon.getLog(), KettleExtensionPoint.TransAfterSave.id, lmeta );
} catch ( KettleException e ) {
// fails gracefully
}
}
return saveStatus;
}
public void syncMetaName( EngineMetaInterface meta, String name ) {
( (TransMeta) meta ).setName( name );
}
public boolean accepts( String fileName ) {
if ( fileName == null || fileName.indexOf( '.' ) == -1 ) {
return false;
}
String extension = fileName.substring( fileName.lastIndexOf( '.' ) + 1 );
return extension.equals( "ktr" );
}
public boolean acceptsXml( String nodeName ) {
if ( "transformation".equals( nodeName ) ) {
return true;
}
return false;
}
public String[] getFileTypeDisplayNames( Locale locale ) {
return new String[]{ "Transformations", "XML" };
}
public String getRootNodeName() {
return "transformation";
}
public String[] getSupportedExtensions() {
return new String[]{ "ktr", "xml" };
}
}