ProcessTask.java

package org.docascode.ant;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.taskdefs.MacroDef;
import org.apache.tools.ant.taskdefs.MacroInstance;
import org.apache.tools.ant.types.Mapper;
import org.apache.tools.ant.util.FileNameMapper;
import org.docascode.api.DocAsCode;
import org.docascode.api.core.Substitute;
import org.docascode.api.core.chrono.OutputMap;
import org.docascode.api.core.chrono.generated.*;
import org.docascode.api.core.errors.DocAsCodeException;
import org.docascode.api.core.office.PropertiesProcessor;

import java.io.File;
import java.util.*;

public class ProcessTask extends Task {
    private static final String CLASSIFIER="classifier";

    private static final String OUTPUT="output";

    private List<String> ids = new ArrayList<>();
    public void setIds(String ids){
        if (!ids.equals("")) {
            this.ids = Arrays.asList(ids.split(","));
        }
    }

    private String name = "default";
    public void setName(String name){
        this.name = name;
    }

    public Mapper createMapper() {
        if (elementMapper != null) {
            throw new BuildException("Cannot define more than one mapper",
                    getLocation());
        }
        elementMapper = new Mapper(getProject());
        return elementMapper;
    }

    private Mapper elementMapper;
    public void add(FileNameMapper mapper){
        createMapper().add(mapper);
    }

    private FileNameMapper getMapper() {
        FileNameMapper mapper;
        if (elementMapper!=null) {
            mapper = elementMapper.getImplementation();
        } else {
            mapper = null;
        }
        return mapper;
    }

    private MacroDef macro;
    public Object createActions() {
        macro = new MacroDef();
        return macro.createSequential();
    }

    private Map<String, String> handleFile(MacroInstance instance, BaseArtifact a) throws DocAsCodeException {
        Map<String, String> dict;
        if (a.getFile()==null){
            instance.setDynamicAttribute("file","");
            dict = new HashMap<>();
        } else {
            instance.setDynamicAttribute("file",a.getFile());
            dict = new PropertiesProcessor().list(new File(getProject().getBaseDir(),
                    a.getFile()));
        }
        return dict;
    }

    private void handleMaven(MacroInstance instance, Artifact a, Map<String, String> dict) throws DocAsCodeException {
        Maven n = a.getMaven();
        if (n == null) {
            n = new Maven();
        }
        instance.setDynamicAttribute("groupId",
                nullToEmpty(
                        Substitute.substitute(n.getGroupId(),dict)));
        instance.setDynamicAttribute("artifactId",
                nullToEmpty(
                        Substitute.substitute(n.getArtifactId(),dict)));
        instance.setDynamicAttribute("version",
                nullToEmpty(
                        Substitute.substitute(n.getVersion(),dict)));

    }

    /**
     * executes the Ant task
     *
     * @throws BuildException
     */
    @Override
    public void execute() {
        MacroInstance instance = new MacroInstance();
        instance.setProject(getProject());
        instance.setMacroDef(macro);
        MacroDef.Attribute id = new MacroDef.Attribute();
        id.setName("id");
        macro.addConfiguredAttribute(id);
        MacroDef.Attribute classifier = new MacroDef.Attribute();
        classifier.setName(CLASSIFIER);
        macro.addConfiguredAttribute(classifier);
        MacroDef.Attribute file = new MacroDef.Attribute();
        file.setName("file");
        macro.addConfiguredAttribute(file);
        MacroDef.Attribute groupId = new MacroDef.Attribute();
        groupId.setName("groupId");
        macro.addConfiguredAttribute(groupId);
        MacroDef.Attribute artifactId = new MacroDef.Attribute();
        artifactId.setName("artifactId");
        macro.addConfiguredAttribute(artifactId);
        MacroDef.Attribute version = new MacroDef.Attribute();
        version.setName("version");
        macro.addConfiguredAttribute(version);
        MacroDef.Attribute output = new MacroDef.Attribute();
        output.setName(OUTPUT);
        macro.addConfiguredAttribute(output);
        Delivery delivery;
        Map<String, String> dict;
        try (DocAsCode docascode = DocAsCode.open(getProject().getBaseDir())) {
             delivery = docascode
                    .getRepository()
                    .chrono()
                    .getDelivery();
            for (String i : this.ids){
                Artifact a = delivery.getArtifacts().get(i);
                instance.setDynamicAttribute("id",i);
                instance.setDynamicAttribute(CLASSIFIER,"");
                dict = handleFile(instance,a);
                handleMaven(instance,a,dict);
                handleOutput(instance,a,dict);

                if (a.getAttach()!=null){
                    for (Map.Entry<String, BaseArtifact> base : a.getAttach().entrySet()){
                        instance.setDynamicAttribute(CLASSIFIER,base.getKey());
                        dict = handleFile(instance,base.getValue());
                        handleOutput(instance,base.getValue(),dict);
                    }
                }
            }
        } catch (DocAsCodeException e) {
            throw new BuildException(e);
        }
    }

    private void handleOutput(MacroInstance instance, BaseArtifact a, Map<String, String> dict) throws DocAsCodeException {
        FileNameMapper mapper = getMapper();
        if (mapper!=null){
            for (String o : mapper.mapFileName(a.getFile())){
                if (o!=null){
                    instance.setDynamicAttribute(OUTPUT,o);
                    instance.execute();
                }
            }
        } else {
            OutputMap outputs = a.getOutputs();
            if (outputs == null) {
                outputs = new OutputMap();
            }
            instance.setDynamicAttribute(OUTPUT,
                    nullToEmpty(
                            Substitute.substitute((String) outputs.get(this.name),
                                    dict)));
            instance.execute();
        }
    }

    private String nullToEmpty(String str){
        return str == null ? "" : str;
    }
}