Package org.tmatesoft.svn.core.internal.wc

Source Code of org.tmatesoft.svn.core.internal.wc.SVNTreeConflictUtil

/*
* ====================================================================
* Copyright (c) 2004-2009 TMate Software Ltd.  All rights reserved.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution.  The terms
* are also available at http://svnkit.com/license.html
* If newer versions of this license are posted there, you may use a
* newer version instead, at your option.
* ====================================================================
*/
package org.tmatesoft.svn.core.internal.wc;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.Map;

import org.tmatesoft.svn.core.SVNErrorCode;
import org.tmatesoft.svn.core.SVNErrorMessage;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNNodeKind;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.internal.util.SVNHashMap;
import org.tmatesoft.svn.core.internal.util.SVNSkel;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.wc.SVNConflictAction;
import org.tmatesoft.svn.core.wc.SVNConflictReason;
import org.tmatesoft.svn.core.wc.SVNOperation;
import org.tmatesoft.svn.core.wc.SVNTreeConflictDescription;
import org.tmatesoft.svn.util.SVNLogType;

/**
* @author  TMate Software Ltd.
* @version 1.3
*/
public class SVNTreeConflictUtil {

    public static Map readTreeConflicts(File dirPath, String conflictData) throws SVNException {
        if (conflictData == null) {
            return new SVNHashMap();
        }
       
        byte[] data;
        try {
            data = conflictData.getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
            data = conflictData.getBytes();
        }
        return readTreeConflicts(dirPath, data);
    }

    public static Map readTreeConflicts(File dirPath, byte[] conflictData) throws SVNException {
        Map conflicts = new SVNHashMap();
        if (conflictData == null) {
            return conflicts;
        }
        SVNSkel skel = SVNSkel.parse(conflictData);
        if (skel == null || skel.isAtom()) {
            SVNErrorMessage error = SVNErrorMessage.create(SVNErrorCode.WC_CORRUPT, "Error parsing tree conflict skel");
            SVNErrorManager.error(error, SVNLogType.WC);
        }
        for (Iterator iterator = skel.getList().iterator(); iterator.hasNext();) {
            SVNSkel conflictSkel = (SVNSkel) iterator.next();
            SVNTreeConflictDescription conflict = readSingleTreeConflict(conflictSkel, dirPath);
            if (conflict != null) {
                conflicts.put(conflict.getPath(), conflict);
            }
        }
        return conflicts;
    }

    private static SVNTreeConflictDescription readSingleTreeConflict(SVNSkel skel, File dirPath) throws SVNException {
        if (!isValidConflict(skel)) {
            SVNErrorMessage error = SVNErrorMessage.create(SVNErrorCode.WC_CORRUPT, "Invalid conflict info in tree conflict description");
            SVNErrorManager.error(error, SVNLogType.WC);
        }
        if (skel.getChild(1).getData().length == 0) {
            SVNErrorMessage error = SVNErrorMessage.create(SVNErrorCode.WC_CORRUPT, "Empty \'victim\' field in tree conflict description");
            SVNErrorManager.error(error, SVNLogType.WC);
        }
        String victimBasename = skel.getChild(1).getValue();

        SVNNodeKind kind = getNodeKind(skel.getChild(2).getValue());
        if (kind != SVNNodeKind.FILE && kind != SVNNodeKind.DIR) {
            SVNErrorMessage error = SVNErrorMessage.create(SVNErrorCode.WC_CORRUPT, "Invalid \'node_kind\' field in tree conflict description");
            SVNErrorManager.error(error, SVNLogType.WC);
        }

        SVNOperation operation = getOperation(skel.getChild(3).getValue());
        SVNConflictAction action = getAction(skel.getChild(4).getValue());
        SVNConflictReason reason = getConflictReason(skel.getChild(5).getValue());
        SVNConflictVersion srcLeftVersion = readConflictVersion(skel.getChild(6));
        SVNConflictVersion srcRightVersion = readConflictVersion(skel.getChild(7));

        return new SVNTreeConflictDescription(new File(dirPath, victimBasename), kind, action, reason, operation, srcLeftVersion, srcRightVersion);
    }

    private static SVNConflictVersion readConflictVersion(SVNSkel skel) throws SVNException {
        if (!isValidVersionInfo(skel)) {
            SVNErrorMessage error = SVNErrorMessage.create(SVNErrorCode.WC_CORRUPT, "Invalid version info in tree conflict description");
            SVNErrorManager.error(error, SVNLogType.WC);
        }
        String repoURLString = skel.getChild(1).getValue();
        SVNURL repoURL = repoURLString.length() == 0 ? null : SVNURL.parseURIEncoded(repoURLString);
        long pegRevision = Long.parseLong(skel.getChild(2).getValue());
        String path = skel.getChild(3).getValue();
        path = path.length() == 0 ? null : path;
        SVNNodeKind kind = getNodeKind(skel.getChild(4).getValue());
        return new SVNConflictVersion(repoURL, path, pegRevision, kind);
    }

    private static boolean isValidVersionInfo(SVNSkel skel) throws SVNException {
        if (skel.getListSize() != 5 || !skel.getChild(0).contentEquals("version")) {
            return false;
        }
        return skel.containsAtomsOnly();
    }

    private static boolean isValidConflict(SVNSkel skel) throws SVNException {
        if (skel.getListSize() != 8 || !skel.getChild(0).contentEquals("conflict")) {
            return false;
        }
        for (int i = 1; i < 6; i++) {
            SVNSkel element = skel.getChild(i);
            if (!element.isAtom()) {
                return false;
            }
        }
        return isValidVersionInfo(skel.getChild(6)) && isValidVersionInfo(skel.getChild(7));
    }

    public static String getTreeConflictData(Map conflicts) throws SVNException {
        if (conflicts == null) {
            return null;
        }
        byte[] rawData = getTreeConflictRawData(conflicts);
        String conflictData;
        try {
            conflictData = new String(rawData, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            conflictData = new String(rawData);
        }
        return conflictData;
    }

    public static byte[] getTreeConflictRawData(Map conflicts) throws SVNException {
        if (conflicts == null) {
            return null;
        }
        SVNConflictVersion nullVersion = new SVNConflictVersion(null, null, SVNRepository.INVALID_REVISION, SVNNodeKind.UNKNOWN);
        SVNSkel skel = SVNSkel.createEmptyList();
        for (Iterator iterator = conflicts.values().iterator(); iterator.hasNext();) {
            SVNTreeConflictDescription conflict = (SVNTreeConflictDescription) iterator.next();
            SVNSkel conflictSkel = SVNSkel.createEmptyList();

            SVNConflictVersion sourceRightVersion = conflict.getSourceRightVersion();
            sourceRightVersion = sourceRightVersion == null ? nullVersion : sourceRightVersion;
            prependVersionInfo(conflictSkel, sourceRightVersion);

            SVNConflictVersion sourceLeftVersion = conflict.getSourceLeftVersion();
            sourceLeftVersion = sourceLeftVersion == null ? nullVersion : sourceLeftVersion;
            prependVersionInfo(conflictSkel, sourceLeftVersion);

            conflictSkel.addChild(SVNSkel.createAtom(conflict.getConflictReason().toString()));
            conflictSkel.addChild(SVNSkel.createAtom(conflict.getConflictAction().toString()));
            conflictSkel.addChild(SVNSkel.createAtom(conflict.getOperation().toString()));

            if (conflict.getNodeKind() != SVNNodeKind.DIR && conflict.getNodeKind() != SVNNodeKind.FILE) {
                SVNErrorMessage error = SVNErrorMessage.create(SVNErrorCode.WC_CORRUPT,
                        "Invalid \'node_kind\' field in tree conflict description");
                SVNErrorManager.error(error, SVNLogType.WC);
            }
            conflictSkel.addChild(SVNSkel.createAtom(getNodeKindString(conflict.getNodeKind())));

            String path = conflict.getPath().getName();
            if (path.length() == 0) {
                SVNErrorMessage error = SVNErrorMessage.create(SVNErrorCode.WC_CORRUPT,
                        "Empty path basename in tree conflict description");
                SVNErrorManager.error(error, SVNLogType.WC);
            }
            conflictSkel.addChild(SVNSkel.createAtom(path));
            conflictSkel.addChild(SVNSkel.createAtom("conflict"));

            if (!isValidConflict(conflictSkel)) {
                SVNErrorMessage error = SVNErrorMessage.create(SVNErrorCode.WC_CORRUPT,
                        "Failed to create valid conflict description skel: ''{0}''", skel.toString());
                SVNErrorManager.error(error, SVNLogType.WC);
            }
            skel.addChild(conflictSkel);
        }
        return skel.unparse();
    }

    public static String getHumanReadableConflictDescription(SVNTreeConflictDescription treeConflict) {
        String reasonStr = getReasonString(treeConflict);
        String actionStr = getActionString(treeConflict);
        String operationStr = treeConflict.getOperation().getName();
        String description = "local " + reasonStr + ", incoming " + actionStr + " upon " + operationStr;
        return description;
    }

    public static String getHumanReadableConflictVersion(SVNConflictVersion version) {
      String url = version.getRepositoryRoot() != null ? version.getRepositoryRoot().toString() : null;
      if (url != null && version.getPath() != null) {
        url = url + "/" + version.getPath();
      } else if (url != null) {
        url = url + "/...";
      } else if (version.getPath() != null) {
        url = version.getPath();
      } else {
        url = "...";
      }
        return "(" + getNodeKindString(version.getKind()) + ") " + url + "@" + version.getPegRevision();
    }
   
    private static String getReasonString(SVNTreeConflictDescription treeConflict) {
        SVNConflictReason reason = treeConflict.getConflictReason();
        if (reason == SVNConflictReason.EDITED) {
            return "edit";
        } else if (reason == SVNConflictReason.OBSTRUCTED) {
            return "obstruction";
        } else if (reason == SVNConflictReason.DELETED) {
            return "delete";
        } else if (reason == SVNConflictReason.ADDED) {
            return "add";
        } else if (reason == SVNConflictReason.MISSING) {
            return "missing";
        } else if (reason == SVNConflictReason.UNVERSIONED) {
            return "unversioned";
        }
        return null;
    }
   
    private static String getActionString(SVNTreeConflictDescription treeConflict) {
        SVNConflictAction action = treeConflict.getConflictAction();
        if (action == SVNConflictAction.ADD) {
            return "add";
        } else if (action == SVNConflictAction.EDIT) {
            return "edit";
        } else if (action == SVNConflictAction.DELETE) {
            return "delete";
        }
        return null;
    }
   
    private static SVNSkel prependVersionInfo(SVNSkel parent, SVNConflictVersion versionInfo) throws SVNException {
        parent = parent == null ? SVNSkel.createEmptyList() : parent;
        SVNSkel skel = SVNSkel.createEmptyList();
        skel.addChild(SVNSkel.createAtom(getNodeKindString(versionInfo.getKind())));
        String path = versionInfo.getPath() == null ? "" : versionInfo.getPath();
        skel.addChild(SVNSkel.createAtom(path));
        skel.addChild(SVNSkel.createAtom(String.valueOf(versionInfo.getPegRevision())));
        String repoURLString = versionInfo.getRepositoryRoot() == null ? "" : versionInfo.getRepositoryRoot().toString();
        skel.addChild(SVNSkel.createAtom(repoURLString));
        skel.addChild(SVNSkel.createAtom("version"));
        if (!isValidVersionInfo(skel)) {
            SVNErrorMessage error = SVNErrorMessage.create(SVNErrorCode.WC_CORRUPT, "Failed to create valid conflict version skel: ''{0}''", skel.toString());
            SVNErrorManager.error(error, SVNLogType.WC);
        }
        parent.addChild(skel);
        return parent;
    }

    private static SVNNodeKind getNodeKind(String name) throws SVNException {
        if ("".equals(name)) {
            return SVNNodeKind.UNKNOWN;
        }
        SVNNodeKind kind = SVNNodeKind.parseKind(name);
        if (kind == SVNNodeKind.UNKNOWN) {
            mappingError("node kind");
        }
        return kind;
    }

    private static String getNodeKindString(SVNNodeKind kind) {
        if (kind ==SVNNodeKind.UNKNOWN) {
            return "";
        }
        return kind.toString();
    }

    private static SVNOperation getOperation(String name) throws SVNException {
        SVNOperation operation = SVNOperation.fromString(name);
        if (operation == null) {
            mappingError("operation");
        }
        return operation;
    }

    private static SVNConflictAction getAction(String name) throws SVNException {
        SVNConflictAction action = SVNConflictAction.fromString(name);
        if (action == null) {
            mappingError("conflict action");
        }
        return action;
    }

    private static SVNConflictReason getConflictReason(String name) throws SVNException {
        SVNConflictReason reason;
        if (SVNConflictReason.UNVERSIONED.getName().equals(name)) {
            reason = null;
        } else {
            reason = SVNConflictReason.fromString(name);
        }
        if (reason == null) {
            mappingError("conflict reason");
        }
        return reason;
    }

    private static void mappingError(String type) throws SVNException {
        SVNErrorMessage error = SVNErrorMessage.create(SVNErrorCode.WC_CORRUPT, "Unknown {0} value in tree conflict description", type);
        SVNErrorManager.error(error, SVNLogType.WC);
    }
}
TOP

Related Classes of org.tmatesoft.svn.core.internal.wc.SVNTreeConflictUtil

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.