org.pepstock.jem.ant.tasks.WrapperTask.java Source code

Java tutorial

Introduction

Here is the source code for org.pepstock.jem.ant.tasks.WrapperTask.java

Source

/**
JEM, the BEE - Job Entry Manager, the Batch Execution Environment
Copyright (C) 2012-2015   Andrea "Stock" Stocchero
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
any later version.
    
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
    
You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.pepstock.jem.ant.tasks;

import java.io.IOException;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.PropertyHelper;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.TaskContainer;
import org.apache.tools.ant.property.LocalProperties;
import org.pepstock.catalog.DataDescriptionImpl;
import org.pepstock.catalog.DataSetImpl;
import org.pepstock.catalog.gdg.GDGManager;
import org.pepstock.jem.ant.AntMessage;
import org.pepstock.jem.ant.DataDescriptionStep;
import org.pepstock.jem.log.LogAppl;

/**
 * Is a special <code>Sequential</code> ANT task implementation, with only 1
 * task, where is possible to declare all files and resources job needs to be
 * executed.<br>
 * All the files references are passed by properties to command which is able to
 * have the file name just accessing to properties and without coding them
 * inside the code.
 * 
 * @author Andrea "Stock" Stocchero
 * @version 1.4
 */
public class WrapperTask extends Task implements TaskContainer, DataDescriptionStep {

    private String id = DataDescriptionStep.DEFAULT_ID;

    private String name = null;

    private int order = 0;

    private final List<DataDescription> dataDescriptions = new ArrayList<DataDescription>();

    private final List<Lock> locks = new ArrayList<Lock>();

    private Task nestedTask = null;

    /**
     * @return the id
     */
    @Override
    public String getId() {
        return id;
    }

    /**
     * @param id the id to set
     */
    public void setId(String id) {
        this.id = id;
    }

    /**
     * @return the name
     */
    public String getName() {
        return (name == null) ? getTaskName() : name;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return the order
     */
    public int getOrder() {
        return order;
    }

    /**
     * @param order the order to set
     */
    public void setOrder(int order) {
        this.order = order;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.pepstock.jem.ant.DataDescriptionItem#getTargetName()
     */
    @Override
    public String getTargetName() {
        return getOwningTarget().getName();
    }

    /**
     * Called by ANT engine to add data description object defined inside the
     * task element.
     * 
     * @see DataDescription
     * @param dd data description object
     */
    public void addDataDescription(DataDescription dd) {
        for (DataSet dataset : dd.getDatasets()) {
            if (dataset.isInline() && dataset.isReplaceProperties()) {
                String changed = getProject().replaceProperties(dataset.getText().toString());
                dataset.setTextBuffer(new StringBuilder(changed));
            }
        }
        dataDescriptions.add(dd);
    }

    /**
     * @return the dataDescriptions
     */
    @Override
    public List<DataDescription> getDataDescriptions() {
        return dataDescriptions;
    }

    /**
     * Called by ANT engine to add lock object defined inside the task element.
     * 
     * @param lock
     */
    public void addLock(Lock lock) {
        locks.add(lock);
    }

    /**
     * Returns the list of locks
     * 
     * @return the list of locks
     */
    @Override
    public List<Lock> getLocks() {
        return locks;
    }

    /**
     * Add the task to execute
     * 
     * @param task task to execute
     */
    public void addTask(Task task) {
        if (nestedTask != null) {
            throw new BuildException(AntMessage.JEMA052E.toMessage().getFormattedMessage());
        }
        this.nestedTask = task;
    }

    /**
     * Prepares the files required by ANT file using the data description, locks
     * them, and prepares the right file name for GDG. Afterwards calls the
     * defined task.
     * 
     * @throws BuildException occurs if an error occurs
     */
    @Override
    public void execute() throws BuildException {
        // this boolean is necessary to understand if I have an exception
        // before calling the main class
        boolean isExecutionStarted = false;

        AntBatchSecurityManager batchSM = (AntBatchSecurityManager) System.getSecurityManager();
        batchSM.setInternalAction(true);
        // creates a list with all data description impl
        List<DataDescriptionImpl> ddList = null;

        PropertyHelper propertyHelper = PropertyHelper.getPropertyHelper(getProject());

        // creates a thread local properties
        LocalProperties localProperties = LocalProperties.get(getProject());

        try {
            // gets all data description requested by this task
            ddList = ImplementationsContainer.getInstance().getDataDescriptionsByItem(this);

            // if list of data description is empty, go to execute the command
            if (!ddList.isEmpty()) {
                // sets scope per properties and calls task
                // MUST BE CALLED BEFORE ADDLOCAL
                localProperties.enterScope();

                // this cycle must load variables to local properties
                for (DataDescriptionImpl ddImpl : ddList) {
                    // MUST BE CALLED BEFORE setProperty of all proprties
                    localProperties.addLocal(StepExec.DD_PREFIX + ddImpl.getName());
                }

                // after locking, checks for GDG
                // is sure here the root (is a properties file) of GDG is locked
                // (doesn't matter if in READ or WRITE)
                // so can read a consistent data from root and gets the right
                // generation
                // starting from relative position
                for (DataDescriptionImpl ddImpl : ddList) {
                    // loads GDG generation!! it meeans the real file name of
                    // generation
                    GDGManager.load(ddImpl);
                    log(AntMessage.JEMA034I.toMessage().getFormattedMessage(ddImpl));
                    // scans all datasets of datadescription adding new
                    // environment variable
                    for (DataSetImpl dataset : ddImpl.getDatasets()) {
                        propertyHelper.setProperty(StepExec.DD_PREFIX + ddImpl.getName(),
                                dataset.getRealFile().getAbsolutePath(), true);
                    }
                }

            }
            // calls super-method to execute the command configured into JCL
            batchSM.setInternalAction(false);
            // executes the program defined in JCL
            // setting the boolean to TRUE
            isExecutionStarted = true;
            nestedTask.perform();
        } catch (BuildException e1) {
            throw e1;
        } catch (RemoteException e) {
            throw new BuildException(e);
        } catch (IOException e) {
            throw new BuildException(e);
        } finally {
            batchSM.setInternalAction(true);
            // finally and always must release the locks previously asked
            // checks datasets list
            if (ddList != null && !ddList.isEmpty()) {
                // clean scope of properties
                localProperties.exitScope();

                StringBuilder exceptions = new StringBuilder();
                // scans data descriptions
                for (DataDescriptionImpl ddImpl : ddList) {
                    try {
                        // consolidates the GDG situation
                        // changing the root (is a properties file)
                        // only if execution started
                        if (isExecutionStarted) {
                            GDGManager.store(ddImpl);
                        }
                    } catch (IOException e) {
                        // ignore
                        LogAppl.getInstance().ignore(e.getMessage(), e);
                        log(AntMessage.JEMA036E.toMessage().getFormattedMessage(e.getMessage()));
                        if (exceptions.length() == 0) {
                            exceptions.append(AntMessage.JEMA036E.toMessage().getFormattedMessage(e.getMessage()));
                        } else {
                            exceptions.append(AntMessage.JEMA036E.toMessage().getFormattedMessage(e.getMessage()))
                                    .append("\n");
                        }
                    }
                }
                if (exceptions.length() > 0) {
                    log(StringUtils.center("ATTENTION", 40, "-"));
                    log(exceptions.toString());
                }
            }
            batchSM.setInternalAction(false);
        }
    }
}