Package com.aragost.javahg.merge

Source Code of com.aragost.javahg.merge.ConflictResolvingContext

package com.aragost.javahg.merge;

import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import com.aragost.javahg.Changeset;
import com.aragost.javahg.Repository;
import com.aragost.javahg.WorkingCopy;
import com.aragost.javahg.commands.LogCommand;
import com.aragost.javahg.commands.ResolveCommand;
import com.aragost.javahg.commands.ResolveStatusLine;
import com.aragost.javahg.internals.AbstractCommand;
import com.aragost.javahg.internals.HgInputStream;
import com.aragost.javahg.internals.UnexpectedCommandOutputException;
import com.aragost.javahg.internals.Utils;
import com.google.common.collect.Lists;

/**
* Base class for a context where conflicts are resolved.
* <p>
* That is for example after a merge or graft.
*/
public abstract class ConflictResolvingContext {

    private static final byte[] USE_RESOLVE_EXPLANATION = "use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon\n".getBytes();
    private static final byte[] USE_RESOLVE_SHORT_EXPLANATION = "use 'hg resolve' to retry unresolved file merges\n".getBytes();
    private static final byte[] BRANCH_MERGE_EXPLANATION = "(branch merge, don't forget to commit)\n".getBytes();
    private static final byte[] FILES_REMOVED = " files removed, ".getBytes();
    private static final byte[] FILES_MERGED = " files merged, ".getBytes();
    private static final byte[] FILES_UPDATED = " files updated, ".getBytes();
    private static final byte[] LOCAL_CHANGED_AFTER = " which remote deleted\nuse (c)hanged version or (d)elete? c\n".getBytes();
    private static final byte[] LOCAL_CHANGED = " local changed ".getBytes();
    private static final byte[] REMOVED_CHANGE_AFTER = " which local deleted\nuse (c)hanged version or leave (d)eleted? c\n".getBytes();
    private static final byte[] REMOTE_CHANGED = "remote changed ".getBytes();
    private static final byte[] CONFLICTING_FLAGS = " conflicting flags for ".getBytes();
    private static final String NONE_EXEC_SYMLINK = "(n)one, e(x)ec or sym(l)ink? n\n";

    private AbstractCommand command;

    private WorkingCopy workingCopy;

    private List<KeepDeleteConflict> keepDeleteConflicts = Lists.newArrayList();

    private List<FlagConflict> flagConflicts = Lists.newArrayList();

    private List<MergeConflict> mergeConflicts;

    private Changeset base;

    public ConflictResolvingContext(AbstractCommand command) {
        this.command = command;
        this.workingCopy = this.command.getRepository().workingCopy();
    }

    public WorkingCopy getWorkingCopy() {
        return workingCopy;
    }

    public Collection<FlagConflict> getFlagConflicts() {
        return flagConflicts;
    }

    public List<KeepDeleteConflict> getKeepDeleteConflicts() {
        return keepDeleteConflicts;
    }

    public synchronized List<MergeConflict> getMergeConflicts() {
        if (this.mergeConflicts == null) {
            List<ResolveStatusLine> lines = ResolveCommand.on(getRepository()).list();
            List<MergeConflict> conflicts = Lists.newArrayListWithCapacity(lines.size());
            for (ResolveStatusLine line : lines) {
                MergeConflict mergeConflict = new MergeConflict(this, line.getFileName());
                conflicts.add(mergeConflict);
            }
            this.mergeConflicts = conflicts;
        }
        return mergeConflicts;
    }

    public Repository getRepository() {
        return this.command.getRepository();
    }

    public AbstractCommand getCommand() {
        return command;
    }

    /**
     * Read input from the stream record conflicts.
     * <p>
     *
     * @param in
     * @param whenUnknowReturn
     * @throws IOException
     */
    public void processStream(HgInputStream in, boolean whenUnknowReturn) throws IOException {
        while (!in.isEof()) {
            byte[] endPattern = null;
            KeepDeleteConflict.State keepState = null;
            if (in.match(REMOTE_CHANGED)) {
                endPattern = REMOVED_CHANGE_AFTER;
                keepState = KeepDeleteConflict.State.DELETE;
            } else if (in.match(LOCAL_CHANGED)) {
                endPattern = LOCAL_CHANGED_AFTER;
                keepState = KeepDeleteConflict.State.KEEP;
            } else if (in.match(CONFLICTING_FLAGS)) {
                String fileName = in.textUpTo('\n');
                in.mustMatch(NONE_EXEC_SYMLINK.getBytes());
                FlagConflict flagConflict = new FlagConflict(this, fileName);
                this.flagConflicts.add(flagConflict);

            } else if ((in.readDecimal()) != null) {
                in.mustMatch(FILES_UPDATED);
                Integer merged = in.readDecimal();
                in.mustMatch(FILES_MERGED);
                Integer removed = in.readDecimal();
                in.mustMatch(FILES_REMOVED);
                Integer unresolved = in.readDecimal();
                in.mustMatch(" files unresolved\n".getBytes());
                if (merged == null || removed == null || unresolved == null) {
                    throw new UnexpectedCommandOutputException(this.command, null);
                }
                if (unresolved.intValue() == 0) {
                    this.mergeConflicts = Collections.emptyList();
                    // If there is merge conflicts it will be lazy
                    // intialized
                }
            } else if (in.match(USE_RESOLVE_EXPLANATION)) {
                // ignore
            } else if (in.match(USE_RESOLVE_SHORT_EXPLANATION)) {
                // ignore
            } else if (in.match(BRANCH_MERGE_EXPLANATION)) {
                // ignore
            } else {
                if (whenUnknowReturn) {
                    return;
                } else {
                    throw new UnexpectedCommandOutputException(Utils.readStream(in,
                            command.getRepository().getServer().newDecoder()));
                }
            }
            if (endPattern != null) {
                String fileName = in.textUpTo(endPattern);
                KeepDeleteConflict keepRemoveConflict = new KeepDeleteConflict(this, fileName, keepState);
                this.keepDeleteConflicts.add(keepRemoveConflict);
            }
        }
    }

    public Changeset getLocal() {
        return getWorkingCopy().getParent1();
    }

    public Changeset getRemote() {
        return getWorkingCopy().getParent2();
    }

    public synchronized Changeset getBase() {
        if (base == null) {
            String ancestorRev = "ancestor(" + getLocal().getNode() + "," + getRemote().getNode() + ")";
            this.base = LogCommand.on(getRepository()).rev(ancestorRev).single();
        }
        return this.base;
    }

}
TOP

Related Classes of com.aragost.javahg.merge.ConflictResolvingContext

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.