org.pentaho.di.job.entry.JobEntryCopy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kettle-engine Show documentation
Show all versions of kettle-engine Show documentation
Container pom for Pentaho Data Integration modules
The newest version!
/*! ******************************************************************************
*
* Pentaho Data Integration
*
* Copyright (C) 2002-2018 by Hitachi Vantara : 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.job.entry;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.ArrayUtils;
import org.pentaho.di.base.BaseMeta;
import org.pentaho.di.cluster.SlaveServer;
import org.pentaho.di.core.AttributesInterface;
import org.pentaho.di.core.Const;
import org.pentaho.di.core.attributes.AttributesUtil;
import org.pentaho.di.core.changed.ChangedFlagInterface;
import org.pentaho.di.core.database.DatabaseMeta;
import org.pentaho.di.core.exception.KettleXMLException;
import org.pentaho.di.core.gui.GUIPositionInterface;
import org.pentaho.di.core.gui.Point;
import org.pentaho.di.core.plugins.JobEntryPluginType;
import org.pentaho.di.core.plugins.PluginInterface;
import org.pentaho.di.core.plugins.PluginRegistry;
import org.pentaho.di.core.xml.XMLHandler;
import org.pentaho.di.core.xml.XMLInterface;
import org.pentaho.di.i18n.BaseMessages;
import org.pentaho.di.job.JobMeta;
import org.pentaho.di.job.entries.missing.MissingEntry;
import org.pentaho.di.repository.ObjectId;
import org.pentaho.di.repository.Repository;
import org.pentaho.metastore.api.IMetaStore;
import org.w3c.dom.Node;
/**
* This class describes the fact that a single JobEntry can be used multiple times in the same Job. Therefore it contains
* a link to a JobEntry, a position, a number, etc.
*
* @author Matt
* @since 01-10-2003
*
*/
public class JobEntryCopy implements Cloneable, XMLInterface, GUIPositionInterface, ChangedFlagInterface,
AttributesInterface, BaseMeta {
private static final String XML_TAG = "entry";
private static final String XML_ATTRIBUTE_JOB_ENTRY_COPY = AttributesUtil.XML_TAG + "_kjc";
private JobEntryInterface entry;
private String suggestion = "";
private int nr; // Copy nr. 0 is the base copy...
private boolean selected;
private boolean isDeprecated;
private Point location;
/**
* Flag to indicate that the job entries following this one are launched in parallel
*/
private boolean launchingInParallel;
private boolean draw;
private ObjectId id;
private JobMeta parentJobMeta;
private Map> attributesMap;
public JobEntryCopy() {
clear();
}
public JobEntryCopy( JobEntryInterface entry ) {
this();
setEntry( entry );
}
public String getXML() {
StringBuilder retval = new StringBuilder( 100 );
retval.append( " " ).append( XMLHandler.openTag( XML_TAG ) ).append( Const.CR );
entry.setParentJobMeta( parentJobMeta ); // Attempt to set the JobMeta for entries that need it
retval.append( entry.getXML() );
retval.append( " " ).append( XMLHandler.addTagValue( "parallel", launchingInParallel ) );
retval.append( " " ).append( XMLHandler.addTagValue( "draw", draw ) );
retval.append( " " ).append( XMLHandler.addTagValue( "nr", nr ) );
retval.append( " " ).append( XMLHandler.addTagValue( "xloc", location.x ) );
retval.append( " " ).append( XMLHandler.addTagValue( "yloc", location.y ) );
retval.append( AttributesUtil.getAttributesXml( attributesMap, XML_ATTRIBUTE_JOB_ENTRY_COPY ) );
retval.append( " " ).append( XMLHandler.closeTag( XML_TAG ) ).append( Const.CR );
return retval.toString();
}
/**
*
* @param entrynode
* @param databases
* @param slaveServers
* @param rep
* @throws KettleXMLException
* @deprecated
*/
@Deprecated
public JobEntryCopy( Node entrynode, List databases, List slaveServers, Repository rep ) throws KettleXMLException {
this( entrynode, databases, slaveServers, rep, null );
}
public JobEntryCopy( Node entrynode, List databases, List slaveServers, Repository rep,
IMetaStore metaStore ) throws KettleXMLException {
try {
String stype = XMLHandler.getTagValue( entrynode, "type" );
PluginRegistry registry = PluginRegistry.getInstance();
PluginInterface jobPlugin = registry.findPluginWithId( JobEntryPluginType.class, stype, true );
if ( jobPlugin == null ) {
String name = XMLHandler.getTagValue( entrynode, "name" );
entry = new MissingEntry( name, stype );
} else {
entry = registry.loadClass( jobPlugin, JobEntryInterface.class );
}
// Get an empty JobEntry of the appropriate class...
if ( entry != null ) {
if ( jobPlugin != null ) {
entry.setPluginId( jobPlugin.getIds()[0] );
}
entry.setMetaStore( metaStore ); // inject metastore
entry.loadXML( entrynode, databases, slaveServers, rep, metaStore );
compatibleLoadXml( entrynode, databases, slaveServers, rep );
// Handle GUI information: nr & location?
setNr( Const.toInt( XMLHandler.getTagValue( entrynode, "nr" ), 0 ) );
setLaunchingInParallel( "Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, "parallel" ) ) );
setDrawn( "Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, "draw" ) ) );
int x = Const.toInt( XMLHandler.getTagValue( entrynode, "xloc" ), 0 );
int y = Const.toInt( XMLHandler.getTagValue( entrynode, "yloc" ), 0 );
setLocation( x, y );
Node jobEntryCopyAttributesNode = XMLHandler.getSubNode( entrynode, XML_ATTRIBUTE_JOB_ENTRY_COPY );
if ( jobEntryCopyAttributesNode != null ) {
attributesMap = AttributesUtil.loadAttributes( jobEntryCopyAttributesNode );
} else {
// [PDI-17345] If the appropriate attributes node wasn't found, this must be an old file (prior to this fix).
// Before this fix it was very probable to exist two attributes groups. While this is not very valid, in some
// scenarios the Job worked as expected; so by trying to load the LAST one into the JobEntryCopy, we
// simulate that behaviour.
attributesMap =
AttributesUtil.loadAttributes( XMLHandler.getLastSubNode( entrynode, AttributesUtil.XML_TAG ) );
}
setDeprecationAndSuggestedJobEntry();
}
} catch ( Throwable e ) {
String message = "Unable to read Job Entry copy info from XML node : " + e.toString();
throw new KettleXMLException( message, e );
}
}
/**
* Backward compatible loading of XML, using deprecated method.
*
* @param entrynode
* @param databases
* @param slaveServers
* @param rep
* @throws KettleXMLException
*/
@SuppressWarnings( "deprecation" )
protected void compatibleLoadXml( Node entrynode, List databases, List slaveServers,
Repository rep ) throws KettleXMLException {
entry.loadXML( entrynode, databases, slaveServers, rep );
}
public void clear() {
location = null;
entry = null;
nr = 0;
launchingInParallel = false;
attributesMap = new HashMap<>();
setObjectId( null );
}
public Object clone() {
JobEntryCopy ge = new JobEntryCopy();
ge.replaceMeta( this );
ge.setObjectId( null );
for ( final Map.Entry> attribute : attributesMap.entrySet() ) {
ge.attributesMap.put( attribute.getKey(), attribute.getValue() );
}
return ge;
}
public void replaceMeta( JobEntryCopy jobEntryCopy ) {
entry = (JobEntryInterface) jobEntryCopy.entry.clone();
nr = jobEntryCopy.nr; // Copy nr. 0 is the base copy...
selected = jobEntryCopy.selected;
if ( jobEntryCopy.location != null ) {
location = new Point( jobEntryCopy.location.x, jobEntryCopy.location.y );
}
launchingInParallel = jobEntryCopy.launchingInParallel;
draw = jobEntryCopy.draw;
id = jobEntryCopy.id;
setChanged();
}
public Object clone_deep() {
JobEntryCopy ge = (JobEntryCopy) clone();
// Copy underlying object as well...
ge.entry = (JobEntryInterface) entry.clone();
return ge;
}
public void setObjectId( ObjectId id ) {
this.id = id;
}
public boolean equals( Object o ) {
if ( o == null ) {
return false;
}
JobEntryCopy je = (JobEntryCopy) o;
return je.entry.getName().equalsIgnoreCase( entry.getName() ) && je.getNr() == getNr();
}
@Override
public int hashCode() {
return entry.getName().hashCode() ^ Integer.valueOf( getNr() ).hashCode();
}
public ObjectId getObjectId() {
return id;
}
public void setEntry( JobEntryInterface je ) {
entry = je;
if ( entry != null ) {
if ( entry.getPluginId() == null ) {
entry.setPluginId( PluginRegistry.getInstance().getPluginId( JobEntryPluginType.class, entry ) );
}
setDeprecationAndSuggestedJobEntry();
}
}
public JobEntryInterface getEntry() {
return entry;
}
/**
* @return entry in JobEntryInterface.typeCode[] for native jobs, entry.getTypeCode() for plugins
*/
public String getTypeDesc() {
PluginInterface plugin =
PluginRegistry.getInstance().findPluginWithId( JobEntryPluginType.class, entry.getPluginId() );
return plugin.getDescription();
}
public void setLocation( int x, int y ) {
int nx = ( x >= 0 ? x : 0 );
int ny = ( y >= 0 ? y : 0 );
Point loc = new Point( nx, ny );
if ( !loc.equals( location ) ) {
setChanged();
}
location = loc;
}
public void setLocation( Point loc ) {
if ( loc != null && !loc.equals( location ) ) {
setChanged();
}
location = loc;
}
public Point getLocation() {
return location;
}
public void setChanged() {
setChanged( true );
}
public void setChanged( boolean ch ) {
entry.setChanged( ch );
}
public void clearChanged() {
entry.setChanged( false );
}
public boolean hasChanged() {
return entry.hasChanged();
}
public int getNr() {
return nr;
}
public void setNr( int n ) {
nr = n;
}
public void setLaunchingInParallel( boolean p ) {
launchingInParallel = p;
}
public boolean isDrawn() {
return draw;
}
public void setDrawn() {
setDrawn( true );
}
public void setDrawn( boolean d ) {
draw = d;
}
public boolean isLaunchingInParallel() {
return launchingInParallel;
}
public void setSelected( boolean sel ) {
selected = sel;
}
public void flipSelected() {
selected = !selected;
}
public boolean isSelected() {
return selected;
}
public void setDescription( String description ) {
entry.setDescription( description );
}
public String getDescription() {
return entry.getDescription();
}
public boolean isStart() {
return entry.isStart();
}
public boolean isDummy() {
return entry.isDummy();
}
public boolean isMissing() {
return entry instanceof MissingEntry;
}
public boolean isTransformation() {
return entry.isTransformation();
}
public boolean isJob() {
return entry.isJob();
}
public boolean evaluates() {
if ( entry != null ) {
return entry.evaluates();
}
return false;
}
public boolean isUnconditional() {
if ( entry != null ) {
return entry.isUnconditional();
}
return true;
}
public boolean isEvaluation() {
return entry.isEvaluation();
}
public boolean isMail() {
return entry.isMail();
}
public boolean isSpecial() {
return entry.isSpecial();
}
public String toString() {
if ( entry != null ) {
return entry.getName() + "." + getNr();
} else {
return "null." + getNr();
}
}
public String getName() {
if ( entry != null ) {
return entry.getName();
} else {
return "null";
}
}
public void setName( String name ) {
entry.setName( name );
}
public boolean resetErrorsBeforeExecution() {
return entry.resetErrorsBeforeExecution();
}
public JobMeta getParentJobMeta() {
return parentJobMeta;
}
public void setParentJobMeta( JobMeta parentJobMeta ) {
this.parentJobMeta = parentJobMeta;
this.entry.setParentJobMeta( parentJobMeta );
}
@Override
public void setAttributesMap( Map> attributesMap ) {
this.attributesMap = attributesMap;
}
@Override
public Map> getAttributesMap() {
return attributesMap;
}
@Override
public void setAttribute( String groupName, String key, String value ) {
Map attributes = getAttributes( groupName );
if ( attributes == null ) {
attributes = new HashMap<>();
attributesMap.put( groupName, attributes );
}
attributes.put( key, value );
}
@Override
public void setAttributes( String groupName, Map attributes ) {
attributesMap.put( groupName, attributes );
}
@Override
public Map getAttributes( String groupName ) {
return attributesMap.get( groupName );
}
@Override
public String getAttribute( String groupName, String key ) {
Map attributes = attributesMap.get( groupName );
if ( attributes == null ) {
return null;
}
return attributes.get( key );
}
public boolean isDeprecated() {
return isDeprecated;
}
public String getSuggestion() {
return suggestion;
}
private void setDeprecationAndSuggestedJobEntry() {
PluginRegistry registry = PluginRegistry.getInstance();
final List deprecatedJobEntries = registry.getPluginsByCategory( JobEntryPluginType.class,
BaseMessages.getString( JobMeta.class, "JobCategory.Category.Deprecated" ) );
for ( PluginInterface p : deprecatedJobEntries ) {
String[] ids = p.getIds();
if ( !ArrayUtils.isEmpty( ids ) && ids[0].equals( this.entry != null ? this.entry.getPluginId() : "" ) ) {
this.isDeprecated = true;
this.suggestion = registry.findPluginWithId( JobEntryPluginType.class, this.entry.getPluginId() ) != null
? registry.findPluginWithId( JobEntryPluginType.class, this.entry.getPluginId() ).getSuggestion() : "";
break;
}
}
}
}