/*
 * ====================================================================
 * Copyright (c) 2008 JavaGit Project.  All rights reserved.
 *
 * This software is licensed using the GNU LGPL v2.1 license.  A copy
 * of the license is included with the distribution of this source
 * code in the LICENSE.txt file.  The text of the license can also
 * be obtained at:
 *
 *   http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
 *
 * For more information on the JavaGit project, see:
 *
 *   http://www.javagit.com
 * ====================================================================
 */
package edu.nyu.cs.javagit.api.commands;

import java.io.File;
import java.io.IOException;
import java.util.List;

import edu.nyu.cs.javagit.api.JavaGitException;
import edu.nyu.cs.javagit.api.Ref;
import edu.nyu.cs.javagit.api.Ref.RefType;
import edu.nyu.cs.javagit.client.ClientManager;
import edu.nyu.cs.javagit.client.IClient;
import edu.nyu.cs.javagit.client.IGitCheckout;
import edu.nyu.cs.javagit.utilities.CheckUtilities;
import edu.nyu.cs.javagit.utilities.ExceptionMessageMap;

/**
 * GitCheckout provides an interface for checking out files from a particular branch
 * in the repository or creating a new branch and switching to it.
 */
public final class GitCheckout {

  /**
   * For checking out a branch or creating a new branch. The <new-branch> is the value of the option
   * '-b' passed in GitCheckoutOptions starting at <branch-name> provided as the last
   * argument to the checkout method.
   *
   * @param repositoryPath
   *          Path to the Git repository.
   * @param options
   *          GitCheckoutOptions passed.
   * @param branch
   *          name of the branch that will be checked out OR if creating a new branch then the
   *          starting for the new branch will be this branch.
   * @return GitCheckoutResponse object
   * @throws JavaGitException thrown if -
   *
if the output for <git-checkout> command generated an error.

   *
if options provided are incorrect.

   *
if processBuilder not able to run the command.

   *

   * @throws IOException
   *          thrown if -
   *

   *
paths given do not have proper permissions.

   *
paths given do not exist at all.

   *

   */
  public GitCheckoutResponse checkout(File repositoryPath, GitCheckoutOptions options, Ref branch)
      throws IOException, JavaGitException {
    CheckUtilities.checkFileValidity(repositoryPath);
    CheckUtilities.validateArgumentRefType(branch, RefType.BRANCH, "Branch name");
    IClient client = ClientManager.getInstance().getPreferredClient();
    IGitCheckout gitCheckout = client.getGitCheckoutInstance();
    return gitCheckout.checkout(repositoryPath, options, branch);
  }

  /**
   * For checking a file or list of files from a branch.
   *
   * @param repositoryPath
   *          path to the Git repository.
   * @param paths
   *          List of file paths that are to be checked out.
   * @return GitCheckoutResponse object
   * @throws JavaGitException thrown if -
   *
if the output for <git-checkout> command generated an error.

   *
if processBuilder not able to run the command.

   *

   * @throws IOException
   *           thrown if -
   *

   *
paths given do not have proper permissions.

   *
paths given do not exist at all.

   *

   */
  public GitCheckoutResponse checkout(File repositoryPath, List<File> paths) throws IOException,
      JavaGitException {
    CheckUtilities.checkFileValidity(repositoryPath);
    CheckUtilities.checkNullListArgument(paths, "List of Paths");
    IClient client = ClientManager.getInstance().getPreferredClient();
    IGitCheckout gitCheckout = client.getGitCheckoutInstance();
    return gitCheckout.checkout(repositoryPath, paths);
  }

  /**
   *
   * For checking out a file from some other branch into the current branch.
   *
   * @param repositoryPath
   *          path to the Git repository.
   * @param options
   *          GitCheckoutOptions that are passed to <git-checkout> command
   * @param branch
   *          Ref branch-name from where the file will be checked out
   * @param file
   *          File to be checked out.
   * @return GitCheckoutResponse object
   * @throws JavaGitException thrown if -
   *
if the output for <git-checkout> command generated an error.

   *
if options provided are incorrect

   *
if processBuilder not able to run the command.

   *

   * @throws
   *           IOException thrown if -
   *

   *
paths given do not have proper permissions.

   *
paths given do not exist at all.

   *

   */
  public GitCheckoutResponse checkout(File repositoryPath, GitCheckoutOptions options, Ref branch,
      File file) throws IOException, JavaGitException {
    CheckUtilities.checkFileValidity(repositoryPath);
    CheckUtilities.validateArgumentRefType(branch, RefType.BRANCH, "Branch name");
    IClient client = ClientManager.getInstance().getPreferredClient();
    IGitCheckout gitCheckout = client.getGitCheckoutInstance();
    return gitCheckout.checkout(repositoryPath, options, branch, file);
  }

  /**
   *
   * Checks out a List of files from some other branch into the current branch.
   *
   * @param repositoryPath
   *          path to the Git repository.
   * @param options
   *          GitCheckoutOptions that are passed to <git-checkout> command
   * @param branch
   *          Ref branch-name from where the file will be checked out
   * @param paths
   *          List of file paths that are to be checked out.
   * @return GitCheckoutResponse object
   * @throws JavaGitException
   *           thrown if -
   *
if the output for <git-checkout> command generated an error.

   *
if options provided are incorrect

   *
if processBuilder not able to run the command.

   *

   * @throws IOException
   *           Thrown if -
   *

   *
paths given do not have proper permissions.

   *
paths given do not exist at all.

   *

   */
  public GitCheckoutResponse checkout(File repositoryPath, GitCheckoutOptions options, Ref branch,
      List<File> paths) throws IOException, JavaGitException {
    CheckUtilities.checkFileValidity(repositoryPath);
    CheckUtilities.checkNullListArgument(paths, "List of files");
    CheckUtilities.validateArgumentRefType(branch, RefType.BRANCH, "Branch name");
    IClient client = ClientManager.getInstance().getPreferredClient();
    IGitCheckout gitCheckout = client.getGitCheckoutInstance();
    return gitCheckout.checkout(repositoryPath, options, branch, paths);
  }

  /**
   * Checks out files from the repository when a tree-ish object is given as the reference.
   *
   * @param repositoryPath
   *          Path to the Git repository.
   * @param ref
   *          A branch, or sha1 object.
   * @param paths
   *          List of file paths that are to be checked out.
   * @return GitCheckoutResponse object
   * @throws JavaGitException
   *           Thrown if -
   *
the output for <git-checkout> command generated an error.

   *
processBuilder not able to run the command.

   *

   * @throws IOException
   *           Thrown if -
   *

   *
paths given do not have proper permissions.

   *
paths given do not exist at all.

   *

   */
  public GitCheckoutResponse checkout(File repositoryPath, Ref ref, List<File> paths)
      throws JavaGitException, IOException {
    CheckUtilities.checkFileValidity(repositoryPath);
    if ( ref != null && ( ref.getRefType() != RefType.BRANCH && ref.getRefType() != RefType.SHA1) ) {
      throw new JavaGitException(100000, ExceptionMessageMap.getMessage("100000")
          + " RefType passed: " + ref.getRefType());
    }
    CheckUtilities.checkNullListArgument(paths, "List of files");
    IClient client = ClientManager.getInstance().getPreferredClient();
    IGitCheckout gitCheckout = client.getGitCheckoutInstance();
    return gitCheckout.checkout(repositoryPath, ref, paths);
  }
}


/*
 * ====================================================================
 * Copyright (c) 2008 JavaGit Project.  All rights reserved.
 *
 * This software is licensed using the GNU LGPL v2.1 license.  A copy
 * of the license is included with the distribution of this source
 * code in the LICENSE.txt file.  The text of the license can also
 * be obtained at:
 *
 *   http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
 *
 * For more information on the JavaGit project, see:
 *
 *   http://www.javagit.com
 * ====================================================================
 */
package edu.nyu.cs.javagit.client;

import java.io.File;

import edu.nyu.cs.javagit.api.commands.GitAddResponse;

/**
 * Class implementing GitAddResponse for setting values in it.
 */
public class GitAddResponseImpl extends GitAddResponse {

  /**
   * Sets the value of no output flag.
   *
   * @param noOutput
   *          true if there was no output generated. This is a helper flag that tells the consumer
   *          of GitAddResponse that there was no resulting output for executed
   *          <git-add> command.
   */
  public void setNoOutput(boolean noOutput) {
    this.noOutput = noOutput;
  }

  /**
   * Sets the flag if dry run flag need to be used
   *
   * @param dryRun
   *          true if dry run should be used, otherwise false.
   */
  public void setDryRun(boolean dryRun) {
    this.dryRun = dryRun;
  }

  /**
   * Sets the non-error message generated in the output of the <git-add> command.
   *
   * @param lineNumber
   *          line number at which the message appeared in output.
   * @param commentString
   *          message itself.
   */
  public void setComment(int lineNumber, String commentString) {
    ResponseString comment = new ResponseString(lineNumber, commentString);
    comments.add(comment);
  }

  /**
   * Adds a file and action to the list.
   *
   * @param file
   *          File to be added to the List.
   */
  public void add(File file) {
    filePathsList.add(file);
  }

}


/*
 * ====================================================================
 * Copyright (c) 2008 JavaGit Project.  All rights reserved.
 *
 * This software is licensed using the GNU LGPL v2.1 license.  A copy
 * of the license is included with the distribution of this source
 * code in the LICENSE.txt file.  The text of the license can also
 * be obtained at:
 *
 *   http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
 *
 * For more information on the JavaGit project, see:
 *
 *   http://www.javagit.com
 * ====================================================================
 */
package edu.nyu.cs.javagit.client.cli;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import edu.nyu.cs.javagit.api.JavaGitConfiguration;
import edu.nyu.cs.javagit.api.JavaGitException;
import edu.nyu.cs.javagit.api.Ref;
import edu.nyu.cs.javagit.api.commands.GitBranchOptions;
import edu.nyu.cs.javagit.api.commands.GitBranchResponse;
import edu.nyu.cs.javagit.api.commands.GitBranchResponse.BranchRecord;
import edu.nyu.cs.javagit.api.commands.GitBranchResponse.responseType;
import edu.nyu.cs.javagit.client.GitBranchResponseImpl;
import edu.nyu.cs.javagit.client.IGitBranch;
import edu.nyu.cs.javagit.utilities.CheckUtilities;
import edu.nyu.cs.javagit.utilities.ExceptionMessageMap;

/**
 * Command-line implementation of the IGitBranch interface.
 */
public class CliGitBranch implements IGitBranch {
  public GitBranchResponse branch(File repoPath) throws IOException, JavaGitException {
    return branchProcess(repoPath, null, null, null, null);
  }

  public GitBranchResponseImpl branch(File repoPath, GitBranchOptions options) throws IOException,
      JavaGitException {
    return branchProcess(repoPath, options, null, null, null);
  }

  public GitBranchResponseImpl deleteBranch(File repoPath, boolean forceDelete, boolean remote,
      Ref branchName) throws IOException, JavaGitException {
    GitBranchOptions options = new GitBranchOptions();
    setDeleteOptions(options, forceDelete, remote);
    return branchProcess(repoPath, options, branchName, null, null);
  }

  public GitBranchResponseImpl deleteBranches(File repoPath, boolean forceDelete, boolean remote,
      List<Ref> branchList) throws IOException, JavaGitException {
    GitBranchOptions options = new GitBranchOptions();
    setDeleteOptions(options, forceDelete, remote);
    return branchProcess(repoPath, options, null, null, branchList);
  }

  public GitBranchResponseImpl renameBranch(File repoPath, boolean forceRename, Ref newName)
      throws IOException, JavaGitException {
    GitBranchOptions options = new GitBranchOptions();
    if (forceRename) {
      options.setOptMUpper(true);
    } else {
      options.setOptMLower(true);
    }
    return branchProcess(repoPath, options, newName, null, null);
  }

  public GitBranchResponseImpl renameBranch(File repoPath, boolean forceRename, Ref oldName, Ref newName)
      throws IOException, JavaGitException {
    GitBranchOptions options = new GitBranchOptions();
    if (forceRename) {
      options.setOptMUpper(true);
    } else {
      options.setOptMLower(true);
    }
    return branchProcess(repoPath, options, oldName, newName, null);
  }

  public GitBranchResponseImpl createBranch(File repoPath, Ref branchName) throws IOException,
      JavaGitException {
    return branchProcess(repoPath, null, branchName, null, null);
  }

  public GitBranchResponseImpl createBranch(File repoPath, GitBranchOptions options, Ref branchName)
      throws IOException, JavaGitException {
    return branchProcess(repoPath, options, branchName, null, null);
  }

  public GitBranchResponseImpl createBranch(File repoPath, Ref branchName, Ref startPoint)
      throws IOException, JavaGitException {
    return branchProcess(repoPath, null, branchName, startPoint, null);
  }

  public GitBranchResponseImpl createBranch(File repoPath, GitBranchOptions options, Ref branchName,
      Ref startPoint) throws IOException, JavaGitException {
    return branchProcess(repoPath, options, branchName, startPoint, null);
  }

  /**
   * Process the git-branch command, to show/delete/create/rename branches.
   *
   * @param repoPath
   *          A File instance for the path to the repository. If null is passed, a
   *          NullPointerException will be thrown.
   * @param options
   *          The options to include on the command line.
   * @param arg1
   *          When renaming a branch to a different name, this is the old branch. When creating a
   *          branch this the branch name.
   * @param arg2
   *          When renaming a branch to a new branch name, this is the new branch name. When
   *          creating a branch, this is the head to start from.
   * @param branchList
   *          List of branches need to be deleted.
   * @return The result of the git branch.
   * @throws IOException
   *           There are many reasons for which an IOException may be thrown.
   *           Examples include:
   *

   *
a directory doesn't exist

   *
a command is not found on the PATH

   *

   * @throws JavaGitException
   *           Thrown when there is an error executing git-branch.
   */
  public GitBranchResponseImpl branchProcess(File repoPath, GitBranchOptions options, Ref arg1,
      Ref arg2, List<Ref> branchList) throws IOException, JavaGitException {
    CheckUtilities.checkNullArgument(repoPath, "repository path");
    List<String> commandLine = buildCommand(options, arg1, arg2, branchList);
    GitBranchParser parser = new GitBranchParser();

    return (GitBranchResponseImpl) ProcessUtilities.runCommand(repoPath, commandLine, parser);
  }

  /**
   * Builds a list of command arguments to pass to ProcessBuilder.
   *
   * @param options
   *          The options to include on the command line.
   * @param arg1
   *          When renaming a branch to a different name, this is the old branch. When creating a
   *          branch this the branch name.
   * @param arg2
   *          When renaming a branch to a new branch name, this is the new branch name. When
   *          creating a branch, this is the head to start from.
   * @param branchList
   *          List of branches need to be deleted.
   * @return A list of the individual arguments to pass to ProcessBuilder.
   */
  protected List<String> buildCommand(GitBranchOptions options, Ref arg1, Ref arg2,
      List<Ref> branchList) {
    List<String> cmd = new ArrayList<String>();

    cmd.add(JavaGitConfiguration.getGitCommand());
    cmd.add("branch");

    if (null != options) {
      Ref commit = options.getOptContains();
      if (null != commit) {
        cmd.add("--contains");
        cmd.add(commit.getName());
      }
      if (options.isOptVerbose()) {
        cmd.add("--verbose");
      }
      if (options.isOptAbbrev()) {
        if (options.getOptAbbrevLen() != GitBranchOptions.DEFAULT_ABBREV_LEN) {
          cmd.add("--abbrev=" + Integer.toString(options.getOptAbbrevLen()));
        } else {
          cmd.add("--abbrev");
        }
      }
      if (options.isOptNoAbbrev()) {
        cmd.add("--no-abbrev");
      }
      if (options.isOptA()) {
        cmd.add("-a");
      }
      if (options.isOptDLower()) {
        cmd.add("-d");
      }
      if (options.isOptMLower()) {
        cmd.add("-m");
      }
      if (options.isOptDUpper()) {
        cmd.add("-D");
      }
      if (options.isOptMUpper()) {
        cmd.add("-M");
      }
      if (options.isOptColor()) {
        cmd.add("--color");
      }
      if (options.isOptNoColor()) {
        cmd.add("--no-color");
      }
      if (options.isOptF()) {
        cmd.add("-f");
      }
      if (options.isOptL()) {
        cmd.add("-l");
      }
      if (options.isOptMerged()) {
        cmd.add("--merged");
      }
      if (options.isOptNoMerged()) {
        cmd.add("--no-merged");
      }
      if (options.isOptR()) {
        cmd.add("-r");
      }
      if (options.isOptTrack()) {
        cmd.add("--track");
      }
      if (options.isOptNoTrack()) {
        cmd.add("--no-track");
      }
    }
    if (null != branchList) {
      if ((null != arg1) || (null != arg2)) {
        throw new IllegalArgumentException();
      }
      for (Ref branch : branchList) {
        cmd.add(branch.getName());
      }
    } else {
      if (null != arg1) {
        cmd.add(arg1.getName());
      }
      if (null != arg2) {
        cmd.add(arg2.getName());
      }
    }
    return cmd;
  }

  /**
   * Sets the options for delete.
   *
   * @param options
   *          The GitBranchOptions object.
   * @param forceDelete
   *          The forceDelete boolean flag. True if branch to be force deleted, false otherwise.
   * @param remote
   *          The remote boolean flag. True if a remote branch is being deleted, false otherwise.
   */
  public void setDeleteOptions(GitBranchOptions options, boolean forceDelete, boolean remote) {
    if (forceDelete) {
      options.setOptDUpper(true);
    } else {
      options.setOptDLower(true);
    }
    if (remote) {
      options.setOptR(true);
    }
  }

  /**
   * Implementation of the IParser interface in GitBranchParser class.
   */
  public class GitBranchParser implements IParser {
    // The response object for a branch operation.
    private GitBranchResponseImpl response;

    // While handling the error cases this buffer will have the error messages.
    private StringBuffer errorMessage = null;

    // Track the number of lines parsed.
    private int numLinesParsed = 0;

    /**
     * Parses the line from the git-branch response text.
     *
     * @param line
     *          The line of text to process.
     */
    public void parseLine(String line) {
      ++numLinesParsed;
      if (null != errorMessage) {
        errorMessage.append(", line" + numLinesParsed + "=[" + line + "]");
        return;
      }
      if (line.contains("fatal:") || line.contains("error:")) {
        if (null == errorMessage) {
          errorMessage = new StringBuffer();
        }
        errorMessage.append("line1=[" + line + "]");
      } else {
        if (null == response) {
          response = new GitBranchResponseImpl();
        }

        if (line.startsWith("Deleted branch")) {
          int indexOfBranch = line.indexOf("branch");
          String branchName = line.substring(indexOfBranch + 7, line.length()-1);
          response.setResponseType(responseType.MESSAGE);
          if (1 == numLinesParsed) {
            response.addMessages(line.substring(0, indexOfBranch + 6));
          }
          response.addIntoBranchList(Ref.createBranchRef(branchName));
        } else if (null == line) {
          response.setResponseType(responseType.EMPTY);
        } else {
          handleBranchDisplay(line);
        }
      }
    }

    /**
     * Parses the output of git-branch with different options and without any argumen.
     *
     * @param line
     *          The line of text to be parsed.
     */
    public void handleBranchDisplay(String line) {
      String nextWord;
      boolean isCurrentBranch = false;
      StringTokenizer st = new StringTokenizer(line);

      nextWord = st.nextToken();
      response.setResponseType(responseType.BRANCH_LIST);

      if ('*' == nextWord.charAt(0)) {
        isCurrentBranch = true;
        nextWord = st.nextToken();
        response.setCurrentBranch(Ref.createBranchRef(nextWord));
      }
      response.addIntoBranchList(Ref.createBranchRef(nextWord));

      if (st.hasMoreTokens()) {
        Ref branch = Ref.createBranchRef(nextWord);
        nextWord = st.nextToken();
        Ref sha1 = Ref.createSha1Ref(nextWord);
        int indexOfSha = line.indexOf(nextWord);
        String comment = line.substring(indexOfSha+nextWord.length()+1);
        BranchRecord record = new BranchRecord(branch, sha1, comment, isCurrentBranch);
        response.addIntoListOfBranchRecord(record);
      }
    }

    public void processExitCode(int code) {
    }

    /**
     * Throws appropriate JavaGitException for an error case or returns the
     * GitBranchResponse object to the upper layer.
     *
     * @return GitBranchResponse object.
     * @throws JavaGitException
     *           Thrown when there is an error executing git-branch.
     */
    public GitBranchResponse getResponse() throws JavaGitException {
      if (null != errorMessage) {
        throw new JavaGitException(404000, ExceptionMessageMap.getMessage("404000")
            + "  The git-branch error message:  { " + errorMessage.toString() + " }");
      }
      return response;
    }
  }
}


package org.ucmtwine.proxy.injector;

import intradoc.data.DataException;
import intradoc.server.Action;
import intradoc.server.ServiceData;
import intradoc.server.ServiceManager;

import java.lang.reflect.Method;
import java.net.URL;

import org.ucmtwine.annotation.ServiceMethod;
import org.ucmtwine.proxy.ServiceProxy;

public class ServiceInjector extends BaseInjector {

  /**
   * {@inheritDoc}
   */
  @Override
  public void injectClasses(URL propertiesFile) {
    injectClasses(propertiesFile, "ucm.service");
  }

  /**
   * Inject a service into the service manager registry.
   *
   * @param klass
   *          Class to inject
   * @throws DataException
   * @throws IllegalAccessException
   * @throws InstantiationException
   */
  @Override
  public void inject(Class<?> klass) throws DataException {

    Method[] classMethods = klass.getMethods();

    for (Method method : classMethods) {
      ServiceMethod annotation = (ServiceMethod) method.getAnnotation(ServiceMethod.class);

      if (annotation != null) {
        injectServiceMethod(method, annotation);
      }
    }
  }

  /**
   * Injects a single UCMService annotation into the ServiceManager registry.
   *
   * @param className
   *          Fully qualified class name
   * @param annotation
   *          A reference to a UCMService annotation
   * @throws DataException
   */
  private static void injectServiceMethod(Method method, ServiceMethod annotation) throws DataException {
    ServiceData serviceData = new ServiceData();

    String template = annotation.template();
    int accessLevel = annotation.accessLevel();
    String serviceType = (!annotation.type().equals("")) ? annotation.type() : null;
    String errorMessage = annotation.errorMessage();
    String subjects = annotation.subjects();
    String serviceName = annotation.name();

    try {
      serviceData.init(serviceName, ServiceProxy.class.getName(), accessLevel, template, serviceType, errorMessage,
          subjects);
    } catch (Exception e) {
      throw new DataException("Cannot create ServiceData object for " + serviceName + " - " + e.getMessage());
    }

    // action parameters, none by default
    String controlFlags = "";

    String methodHashCode = MethodRegistry.addMethod(method);

    if (methodHashCode == null) {
      throw new DataException("Cannot register method " + method.toString() + " because it has a null hashCode");
    }

    try {
      serviceData.addAction(Action.CODE_TYPE, "delegateWithParameters", methodHashCode, controlFlags, "");

    } catch (DataException e) {
      throw new DataException("Cannot add defaut action to service" + serviceName + " - " + e.getMessage());
    }

    // inject service
    ServiceManager.putService(serviceName, serviceData);
  }
}


/*
 * ====================================================================
 * Copyright (c) 2008 JavaGit Project.  All rights reserved.
 *
 * This software is licensed using the GNU LGPL v2.1 license.  A copy
 * of the license is included with the distribution of this source
 * code in the LICENSE.txt file.  The text of the license can also
 * be obtained at:
 *
 *   http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
 *
 * For more information on the JavaGit project, see:
 *
 *   http://www.javagit.com
 * ====================================================================
 */
package edu.nyu.cs.javagit.api;

import edu.nyu.cs.javagit.utilities.CheckUtilities;

/**
 * This class represents the name of a ref. The types of Refs, specified in the
 * RefType enumeration, are:
 *
 *

 *
 BRANCH

 *
 HEAD

 *
 REMOTE

 *
 SHA1

 *
 TAG

 *

 *
 * If the RefType of a Ref instance is BRANCH, then
 * the branch name is maintained by the instance. The branch name is simply a String
 * representing the name of the branch. Examples:
 *
 *

 *
 master

 *
 testing

 *
 crazyidea

 *

 *
 * If the RefType of a Ref instance is HEAD, then a
 * commit offset value is maintained as an int. This commit offset indicates the
 * commit back from the HEAD commit on the branch checked out in the working tree. Values greater
 * than or equal to zero are acceptable and correspond to:
 *
 *

 *
 0 - The current HEAD commit

 *
 1 - The commit prior to the current HEAD commit

 *
 2 - The second commit prior to the current HEAD commit

 *
 etc...

 *

 *
 * If the RefType of a Ref instance is REMOTE, then
 * the remote repository name and remote branch name are maintained as a Strings by
 * the instance.

 *

 *
 * Note: It is possible for the remote repository name to be non-existent. In such cases, the
 * repository value is null.

 *

 *
 * Examples:
 *
 *

 *
 remote repository name: origin, remote branch name: master

 *
 remote repository name: davidsrepo, remote branch name: testing

 *
 remote repository name: <no_repo_name>, remote branch name: crazyidea

 *

 *
 * If the RefType of a Ref instance is SHA1, then the
 * SHA1 value is maintained as a String value. This string value can be:
 *
 *

 *
 the full SHA1

 *
 a SHA1 truncated to the first n characters

 *

 *
 * If the RefType of a Ref instance is TAG, then the
 * name of the tag is maintained as a String value. Examples:
 *
 *

 *
 Release1.0.8

 *
 6.3-RC1

 *

 */
public class Ref {

  /*
   * TODO (jhl388): add the field "isCurrentBranch" to indicate if the ref is the current working
   * branch. Refs of the current working branch and all HEAD refs should have the value "true". All
   * other refs should have the value "false".
   */

  /**
   * An enumeration of the types of refs.
   */
  public static enum RefType {
    BRANCH, HEAD, REMOTE, SHA1, TAG
  }

  /** The HEAD commit. */
  public static final Ref HEAD;

  /** The prior HEAD commit. */
  public static final Ref HEAD_1;

  static {
    HEAD = new Ref();
    HEAD.refType = RefType.HEAD;
    HEAD.headOffset = 0;

    HEAD_1 = new Ref();
    HEAD_1.refType = RefType.HEAD;
    HEAD_1.headOffset = 1;
  }

  // The type of this ref.
  private Ref.RefType refType;

  /*
   * If the ref's type is HEAD, this is the number of commits back from the head of the current
   * working branch.
   */
  private int headOffset = -1;

  // If the ref's type is BRANCH, REMOTE, SHA1, or TAG, this is the name of the ref.
  private String name = null;

  /*
   * If the ref's type is REMOTE, this is the name of the remote repository iff a repository name is
   * associated with the remote name.
   */
  private String repositoryName = null;

  /**
   * Creates a Ref of type BRANCH.
   *
   * @param name
   *          The branch name of this ref. If the value is null, a NullPointerException
   *          is thrown. If the value has length zero, an IllegalArgumentException is
   *          thrown.
   * @return A Ref instance of type BRANCH.
   */
  public static Ref createBranchRef(String name) {
    CheckUtilities.checkStringArgument(name, "name");

    Ref cn = new Ref();
    cn.refType = RefType.BRANCH;
    cn.name = name;
    return cn;
  }

  /**
   * Creates a Ref of type HEAD.
   *
   * @param headOffset
   *          The offset of the commit back from the HEAD commit on the current working branch. If
   *          the value is less than zero, an IllegalArgumentException is thrown.
   * @return A Ref instance of type HEAD.
   */
  public static Ref createHeadRef(int headOffset) {
    CheckUtilities.checkIntArgumentGreaterThan(headOffset, -1, "headOffset");

    if (0 == headOffset) {
      return HEAD;
    } else if (1 == headOffset) {
      return HEAD_1;
    }

    Ref cn = new Ref();
    cn.refType = RefType.HEAD;
    cn.headOffset = headOffset;
    return cn;
  }

  /**
   * Creates a Ref of type REMOTE.
   *
   * @param repositoryName
   *          The remote repository name of this ref. If the value is blank or null, the value will
   *          be maintained as null.
   * @param name
   *          The remote branch name of this ref. If the value is null, a
   *          NullPointerException is thrown. If the value has length zero, an
   *          IllegalArgumentException is thrown.
   * @return A Ref instance of type REMOTE.
   */
  public static Ref createRemoteRef(String repositoryName, String name) {
    CheckUtilities.checkStringArgument(name, "name");

    Ref cn = new Ref();
    cn.refType = RefType.REMOTE;
    cn.name = name;

    if (null != repositoryName && repositoryName.length() > 0) {
      cn.repositoryName = repositoryName;
    }

    return cn;
  }

  /**
   * Creates a Ref of type SHA1.
   *
   * @param name
   *          The SHA1 name of this ref. The value can be a short name or the full SHA1 value. If
   *          the value is null, a NullPointerException is thrown. If the value has
   *          length zero, an IllegalArgumentException is thrown.
   * @return A Ref instance of type SHA1.
   */
  public static Ref createSha1Ref(String name) {
    CheckUtilities.checkStringArgument(name, "name");

    Ref cn = new Ref();
    cn.refType = RefType.SHA1;
    cn.name = name;
    return cn;
  }

  /**
   * Creates a Ref of type TAG.
   *
   * @param name
   *          The tag name of this ref. If the value is null, a NullPointerException
   *          is thrown. If the value has length zero, an IllegalArgumentException is
   *          thrown.
   * @return A Ref instance of type TAG.
   */
  public static Ref createTagRef(String name) {
    CheckUtilities.checkStringArgument(name, "name");

    Ref cn = new Ref();
    cn.refType = RefType.TAG;
    cn.name = name;
    return cn;
  }

  /**
   * Gets the type of the Ref instance.
   *
   * @return The type of the Ref instance.
   */
  public Ref.RefType getRefType() {
    return refType;
  }

  /**
   * Gets the offset of the commit back from the HEAD commit on the current working branch for this
   * Ref instance.
   *
   * @return If the type of this Ref is not HEAD, then -1 is
   *         returned. Otherwise, the offset of the commit back from the HEAD commit on the current
   *         working branch is returned.
   */
  public int getHeadOffset() {
    return headOffset;
  }

  /**
   * Gets the name of this ref.
   *
   * @return If the type of this Ref is not BRANCH,
   *         REMOTE, SHA1 or TAG, then null is
   *         returned. Otherwise, the name of this ref is returned.
   */
  public String getName() {
    return name;
  }

  /**
   * Gets the repository name of this ref.
   *
   * @return If the type of this Ref is not REMOTE, then null is
   *         returned. If the type of this Ref is REMOTE and there is
   *         no associated repository name, then null is returned. Otherwise, the repository name of
   *         this ref is returned.
   */
  public String getRepositoryName() {
    return repositoryName;
  }

  @Override
  public String toString() {
    if (RefType.HEAD == refType) {
      if (0 == headOffset) {
        return "HEAD";
      } else if (1 == headOffset) {
        return "HEAD^1";
      } else {
        return "HEAD~" + Integer.toString(headOffset);
      }
    } else if (RefType.BRANCH == refType || RefType.SHA1 == refType || RefType.TAG == refType) {
      return name;
    } else if (RefType.REMOTE == refType) {
      if (null != repositoryName) {
        return repositoryName + "/" + name;
      } else {
        return name;
      }
    } else {
      return "";
    }
  }

  @Override
  public boolean equals(Object o) {
    if (!(o instanceof Ref)) {
      return false;
    }

    Ref cn = (Ref) o;

    if (!CheckUtilities.checkObjectsEqual(refType, cn.getRefType())) {
      return false;
    }
    if (!CheckUtilities.checkObjectsEqual(name, cn.getName())) {
      return false;
    }
    if (!CheckUtilities.checkObjectsEqual(repositoryName, cn.getRepositoryName())) {
      return false;
    }
    if (cn.getHeadOffset() != headOffset) {
      return false;
    }

    return true;
  }

  @Override
  public int hashCode() {
    int ret = refType.hashCode() + headOffset;
    ret += (null == name) ? 0 : name.hashCode();
    ret += (null == repositoryName) ? 0 : repositoryName.hashCode();
    return ret;
  }

}


/*
 * ====================================================================
 * Copyright (c) 2008 JavaGit Project.  All rights reserved.
 *
 * This software is licensed using the GNU LGPL v2.1 license.  A copy
 * of the license is included with the distribution of this source
 * code in the LICENSE.txt file.  The text of the license can also
 * be obtained at:
 *
 *   http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
 *
 * For more information on the JavaGit project, see:
 *
 *   http://www.javagit.com
 * ====================================================================
 */
package edu.nyu.cs.javagit.api.commands;

import edu.nyu.cs.javagit.api.Ref;
import edu.nyu.cs.javagit.api.Ref.RefType;
import edu.nyu.cs.javagit.utilities.CheckUtilities;
import edu.nyu.cs.javagit.utilities.ExceptionMessageMap;

/**
 * Class for managing options for <git-checkout> command.
 */
public class GitCheckoutOptions {

  /**
   * Option for creating a new branch with the name provided.
   */
  private Ref optB;

  /**
   * Quiet, suppress feedback messages.
   */
  private boolean optQ;

  /**
   * Proceed even if the index or the working tree differs from HEAD. This is used to throw away
   * local changes.
   */
  private boolean optF;

  /**
   * Track options for setting configuration so that <git-pull> retrieves data automatically
   * from starting point.
   */
  private boolean optTrack;
  /**
   * Set this option to ignore the branch.autosetupmerge.
   */
  private boolean optNoTrack;
  /**
   * Create the new branch's reflog. It also enables use of date based sha1 expressions.
   */
  private boolean optL;
  /**
   * Use this option, if merging need to be done between the current branch, working tree contents,
   * and the new branch. Also, brings you to the new branch.
   */
  private boolean optM;

  /**
   * Sets the name of the new branch that need to be created from the base branch.
   *
   * @param newBranch
   *          New branch of type Ref that will be created by <git-checkout>.
   */
  public void setOptB(Ref newBranch) {
    CheckUtilities.validateArgumentRefType(newBranch, RefType.BRANCH, "New Branch Name");
    optB = newBranch;
  }

  /**
   * Gets the Ref of type branch that is created by <git-checkout> command.
   *
   * @return Returns the new branch of type Ref.
   */
  public Ref getOptB() {
    return optB;
  }

  /**
   * Gets the value of Quiet option.
   *
   * @return true if Quiet option is set, else false.
   */
  public boolean optQ() {
    return optQ;
  }

  /**
   * Sets the Quiet option
   *
   * @param optQ
   *          True if quiet option should be set, false otherwise.
   */
  public void setOptQ(boolean optQ) {
    this.optQ = optQ;
  }

  /**
   * Gets the value of force option.
   *
   * @return true
   *          If force is set, or false.
   */
  public boolean optF() {
    return optF;
  }

  /**
   * Sets the value of force option
   *
   * @param optF
   *          True if force should be set, false otherwise.
   */
  public void setOptF(boolean optF) {
    this.optF = optF;
  }

  /**
   * Gets the value value of track option.
   *
   * @return true
   *          If track option is set, else false.
   */
  public boolean optTrack() {
    return optTrack;
  }

  /**
   * Sets the track option.
   *
   * @param optTrack
   *          True if the track option should be set, else false.
   */
  public void setOptTrack(boolean optTrack) {
    if ( optNoTrack ) {
      throw new IllegalArgumentException(ExceptionMessageMap.getMessage("000130")
          + "  The \"track\" option can not be set when the \"noTrack\" option is set.");
    }
    this.optTrack = optTrack;
  }

  /**
   * Gets the notrack option.
   *
   * @return true if notrack option is set, else false.
   */
  public boolean optNoTrack() {
    return optNoTrack;
  }

  /**
   * Sets the noTrack option.
   *
   * @param optNoTrack
   *          True if noTrack options need to be set, else false.
   */
  public void setOptNoTrack(boolean optNoTrack) {
    if ( optTrack ) {
      throw new IllegalArgumentException(ExceptionMessageMap.getMessage("000130")
          + "  The \"noTrack\" option can not be set when the \"Track\" option is set.");
    }
    this.optNoTrack = optNoTrack;
  }

  /**
   * Gets the reflog option for the new branch.
   *
   * @return true
   *        If refLog option need to be set, else false.
   */
  public boolean optL() {
    return optL;
  }

  /**
   * Sets the reflog option for the newbranch.
   *
   * @param optL
   *          True if reflog option should be set, else false.
   */
  public void setOptL(boolean optL) {
    this.optL = optL;
  }

  /**
   * Gets the merge option
   *
   * @return true
   *        If merge option to be used, else false
   */
  public boolean optM() {
    return optM;
  }

  /**
   * Sets the merge option.
   *
   * @param optM
   *          True if merge need to be used, else false.
   */
  public void setOptM(boolean optM) {
    this.optM = optM;
  }

}


/*
 * ====================================================================
 * Copyright (c) 2008 JavaGit Project.  All rights reserved.
 *
 * This software is licensed using the GNU LGPL v2.1 license.  A copy
 * of the license is included with the distribution of this source
 * code in the LICENSE.txt file.  The text of the license can also
 * be obtained at:
 *
 *   http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
 *
 * For more information on the JavaGit project, see:
 *
 *   http://www.javagit.com
 * ====================================================================
 */
package edu.nyu.cs.javagit.client.cli;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import edu.nyu.cs.javagit.api.JavaGitConfiguration;
import edu.nyu.cs.javagit.api.JavaGitException;
import edu.nyu.cs.javagit.api.commands.CommandResponse;
import edu.nyu.cs.javagit.api.commands.GitCloneOptions;
import edu.nyu.cs.javagit.client.GitCloneResponseImpl;
import edu.nyu.cs.javagit.client.IGitClone;

/**
 * Command-line implementation of the IGitClone interface.
 */
public class CliGitClone implements IGitClone {

  public GitCloneResponseImpl clone(File workingDirectoryPath, URL repository) throws IOException,
      JavaGitException {
    return cloneProcess(workingDirectoryPath, null, repository, null);
  }

  public GitCloneResponseImpl clone(File workingDirectoryPath, GitCloneOptions options, URL repository)
      throws IOException, JavaGitException {
    return cloneProcess(workingDirectoryPath, options, repository, null);
  }

  public GitCloneResponseImpl clone(File workingDirectoryPath, URL repository, File directory)
      throws IOException, JavaGitException {
    return cloneProcess(workingDirectoryPath, null, repository, directory);
  }

  public GitCloneResponseImpl clone(File workingDirectoryPath, GitCloneOptions options, URL repository,
      File directory) throws IOException, JavaGitException {
    return cloneProcess(workingDirectoryPath, options, repository, directory);
  }

  /**
   * Process the git-clone command, to make a clone of the git repository.
   *
   * @param workingDirectoryPath
   *          A File instance for the path to the working directory. This argument
   *          must represent the absolute path to the desired directory as returned by the
   *          File.getPath() method. If null is passed, a
   *          NullPointerException will be thrown.
   * @param options
   *          The options for the git-clone command. If the value is null, a
   *          NullPointerException will be thrown.
   * @param repository
   *          A URL instance for the repository to be cloned. If null is passed, a
   *          NullPointerException will be thrown.
   * @param directory
   *          A File instance for the directory where the repository is to be cloned.
   *          If null is passed, a NullPointerException will be thrown.
   * @return The result of the git clone.
   * @throws IOException
   *           There are many reasons for which an IOException may be thrown.
   *           Examples include:
   *

   *
a directory doesn't exist

   *
a command is not found on the PATH

   *

   * @throws JavaGitException
   *           Thrown when there is an error executing git-clone.
   */
  public GitCloneResponseImpl cloneProcess(File workingDirectoryPath, GitCloneOptions options,
      URL repository, File directory) throws IOException, JavaGitException {
    List<String> commandLine = buildCommand(options, repository, directory);
    GitCloneParser parser = new GitCloneParser();

    return (GitCloneResponseImpl) ProcessUtilities.runCommand(workingDirectoryPath, commandLine, parser);
  }

  /**
   * Builds a list of command arguments to pass to ProcessBuilder.
   * @param options
   *          The options for the git-clone command. If the value is null, a
   *          NullPointerException will be thrown.
   * @param repository
   *          A URL instance for the repository to be cloned. If null is passed, a
   *          NullPointerException will be thrown.
   * @param directory
   *          A File instance for the directory where the repository is to be cloned.
   *          If null is passed, a NullPointerException will be thrown.
   * @return The result of the git clone.
   */
  protected List<String> buildCommand(GitCloneOptions options, URL repository, File directory) {
    List<String> cmd = new ArrayList<String>();

    cmd.add(JavaGitConfiguration.getGitCommand());
    cmd.add("clone");
    return cmd;
  }

  /**
   * Implementation of the IParser interface in GitCloneParser class.
   */
  public class GitCloneParser implements IParser {

    public CommandResponse getResponse() throws JavaGitException {
      // TODO Auto-generated method stub
      return null;
    }

    public void parseLine(String line) {
      // TODO Auto-generated method stub

    }

    public void processExitCode(int code) {
      // TODO Auto-generated method stub

    }
  }
}


package org.ucmtwine;

import intradoc.common.ExecutionContext;
import intradoc.common.ServiceException;
import intradoc.common.SystemUtils;
import intradoc.data.DataBinder;
import intradoc.data.DataException;
import intradoc.data.Workspace;
import intradoc.io.zip.IdcZipFile;
import intradoc.shared.FilterImplementor;

import java.io.IOException;
import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.ucmtwine.proxy.injector.FilterInjector;
import org.ucmtwine.proxy.injector.IClassInjector;
import org.ucmtwine.proxy.injector.IdocScriptInjector;
import org.ucmtwine.proxy.injector.ServiceInjector;

public class Bootstrapper implements FilterImplementor {

  /**
   * Begins injection of filters, including the Service and IdocScript injectors
   * required to load other ucm entities.
   */
  public int doFilter(Workspace ws, DataBinder binder, ExecutionContext ctx) throws DataException, ServiceException {
    String configFileName = (String) ctx.getCachedObject("filterParameter");

    try {
      ClassLoader cl = getClass().getClassLoader();
      Enumeration<URL> propFiles = cl.getResources(configFileName);

      // There should be at least one entry (TwineLib contains an example file)
      if (!propFiles.hasMoreElements()) {
        propFiles = getResources11g(cl, configFileName);
      }

      while (propFiles.hasMoreElements()) {
        URL propFile = propFiles.nextElement();

        if (SystemUtils.m_verbose) {
          SystemUtils.trace("twine", "Loading config file: " + propFile.toString());
        }

        IClassInjector filterInjector = new FilterInjector();
        filterInjector.injectClasses(propFile);

        IClassInjector serviceInjector = new ServiceInjector();
        serviceInjector.injectClasses(propFile);

        IClassInjector scriptInjector = new IdocScriptInjector();
        scriptInjector.injectClasses(propFile);

      }
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }

    return CONTINUE;
  }

  /**
   * Replacement for getResources which works on 11g.
   *
   *

   * The UCM 11G {@link ClassLoader} does not load component jars in the
   * standard manner, which means you cannot use
   * {@link ClassLoader#getResources(String)} to find all instances of a
   * specific file in the jar path, instead we inspect the m_zipfiles map, where
   * we can query each zip file for the properties file.
   *

   *
   *

   * Instead, we use reflection to find all the loaded component jar files and
   * search manually
   *

   *
   * @param classLoader
   * @param configFileName
   * @throws MalformedURLException
   */
  private Enumeration<URL> getResources11g(ClassLoader classLoader, String configFileName) {
    List<URL> newProps = new ArrayList<URL>();
    if (classLoader.getClass().getSimpleName().equalsIgnoreCase("IdcClassLoader")) {
      try {
        Field field = classLoader.getClass().getField("m_zipfiles");

        @SuppressWarnings("unchecked")
        Map<String, IdcZipFile> zipFiles = (Map<String, IdcZipFile>) field.get(classLoader);

        for (Entry<String, IdcZipFile> entry : zipFiles.entrySet()) {
          if (entry.getValue().m_entries.get(configFileName) != null) {
            String jarFile = entry.getKey();

            // windows needs a slash before the C:/
            if (!jarFile.startsWith("/")) {
              jarFile = "/" + jarFile;
            }

            try {
              URL u = new URL("jar:file:" + entry.getKey() + "!/" + configFileName);
              newProps.add(u);

            } catch (MalformedURLException e) {
              e.printStackTrace();
            }
          }
        }

      } catch (Exception e) {
        // If there is any exception the ClassLoader is an unrecognised format
        e.printStackTrace();
      }
    }
    return Collections.enumeration(newProps);
  }
}


package edu.nyu.cs.javagit.client.cli;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import edu.nyu.cs.javagit.api.JavaGitConfiguration;
import edu.nyu.cs.javagit.api.JavaGitException;
import edu.nyu.cs.javagit.api.commands.CommandResponse;
import edu.nyu.cs.javagit.api.commands.GitInitOptions;
import edu.nyu.cs.javagit.api.commands.GitInitResponse;
import edu.nyu.cs.javagit.client.IGitInit;
import edu.nyu.cs.javagit.utilities.CheckUtilities;

public class CliGitInit implements IGitInit {

	public GitInitResponse init(File repoDirectory, GitInitOptions options)
	throws JavaGitException, IOException  {
		CheckUtilities.checkFileValidity(repoDirectory);
		GitInitParser parser = new GitInitParser();
		List<String> command = buildCommand(repoDirectory, options);
		GitInitResponse response =  (GitInitResponse) ProcessUtilities.runCommand(repoDirectory,
				command, parser);
		if (response.containsError()) {
			throw new JavaGitException(418001, "Git Init error");
		}
		return response;
	}

	public GitInitResponse init(File repoDirectory)
	throws JavaGitException, IOException  {
		CheckUtilities.checkFileValidity(repoDirectory);
		GitInitParser parser = new GitInitParser();
		List<String> command = buildCommand(repoDirectory, null);
		GitInitResponse response =  (GitInitResponse) ProcessUtilities.runCommand(repoDirectory,
				command, parser);
		if (response.containsError()) {
			throw new JavaGitException(418001, "Git Init error");
		}
		return response;
	}

	/*
	 * Build the command to be executed using the Git Init method
	 */
	private List<String> buildCommand(File repoDirectory, GitInitOptions options) {
		List<String> command = new ArrayList<String>();
		command.add(JavaGitConfiguration.getGitCommand());
		command.add("init");
		if(options!=null){

			if (options.isOptBare()) {
				command.add("--bare");
			}
			if (options.isOptTemplate()) {
				command.add("--template="+options.getOptTemplateDirecory());
			}
			if (options.isOptSharedUmask()) {
				command.add("--shared=");
			}
			if (options.isOptSharedGroup()) {
				command.add("--shared="+options.getOptSharedGroupName());
			}
			if (options.isOptSharedAll()) {
				command.add("--shared=");
			}
			if (options.isOptSharedOctal()) {
				command.add("--shared="+options.getOptSharedOctalValue());
			}
		}
		return command;
	}

	/**
	 * Parser class to parse the output generated by git init and return a
	 * GitInitResponse object.
	 */
	public class GitInitParser implements IParser {

		private GitInitResponse response = new GitInitResponse();

		/**
		 * Add the final parsed commit. and returns the response of git init execution.
		 */
		public CommandResponse getResponse() throws JavaGitException {
			return this.response;
		}

		/**
		 *  Parses a line at a time from the commandline execution output of git init
		 */
		public void parseLine(String line) {
			if(line.length() == 0){
				return;
			}
			//initialized
			if (line.contains("Initialized")){
				response.setInitialized(true);
			}
			//reinitialized
			else if (line.contains("Reinitialized") || line.contains("Initialized")){
				response.setReinitialized(true);
			}
		}

		public void processExitCode(int code) {

		}
	}
}


/*
 * ====================================================================
 * Copyright (c) 2008 JavaGit Project.  All rights reserved.
 *
 * This software is licensed using the GNU LGPL v2.1 license.  A copy
 * of the license is included with the distribution of this source
 * code in the LICENSE.txt file.  The text of the license can also
 * be obtained at:
 *
 *   http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
 *
 * For more information on the JavaGit project, see:
 *
 *   http://www.javagit.com
 * ====================================================================
 */
package edu.nyu.cs.javagit.api.commands;

import edu.nyu.cs.javagit.api.Ref;
import edu.nyu.cs.javagit.utilities.CheckUtilities;

/**
 * A class to manage passing arguments to the GitReset command.
 * GitReset resets the HEAD of the current checked out branch to the state of a
 * previous commit.

 *

 *
 * Default values:
 *

 *
 resetType - ResetType.MIXED

 *
 commitName - CommitName.HEAD

 *
 quiet - false

 *

 */
public class GitResetOptions {

  /**
   * An enumeration of the types of resets that can be performed.
   *
   *

   *
 MIXED - resets the checked out branch and the index but not the working tree

   *
 SOFT - resets only the checked out branch

   *
 HARD - resets the checked out branch, the index and the working tree

   *

   */
  public static enum ResetType {
    MIXED("mixed"), SOFT("soft"), HARD("hard");

    private String cliOpt;

    private ResetType(String cliOpt) {
      this.cliOpt = cliOpt;
    }

    public String toString() {
      return "--" + cliOpt;
    }
  }

  // The name of the commit to reset to.
  private Ref commitName;

  // The type of reset to perform.
  private ResetType resetType;

  // Suppress feedback.
  private boolean quiet = false;

  /**
   * Construct a GitResetOptions instance with the default values.
   */
  public GitResetOptions() {
    setup(ResetType.MIXED, Ref.HEAD);
  }

  /**
   * Construct a GitResetOptions instance with the specified CommitName.
   *
   * @param commitName
   *          The name of the commit to reset to.
   */
  public GitResetOptions(Ref commitName) {
    setup(ResetType.MIXED, commitName);
  }

  /**
   * Construct a GitResetOptions instance with the specified ResetType.
   *
   * @param resetType
   *          The type of reset to perform.
   */
  public GitResetOptions(ResetType resetType) {
    setup(resetType, Ref.HEAD);
  }

  /**
   * Construct a GitResetOptions instance with the specified ResetType
   * and CommitName.
   *
   * @param resetType
   *          The type of reset to perform.
   * @param commitName
   *          The name of the commit to reset to.
   */
  public GitResetOptions(ResetType resetType, Ref commitName) {
    setup(resetType, commitName);
  }

  /**
   * Central instance construction setup method.
   *
   * @param resetType
   *          The type of reset to perform.
   * @param commitName
   *          The name of the commit to reset to.
   */
  private void setup(ResetType resetType, Ref commitName) {
    CheckUtilities.checkNullArgument(resetType, "resetType");
    CheckUtilities.checkNullArgument(commitName, "commitName");

    this.resetType = resetType;
    this.commitName = commitName;
  }

  /**
   * Get the name of the commit to reset to.
   *
   * @return The name of the commit this instance says to reset to.
   */
  public Ref getCommitName() {
    return commitName;
  }

  /**
   * Gets the type of reset for this instance.
   *
   * @return The type of reset for this instance.
   */
  public ResetType getResetType() {
    return resetType;
  }

  /**
   * Is the reset to perform quietly?
   *
   * @return True if the reset is to perform quietly. False if the reset is to perform as normal.
   */
  public boolean isQuiet() {
    return quiet;
  }

  /**
   * Set the name of the commit to reset to.
   *
   * @param commitName
   *          The name of the commit to reset to.
   */
  public void setCommitName(Ref commitName) {
    this.commitName = commitName;
  }

  /**
   * Set the reset to perform quietly or with normal progress information.
   *
   * @param quiet
   *          True if the reset is to perform quietly. False if the reset is to perform as normal.
   */
  public void setQuiet(boolean quiet) {
    this.quiet = quiet;
  }

  /**
   * Set the type of reset to perform.
   *
   * @param resetType
   *          The type of reset to perform.
   */
  public void setResetType(ResetType resetType) {
    this.resetType = resetType;
  }

  public String toString() {
    StringBuffer buf = new StringBuffer();

    buf.append(resetType.toString());
    buf.append(" ");

    if (quiet) {
      buf.append("-q ");
    }

    buf.append(commitName.toString());
    return buf.toString();
  }

  public boolean equals(Object o) {
    if (!(o instanceof GitResetOptions)) {
      return false;
    }

    GitResetOptions grOpts = (GitResetOptions) o;

    if (!CheckUtilities.checkObjectsEqual(commitName, grOpts.getCommitName())) {
      return false;
    }

    if (!CheckUtilities.checkObjectsEqual(resetType, grOpts.getResetType())) {
      return false;
    }

    if (grOpts.isQuiet() != quiet) {
      return false;
    }

    return true;
  }

  public int hashCode() {
    int ret = resetType.hashCode() + commitName.hashCode();
    return (quiet) ? ret + 1 : ret;
  }

}


package org.ucmtwine.proxy.injector;

import java.lang.reflect.Method;
import java.util.HashMap;

public class MethodRegistry {

  private static HashMap<String, Method> methods;

  /**
   * Adds a method to the registry and returns the UUID.
   *
   * @return
   */
  public static String addMethod(Method m) {
    if (methods == null) {
      methods = new HashMap<String, Method>();
    }

    String hashCode = String.valueOf(m.hashCode());

    if (!methods.containsKey(hashCode)) {
      methods.put(hashCode, m);
    }

    return String.valueOf(m.hashCode());
  }

  public static Method getMethod(String methodID) {

    if (methods == null)
      return null;

    return methods.get(methodID);
  }
}


package org.ucmtwine.proxy.injector;

import intradoc.common.Log;
import intradoc.common.ServiceException;
import intradoc.common.SystemUtils;
import intradoc.data.DataException;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

public abstract class BaseInjector implements IClassInjector {

  /**
   * {@inheritDoc}
   */
  public List<Class<?>> enumerateClasses(URL propertiesFile, String prefix) {
    // find mapped service classes in service.properties
    Properties properties = new Properties();

    InputStream is = null;
    try {
      is = propertiesFile.openStream();

      if (is != null) {
        properties.load(is);
      }

    } catch (IOException e) {
      Log.warn(e.getMessage());

    } finally {
      if (is != null) {
        try {
          is.close();
        } catch (IOException ignore) {

        }
      }
    }

    List<Class<?>> classes = new ArrayList<Class<?>>();

    if (properties.size() > 0) {
      for (Object key : properties.keySet()) {
        if (key.toString().startsWith(prefix)) {
          try {
            // does the class resolve?
            Class<?> klass = Class.forName(properties.get(key).toString());

            // if so, add it
            classes.add(klass);

          } catch (ClassNotFoundException e) {
            Log.warn("Unable to find class [" + properties.get(key).toString() + "]");
          }
        }
      }
    }

    return classes;
  }

  /**
   * {@inheritDoc}
   */
  public void injectClasses(List<Class<?>> classes) {
    for (Class<?> klass : classes) {
      try {
        inject(klass);
      } catch (Exception e) {
        String msg = "Failed to inject: " + klass.getName().toString() + " - " + e.getMessage();
        Log.warn(msg);
        SystemUtils.trace("twine", msg);
      }
    }
  }

  /**
   * {@inheritDoc}
   */
  public void injectClasses(URL propertiesFile, String prefix) {
    List<Class<?>> classes = enumerateClasses(propertiesFile, prefix);
    injectClasses(classes);
  }

  /**
   * {@inheritDoc}
   */
  public abstract void injectClasses(URL propertiesFile);

  /**
   * {@inheritDoc}
   */
  public abstract void inject(Class<?> klass) throws DataException, ServiceException;
}


package org.ucmtwine.proxy;

import intradoc.common.ExecutionContext;
import intradoc.common.ServiceException;
import intradoc.data.DataBinder;
import intradoc.data.DataException;
import intradoc.data.Workspace;
import intradoc.shared.FilterImplementor;

import java.lang.reflect.Method;

import org.ucmtwine.parameter.ParameterMarshaller;
import org.ucmtwine.proxy.injector.MethodRegistry;

public class FilterProxy implements FilterImplementor {

  /**
   * Main entry point which will delegate to the filter method with dependency
   * injection.
   */
  public int doFilter(Workspace ws, DataBinder binder, ExecutionContext ctx) throws DataException, ServiceException {

    Object returnVal = null;

    try {

      String methodID = (String) ctx.getCachedObject("filterParameter");

      Method m = MethodRegistry.getMethod(methodID);

      ParameterMarshaller marshaller = new ParameterMarshaller(m);

      Object[] params = marshaller.getValueArray(ws, binder, ctx);

      Object context = m.getDeclaringClass().newInstance();

      returnVal = m.invoke(context, params);

    } catch (IllegalArgumentException e) {

      throw new DataException(e.getMessage(), e);

    } catch (Exception e) {

      throw new ServiceException(e.getMessage(), e);
    }

    if (returnVal != null && returnVal instanceof Integer) {
      return ((Integer) returnVal).intValue();
    }

    return CONTINUE;
  }
}


/*
 * Copyright (C) 2014 The droitated DB Authors
 *
 * 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 org.droitateddb;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import org.droitateddb.hooks.DbCreate;
import org.droitateddb.hooks.DbUpdate;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * Handles db creation and updates.
 *
 * @author Falk Appel
 * @author Alexander Frank
 */
public class DbCreator extends SQLiteOpenHelper {

	private static final Object        LOCK             = new Object();
	private static final AtomicInteger OPEN_CONNECTIONS = new AtomicInteger(0);

	private static          PersistenceDefinition PERSISTENCE_DEFINITION;
	private static          DbCreator             DB_CREATOR_INSTANCE;
	protected static volatile SQLiteDatabase        dbConnection;

	private final PersistenceDefinition persistence;

	protected DbCreator(final Context context, final PersistenceDefinition persistence) {
		super(context, persistence.getName(), null, persistence.getVersion());
		this.persistence = persistence;
	}

	public static DbCreator getInstance(final Context context) {
		synchronized (LOCK) {
			if (PERSISTENCE_DEFINITION == null) {
				PERSISTENCE_DEFINITION = PersistenceDefinition.create(DroitatedDB.getBasePackage());
			}
			if (DB_CREATOR_INSTANCE == null) {
				DB_CREATOR_INSTANCE = new DbCreator(context, PERSISTENCE_DEFINITION);
			}
			return DB_CREATOR_INSTANCE;
		}
	}

	/**
	 * Gives you a database connection you can access the database with.

	 * Don't forget to call reduceDatabaseConnection when you are done with the connection.
	 *
	 * @return Connection to the local SQLite database
	 */
	public SQLiteDatabase getDatabaseConnection() {
		synchronized (LOCK) {
			if (dbConnection == null) {
				OPEN_CONNECTIONS.set(0);
				dbConnection = super.getWritableDatabase();
			}
			OPEN_CONNECTIONS.incrementAndGet();
			return dbConnection;
		}
	}

	/**
	 * Reduce the connection opened. This should always be called after calling getDatabaseConnection and only after that.
	 */
	public void reduceDatabaseConnection() {
		synchronized (LOCK) {
			int numberOfOpenConnections = OPEN_CONNECTIONS.decrementAndGet();
			if (numberOfOpenConnections == 0 && dbConnection != null) {
				dbConnection.close();
				dbConnection = null;
			}
		}
	}

	/**
	 * Execute a function on the database, to return some values. The opening and closing of the database connection is handled for you.

	 * Note if you want to query a cursor from the database consider using the {@code DbCreator#query} or {@code DbCreator#rawQuery} method.

	 * This can be useful when working with {@code CursorAdapter}
	 *
	 * @param <T>        Resulting type
	 * @param dbFunction Function you want to execute on the database
	 * @return The result of the function call
	 */
	public <T> T functionOnDatabase(DbFunction<T> dbFunction) {
		SQLiteDatabase db = getDatabaseConnection();
		try {
			return dbFunction.apply(db);
		} finally {
			reduceDatabaseConnection();
		}
	}

	/**
	 * Execute an action on the database. The opening and closing of the database connection is handled for you.
	 *
	 * @param dbConsumer Action you want to execute on the database
	 */
	public void consumeDatabase(DbConsumer dbConsumer) {
		SQLiteDatabase db = getDatabaseConnection();
		try {
			dbConsumer.consume(db);
		} finally {
			reduceDatabaseConnection();
		}
	}

	/**
	 * Executes a query on the database. Note that when calling close on the returned cursor the database connection count is reduces as well.
	 *
	 * @param table         Name of the table
	 * @param columns       Used columns of the queried table
	 * @param selection     Selection statement
	 * @param selectionArgs Selection arguments
	 * @param groupBy       SQL group by
	 * @param having        SQL having
	 * @param orderBy       SQL order by
	 * @return A Cursor containing the result, which reduces the database connection count when closed
	 */
	public Cursor query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy) {
		SQLiteDatabase db = getDatabaseConnection();
		return new DbClosingCursor(db.query(table, columns, selection, selectionArgs, groupBy, having, orderBy), this);
	}

	/**
	 * Executes a raw query on the database. Note that when calling close on the returned cursor the database connection count is reduces as well.
	 *
	 * @param sql Raw SQL statement
	 * @return A Cursor containing the result, which reduces the database connection count when closed
	 */
	public Cursor rawQuery(String sql) {
		SQLiteDatabase db = getDatabaseConnection();
		return new DbClosingCursor(db.rawQuery(sql, null), this);
	}

	/**
	 * This method is not supported with this helper. You have to use getDatabaseConnection and reduceDatabaseConnection
	 *
	 * @throws UnsupportedOperationException Use the getDatabaseConnection method and the reduceDatabaseConnection method to access the {@code SQLiteDatabase}
	 * @deprecated Don't use this method any more. Use getDatabaseConnection.
	 */
	@Override
	@Deprecated
	public synchronized SQLiteDatabase getReadableDatabase() {
		throw new UnsupportedOperationException("Use getDatabaseConnection and reduceDatabaseConnection or one of the performOnDatabase methods");
	}

	/**
	 * This method is not supported with this helper. You have to use getDatabaseConnection and reduceDatabaseConnection
	 *
	 * @throws UnsupportedOperationException Use the getDatabaseConnection method and the reduceDatabaseConnection method to access the {@code SQLiteDatabase}
	 * @deprecated Don't use this method any more. Use getDatabaseConnection.
	 */
	@Override
	@Deprecated
	public synchronized SQLiteDatabase getWritableDatabase() {
		throw new UnsupportedOperationException("Use getDatabaseConnection and reduceDatabaseConnection or one of the performOnDatabase methods");
	}

	@Override
	public void onCreate(final SQLiteDatabase db) {
		for (String statement : persistence.getSqlCreationStatements()) {
			db.execSQL(statement);
		}

		for (String index : persistence.getIndexStatements()) {
			db.execSQL(index);
		}

		Class<?> createHook = persistence.getCreateHook();
		if (createHook != null) {
			try {
				DbCreate createHookInstance = (DbCreate) createHook.newInstance();
				createHookInstance.onCreate(db);
			} catch (Exception e) {
				throw new IllegalStateException("Couldn't invoke the create hook", e);
			}
		}
	}

	@Override
	public void onUpgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) {
		Class<?> updateHook = persistence.getUpdateHook();
		if (updateHook != null) {
			try {
				DbUpdate updater = (DbUpdate) updateHook.newInstance();
				updater.onUpdate(db, oldVersion, newVersion);
			} catch (Exception e) {
				throw new IllegalStateException("Couldn't invoke the update hook", e);
			}
		}
	}
}


/*
 * ====================================================================
 * Copyright (c) 2008 JavaGit Project.  All rights reserved.
 *
 * This software is licensed using the GNU LGPL v2.1 license.  A copy
 * of the license is included with the distribution of this source
 * code in the LICENSE.txt file.  The text of the license can also
 * be obtained at:
 *
 *   http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
 *
 * For more information on the JavaGit project, see:
 *
 *   http://www.javagit.com
 * ====================================================================
 */
package edu.nyu.cs.javagit.client.cli;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import edu.nyu.cs.javagit.api.JavaGitConfiguration;
import edu.nyu.cs.javagit.api.JavaGitException;
import edu.nyu.cs.javagit.api.commands.GitRmOptions;
import edu.nyu.cs.javagit.api.commands.GitRmResponse;
import edu.nyu.cs.javagit.client.GitRmResponseImpl;
import edu.nyu.cs.javagit.client.IGitRm;
import edu.nyu.cs.javagit.utilities.ExceptionMessageMap;

/**
 * Command-line implementation of the IGitRm interface.
 */
public class CliGitRm implements IGitRm {

  // TODO (jhl388): Add test cases for this class.

  public GitRmResponse rm(File repository, File path) throws IOException, JavaGitException {
    return processRm(repository, null, path, null);
  }

  public GitRmResponse rm(java.io.File repository, GitRmOptions options, File path)
      throws IOException, JavaGitException {
    return processRm(repository, options, path, null);
  }

  public GitRmResponse rm(File repository, List<File> paths) throws IOException, JavaGitException {
    return processRm(repository, null, null, paths);
  }

  public GitRmResponse rm(File repository, GitRmOptions options, List<File> paths)
      throws IOException, JavaGitException {
    return processRm(repository, options, null, paths);
  }

  public GitRmResponse rmCached(File repository, List<File> paths) throws IOException,
      JavaGitException {
    GitRmOptions options = new GitRmOptions();
    options.setOptCached(true);
    return processRm(repository, options, null, paths);
  }

  public GitRmResponse rmRecursive(File repository, List<File> paths) throws IOException,
      JavaGitException {
    GitRmOptions options = new GitRmOptions();
    options.setOptR(true);
    return processRm(repository, options, null, paths);
  }

  /**
   * Processes an incoming GitRm request.
   *
   * @param repository
   *          The path to the repository.
   * @param options
   *          The options to use in constructing the command line.
   * @param path
   *          A single file/directory to delete. This should be null if there is a list of paths to
   *          delete.
   * @param paths
   *          A list of files/paths to delete. This should be null if there is a single path to
   *          delete.
   * @return The response from running the command.
   * @exception IOException
   *              There are many reasons for which an IOException may be thrown.
   *              Examples include:
   *

   *
a directory doesn't exist

   *
access to a file is denied

   *
a command is not found on the PATH

   *

   * @exception JavaGitException
   *              Thrown when there is an error making the commit.
   */
  private GitRmResponse processRm(File repository, GitRmOptions options, File path, List<File> paths)
      throws IOException, JavaGitException {
    List<String> cmdline = buildCommandLine(options, path, paths);

    GitRmParser parser = new GitRmParser();
    return (GitRmResponse) ProcessUtilities.runCommand(repository, cmdline, parser);
  }

  /**
   * Builds the command line.
   *
   * @param options
   *          The options to build with.
   * @param path
   *          If just a single path, this is it.
   * @param paths
   *          If there are multiple paths, these are they. path must be null for
   *          these paths to be used.
   * @return The list of arguments for the command line.
   */
  private List<String> buildCommandLine(GitRmOptions options, File path, List<File> paths) {
    List<String> cmdline = new ArrayList<String>();

    cmdline.add(JavaGitConfiguration.getGitCommand());
    cmdline.add("rm");

    if (null != options) {
      if (options.isOptCached()) {
        cmdline.add("--cached");
      }
      if (options.isOptF()) {
        cmdline.add("-f");
      }
      if (options.isOptN()) {
        cmdline.add("-n");
      }
      if (options.isOptQ()) {
        cmdline.add("-q");
      }
      if (options.isOptR()) {
        cmdline.add("-r");
      }
    }
    if (null != path) {
      cmdline.add(path.getPath());
    } else {
      for (File f : paths) {
        cmdline.add(f.getPath());
      }
    }
    return cmdline;
  }

  class GitRmParser implements IParser {

    // Holding onto the error message to make part of an exception
    private StringBuffer errorMsg = null;

    // Track the number of lines parsed.
    private int numLinesParsed = 0;

    // The response.
    private GitRmResponseImpl response = new GitRmResponseImpl();

    public void parseLine(String line) {

      // TODO (jhl388): handle error messages in a better manner.

      if (null != errorMsg) {
        ++numLinesParsed;
        errorMsg.append(", line" + numLinesParsed + "=[" + line + "]");
        return;
      }

      if (line.startsWith("rm '")) {
        int locQuote = line.indexOf('\'');
        int locLastQuote = line.lastIndexOf('\'');
        response.addFileToRemovedFilesList(new File(line.substring(locQuote + 1, locLastQuote)));
      } else {
        errorMsg = new StringBuffer();
        errorMsg.append("line1=[" + line + "]");
      }
    }

    public void processExitCode(int code) {
    }

   public GitRmResponse getResponse() throws JavaGitException {
      if (null != errorMsg) {
        throw new JavaGitException(434000, ExceptionMessageMap.getMessage("434000") + "  { "
            + errorMsg.toString() + " }");
      }
      return response;
    }
  }

}


/*
 * ====================================================================
 * Copyright (c) 2008 JavaGit Project.  All rights reserved.
 *
 * This software is licensed using the GNU LGPL v2.1 license.  A copy
 * of the license is included with the distribution of this source
 * code in the LICENSE.txt file.  The text of the license can also
 * be obtained at:
 *
 *   http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
 *
 * For more information on the JavaGit project, see:
 *
 *   http://www.javagit.com
 * ====================================================================
 */
package edu.nyu.cs.javagit.api.commands;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import edu.nyu.cs.javagit.api.Ref;
import edu.nyu.cs.javagit.utilities.CheckUtilities;

/**
 * Response data object for <git-checkout> command.
 */
public abstract class GitCheckoutResponse implements CommandResponse {

  /**
   * List of files that have been modified but not committed.
   */
  protected final List<File> modifiedFiles;
  /**
   * List of files added by <git-add> but not committed.
   */
  protected final List<File> addedFiles;
  /**
   * List of files deleted but not committed.
   */
  protected final List<File> deletedFiles;

  /**
   * The new branch that is created and switched to by -b option provided by <git-checkout>.
   */
  protected Ref newBranch;
  /**
   * The name of the branch to which <git-checkout> switches.
   */
  protected Ref branch;

  /**
   * Constructor
   */
  protected GitCheckoutResponse() {
    modifiedFiles = new ArrayList<File>();
    addedFiles = new ArrayList<File>();
    deletedFiles = new ArrayList<File>();
  }

  /**
   * Returns the newly created branch by -b option by <git-checkout>.
   *
   * @return Name of the new branch
   */
  public Ref getNewBranch() {
    return newBranch;
  }

  /**
   * Returns the branch to which <git-checkout> switches to.
   *
   * @return Name of the branch
   */
  public Ref getBranch() {
    return branch;
  }

  /**
   * Returns iterator to the modified files list
   *
   * @return iterator to the list.
   */
  public Iterator<File> getModifiedFilesIterator() {
    return (new ArrayList<File>(modifiedFiles).iterator());
  }

  /**
   * Gets iterator to the copy of addedFiles list.
   *
   * @return iterator to the list.
   *
   */
  public Iterator<File> getAddedFilesIterator() {
    return (new ArrayList<File>(addedFiles).iterator());
  }

  /**
   * Gets iterator to the copy of deletedFiles list.
   *
   * @return iterator to the list.
   */
  public Iterator<File> getDeletedFilesIterator() {
    return (new ArrayList<File>(deletedFiles).iterator());
  }

  /**
   * Returns the file at a given location in the addedFiles list
   *
   * @param index
   *          in the list and should be positive and less than no. of files added.
   * @return added file at the index in addedFiles list.
   */
  public File getAddedFile(int index) {
    CheckUtilities.checkIntIndexInListRange(addedFiles, index);
    return addedFiles.get(index);
  }

  /**
   * Returns the file at a given location in the deletedFiles list
   *
   * @param index
   *          in the list and should be positive and less than no. of files deleted.
   * @return deleted file at the index in deleteFiles list.
   */
  public File getDeletedFile(int index) {
    CheckUtilities.checkIntIndexInListRange(deletedFiles, index);
    return deletedFiles.get(index);
  }

  /**
   * Returns the file at a given location in the modifiedFiles list.
   *
   * @param index
   *          in the list and it should be positive and less than total no. of files modified.
   * @return modified file at the index in modifiedFiles list.
   */
  public File getModifiedFile(int index) {
    CheckUtilities.checkIntIndexInListRange(modifiedFiles, index);
    return modifiedFiles.get(index);
  }

  /**
   * Gets the total no. of files in addedFiles list.
   *
   * @return no. of files
   */
  public int getNumberOfAddedFiles() {
    return addedFiles.size();
  }

  /**
   * Gets total no. of files in modifiedFiles list.
   *
   * @return no. of files.
   */
  public int getNumberOfModifiedFiles() {
    return modifiedFiles.size();
  }

  /**
   * Gets total no. o files in addedFiles List.
   *
   * @return no. of files.
   */
  public int getNumberOfDeletedFiles() {
    return deletedFiles.size();
  }
}


/*
 * ====================================================================
 * Copyright (c) 2008 JavaGit Project.  All rights reserved.
 *
 * This software is licensed using the GNU LGPL v2.1 license.  A copy
 * of the license is included with the distribution of this source
 * code in the LICENSE.txt file.  The text of the license can also
 * be obtained at:
 *
 *   http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
 *
 * For more information on the JavaGit project, see:
 *
 *   http://www.javagit.com
 * ====================================================================
 */
package edu.nyu.cs.javagit.api;

import java.io.File;
import java.io.IOException;
import java.util.List;

import edu.nyu.cs.javagit.api.commands.GitLog;
import edu.nyu.cs.javagit.api.commands.GitLogOptions;
import edu.nyu.cs.javagit.api.commands.GitStatus;
import edu.nyu.cs.javagit.api.commands.GitLogResponse.Commit;

/**
 * GitFile a file object in a git working tree.
 */
public class GitFile extends GitFileSystemObject {
  /**
   * The constructor. Both arguments are required (i.e. cannot be null).
   *
   * @param file
   *          underlying java.io.File object
   * @param workingTree
   *          The WorkingTree that this file falls under.
   *
   */
  protected GitFile(File file, WorkingTree workingTree) throws JavaGitException {
    super(file, workingTree);
  }

  @Override
  public boolean equals(Object obj) {
    if (!(obj instanceof GitFile)) {
      return false;
    }

    GitFileSystemObject gitObj = (GitFileSystemObject) obj;
    return super.equals(gitObj);
  }

  /**
   * Show object's status in the working directory
   *
   * @return Object's status in the working directory (untracked, changed but not updated, etc).
   */
  public Status getStatus() throws IOException, JavaGitException {
    GitStatus gitStatus = new GitStatus();
    // run git-status command
    return gitStatus.getFileStatus(workingTree.getPath(), relativePath);
  }

  /**
	 * Show commit logs
	 *
	 * @return List of commits for the working directory
	 * @throws IOException
	 * @throws JavaGitException
	 */
	public List<Commit> getLog() throws JavaGitException, IOException {
		GitLog gitLog = new GitLog();
		GitLogOptions options = new GitLogOptions();
		options.setOptRelative(true,this.relativePath.toString());
		return gitLog.log(this.file);
	}

	/**
	 *
	 * @param options	Options to the git log command
	 * @return	List of commits for the working directory
	 * @throws JavaGitException
	 * @throws IOException
	 */
	public List<Commit> getLog(GitLogOptions options) throws JavaGitException, IOException {
		GitLog gitLog = new GitLog();
		options.setOptRelative(true,this.relativePath.toString());
		return gitLog.log(this.file,options);
	}

}


package com.github.andrezimmermann.dropzone.client.injector;

import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.HeadElement;

/**
 * Base class for classes that inject someting into the document header. From
 * https://gwtbootstrap.github.io/
 *
 */
abstract class AbstractInjector {

    private static HeadElement head;

    /**
     * Gets the document header.
     *
     * @return the document header
     */
    protected static HeadElement getHead() {
        if (head == null) {
            final Element element = Document.get().getElementsByTagName("head").getItem(0);
            assert element != null : "HTML Head element required";
            final HeadElement head = HeadElement.as(element);
            AbstractInjector.head = head;
        }
        return AbstractInjector.head;
    }
}


package com.github.andrezimmermann.dropzone.client.injector;

import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.HeadElement;
import com.google.gwt.dom.client.ScriptElement;

class JavaScriptInjector extends AbstractInjector {

  private static ScriptElement createScriptElement() {
    ScriptElement script = Document.get().createScriptElement();
    script.setAttribute("type", "text/javascript");
    script.setAttribute("charset", "UTF-8");
    return script;
  }

  /**
   * Injects the JavaScript code into a
   * {@code <script type="text/javascript">...</script>} element in the
   * document header.
   *
   * @param javascript the JavaScript code
   */
  public static void inject(String javascript) {
    HeadElement head = getHead();
    ScriptElement element = createScriptElement();
    element.setText(javascript);
    head.appendChild(element);
  }

}


package com.github.andrezimmermann.dropzone.client;

import java.util.ArrayList;

import com.github.andrezimmermann.dropzone.client.data.FileJS;
import com.github.andrezimmermann.dropzone.client.event.DropzoneEventHandler;
import com.github.andrezimmermann.dropzone.client.injector.ResourceInjector;
import com.github.andrezimmermann.dropzone.client.injector.resources.Resources;
import com.github.andrezimmermann.dropzone.client.interfaces.DropzoneDictonary;
import com.github.andrezimmermann.dropzone.client.interfaces.DropzoneOptions;
import com.github.andrezimmermann.dropzone.client.interfaces.File;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.core.shared.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTML;

/**
 * Main class, that is used to interact
 *
 * @author andrezimmermann
 *
 */
public class Dropzone extends Composite {

	/**
	 * Create the object that contains the Dictionary used by {@link Dropzone}
	 *
	 * @return a default (en-us) {@link DropzoneDictonary} instance
	 */
	public static DropzoneDictonary dictionary() {
		return Dictionary.create();
	}

	/**
	 * Create the object that contains the Options used by {@link Dropzone}
	 *
	 * @return a default {@link DropzoneOptions} instance
	 */
	public static DropzoneOptions options() {
		return Options.create();
	}

	private final DropzoneOptions options;

	private final DropzoneEventHandler handler;

	private final DropzoneDictonary dictionary;

	public Dropzone(DropzoneOptions options) {
		this(options, null, null, (Resources) GWT.create(Resources.class));
	}

	public Dropzone(DropzoneOptions options, DropzoneDictonary dictionary) {
		this(options, null, dictionary, (Resources) GWT.create(Resources.class));
	}

	public Dropzone(DropzoneOptions options, DropzoneEventHandler handler) {
		this(options, handler, null, (Resources) GWT.create(Resources.class));
	}

	public Dropzone(DropzoneOptions options, DropzoneEventHandler handler, DropzoneDictonary dictionary) {
		this(options, handler, dictionary, (Resources) GWT.create(Resources.class));
	}

	public Dropzone(DropzoneOptions options, DropzoneEventHandler handler, DropzoneDictonary dictionary,
			Resources resources) {
		this.options = options;
		this.handler = handler;
		this.dictionary = dictionary;
		injectResources(resources);
		initWidget();
		initDropzone(getElement(), options, handler, dictionary);
	}

	/**
	 * Add file information manually to Dropzone. Added file is not uploaded, it is just shown in the dropzone.
	 * This feature is useful for displaying e.g. files that already exists on the server.
	 *
	 * @param fileName     name of file to add
	 * @param fileSize     size of file to add
	 * @param thumbnailUrl thumbnail image for file
	 */
	public void addFile(String fileName, Integer fileSize, String thumbnailUrl) {
		addFileNative(getElement(), fileName, fileSize, thumbnailUrl);
	}

	/**
	 * Native implementation of {@link Dropzone#addFile(String, Integer, String)} method.
	 *
	 * @param e            dropzone element
	 * @param fileName     name of file to add
	 * @param fileSize     size of file to add
	 * @param thumbnailUrl thumbnail image for file
	 */
	private native void addFileNative(Element e, String fileName, Integer fileSize, String thumbnailUrl) /*-{
		var mockFile = {
			name : fileName,
			size : fileSize,
			status : @com.github.andrezimmermann.dropzone.client.data.FileConstants::SUCCESS
		};

		e.dropzone.files.push(mockFile);
		e.dropzone.emit("addedfile", mockFile);
		e.dropzone.emit("thumbnail", mockFile, thumbnailUrl);
		e.dropzone.emit("complete", mockFile);
		e.dropzone.emit("success", mockFile);
    }-*/;

	/**
	 * Return information about particular file added to dropzone.
	 *
	 * @param index of the file
	 * @return file information
	 */
	public File getFile(int index) {
		return getFilesNative(getElement()).get(index);
	}

	/**
	 * Return array if all files added to dropzone.
	 *
	 * @return all files added to dropzone.
	 */
	public ArrayList<File> getFiles() {
		//TODO Why ArrayList, change to list when in a proper IDE

		final JsArray<FileJS> filesJS = getFilesNative(getElement());
		final ArrayList<File> files = new ArrayList<File>();

		if (filesJS != null) {
			for (int i = 0; i < filesJS.length(); i++) {
				files.add(filesJS.get(i));
			}
		}

		return files;
	}

	/**
	 * Return number of added files.
	 *
	 * @return number of files
	 */
	public int getFilesCount() {
		final JsArray<FileJS> files = getFilesNative(getElement());
		return files != null ? files.length() : 0;
	}

	/**
	 * Native implementation of {@Link Dropzone#getFiles()}
	 *
	 * @param e dropzone element
	 * @return array of {@link FileJS} elements
	 */
	private native JsArray<FileJS> getFilesNative(Element e) /*-{
		return e.dropzone.files;
    }-*/;

	private native void initDropzone(Element e, DropzoneOptions options, DropzoneEventHandler handler,
			DropzoneDictonary dictionary)
			/*-{
		//if there is a dictionary, iterate over it and transfer the values

		if (dictionary) {
			for ( var key in dictionary) {
				if (dictionary.hasOwnProperty(key)) {
					options[key] = dictionary[key];
				}
			}
		}

		var dropzone = new $wnd.Dropzone(e, options);

		//If not loaded, don't add the handlers.
		if (!(dropzone instanceof $wnd.Dropzone)) {
			return;
		}
		//I'm loaded, add the eventHandlers

		//TODO: refactor this to another method

		if (this.@com.github.andrezimmermann.dropzone.client.Dropzone::handler) {

			dropzone
					.on(
							"addedfile",
							function(file) {
								handler.@com.github.andrezimmermann.dropzone.client.event.DropzoneEventHandler::onAddedFile(Lcom/github/andrezimmermann/dropzone/client/interfaces/File;)(file);
							});
			dropzone
					.on(
							"removedfile",
							function(file) {
								handler.@com.github.andrezimmermann.dropzone.client.event.DropzoneEventHandler::onRemovedfile(Lcom/github/andrezimmermann/dropzone/client/interfaces/File;)(file);
							});
			dropzone
					.on(
							"thumbnail",
							function(file, dataUri) {
								handler.@com.github.andrezimmermann.dropzone.client.event.DropzoneEventHandler::onThumbnail(Lcom/github/andrezimmermann/dropzone/client/interfaces/File;Ljava/lang/String;)(file,dataUri);
							});
			dropzone
					.on(
							"error",
							function(file, message, xhrObject) {
								handler.@com.github.andrezimmermann.dropzone.client.event.DropzoneEventHandler::onError(Lcom/github/andrezimmermann/dropzone/client/interfaces/File;Ljava/lang/String;Lcom/github/andrezimmermann/dropzone/client/interfaces/XHRObjet;)(file,message,xhrObject);
							});
			dropzone
					.on(
							"processing",
							function(file) {
								handler.@com.github.andrezimmermann.dropzone.client.event.DropzoneEventHandler::onProcessing(Lcom/github/andrezimmermann/dropzone/client/interfaces/File;)(file);
							});
			dropzone
					.on(
							"uploadprogress",
							function(file, progress, bytesSent) {
								handler.@com.github.andrezimmermann.dropzone.client.event.DropzoneEventHandler::onUploadProgress(Lcom/github/andrezimmermann/dropzone/client/interfaces/File;II)(file,progress,bytesSent);
							});
			dropzone
					.on(
							"sending",
							function(file, xhrObject, formData) {
								handler.@com.github.andrezimmermann.dropzone.client.event.DropzoneEventHandler::onSending(Lcom/github/andrezimmermann/dropzone/client/interfaces/File;Lcom/github/andrezimmermann/dropzone/client/interfaces/FormData;Lcom/github/andrezimmermann/dropzone/client/interfaces/XHRObjet;)(file,xhrObject,formData);
							});

			dropzone
					.on(
							"success",
							function(file, response) {
								handler.@com.github.andrezimmermann.dropzone.client.event.DropzoneEventHandler::onSuccess(Lcom/github/andrezimmermann/dropzone/client/interfaces/File;Ljava/lang/String;)(file,response);
							});

			dropzone
					.on(
							"complete",
							function(file) {
								handler.@com.github.andrezimmermann.dropzone.client.event.DropzoneEventHandler::onComplete(Lcom/github/andrezimmermann/dropzone/client/interfaces/File;)(file);
							});

			dropzone
					.on(
							"canceled",
							function(file) {
								handler.@com.github.andrezimmermann.dropzone.client.event.DropzoneEventHandler::onCancelled(Lcom/github/andrezimmermann/dropzone/client/interfaces/File;)(file);
							});

			dropzone
					.on(
							"maxfilesreached",
							function(file) {
								handler.@com.github.andrezimmermann.dropzone.client.event.DropzoneEventHandler::onMaxFilesReached(Lcom/github/andrezimmermann/dropzone/client/interfaces/File;)(file);
							});

			dropzone
					.on(
							"maxfilesexceeded",
							function(file) {
								handler.@com.github.andrezimmermann.dropzone.client.event.DropzoneEventHandler::onMaxFilesExceeded(Lcom/github/andrezimmermann/dropzone/client/interfaces/File;)(file);
							});

		}

    }-*/;

	private void initWidget() {
		// To conform with the standard stylesheet
		final HTML widget = new HTML();
		widget.setStylePrimaryName("dropzone");
		initWidget(widget);
	}

	private void injectResources(Resources resources) {
		ResourceInjector.configure(resources);
	}

	/**
	 *  Checks how many files are currently uploading,
	 *  and if it’s less than options.parallelUploads,
	 *  .processFile(file) is called.
	 *
	 *

	 *  If you set autoProcessQueue to false, then .processQueue() is
	 *  never called implicitly.
	 *  This means that you have to call it yourself when
	 *  you want to upload all files currently queued.
	 *

	 */
	public void processQueue() {
		processQueueNative(getElement());
	}

	private native void processQueueNative(Element e)/*-{
		e.dropzone.processQueue();
    }-*/;

	/**
	 * Removes all files from dropzone.
	 */
	public void removeAllFiles() {
		removeAllFilesNative(getElement());
	}

	/**
	 * Native implementation of {@link Dropzone#removeAllFiles()}
	 *
	 * @param e dropzone element
	 */
	private native void removeAllFilesNative(Element e) /*-{
		e.dropzone.removeAllFiles(true);
    }-*/;

	/**
	 * Removes file at index i.
	 *
	 * @param i index of the file to remove.
	 */
	public void removeFile(int i) {
		removeFileNative(getElement(), i);
	}

	/**
	 * Removes file at index i.
	 *
	 * @param i index of the file to remove.
	 */
	public void removeFile(File file) {
		removeFileNative(getElement(), file);
	}

	private native void removeFileNative(Element e, File file)  /*-{
		e.dropzone.removeFile(file);
    }-*/;

	/**
	 * Native implementation of {@link Dropzone#removeFile(int)}
	 *
	 * @param e dropzone element
	 * @param i index of the file to remove
	 */
	private native void removeFileNative(Element e, int i) /*-{
		if (e.dropzone.files[i] != null) {
			e.dropzone.removeFile(e.dropzone.files[i]);
		}
    }-*/;

	/**
	 * Return dropzone options.
	 *
	 * @return dropzone options.
	 */
	public native Options getOptions() /*-{
		var e = this.@com.github.andrezimmermann.dropzone.client.Dropzone::getElement()();
		return e.dropzone.options;
	}-*/;
}