/******************************************************************************* * Copyright (c) 2012-2017 Codenvy, S.A. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.eclipse.che.plugin.svn.server.utils; import org.eclipse.che.commons.annotation.Nullable; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Strings.isNullOrEmpty; /** * Subversion utilities. */ public class SubversionUtils { private static Pattern AT_REV_NUM_PATTERN = Pattern.compile("^At revision ([0-9]+).*"); private static Pattern CHECKOUT_REV_NUM_PATTERN = Pattern.compile("^Checked out revision ([0-9]+).*"); private static Pattern COMMIT_REV_NUM_PATTERN = Pattern.compile("^Committed revision ([0-9]+).*"); private static Pattern UPDATE_REV_NUM_PATTERN = Pattern.compile("^Updated to revision ([0-9]+).*"); private SubversionUtils() { } /** * Returns the revision number from the checkout output. * * @param output the checkout output * * @return the revision number or -1 if one could not be found */ public static long getCheckoutRevision(final List<String> output) { return findRevision(output, CHECKOUT_REV_NUM_PATTERN); } /** * Returns the revision number from the commit output. * * @param output the commit output * * @return the revision number or -1 if one could not be found */ public static long getCommitRevision(final List<String> output) { return findRevision(output, COMMIT_REV_NUM_PATTERN); } /** * Returns the revision number from the update output. * * @param output the checkout output * * @return the revision number or -1 if one could not be found */ public static long getUpdateRevision(final List<String> output) { long rev = findRevision(output, UPDATE_REV_NUM_PATTERN); if (rev == -1) { rev = findRevision(output, AT_REV_NUM_PATTERN); } return rev; } /** * For the given pattern, find the revision number. * * @param output the output to parse * @param pattern the pattern to use * * @return the revision number or -1 if one could not be found */ public static long findRevision(final List<String> output, final Pattern pattern) { long revision = -1; for (final String line : output) { final Matcher matcher = pattern.matcher(line); if (matcher.find()) { revision = Long.parseLong(matcher.group(1)); break; } } return revision; } /** * Indicates if path is absolute or a relative. */ public static boolean isRelativePath(final String path) { return path.startsWith("^/"); } /** * Combines {@code repoRoot} and {@code relativeProjectPath} and returns absolute project path. * {@code relativeProjectPath} can point to a branch, tag or any directory inside a project: * ^/project/trunk * ^/project/dir1/dir2 * ^/project/branches/1.0-SNAPSHOT * ^/project/tags/2.0 * ^/project * The important thing that the first entry of the relative path is treated as a project name. * Otherwise the {@code repoRoot} will be returned as an absolute project path: * ^/ * ^/trunk * * @param repoRoot * the repository uri * @param relativeProjectPath * the relative project path * @return absolute project uri */ @Nullable public static String recognizeProjectUri(@Nullable final String repoRoot, @Nullable final String relativeProjectPath) { if (isNullOrEmpty(repoRoot) || isNullOrEmpty(relativeProjectPath)) { return null; } checkState(isRelativePath(relativeProjectPath), "Illegal relative project path " + relativeProjectPath); String[] entries = relativeProjectPath.split("/"); if (entries.length == 1) { return repoRoot; } String candidateToProjectName = entries[1]; if (candidateToProjectName.equals("trunk") || candidateToProjectName.equals("branches") || candidateToProjectName.equals("tags")) { return repoRoot; } return repoRoot + "/" + candidateToProjectName; } }