All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.canoo.ant.task.PropertyTableTask Maven / Gradle / Ivy

package com.canoo.ant.task;

import java.io.File;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;

import org.apache.log4j.Logger;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.RuntimeConfigurable;
import org.apache.tools.ant.Target;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.TaskContainer;
import org.apache.tools.ant.UnknownElement;
import org.apache.tools.ant.taskdefs.MacroInstance;

import com.canoo.ant.filter.ITableFilter;
import com.canoo.ant.table.APropertyTable;
import com.canoo.ant.table.ExcelPropertyTable;
import com.canoo.ant.table.IPropertyTable;
import com.canoo.ant.table.TableFactory;

/**
 * 
 * @author Dierk K?nig
 * @author Marc Guillemot
 * @webtest.step
 *   category="Extension"
 *   name="dataDriven"
 *   description="This is an Ant task that calls its nested element as often as specified by the tableContainer.
 *   In each run a new set of properties from the the tableContainer is made available to the nested steps"
 */
public class PropertyTableTask extends Task implements TaskContainer {
    private static final Logger LOG = Logger.getLogger(PropertyTableTask.class);

    private List fTasks = new LinkedList();
    private Properties fProps = new Properties();
    private String fName;
    private String fValue;
    private boolean fFailASAP = false;
    private File fTableContainer;
    private boolean replaceProperties;

    /**
     * @webtest.parameter required="no"
     * default="no"
     * description="Specifies whether properties contained in the table's values
     * should be expanded or not"
     * @param replaceProperties
     */
    public void setReplaceProperties(boolean replaceProperties) {
        this.replaceProperties = replaceProperties;
    }

    public void setValue(final String value) {
        fValue = value;
    }

    public void setName(String name) {
        fName = name;
    }

    public void setTableclass(String tableClass) {
        fProps.setProperty(TableFactory.KEY_TABLE_CLASS, tableClass);
    }

    /**
     * @webtest.parameter required="no" default="FirstEquals"
     * description="The filter to apply on the foreign table after the lookup.
     * One of \"All\", \"Empty\", \"FirstEquals\", \"AllEquals\" or \"Group\"."
     */
    public void setFilterclass(String filterClass) {
        fProps.setProperty(TableFactory.KEY_FILTER_CLASS, filterClass);
    }

    /**
     * @webtest.parameter required="no"
     * default="the first table"
     * description="The name of the source table in the current container. 
     * For instance the name of the sheet when the table container is an Excel document."
     */
    public void setTable(final String table) {
        fProps.setProperty(TableFactory.KEY_FOREIGN_TABLE, table); // unlucky naming in this context
    }

    /**
    * @webtest.parameter required="yes"
    * description="The container for the table containing the data.
    * Typically this is the path to an Excel file but this can also be a directory structure."
    */
    public void setTableContainer(final File container) throws IOException {
    	fTableContainer = container;
    }
    public void setContainer(final File container) throws IOException {
    	setTableContainer(container);
    }

    /**
     * @webtest.parameter required="no"
     * default="false"
     * description="Indicates if the task should fail at the first failure of the nested content (when set to true)
     * or continue the execution for all records and then throw a BuildException when one or more error occurred (when set to false)."
     */
    public void setFailASAP(final boolean newValue) {
    	fFailASAP = newValue;
    }

    /**
     * Called by Ant to add nested tasks
     * @see org.apache.tools.ant.TaskContainer#addTask(org.apache.tools.ant.Task)
     * @webtest.nested.parameter required="yes"
     * description="Any Ant task."
     */
    public void addTask(final Task task) {
        fTasks.add(task);
    }

    public void execute() throws BuildException {
        final IPropertyTable table;
        final ITableFilter filter;
        try {
            table = TableFactory.createTable(fProps, ExcelPropertyTable.class.getName());
            filter = TableFactory.createFilter(fProps);
        } 
        catch (final Exception e) {
            throw new BuildException("cannot create container", e, getLocation());
        }

        TableFactory.initOrDefault(table, filter, fProps, fTableContainer, fName);

        final List propertiesList = table.getPropertiesList(fValue, null);
        LOG.debug("propertiesList.size() = " + propertiesList.size());
        if (propertiesList.isEmpty()) {
            LOG.warn("no match found in table " + table.getClass().getName() +
                    " with filter " + table.getFilter().getClass().getName() +
                    " and settings " + fProps.toString() +
                    " raw data:" + ((APropertyTable) table).getRawTable());
        }

        int nbFailures = 0;
        int nbRuns = 0;
        for (final Iterator eachPropSet = propertiesList.iterator(); eachPropSet.hasNext();) {
        	++nbRuns;
            final Properties propSet = (Properties) eachPropSet.next();
            for (final Iterator eachKey = propSet.keySet().iterator(); eachKey.hasNext();) {
                final String key = (String) eachKey.next();
                String value = propSet.getProperty(key);
                if (replaceProperties) {
                    value = getProject().replaceProperties(value);
                }
                LOG.debug("setting key/value " + key + "/" + value);
                getProject().setInheritedProperty(key, value);
            }
            
            for (final Iterator eachTask = fTasks.iterator(); eachTask.hasNext();) {
            	Task task = (Task) eachTask.next();
                // It's probably allways the case
                if (task instanceof UnknownElement)
                {
                	task = copy((UnknownElement) task);
                }
                try {
                	task.perform();
                }
                catch (final BuildException e)
                {
                	if (fFailASAP)
                		throw e;
                	else
                		nbFailures++;
                }
            }
        }
        if (nbFailures > 0) {
        	throw new BuildException("" + nbFailures + "/" + nbRuns + " executions of nested tasks failed");
        }
    }

    /**
     * Performs a fresh copy of the element. Inspired from {@link MacroInstance#copy}
     * Ideally Ant should offer a method for it
     * See https://issues.apache.org/bugzilla/show_bug.cgi?id=44795
     */
    private UnknownElement copy(UnknownElement ue) {
        UnknownElement ret = new UnknownElement(ue.getTag());
        ret.setNamespace(ue.getNamespace());
        ret.setProject(getProject());
        ret.setQName(ue.getQName());
        ret.setTaskType(ue.getTaskType());
        ret.setTaskName(ue.getTaskName());
        ret.setLocation(ue.getLocation());
        if (getOwningTarget() == null) {
            Target t = new Target();
            t.setProject(getProject());
            ret.setOwningTarget(t);
        } else {
            ret.setOwningTarget(getOwningTarget());
        }
        RuntimeConfigurable rc = new RuntimeConfigurable(
            ret, ue.getTaskName());
        rc.setPolyType(ue.getWrapper().getPolyType());
        final Map m = ue.getWrapper().getAttributeMap();
        for (Iterator i = m.entrySet().iterator(); i.hasNext();) {
            Map.Entry entry = (Map.Entry) i.next();
            rc.setAttribute(
                (String) entry.getKey(),
                (String) entry.getValue());
        }
        rc.addText(ue.getWrapper().getText().toString());

        final Enumeration e = ue.getWrapper().getChildren();
        while (e.hasMoreElements()) {
            RuntimeConfigurable r = (RuntimeConfigurable) e.nextElement();
            UnknownElement unknownElement = (UnknownElement) r.getProxy();
            String tag = unknownElement.getTaskType();
            if (tag != null) {
                tag = tag.toLowerCase(Locale.US);
            }

            UnknownElement child = copy(unknownElement);
            rc.addChild(child.getWrapper());
            ret.addChild(child);

        }
        return ret;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy