MergeCommand.java

package org.docascode.api;

import com.profesorfalken.jpowershell.PowerShell;
import com.profesorfalken.jpowershell.PowerShellResponse;
import org.docascode.api.core.errors.DocAsCodeException;
import org.docascode.api.core.DocAsCodeRepository;
import org.docascode.api.event.Event;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Paths;

public class MergeCommand extends DocAsCodeCommand<File>  {
    private static final String DOCX =".docx";

    private static final String FAILED_TO_MOVE = "Failed to move '%s' to '%s'.";

    private String format;

    public MergeCommand setFormat(String format){
        this.format = format;
        return this;
    }

    private File ancestor;

    public MergeCommand setAncestor(String ancestor){
        this.ancestor = new File(
                getRepository().getWorkTree(),ancestor);
        return this;
    }

    private File current;

    public MergeCommand setCurrent(String current){
        this.current = new File(
                getRepository().getWorkTree(),current);
        return this;
    }

    private File other;

    public MergeCommand setOther(String other){
        this.other = new File(
                getRepository().getWorkTree(),other);
        return this;
    }

    private String placeHolder;

    public MergeCommand setPlaceHolder(String placeHolder){
        this.placeHolder = placeHolder;
        return this;
    }

    MergeCommand(DocAsCodeRepository repo) {
        super(repo);
    }

    @Override
    public File call() throws DocAsCodeException {
        Event e = new Event(this)
                .setMessage(String.format(
                        "Resolving conflicts for %s...",
                        placeHolder));
        fireEvent(e);
        switch (format){
            case "docx":
                File newAncestor = new File(
                        ancestor,DOCX);
                if (!ancestor.renameTo(newAncestor)){
                    throw new DocAsCodeException(
                            String.format(FAILED_TO_MOVE,
                                    ancestor.getAbsolutePath(),
                                    newAncestor.getAbsolutePath())
                    );
                }
                File newOther = new File(
                        other,DOCX);
                if (!other.renameTo(newOther)){
                    throw new DocAsCodeException(
                            String.format(FAILED_TO_MOVE,
                                    other.getAbsolutePath(),
                                    newOther.getAbsolutePath())
                    );
                }
                File newCurrent = new File(
                        current,DOCX);
                if(!current.renameTo(newCurrent)){
                    throw new DocAsCodeException(
                            String.format(FAILED_TO_MOVE,
                                    current.getAbsolutePath(),
                                    newCurrent.getAbsolutePath())
                    );
                }
                try(PowerShell powerShell = PowerShell.openSession()) {
                    String script = "powershell/merge-docx.ps1";

                    //Read the resource
                    BufferedReader srcReader = new BufferedReader(
                            new InputStreamReader(getClass().getClassLoader().getResourceAsStream(script)));
                    PowerShellResponse response = powerShell.executeScript(srcReader,
                            String.format("-sBaseDoc %s -sMyDoc %s -sTheirDoc %s -sTargetDoc %s",
                                    newAncestor.getAbsolutePath(),
                                    newCurrent.getAbsolutePath(),
                                    newOther.getAbsolutePath(),
                                    newCurrent.getAbsolutePath()));
                    if (response.isError()) {
                        throw new DocAsCodeException(
                                String.format("Failed to perform merge. Caused by %s.",
                                        response.getCommandOutput()));
                    }
                    if (!newCurrent.renameTo(current)){
                        log(String.format(
                                "Failed to rename '%s' to '%s'. Please do it manually.",
                                newCurrent.getAbsolutePath(),
                                current.getAbsolutePath()
                        ), Event.Level.WARN);
                    }
                    try {
                        Files.delete(Paths.get(newAncestor.getAbsolutePath()));
                    } catch (IOException ex) {
                        log(String.format(
                           "Failed to remove '%s'. Please do it manually.",
                           newAncestor.getAbsolutePath()
                        ), Event.Level.WARN);
                        log(ex.getMessage(), Event.Level.DEBUG);
                    }
                    try {
                        Files.delete(Paths.get(newOther.getAbsolutePath()));
                    } catch (IOException ex) {
                        log(String.format(
                                "Failed to remove '%s'. Please do it manually.",
                                newOther.getAbsolutePath()
                        ), Event.Level.WARN);
                        log(ex.getMessage(), Event.Level.DEBUG);
                    }
                    return current;

                }
            default:
                throw new DocAsCodeException(
                        String.format("Unsupported format: %s.",
                                format));
        }
    }
}