org.eclipse.orion.server.git.objects.Log.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.orion.server.git.objects.Log.java

Source

/*******************************************************************************
 * Copyright (c) 2011, 2012 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.*;
import org.eclipse.core.runtime.*;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.ListBranchCommand.ListMode;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.*;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.transport.RemoteConfig;
import org.eclipse.orion.internal.server.servlets.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.*;

/**
 * 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 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 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);
        JSONArray children = new JSONArray();
        int i = 0;
        for (RevCommit revCommit : commits) {
            Commit commit = new Commit(cloneLocation, db, revCommit, pattern);
            commit.setCommitToBranchMap(commitToBranchMap);
            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) {
            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()));
            final String q = "page=%d&pageSize=%d"; //$NON-NLS-1$
            if (page > 1) {
                return BaseToCommitConverter.getCommitLocation(cloneLocation, c.toString(), pattern,
                        BaseToCommitConverter.REMOVE_FIRST_2.setQuery(String.format(q, page - 1, pageSize)));
            }
        }
        return null;
    }

    @PropertyDescription(name = ProtocolConstants.KEY_NEXT_LOCATION)
    private URI getNextPageLocation() throws URISyntaxException {
        if (hasNextPage()) {
            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()));
            final String q = "page=%d&pageSize=%d"; //$NON-NLS-1$
            return BaseToCommitConverter.getCommitLocation(cloneLocation, c.toString(), 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;
    }
}