/*! ****************************************************************************** * * Pentaho Data Integration * * Copyright (C) 2002-2013 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.job.entries.special; import java.util.Calendar; import java.util.List; import org.pentaho.di.cluster.SlaveServer; import org.pentaho.di.core.CheckResultInterface; import org.pentaho.di.core.Const; import org.pentaho.di.core.Result; import org.pentaho.di.core.database.DatabaseMeta; import org.pentaho.di.core.exception.KettleDatabaseException; import org.pentaho.di.core.exception.KettleException; import org.pentaho.di.core.exception.KettleJobException; import org.pentaho.di.core.exception.KettleXMLException; import org.pentaho.di.core.variables.VariableSpace; import org.pentaho.di.core.xml.XMLHandler; import org.pentaho.di.job.JobMeta; import org.pentaho.di.job.entry.JobEntryBase; import org.pentaho.di.job.entry.JobEntryInterface; 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 can contain a few special job entries such as Start and Dummy. * * @author Matt * @since 05-11-2003 * */ public class JobEntrySpecial extends JobEntryBase implements Cloneable, JobEntryInterface { public static final int NOSCHEDULING = 0; public static final int INTERVAL = 1; public static final int DAILY = 2; public static final int WEEKLY = 3; public static final int MONTHLY = 4; private boolean start; private boolean dummy; private boolean repeat = false; private int schedulerType = NOSCHEDULING; private int intervalSeconds = 0; private int intervalMinutes = 60; private int dayOfMonth = 1; private int weekDay = 1; private int minutes = 0; private int hour = 12; public JobEntrySpecial() { this( null, false, false ); } public JobEntrySpecial( String name, boolean start, boolean dummy ) { super( name, "" ); this.start = start; this.dummy = dummy; } public Object clone() { JobEntrySpecial je = (JobEntrySpecial) super.clone(); return je; } public String getXML() { StringBuilder retval = new StringBuilder( 200 ); retval.append( super.getXML() ); retval.append( " " ).append( XMLHandler.addTagValue( "start", start ) ); retval.append( " " ).append( XMLHandler.addTagValue( "dummy", dummy ) ); retval.append( " " ).append( XMLHandler.addTagValue( "repeat", repeat ) ); retval.append( " " ).append( XMLHandler.addTagValue( "schedulerType", schedulerType ) ); retval.append( " " ).append( XMLHandler.addTagValue( "intervalSeconds", intervalSeconds ) ); retval.append( " " ).append( XMLHandler.addTagValue( "intervalMinutes", intervalMinutes ) ); retval.append( " " ).append( XMLHandler.addTagValue( "hour", hour ) ); retval.append( " " ).append( XMLHandler.addTagValue( "minutes", minutes ) ); retval.append( " " ).append( XMLHandler.addTagValue( "weekDay", weekDay ) ); retval.append( " " ).append( XMLHandler.addTagValue( "DayOfMonth", dayOfMonth ) ); return retval.toString(); } public void loadXML( Node entrynode, List<DatabaseMeta> databases, List<SlaveServer> slaveServers, Repository rep, IMetaStore metaStore ) throws KettleXMLException { try { super.loadXML( entrynode, databases, slaveServers ); start = "Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, "start" ) ); dummy = "Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, "dummy" ) ); repeat = "Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, "repeat" ) ); setSchedulerType( Const.toInt( XMLHandler.getTagValue( entrynode, "schedulerType" ), NOSCHEDULING ) ); setIntervalSeconds( Const.toInt( XMLHandler.getTagValue( entrynode, "intervalSeconds" ), 0 ) ); setIntervalMinutes( Const.toInt( XMLHandler.getTagValue( entrynode, "intervalMinutes" ), 0 ) ); setHour( Const.toInt( XMLHandler.getTagValue( entrynode, "hour" ), 0 ) ); setMinutes( Const.toInt( XMLHandler.getTagValue( entrynode, "minutes" ), 0 ) ); setWeekDay( Const.toInt( XMLHandler.getTagValue( entrynode, "weekDay" ), 0 ) ); setDayOfMonth( Const.toInt( XMLHandler.getTagValue( entrynode, "dayOfMonth" ), 0 ) ); } catch ( KettleException e ) { throw new KettleXMLException( "Unable to load job entry of type 'special' from XML node", e ); } } public void loadRep( Repository rep, IMetaStore metaStore, ObjectId id_jobentry, List<DatabaseMeta> databases, List<SlaveServer> slaveServers ) throws KettleException { try { start = rep.getJobEntryAttributeBoolean( id_jobentry, "start" ); dummy = rep.getJobEntryAttributeBoolean( id_jobentry, "dummy" ); repeat = rep.getJobEntryAttributeBoolean( id_jobentry, "repeat" ); schedulerType = (int) rep.getJobEntryAttributeInteger( id_jobentry, "schedulerType" ); intervalSeconds = (int) rep.getJobEntryAttributeInteger( id_jobentry, "intervalSeconds" ); intervalMinutes = (int) rep.getJobEntryAttributeInteger( id_jobentry, "intervalMinutes" ); hour = (int) rep.getJobEntryAttributeInteger( id_jobentry, "hour" ); minutes = (int) rep.getJobEntryAttributeInteger( id_jobentry, "minutes" ); weekDay = (int) rep.getJobEntryAttributeInteger( id_jobentry, "weekDay" ); dayOfMonth = (int) rep.getJobEntryAttributeInteger( id_jobentry, "dayOfMonth" ); } catch ( KettleDatabaseException dbe ) { throw new KettleException( "Unable to load job entry of type 'special' from the repository for id_jobentry=" + id_jobentry, dbe ); } } // Save the attributes of this job entry // public void saveRep( Repository rep, IMetaStore metaStore, ObjectId id_job ) throws KettleException { try { rep.saveJobEntryAttribute( id_job, getObjectId(), "start", start ); rep.saveJobEntryAttribute( id_job, getObjectId(), "dummy", dummy ); rep.saveJobEntryAttribute( id_job, getObjectId(), "repeat", repeat ); rep.saveJobEntryAttribute( id_job, getObjectId(), "schedulerType", schedulerType ); rep.saveJobEntryAttribute( id_job, getObjectId(), "intervalSeconds", intervalSeconds ); rep.saveJobEntryAttribute( id_job, getObjectId(), "intervalMinutes", intervalMinutes ); rep.saveJobEntryAttribute( id_job, getObjectId(), "hour", hour ); rep.saveJobEntryAttribute( id_job, getObjectId(), "minutes", minutes ); rep.saveJobEntryAttribute( id_job, getObjectId(), "weekDay", weekDay ); rep.saveJobEntryAttribute( id_job, getObjectId(), "dayOfMonth", dayOfMonth ); } catch ( KettleDatabaseException dbe ) { throw new KettleException( "Unable to save job entry of type 'special' to the repository with id_job=" + id_job, dbe ); } } public boolean isStart() { return start; } public boolean isDummy() { return dummy; } public Result execute( Result previousResult, int nr ) throws KettleJobException { Result result = previousResult; if ( isStart() ) { try { long sleepTime = getNextExecutionTime(); if ( sleepTime > 0 ) { parentJob.getLogChannel().logBasic( parentJob.getJobname(), "Sleeping: " + ( sleepTime / 1000 / 60 ) + " minutes (sleep time=" + sleepTime + ")" ); long totalSleep = 0L; while ( totalSleep < sleepTime && !parentJob.isStopped() ) { Thread.sleep( 1000L ); totalSleep += 1000L; } } } catch ( InterruptedException e ) { throw new KettleJobException( e ); } result = previousResult; result.setResult( true ); } else if ( isDummy() ) { result = previousResult; } return result; } private long getNextExecutionTime() { switch ( schedulerType ) { case NOSCHEDULING: return 0; case INTERVAL: return getNextIntervalExecutionTime(); case DAILY: return getNextDailyExecutionTime(); case WEEKLY: return getNextWeeklyExecutionTime(); case MONTHLY: return getNextMonthlyExecutionTime(); default: break; } return 0; } private long getNextIntervalExecutionTime() { return intervalSeconds * 1000 + intervalMinutes * 1000 * 60; } private long getNextMonthlyExecutionTime() { Calendar calendar = Calendar.getInstance(); long nowMillis = calendar.getTimeInMillis(); int amHour = hour; if ( amHour > 12 ) { amHour = amHour - 12; calendar.set( Calendar.AM_PM, Calendar.PM ); } else { calendar.set( Calendar.AM_PM, Calendar.AM ); } calendar.set( Calendar.HOUR, amHour ); calendar.set( Calendar.MINUTE, minutes ); calendar.set( Calendar.DAY_OF_MONTH, dayOfMonth ); if ( calendar.getTimeInMillis() <= nowMillis ) { calendar.add( Calendar.MONTH, 1 ); } return calendar.getTimeInMillis() - nowMillis; } private long getNextWeeklyExecutionTime() { Calendar calendar = Calendar.getInstance(); long nowMillis = calendar.getTimeInMillis(); int amHour = hour; if ( amHour > 12 ) { amHour = amHour - 12; calendar.set( Calendar.AM_PM, Calendar.PM ); } else { calendar.set( Calendar.AM_PM, Calendar.AM ); } calendar.set( Calendar.HOUR, amHour ); calendar.set( Calendar.MINUTE, minutes ); calendar.set( Calendar.DAY_OF_WEEK, weekDay + 1 ); if ( calendar.getTimeInMillis() <= nowMillis ) { calendar.add( Calendar.WEEK_OF_YEAR, 1 ); } return calendar.getTimeInMillis() - nowMillis; } private long getNextDailyExecutionTime() { Calendar calendar = Calendar.getInstance(); long nowMillis = calendar.getTimeInMillis(); int amHour = hour; if ( amHour > 12 ) { amHour = amHour - 12; calendar.set( Calendar.AM_PM, Calendar.PM ); } else { calendar.set( Calendar.AM_PM, Calendar.AM ); } calendar.set( Calendar.HOUR, amHour ); calendar.set( Calendar.MINUTE, minutes ); if ( calendar.getTimeInMillis() <= nowMillis ) { calendar.add( Calendar.DAY_OF_MONTH, 1 ); } return calendar.getTimeInMillis() - nowMillis; } public boolean evaluates() { return false; } public boolean isUnconditional() { return true; } public int getSchedulerType() { return schedulerType; } public int getHour() { return hour; } public int getMinutes() { return minutes; } public int getWeekDay() { return weekDay; } public int getDayOfMonth() { return dayOfMonth; } public void setDayOfMonth( int dayOfMonth ) { this.dayOfMonth = dayOfMonth; } public void setHour( int hour ) { this.hour = hour; } public void setMinutes( int minutes ) { this.minutes = minutes; } public void setWeekDay( int weekDay ) { this.weekDay = weekDay; } public void setSchedulerType( int schedulerType ) { this.schedulerType = schedulerType; } public boolean isRepeat() { return repeat; } public void setRepeat( boolean repeat ) { this.repeat = repeat; } public int getIntervalSeconds() { return intervalSeconds; } public void setIntervalSeconds( int intervalSeconds ) { this.intervalSeconds = intervalSeconds; } public int getIntervalMinutes() { return intervalMinutes; } public void setIntervalMinutes( int intervalMinutes ) { this.intervalMinutes = intervalMinutes; } /** * @param dummy * the dummy to set */ public void setDummy( boolean dummy ) { this.dummy = dummy; } /** * @param start * the start to set */ public void setStart( boolean start ) { this.start = start; } @Override public void check( List<CheckResultInterface> remarks, JobMeta jobMeta, VariableSpace space, Repository repository, IMetaStore metaStore ) { } }