view mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/Settings.java @ 126:8eab713b01a4

Create repositoryUrl using java.util.URI (it escapes illegal characters)
author Dmitry Neverov <dmitry.neverov@jetbrains.com>
date Tue, 28 Sep 2010 13:09:04 +0400
parents a13422ae169d
children 2159ab641618
line wrap: on
line source
/*
 * 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.mercurial.command;

import jetbrains.buildServer.buildTriggers.vcs.mercurial.Constants;
import jetbrains.buildServer.buildTriggers.vcs.mercurial.PathUtil;
import jetbrains.buildServer.util.Hash;
import jetbrains.buildServer.util.StringUtil;
import jetbrains.buildServer.vcs.VcsRoot;
import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashSet;
import java.util.Set;

/**
 * Represents Mercurial repository settings
 */
public class Settings {
  private String myRepository;
  private String myHgCommandPath;
  private File myWorkingDir;
  private File myWorkFolderParentDir;
  private String myUsername;
  private String myPassword;
  private String myBranchName;
  private static final String DEFAULT_BRANCH_NAME = "default";

  public Settings(@NotNull File workFolderParentDir, @NotNull VcsRoot vcsRoot) {
    myWorkFolderParentDir = workFolderParentDir;
    setRepository(vcsRoot.getProperty(Constants.REPOSITORY_PROP));
    setHgCommandPath(vcsRoot.getProperty(Constants.HG_COMMAND_PATH_PROP));
    myBranchName = vcsRoot.getProperty(Constants.BRANCH_NAME_PROP);

    myUsername = vcsRoot.getProperty(Constants.USERNAME);
    myPassword = vcsRoot.getProperty(Constants.PASSWORD);
  }

  public Settings() {
  }

  public void setRepository(@NotNull final String repository) {
    myRepository = repository;
  }

  /**
   * Returns name of the branch to use (returns 'default' if no branch specified)
   * @return see above
   */
  @NotNull
  public String getBranchName() {
    return StringUtil.isEmpty(myBranchName) ? DEFAULT_BRANCH_NAME : myBranchName;
  }

  /**
   * Returns true if current branch is default branch
   * @return see above
   */
  public boolean isDefaultBranch() {
    return getBranchName().equals(DEFAULT_BRANCH_NAME);
  }

  /**
   * Returns path to hg command
   * @return path to hg command
   */
  @NotNull
  public String getHgCommandPath() {
    return myHgCommandPath;
  }

  public String getUsername() {
    return myUsername;
  }

  public String getPassword() {
    return myPassword;
  }

  private final static Set<String> AUTH_PROTOS = new HashSet<String>();
  static {
    AUTH_PROTOS.add("http");
    AUTH_PROTOS.add("https");
    AUTH_PROTOS.add("ssh");
  }

  /**
   * Returns URL to use for push command
   * @return URL to use for push command
   */
  public String getRepositoryUrl() {
    if (containsCredentials(myRepository)) return myRepository;

    try {
      URI repoURI = createUriWithCredentials(myRepository);
      if (AUTH_PROTOS.contains(repoURI.getScheme())) {
        return repoURI.toASCIIString();
      }
    } catch (URISyntaxException e) {
      //ignore
    }
    return myRepository;
  }

  private boolean containsCredentials(final String repository) {
    try {
      URI repositoryURI = new URI(repository);
      String scheme = repositoryURI.getScheme();
      if (AUTH_PROTOS.contains(scheme)) {
        String userInfo = repositoryURI.getUserInfo();
        return userInfo != null && userInfo.contains(":");
      } else {
        return false;
      }
    } catch (URISyntaxException e) {
      return false;
    }
  }

  private URI createUriWithCredentials(final String uri) throws URISyntaxException {
    URI repositoryURI = new URI(uri);
    return new URI(repositoryURI.getScheme(),
            createUserInfo(),
            repositoryURI.getHost(),
            repositoryURI.getPort(),
            repositoryURI.getPath(),
            repositoryURI.getQuery(),
            repositoryURI.getFragment());
  }

  private String createUserInfo() {
    String userInfo = "";
    if (!StringUtil.isEmpty(myUsername)) {
      userInfo += myUsername;
      if (!StringUtil.isEmpty(myPassword)) {
        userInfo += ":" + myPassword;
      }
    }
    return userInfo;
  }

  public void setHgCommandPath(@NotNull final String hgCommandPath) {
    myHgCommandPath = hgCommandPath;
  }

  public void setWorkingDir(@NotNull final File workingDir) {
    myWorkingDir = PathUtil.getCanonicalFile(workingDir);
  }

  /**
   * Returns directory where repository is supposed to be cloned, i.e. working directory of cloned repository
   * @return repository working directory
   */
  @NotNull
  public File getLocalRepositoryDir() {
    if (myWorkingDir != null) {
      return myWorkingDir;
    }

    return getDefaultWorkDir(myWorkFolderParentDir, myRepository);
  }

  /**
   * Returns true if current working directory contains copy of repository (contains .hg directory)
   * @return see above
   */
  public boolean hasCopyOfRepository() {
    // need better way to check that repository copy is ok
    return getLocalRepositoryDir().isDirectory() && new File(getLocalRepositoryDir(), ".hg").isDirectory();
  }

  public static String DEFAULT_WORK_DIR_PREFIX = "hg_";

  private static File getDefaultWorkDir(@NotNull File workFolderParentDir, @NotNull String repPath) {
    String workingDirname = DEFAULT_WORK_DIR_PREFIX + String.valueOf(Hash.calc(normalize(repPath)));
    return PathUtil.getCanonicalFile(new File(workFolderParentDir, workingDirname));
  }

  private static String normalize(final String path) {
    String normalized = PathUtil.normalizeSeparator(path);
    if (path.endsWith("/")) {
      return normalized.substring(0, normalized.length()-1);
    }
    return normalized;
  }
}