/* * Copyright 2000-2010 JetBrains s.r.o. * * Licensed under the Apache 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.apache.org/licenses/LICENSE-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 jetbrains.buildServer.buildTriggers.vcs.clearcase; import jetbrains.buildServer.util.StringUtil; import jetbrains.buildServer.vcs.VcsException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Stack; public class CCPathElement { private final String myPathElement; private String myVersion = null; private boolean myIsFromViewPath; private CCPathElement(final String pathElement, String fromViewPath, final boolean hasVersion) { this(pathElement, pathElement.equals(fromViewPath), hasVersion); } public CCPathElement(final String pathElement, final boolean isFromViewPath, final boolean hasVersion) { myPathElement = pathElement; myIsFromViewPath = isFromViewPath; if (hasVersion) { myVersion = CCParseUtil.CC_VERSION_SEPARATOR; } } private void appendVersion(String version) { if (myVersion == null) { myVersion = CCParseUtil.CC_VERSION_SEPARATOR; } myVersion += File.separator + version; } public String getPathElement() { return myPathElement; } public String getVersion() { return myVersion; } public void setVersion(final String objectVersion) { if (objectVersion == null) { myVersion = null; } else if (objectVersion.startsWith(CCParseUtil.CC_VERSION_SEPARATOR)) { myVersion = objectVersion; } else { myVersion = CCParseUtil.CC_VERSION_SEPARATOR + objectVersion; } } public boolean isIsFromViewPath() { return myIsFromViewPath; } public static boolean isInsideView(String objectName, String viewPath) { final List pathElements = splitIntoPathElements(objectName); final List viewPathElements = createViewPathElementList(viewPath, pathElements); if (viewPathElements.size() > pathElements.size()) { return false; } for (int i = 0; i < viewPathElements.size(); i++) { if (!viewPathElements.get(i).equals(pathElements.get(i).getPathElement())) { return false; } } return true; } private static List createViewPathElementList(final String viewPath, final List pathElements) { final List viewPathElements = StringUtil.split(viewPath, false, File.separatorChar); if (pathElements.size() > 0 && pathElements.get(0).getPathElement().length() == 0) { if (viewPathElements.size() > 0) { viewPathElements.set(0, ""); } } return viewPathElements; } public static List splitIntoPathAntVersions(String objectName, String viewPath, final int skipAtBeginCount) { List result = splitIntoPathElements(objectName); setInViewAttributes(result, viewPath, skipAtBeginCount); return result; } public static List splitIntoPathElements(final String objectName) { final List result = new ArrayList(); final List subNames = StringUtil.split(objectName, false, File.separatorChar); for (int i = 0, size = subNames.size(); i < size; i++) { String currentViewPath = null; final String subName = subNames.get(i); if (subName.endsWith(CCParseUtil.CC_VERSION_SEPARATOR)) { final CCPathElement currentPair = new CCPathElement(subName.substring(0, subName.length() - CCParseUtil.CC_VERSION_SEPARATOR.length()), currentViewPath, true); result.add(currentPair); i = processVersion(currentPair, i, subNames); } else if (i + 1 < size && "main".equalsIgnoreCase(subNames.get(i + 1))) { final CCPathElement currentPair = new CCPathElement(subName, currentViewPath, true); result.add(currentPair); i = processVersion(currentPair, i, subNames); } else { result.add(new CCPathElement(subName, currentViewPath, false)); } } return removeDots(result); } private static int processVersion(final CCPathElement currentPair, int i, final List subNames) { for (i += 1; i < subNames.size(); i++) { currentPair.appendVersion(subNames.get(i)); try { Integer.parseInt(subNames.get(i)); break; } catch (NumberFormatException e) { //ignore } } return i; } private static List removeDots(final List result) { int i = 1; while (i < result.size()) { final CCPathElement curElement = result.get(i); if (curElement.getPathElement().equals(".")) { final CCPathElement prevElement = result.get(i - 1); prevElement.setVersion(chooseVersion(prevElement.getVersion(), curElement.getVersion())); result.remove(i); } else i++; } return result; } private static String chooseVersion(final String version1, final String version2) { return version1 == null ? version2 : version1; } private static void setInViewAttributes(List pathElements, String viewPath, int skipAtBeginCount) { final List viewPathElements = createViewPathElementList(viewPath, pathElements); for (int i = 0; i < skipAtBeginCount; i++) { if (viewPathElements.isEmpty()) break; viewPathElements.remove(viewPathElements.size() - 1); } for (CCPathElement pathElement : pathElements) { String currentViewPath = null; if (viewPathElements.size() > 0) { currentViewPath = viewPathElements.remove(0); } pathElement.setCorrespondingViewElement(currentViewPath); } } private void setCorrespondingViewElement(final String currentViewPath) { myIsFromViewPath = myPathElement.equals(currentViewPath); } public static String createPath(final List ccPathElements, int length, boolean appentVersion) { return createPath(ccPathElements, 0, length, appentVersion); } public static String createPath(final List ccPathElements, final int startIndex, int endIndex, boolean appentVersion ) { StringBuffer result = new StringBuffer(); boolean first = true; for (int i = startIndex; i < endIndex; i++) { final CCPathElement element = ccPathElements.get(i); try { if (!first) { result.append(File.separatorChar); } } finally { first = false; } result.append(element.getPathElement()); if (appentVersion && element.getVersion() != null) { result.append(element.getVersion()); } } return result.toString(); } private static void appendNameToBuffer(final StringBuffer result, final String subName) { result.append(File.separatorChar); result.append(subName); } public static String createRelativePathWithVersions(final List pathElementList) { StringBuffer result = new StringBuffer(); for (CCPathElement pathElement : pathElementList) { if (!pathElement.isIsFromViewPath()) { if (pathElement.getVersion() == null) { appendNameToBuffer(result, pathElement.getPathElement()); } else { appendNameToBuffer(result, pathElement.getPathElement() + pathElement.getVersion()); } } } return removeFirstSeparatorIfNeeded(result.toString()); } public static String removeFirstSeparatorIfNeeded(final CharSequence s) { return String.valueOf(s.length() > 0 ? s.subSequence(1, s.length()) : ""); } public static String createPathWithoutVersions(final List pathElementList) { StringBuffer result = new StringBuffer(); for (CCPathElement pathElement : pathElementList) { appendNameToBuffer(result, pathElement.getPathElement()); } return removeFirstSeparatorIfNeeded(result.toString()); } public static String replaceLastVersionAndReturnFullPathWithVersions(final String parentDirFullPath, final String viewName, final String version) { final List pathElements = splitIntoPathAntVersions(parentDirFullPath, viewName, 0); pathElements.get(pathElements.size() - 1).setVersion(version); return createPath(pathElements, pathElements.size(), true); } public static String normalizeFileName(final String fullFileName) throws VcsException { final String[] dirs = fullFileName.split(File.separator.replace("\\", "\\\\")); Stack stack = new Stack(); for (String dir : dirs) { if (".".equals(dir)) continue; if ("..".equals(dir)) { if (stack.isEmpty()) { throw new VcsException("Invalid parent links balance: \"" + fullFileName + "\""); } stack.pop(); } else { stack.push(dir); } } StringBuilder sb = new StringBuilder(""); for (String dir : stack) { sb.append(File.separator).append(dir); } return removeFirstSeparatorIfNeeded(sb); } @NotNull private static String removeLastSeparatorIfNeeded(@NotNull final String path) { return path.endsWith(File.separator) && path.length() > 1 ? path.substring(0, path.length() - 1) : path; } @NotNull public static String normalizePath(@Nullable final String path) throws VcsException { return normalizeFileName(removeLastSeparatorIfNeeded(normalizeSeparators(getNotNullString(path).trim()))); } @NotNull private static String getNotNullString(@Nullable final String path) { return path == null ? "" : path; } @NotNull public static String normalizeSeparators(@NotNull String path) { return path.replace('/', File.separatorChar).replace('\\', File.separatorChar); } public static boolean areFilesEqual(@NotNull final File file1, @NotNull final File file2) throws VcsException { return normalizePath(file1.getAbsolutePath()).equals(normalizePath(file2.getAbsolutePath())); } public static String removeUnneededDots(final String fullPath) { final List elementList = splitIntoPathElements(fullPath); return createPath(elementList, elementList.size(), true); } }