BuildCommand.java

package org.docascode.api;

import org.apache.tools.ant.*;
import org.docascode.ant.DocAsCodeAntLogger;
import org.docascode.api.core.DocAsCodeRepository;

import java.util.*;
import java.util.stream.Collectors;

public class BuildCommand extends DocAsCodeCommand<Project> {
    public enum LogLevel{
        INFO(Project.MSG_INFO),
        WARN(Project.MSG_WARN),
        DEBUG(Project.MSG_DEBUG);

        private int antLogLevel;

        LogLevel(int antLogLevel) {
            this.antLogLevel = antLogLevel;
        }

        int getAntLogLevel(){
            return this.antLogLevel;
        }
    }

    private List<String> targets = new ArrayList<>();

    public BuildCommand setTargets(List<String> targets) {
        this.targets = targets;
        return this;
    }

    private Map<String,String> properties = new HashMap<>();

    public BuildCommand setProperties(Map<String,String> properties) {
        if( properties !=null){
            this.properties = properties;
        }
        return this;
    }

    public BuildCommand(DocAsCodeRepository repo) {
        super(repo);
    }

    private Project project = new Project();
    private ProjectHelper projectHelper = ProjectHelper.getProjectHelper();

    private void initProject() {
        project.setUserProperty("ant.file", getRepository().getDeliveryXML().getAbsolutePath());
        for (Map.Entry<String,String> entry : properties.entrySet()){
            project.setUserProperty(entry.getKey(),entry.getValue());
        }
        project.init();
        project.addReference("ant.projectHelper", projectHelper);
        project.setBaseDir(getRepository().getWorkTree());
        projectHelper.parse(project, getRepository().getDeliveryXML());
    }

    private LogLevel logLevel = LogLevel.INFO;

    public BuildCommand setLogLevel(LogLevel logLevel){
        this.logLevel = logLevel;
        return this;
    }

    @Override
    public Project call(){
        initProject();
        DocAsCodeAntLogger consoleLogger = new DocAsCodeAntLogger();
        consoleLogger.setErrorPrintStream(System.err);
        consoleLogger.setOutputPrintStream(System.out);
        consoleLogger.setMessageOutputLevel(this.logLevel.getAntLogLevel());
        project.addBuildListener(consoleLogger);
        if (targets.isEmpty()){
            targets.add(project.getDefaultTarget());
        }
        project.executeTargets(new Vector<>(targets));
        return project;
    }

    public Map<String, Target> listTargets() {
        initProject();
        return removeDuplicateTargets(project.getTargets());
    }

    private static Map<String, Target> removeDuplicateTargets(final Map<String, Target> targets) {
        final Map<Location, Target> locationMap = new HashMap<>();
        targets.forEach((name, target) -> {
            final Target otherTarget = locationMap.get(target.getLocation());
            // Place this entry in the location map if
            //  a) location is not in the map
            //  b) location is in map, but its name is longer
            //     (an imported target will have a name. prefix)
            if (!name.isEmpty() && (otherTarget == null || otherTarget.getName().length() > name.length())) {
                locationMap.put(target.getLocation(), target); // Smallest name wins
            }
        });
        return locationMap.values().stream()
                .collect(Collectors.toMap(Target::getName, target -> target, (a, b) -> b));
    }
}