io.github.svndump_to_git.git.model.branch.BranchDetectorImpl Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2014 The Kuali Foundation Licensed under the
* Educational Community License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may
* obtain a copy of the License at
*
* http://www.osedu.org/licenses/ECL-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an "AS IS"
* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package io.github.svndump_to_git.git.model.branch;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import io.github.svndump_to_git.branch.model.BranchData;
import org.apache.commons.lang3.StringUtils;
import io.github.svndump_to_git.git.model.branch.exceptions.VetoBranchException;
/**
* @author Kuali Student Team
*
*/
public class BranchDetectorImpl implements BranchDetector {
private Set invalidBeforeTagPaths = new HashSet();
private Set standardBackwardMatchPaths = new HashSet();
private Set backwardMatchPaths = new HashSet();
private Set forwardMatchPaths = new HashSet();
private ListalternateTagNames = new ArrayList();
/**
*
*/
public BranchDetectorImpl() {
// TODO Auto-generated constructor stub
}
/**
* @param invalidBeforeTagPaths the invalidBeforeTagPaths to set
*/
public void setInvalidBeforeTagPaths(Set invalidBeforeTagPaths) {
this.invalidBeforeTagPaths = invalidBeforeTagPaths;
}
/**
* @param standardBackwardMatchPaths the standardBackwardMatchPaths to set
*/
public void setStandardBackwardMatchPaths(Set standardBackwardMatchPaths) {
this.standardBackwardMatchPaths = standardBackwardMatchPaths;
}
/**
* @param backwardMatchPaths the backwardMatchPaths to set
*/
public void setBackwardMatchPaths(Set backwardMatchPaths) {
this.backwardMatchPaths = backwardMatchPaths;
}
/**
* @param forwardMatchPaths the forwardMatchPaths to set
*/
public void setForwardMatchPaths(Set forwardMatchPaths) {
this.forwardMatchPaths = forwardMatchPaths;
}
/**
* @param alternateTagNames the alternateTagNames to set
*/
public void setAlternateTagNames(List alternateTagNames) {
this.alternateTagNames = alternateTagNames;
}
/* (non-Javadoc)
* @see BranchDetector#parseBranch(java.lang.Long, java.lang.String, java.lang.String[])
*/
@Override
public BranchData parseBranch(Long revision, String path)
throws VetoBranchException {
String[] parts = path.split("\\/");
List branchPathList = new ArrayList();
List pathList = new ArrayList();
int beforePathRootIndex = Integer.MAX_VALUE;
beforePathRootIndex = lastIndexOfKey(parts, "trunk", true);
if (beforePathRootIndex == -1) {
beforePathRootIndex = lastIndexOfKey(parts, "tags",
invalidBeforeTagPaths, true);
}
if (beforePathRootIndex == -1) {
int alternateTagIndex = 0;
while (alternateTagIndex < alternateTagNames.size()) {
String alternateTag = alternateTagNames.get(alternateTagIndex);
beforePathRootIndex = lastIndexOfKey(parts, alternateTag,
invalidBeforeTagPaths, true);
if (beforePathRootIndex != -1)
break;
else
alternateTagIndex++;
}
}
if (beforePathRootIndex == -1) {
beforePathRootIndex = indexOfKey(parts, standardBackwardMatchPaths,
true);
}
if (beforePathRootIndex == -1) {
beforePathRootIndex = indexOfKey(parts, backwardMatchPaths, false);
}
if (beforePathRootIndex == -1) {
beforePathRootIndex = indexOfKey(parts, forwardMatchPaths, false);
}
if (beforePathRootIndex == -1) {
/*
* No branch was determined.
*/
throw new VetoBranchException("no branch could be computed for path : " + path);
} else {
/*
* on trunk the next element is the path
*
* on branches the next element is the name of the branch and part
* of the branches path
*/
String canidatePart = parts[beforePathRootIndex].toLowerCase();
if (canidatePart.equals("trunk")
|| forwardMatchPaths.contains(canidatePart)) {
parseTrunkParts(beforePathRootIndex, parts, branchPathList,
pathList);
} else {
int branchNameIndex = beforePathRootIndex + 1;
int pathNameStartIndex = branchNameIndex + 1;
if (parts.length < pathNameStartIndex) {
// there is no part after the branches part
for (int i = 0; i <= beforePathRootIndex; i++) {
branchPathList.add(parts[i]);
}
} else {
for (int i = 0; i <= branchNameIndex; i++) {
branchPathList.add(parts[i]);
}
// skips over the branch name?
for (int i = pathNameStartIndex; i < parts.length; i++) {
pathList.add(parts[i]);
}
}
}
}
// make sure there are path elements
if (pathList.size() == 0) {
// this is a atypical path with no branches or tags
// put the whole name into the branches part
return new BranchData(revision, StringUtils.join(branchPathList,
"/"), "");
} else
return new BranchData(revision, StringUtils.join(branchPathList,
"/"), StringUtils.join(pathList, "/"));
}
/*
* @param backwards if true search the parts from last to first.
*/
private int lastIndexOfKey(String parts[], String key,
Set invalidBeforeParts, boolean backwards) {
Map> invalidBeforePartsMap = new HashMap>();
invalidBeforePartsMap.put(key, invalidBeforeParts);
return indexOfKey(parts,
new HashSet(Arrays.asList(new String[] { key })),
invalidBeforePartsMap, backwards);
}
private int indexOfKey(String parts[], Set keys,
Map> invalidBeforePartsMap, boolean backwards) {
if (backwards) {
for (int i = (parts.length - 1); i >= 0; i--) {
String part = parts[i].toLowerCase();
if (keys.contains(part)) {
Set invalidBeforeParts = invalidBeforePartsMap
.get(part);
if (invalidBeforeParts != null) {
String beforePartString = StringUtils.join(parts, '/',
0, i);
boolean invalidBeforePartsFlag = false;
for (String invalidBeforePart : invalidBeforeParts) {
if (beforePartString.matches(".*"
+ invalidBeforePart + ".*")) {
invalidBeforePartsFlag = true;
break;
}
}
if (invalidBeforePartsFlag)
continue; // skip over this part
}
return i;
}
}
} else {
// forward
for (int i = 0; i < parts.length; i++) {
String part = parts[i].toLowerCase();
if (keys.contains(part))
return i;
}
}
// failed to find a match case
return -1;
}
/*
* Split the path into the branch part and the file path part.
*
* @param path
* @return the determined branch data.
* @throws VetoBranchException
*/
private int indexOfKey(String[] parts,
Set standardBackwardMatchPaths, boolean backwards) {
return indexOfKey(parts, standardBackwardMatchPaths,
new HashMap>(), backwards);
}
private int lastIndexOfKey(String[] parts, String key,
boolean backwards) {
return lastIndexOfKey(parts, key, new HashSet(), backwards);
}
private int lastIndexOfKey(String[] parts, String part,
String disallowedBeforePart, boolean backwards) {
Set disallowedBeforePartSet = new HashSet();
disallowedBeforePartSet.add(disallowedBeforePart);
return lastIndexOfKey(parts, part, disallowedBeforePartSet, backwards);
}
private void parseTrunkParts(int beforePathRootIndex,
String[] parts, List branchPathList, List pathList) {
int pathNameStartIndex = beforePathRootIndex + 1;
if (parts.length < pathNameStartIndex) {
// there is no part after the branches part
for (int i = 0; i <= beforePathRootIndex; i++) {
branchPathList.add(parts[i]);
}
} else {
for (int i = 0; i <= beforePathRootIndex; i++) {
branchPathList.add(parts[i]);
}
for (int i = pathNameStartIndex; i < parts.length; i++) {
pathList.add(parts[i]);
}
}
}
}