<commit_before> /**********************************************************************
 **                                                                   **
 **               This code belongs to the KETTLE project.            **
 **                                                                   **
 ** Kettle, from version 2.2 on, is released into the public domain   **
 ** under the Lesser GNU Public License (LGPL).                       **
 **                                                                   **
 ** For more details, please read the document LICENSE.txt, included  **
 ** in this project                                                   **
 **                                                                   **
 ** http://www.kettle.be                                              **
 ** <EMAIL>                                                    **
 **                                                                   **
 **********************************************************************/
 
package be.ibridge.kettle.job;

import java.util.Date;

import be.ibridge.kettle.chef.JobTracker;
import be.ibridge.kettle.core.Const;
import be.ibridge.kettle.core.LogWriter;
import be.ibridge.kettle.core.Result;
import be.ibridge.kettle.core.Row;
import be.ibridge.kettle.core.database.Database;
import be.ibridge.kettle.core.database.DatabaseMeta;
import be.ibridge.kettle.core.exception.KettleDatabaseException;
import be.ibridge.kettle.core.exception.KettleException;
import be.ibridge.kettle.core.exception.KettleJobException;
import be.ibridge.kettle.core.value.Value;
import be.ibridge.kettle.job.entry.JobEntryCopy;
import be.ibridge.kettle.job.entry.JobEntryInterface;
import be.ibridge.kettle.job.entry.special.JobEntrySpecial;
import be.ibridge.kettle.repository.Repository;
import be.ibridge.kettle.trans.StepLoader;


/**
 * This class executes a JobInfo object.
 * 
 * @author Matt
 * @since  07-apr-2003
 * 
 */
public class Job extends Thread
{
	private LogWriter log;
	private JobMeta jobMeta;
	private Repository rep;
	
	/**
	 * Keep a list of the job entries that were executed.
	 */
	private JobTracker jobTracker;
	
	private Date      startDate, endDate, currentDate, logDate, depDate;
	
	private boolean active, stopped;
	
	public Job(LogWriter lw, String name, String file, String args[])
	{
		this.log=lw;
		
		jobMeta = new JobMeta(log);
		jobMeta.setName(name);
		jobMeta.setFilename(file);
		jobMeta.arguments=args;
		active=false;
		stopped=false;
        jobTracker = new JobTracker(jobMeta);
	}

	public Job(LogWriter lw, StepLoader steploader, Repository rep, JobMeta ti)
	{
		this.log        = lw;
		this.rep        = rep;
		this.jobMeta    = ti;
		
		active=false;
		stopped=false;
        jobTracker = new JobTracker(jobMeta);
	}
	
	public void open(Repository rep, String fname, String jobname, String dirname)
		throws KettleException
	{
		this.rep = rep;
		if (rep!=null)
		{
			jobMeta = new JobMeta(log, rep, jobname, rep.getDirectoryTree().findDirectory(dirname));
		}
		else
		{
			jobMeta = new JobMeta(log, fname);
		}
	}

	public String getJobname()
	{
		if (jobMeta==null) return null;
		
		return jobMeta.getName();
	}

	public void setRepository(Repository rep)
	{
		this.rep=rep;
	}
	
	// Threads main loop: called by Thread.start();
	public void run()
	{
		try
		{
			execute(); // Run the job
			endProcessing("end");
		}
		catch(KettleJobException je)
		{
			System.out.println("A serious error occurred!"+Const.CR+je.getMessage());
		}
	}

	public Result execute()
		throws KettleJobException
	{
        // Start the tracking...
        JobEntryResult jerStart = new JobEntryResult(null, "Start of job execution", "start", null);
        jobTracker.addJobTracker(new JobTracker(jobMeta, jerStart));

		active=true;
		// Where do we start?
		JobEntryCopy startpoint;
		beginProcessing();
		startpoint = jobMeta.findJobEntry(JobMeta.STRING_SPECIAL_START, 0);
		if (startpoint == null) 
		{
			throw new KettleJobException("Couldn't find starting point in this job.");
		}
		JobEntrySpecial jes = (JobEntrySpecial)startpoint.getEntry();
		Result res = null;
		boolean isFirst = true;
		while(jes.isRepeat()||isFirst&&!isStopped()) {
			isFirst = false;
			res = execute(0, null, startpoint, null, "start");
		}
		// Save this result...
		JobEntryResult jerEnd = new JobEntryResult(res, "Job execution ended", "end", null);
		jobTracker.addJobTracker(new JobTracker(jobMeta, jerEnd));
        
		active=false;
		return res;	
	}

	/**
	 * Execute called by JobEntryJob: don't clear the jobEntryResults...
	 * @param nr
	 * @param result
	 * @return Result of the job execution
	 * @throws KettleJobException
	 */
	public Result execute(int nr, Result result)
		throws KettleJobException
	{
		Result res =  execute(nr, result, null, null, "start of job entry");

		return res;
	}
	
	private Result execute(int nr, Result prev_result, JobEntryCopy startpoint, JobEntryCopy previous, String reason)
		throws KettleJobException
	{
		Result res = null;
       
		if (stopped)
		{
			res=new Result(nr);
			res.stopped=true;
			return res;
		}
		
		log.logDetailed(toString(), "exec("+nr+", "+(prev_result!=null?prev_result.getNrErrors():0)+", "+(startpoint!=null?startpoint.toString():"null")+")");
		
		// What entry is next?
		JobEntryInterface jei = startpoint.getEntry();

        // Track the fact that we are going to launch the next job entry...
        JobEntryResult jerBefore = new JobEntryResult(null, "Job entry started", reason, startpoint);
        jobTracker.addJobTracker(new JobTracker(jobMeta, jerBefore));

		// Execute this entry...
		Result result = jei.execute(prev_result, nr, rep, this);
		<commit_msg>Always look for the start when starting to execute a job, even if it's a sub-job.<commit_after> /**********************************************************************
 **                                                                   **
 **               This code belongs to the KETTLE project.            **
 **                                                                   **
 ** Kettle, from version 2.2 on, is released into the public domain   **
 ** under the Lesser GNU Public License (LGPL).                       **
 **                                                                   **
 ** For more details, please read the document LICENSE.txt, included  **
 ** in this project                                                   **
 **                                                                   **
 ** http://www.kettle.be                                              **
 ** <EMAIL>                                                    **
 **                                                                   **
 **********************************************************************/
 
package be.ibridge.kettle.job;

import java.util.Date;

import be.ibridge.kettle.chef.JobTracker;
import be.ibridge.kettle.core.Const;
import be.ibridge.kettle.core.LogWriter;
import be.ibridge.kettle.core.Result;
import be.ibridge.kettle.core.Row;
import be.ibridge.kettle.core.database.Database;
import be.ibridge.kettle.core.database.DatabaseMeta;
import be.ibridge.kettle.core.exception.KettleDatabaseException;
import be.ibridge.kettle.core.exception.KettleException;
import be.ibridge.kettle.core.exception.KettleJobException;
import be.ibridge.kettle.core.value.Value;
import be.ibridge.kettle.job.entry.JobEntryCopy;
import be.ibridge.kettle.job.entry.JobEntryInterface;
import be.ibridge.kettle.job.entry.special.JobEntrySpecial;
import be.ibridge.kettle.repository.Repository;
import be.ibridge.kettle.trans.StepLoader;


/**
 * This class executes a JobInfo object.
 * 
 * @author Matt
 * @since  07-apr-2003
 * 
 */
public class Job extends Thread
{
	private LogWriter log;
	private JobMeta jobMeta;
	private Repository rep;
	
	/**
	 * Keep a list of the job entries that were executed.
	 */
	private JobTracker jobTracker;
	
	private Date      startDate, endDate, currentDate, logDate, depDate;
	
	private boolean active, stopped;
	
	public Job(LogWriter lw, String name, String file, String args[])
	{
		this.log=lw;
		
		jobMeta = new JobMeta(log);
		jobMeta.setName(name);
		jobMeta.setFilename(file);
		jobMeta.arguments=args;
		active=false;
		stopped=false;
        jobTracker = new JobTracker(jobMeta);
	}

	public Job(LogWriter lw, StepLoader steploader, Repository rep, JobMeta ti)
	{
		this.log        = lw;
		this.rep        = rep;
		this.jobMeta    = ti;
		
		active=false;
		stopped=false;
        jobTracker = new JobTracker(jobMeta);
	}
	
	public void open(Repository rep, String fname, String jobname, String dirname)
		throws KettleException
	{
		this.rep = rep;
		if (rep!=null)
		{
			jobMeta = new JobMeta(log, rep, jobname, rep.getDirectoryTree().findDirectory(dirname));
		}
		else
		{
			jobMeta = new JobMeta(log, fname);
		}
	}

	public String getJobname()
	{
		if (jobMeta==null) return null;
		
		return jobMeta.getName();
	}

	public void setRepository(Repository rep)
	{
		this.rep=rep;
	}
	
	// Threads main loop: called by Thread.start();
	public void run()
	{
		try
		{
			execute(); // Run the job
			endProcessing("end");
		}
		catch(KettleJobException je)
		{
			System.out.println("A serious error occurred!"+Const.CR+je.getMessage());
		}
	}

	public Result execute()
		throws KettleJobException
	{
        // Start the tracking...
        JobEntryResult jerStart = new JobEntryResult(null, "Start of job execution", "start", null);
        jobTracker.addJobTracker(new JobTracker(jobMeta, jerStart));

		active=true;
        
		// Where do we start?
		JobEntryCopy startpoint;
		beginProcessing();
		startpoint = jobMeta.findJobEntry(JobMeta.STRING_SPECIAL_START, 0);
		if (startpoint == null) 
		{
			throw new KettleJobException("Couldn't find starting point in this job.");
		}
		JobEntrySpecial jes = (JobEntrySpecial)startpoint.getEntry();
		Result res = null;
		boolean isFirst = true;
		while(jes.isRepeat()||isFirst&&!isStopped()) {
			isFirst = false;
			res = execute(0, null, startpoint, null, "start");
		}
		// Save this result...
		JobEntryResult jerEnd = new JobEntryResult(res, "Job execution ended", "end", null);
		jobTracker.addJobTracker(new JobTracker(jobMeta, jerEnd));
        
		active=false;
		return res;	
	}

	/**
	 * Execute called by JobEntryJob: don't clear the jobEntryResults...
	 * @param nr
	 * @param result
	 * @return Result of the job execution
	 * @throws KettleJobException
	 */
	public Result execute(int nr, Result result)
		throws KettleJobException
	{
        // Where do we start?
        JobEntryCopy startpoint;

        startpoint = jobMeta.findJobEntry(JobMeta.STRING_SPECIAL_START, 0);
        if (startpoint == null) 
        {
            throw new KettleJobException("Couldn't find starting point in this job.");
        }

		Result res =  execute(nr, result, startpoint, null, "start of job entry");

		return res;
	}
	
	private Result execute(int nr, Result prev_result, JobEntryCopy startpoint, JobEntryCopy previous, String reason)
		throws KettleJobException
	{
		Result res = null;
       
		if (stopped)
		{
			res=new Result(nr);
			res.stopped=true;
			return res;
		}
		
		log.logDetailed(toString(), "exec("+nr+", "+(prev_result!=null?prev_result.getNrErrors():0)+", "+(startpoint!=null?startpoint.toString():"null")+")");
		
		// What entry is next?
		JobEntryInterface jei = startpoint.getEntry();

        // Track the fact that we are going to launch the next job entry...
        JobEntryResult jerBefore = new JobEntryResult(null, "Job entry started", reason, startpoint);
        jobTracker.addJobTracker(new JobTracker(jobMeta, jerBefore));

		// Execute this entry...
		Result result = jei.execute(prev_result, nr, rep, this);
		
{'fraction_non_alphanumeric': 0.1313955464898861, 'fraction_numerical': 0.001954784973652898, 'mean_word_length': 2.5668384358896636, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 42, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4650186', 'n_tokens_mistral': 3697, 'n_tokens_neox': 3331, 'n_words': 868}