ACIDCommand.java

package org.docascode.api;

import org.docascode.api.core.errors.DocAsCodeException;
import org.docascode.api.event.Event;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class ACIDCommand extends DocAsCodeCommand<File>  {
    private static final String ACID = "acidcmd.exe";

    private static final String ARCHIVE = "/A\"%s\"";

    private String basename = "archive";

    private File destDir;

    private List<File> pubKeys = new ArrayList<>();

    private List<File> files = new ArrayList<>();

    private ProcessBuilder process;

    public ACIDCommand setFiles (List<File> files){
        this.files =files;
        return this;
    }

    public ACIDCommand setPubKeys(List<File> files){
        pubKeys = files;
        return this;
    }

    public ACIDCommand setDestDir(File destDir){
        this.destDir=destDir;
        return this;
    }

    public ACIDCommand setName (String basename){
        this.basename = basename;
        return this;
    }

    private String startProcess() throws DocAsCodeException {
        try {
            Process run = process.start();
            if (run.waitFor()>0){
                InputStream is = run.getErrorStream();
                InputStreamReader isr = new InputStreamReader(is);
                BufferedReader br = new BufferedReader(isr);
                throw new DocAsCodeException(
                        String.format("Error while caliing '%s'. Cause: %s",process.command(),br.readLine()));
            }
            InputStream is = run.getInputStream();
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(isr);
        return br.readLine();
        } catch (IOException e) {
            throw new DocAsCodeException(
                    String.format("Unable to start process '%s'.",process.command()),e);
        } catch (InterruptedException e) {
            log(String.format("Process '%s' interrupted",process.command()), Event.Level.WARN);
            Thread.currentThread().interrupt();
            return null;
        }
    }

    private String createArchive(File archive) throws DocAsCodeException {
        archive.getParentFile().mkdirs();
        process = new ProcessBuilder(
                ACID,
                "/archive.create",
                "/CS",
                String.format(ARCHIVE,archive));
        log(String.format(
                "Creating archive %s.",
                archive.getAbsolutePath()),
                Event.Level.INFO);
        startProcess();
        process = new ProcessBuilder(
                ACID,
                "/archive.open",
                archive.getAbsolutePath());
        return startProcess();
    }

    @Override
    public File call() throws DocAsCodeException {
        File archive = new File(
                String.format("%s/%s.acidcsa",
                        this.destDir,
                        this.basename));
        String id = createArchive(archive);
        addPubKey(id);
        addFiles(id);
        saveAndClose(id);
        return archive;
    }

    private void saveAndClose(String id) throws DocAsCodeException {
        process = new ProcessBuilder(
                ACID,
                "/archive.save",
                String.format(ARCHIVE,id));
        startProcess();
        process = new ProcessBuilder(
                ACID,
                "/archive.close",
                String.format(ARCHIVE,id));
        startProcess();
    }

    private void addFiles(String id) throws DocAsCodeException {
        for (File file : files){
            process = new ProcessBuilder(
                    ACID,
                    "/archive.addfile",
                    String.format("/A%s",id),
                    file.getAbsolutePath());
            if (file.isDirectory()){
                log(String.format(
                    "Adding folder %s.",
                    file.getAbsolutePath()), Event.Level.INFO);
            } else {
                log(String.format(
                    "Adding file %s.",
                    file.getAbsolutePath()), Event.Level.INFO);
            }
            startProcess();
        }
    }

    private void addPubKey(String id) throws DocAsCodeException {
        for (File pubKey : pubKeys) {
            process = new ProcessBuilder(
                    ACID,
                    "/archive.adddest",
                    String.format(ARCHIVE, id),
                    pubKey.getAbsolutePath());
            log(String.format(
                "Adding pubkey %s.",
                pubKey.getAbsolutePath()), Event.Level.INFO);
            startProcess();
        }
    }
}