Package org.eclipse.orion.server.git.objects

Source Code of org.eclipse.orion.server.git.objects.Log

/*******************************************************************************
* Copyright (c) 2011, 2014 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.orion.server.git.objects;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.ListBranchCommand.ListMode;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.transport.RemoteConfig;
import org.eclipse.orion.server.core.ProtocolConstants;
import org.eclipse.orion.server.core.resources.Property;
import org.eclipse.orion.server.core.resources.ResourceShape;
import org.eclipse.orion.server.core.resources.annotations.PropertyDescription;
import org.eclipse.orion.server.core.resources.annotations.ResourceDescription;
import org.eclipse.orion.server.git.BaseToCommitConverter;
import org.eclipse.orion.server.git.GitConstants;
import org.eclipse.orion.server.git.servlets.GitUtils;
import org.eclipse.osgi.util.NLS;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

/**
* A compound object for {@link Commit}s.
*
*/
@ResourceDescription(type = Commit.TYPE)
public class Log extends GitObject {

  private static final ResourceShape DEFAULT_RESOURCE_SHAPE = new ResourceShape();
  {
    Property[] defaultProperties = new Property[] { //
    new Property(ProtocolConstants.KEY_LOCATION), // super
        new Property(GitConstants.KEY_CLONE), // super
        new Property(ProtocolConstants.KEY_CHILDREN), //
        new Property(GitConstants.KEY_REPOSITORY_PATH), //
        new Property(GitConstants.KEY_LOG_TO_REF), //
        new Property(GitConstants.KEY_LOG_FROM_REF), //
        new Property(ProtocolConstants.KEY_PREVIOUS_LOCATION), //
        new Property(ProtocolConstants.KEY_NEXT_LOCATION) };
    DEFAULT_RESOURCE_SHAPE.setProperties(defaultProperties);
  }

  private List<RevCommit> commits;
  private String pattern;
  private String messagePattern;
  private String authorPattern;
  private String committerPattern;
  private String sha1Pattern;
  private String fromDate;
  private String toDate;
  private boolean mergeBase;
  private Ref toRefId;
  private Ref fromRefId;
  private int page;
  private int pageSize;

  public Log(URI cloneLocation, Repository db, Iterable<RevCommit> commits, String pattern, Ref toRefId, Ref fromRefId) {
    super(cloneLocation, db);
    this.commits = commits != null ? toList(commits) : Collections.<RevCommit> emptyList();
    this.pattern = pattern;
    this.toRefId = toRefId;
    this.fromRefId = fromRefId;
  }

  public void setCommits(Iterable<RevCommit> commits) {
    this.commits = toList(commits);
  }

  private static <E> List<E> toList(Iterable<E> iterable) {
    List<E> list = new ArrayList<E>();
    for (E item : iterable)
      list.add(item);
    return list;
  }

  public void setPaging(int page, int pageSize) {
    this.page = page;
    this.pageSize = pageSize;
  }

  public void setMessagePattern(String messagePattern) {
    this.messagePattern = messagePattern;
  }

  public void setAuthorPattern(String authorPattern) {
    this.authorPattern = authorPattern;
  }

  public void setCommitterPattern(String committerPattern) {
    this.committerPattern = committerPattern;
  }

  public void setSHA1Pattern(String sha1Pattern) {
    this.sha1Pattern = sha1Pattern;
  }

  public void setFromDate(String fromDate) {
    this.fromDate = fromDate;
  }

  public void setToDate(String toDate) {
    this.toDate = toDate;
  }

  public void setMergeBaseFilter(boolean mergeBaseFilter) {
    this.mergeBase = mergeBaseFilter;
  }

  @Override
  public JSONObject toJSON() throws JSONException, URISyntaxException, IOException, CoreException {
    Assert.isNotNull(commits, "'commits' is null");
    return jsonSerializer.serialize(this, DEFAULT_RESOURCE_SHAPE);
  }

  @PropertyDescription(name = ProtocolConstants.KEY_CHILDREN)
  private JSONArray getChildren() throws GitAPIException, JSONException, URISyntaxException, IOException, CoreException {
    Map<ObjectId, JSONArray> commitToBranchMap = getCommitToBranchMap(cloneLocation, db);
    Map<ObjectId, Map<String, Ref>> commitToTagMap = getCommitToTagMap(cloneLocation, db);
    JSONArray children = new JSONArray();
    int i = 0;
    for (RevCommit revCommit : commits) {
      Commit commit = new Commit(cloneLocation, db, revCommit, pattern);
      commit.setCommitToBranchMap(commitToBranchMap);
      commit.setCommitToTagMap(commitToTagMap);
      children.put(commit.toJSON());
      if (i++ == pageSize - 1)
        break;
    }
    return children;
  }

  @PropertyDescription(name = GitConstants.KEY_REPOSITORY_PATH)
  private String getRepositoryPath() {
    return pattern == null ? "" : pattern; //$NON-NLS-1$
  }

  @PropertyDescription(name = GitConstants.KEY_LOG_TO_REF)
  private JSONObject getToRef() throws JSONException, URISyntaxException, IOException, CoreException {
    if (toRefId != null)
      return createJSONObjectForRef(toRefId.getTarget());
    return null;
  }

  @PropertyDescription(name = GitConstants.KEY_LOG_FROM_REF)
  private JSONObject getFromRef() throws JSONException, URISyntaxException, IOException, CoreException {
    if (fromRefId != null)
      return createJSONObjectForRef(fromRefId.getTarget());
    return null;
  }

  @PropertyDescription(name = ProtocolConstants.KEY_PREVIOUS_LOCATION)
  private URI getPreviousPageLocation() throws URISyntaxException {
    if (page > 0) {
      String c = getRefRange();
      String q = getCommitQuery();
      if (page > 1) {
        return BaseToCommitConverter.getCommitLocation(cloneLocation, GitUtils.encode(c), pattern,
            BaseToCommitConverter.REMOVE_FIRST_2.setQuery(String.format(q, page - 1, pageSize)));
      }
    }
    return null;
  }

  private String getRefRange() {
    StringBuilder c = new StringBuilder(""); //$NON-NLS-1$
    if (fromRefId != null)
      c.append(fromRefId.getName());
    if (fromRefId != null && toRefId != null)
      c.append(".."); //$NON-NLS-1$
    if (toRefId != null)
      c.append(Repository.shortenRefName(toRefId.getName()));
    return c.toString();
  }

  private String getCommitQuery() {
    String q = "page=%d&pageSize=%d"; //$NON-NLS-1$
    if (this.messagePattern != null) {
      q += "&filter=" + GitUtils.encode(this.messagePattern); //$NON-NLS-1$
    }
    if (this.authorPattern != null) {
      q += "&author=" + GitUtils.encode(this.authorPattern); //$NON-NLS-1$
    }
    if (this.committerPattern != null) {
      q += "&committer=" + GitUtils.encode(this.committerPattern); //$NON-NLS-1$
    }
    if (this.sha1Pattern != null) {
      q += "&sha1=" + GitUtils.encode(this.sha1Pattern); //$NON-NLS-1$
    }
    if (this.fromDate != null) {
      q += "&fromDate=" + this.fromDate; //$NON-NLS-1$
    }
    if (this.toDate != null) {
      q += "&toDate=" + this.toDate; //$NON-NLS-1$
    }
    if (this.mergeBase) {
      q += "&mergeBase=true"; //$NON-NLS-1$
    }
    return q;
  }

  @PropertyDescription(name = ProtocolConstants.KEY_NEXT_LOCATION)
  private URI getNextPageLocation() throws URISyntaxException {
    if (hasNextPage()) {
      String c = getRefRange();
      String q = getCommitQuery();
      return BaseToCommitConverter.getCommitLocation(cloneLocation, GitUtils.encode(c), pattern,
          BaseToCommitConverter.REMOVE_FIRST_2.setQuery(String.format(q, page + 1, pageSize)));
    }
    return null;
  }

  private boolean hasNextPage() {
    return commits.size() > pageSize;
  }

  private JSONObject createJSONObjectForRef(Ref targetRef) throws JSONException, URISyntaxException, IOException, CoreException {
    JSONObject result = null;
    String name = targetRef.getName();
    if (name.startsWith(Constants.R_HEADS)) {
      result = new Branch(cloneLocation, db, targetRef).toJSON();
    } else if (name.startsWith(Constants.R_REMOTES)) {
      Remote remote = findRemote(name);
      String remoteBranchName = computeRemoteBranchName(name, remote);
      result = new RemoteBranch(cloneLocation, db, remote, remoteBranchName).toJSON();
    }
    Assert.isNotNull(result, NLS.bind("Unexpected target Ref: {0}", name));
    return result;
  }

  private Remote findRemote(String refName) throws URISyntaxException {
    Assert.isLegal(refName.startsWith(Constants.R_REMOTES), NLS.bind("Expected Ref starting with {0} was {1}", Constants.R_REMOTES, refName));
    IPath remoteNameCandidate = new Path(refName).removeFirstSegments(2);
    List<RemoteConfig> remoteConfigs = RemoteConfig.getAllRemoteConfigs(getConfig());
    for (int i = 1; i < remoteNameCandidate.segmentCount(); i++) {
      for (RemoteConfig remoteConfig : remoteConfigs) {
        IPath uptoSegment = remoteNameCandidate.uptoSegment(i);
        if (remoteConfig.getName().equals(uptoSegment.toString()))
          return new Remote(cloneLocation, db, remoteConfig.getName());
      }
    }
    Assert.isTrue(false, NLS.bind("Could not find Remote for {0}", refName));
    return null;
  }

  private String computeRemoteBranchName(String targetRefName, Remote remote) {
    String prefix = Constants.R_REMOTES + remote.getName() + "/"; //$NON-NLS-1$
    return targetRefName.substring(prefix.length());
  }

  @Override
  protected URI getLocation() throws URISyntaxException {
    StringBuilder c = new StringBuilder();
    if (fromRefId != null)
      c.append(fromRefId.getName());
    if (fromRefId != null && toRefId != null)
      c.append(".."); //$NON-NLS-1$
    if (toRefId != null)
      c.append(toRefId.getName());
    // TODO: lost paging info
    return BaseToCommitConverter.getCommitLocation(cloneLocation, GitUtils.encode(c.toString()), pattern, BaseToCommitConverter.REMOVE_FIRST_2);
  }

  static Map<ObjectId, JSONArray> getCommitToBranchMap(URI cloneLocation, Repository db) throws GitAPIException, JSONException {
    HashMap<ObjectId, JSONArray> commitToBranch = new HashMap<ObjectId, JSONArray>();
    Git git = new Git(db);
    List<Ref> branchRefs = git.branchList().setListMode(ListMode.ALL).call();
    for (Ref branchRef : branchRefs) {
      ObjectId commitId = branchRef.getLeaf().getObjectId();
      JSONObject branch = new JSONObject();
      branch.put(ProtocolConstants.KEY_FULL_NAME, branchRef.getName());

      JSONArray branchesArray = commitToBranch.get(commitId);
      if (branchesArray != null) {
        branchesArray.put(branch);
      } else {
        branchesArray = new JSONArray();
        branchesArray.put(branch);
        commitToBranch.put(commitId, branchesArray);
      }
    }
    return commitToBranch;
  }

  static Map<ObjectId, Map<String, Ref>> getCommitToTagMap(URI cloneLocation, Repository db) throws MissingObjectException, IOException {
    HashMap<ObjectId, Map<String, Ref>> commitToTag = new HashMap<ObjectId, Map<String, Ref>>();
    for (Entry<String, Ref> tag : db.getTags().entrySet()) {
      Ref ref = db.peel(tag.getValue());
      ObjectId commitId = ref.getPeeledObjectId();
      if (commitId == null)
        commitId = ref.getObjectId();

      Map<String, Ref> tags = commitToTag.get(commitId);
      if (tags != null) {
        tags.put(tag.getKey(), tag.getValue());
      } else {
        tags = new HashMap<String, Ref>();
        tags.put(tag.getKey(), tag.getValue());
        commitToTag.put(commitId, tags);
      }
    }
    return commitToTag;
  }
}
TOP

Related Classes of org.eclipse.orion.server.git.objects.Log

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.