001/* 002 * ModeShape (http://www.modeshape.org) 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.modeshape.connector.git; 017 018import java.io.IOException; 019import org.eclipse.jgit.api.Git; 020import org.eclipse.jgit.api.errors.GitAPIException; 021import org.eclipse.jgit.lib.ObjectId; 022import org.eclipse.jgit.lib.Repository; 023import org.eclipse.jgit.revwalk.RevCommit; 024import org.eclipse.jgit.revwalk.RevWalk; 025import org.modeshape.schematic.document.Document; 026import org.modeshape.jcr.spi.federation.DocumentWriter; 027import org.modeshape.jcr.spi.federation.PageKey; 028import org.modeshape.jcr.spi.federation.PageWriter; 029 030/** 031 * A {@link GitFunction} that returns the history information about the (latest) commits in a particular branch or tag. The 032 * structure of this area of the repository is as follows: 033 * 034 * <pre> 035 * /commits/{branchOrTagNameOrObjectId}/{objectId} 036 * </pre> 037 */ 038public class GitHistory extends GitFunction implements PageableGitFunction { 039 040 protected static Object referenceToHistory( ObjectId id, 041 String branchOrTagName, 042 Values values ) { 043 return values.referenceTo(ID + DELIMITER + branchOrTagName + DELIMITER + id.getName()); 044 } 045 046 protected static final String NAME = "commits"; 047 protected static final String ID = "/commits"; 048 049 protected static int DEFAULT_PAGE_SIZE = 15; 050 051 private int pageSize = DEFAULT_PAGE_SIZE; 052 053 public GitHistory( GitConnector connector ) { 054 super(NAME, connector); 055 } 056 057 @Override 058 public boolean isPaged() { 059 return true; 060 } 061 062 @Override 063 public Document execute( Repository repository, 064 Git git, 065 CallSpecification spec, 066 DocumentWriter writer, 067 Values values ) throws GitAPIException, IOException { 068 if (spec.parameterCount() == 0) { 069 // This is the top-level "/commits" node 070 writer.setPrimaryType(GitLexicon.COMMITS); 071 072 // Generate the child references to the branches, tags, and commits in the history ... 073 addBranchesAsChildren(git, spec, writer); 074 addTagsAsChildren(git, spec, writer); 075 addCommitsAsChildren(git, spec, writer, pageSize); 076 077 } else if (spec.parameterCount() == 1) { 078 // This is the top-level "/commits/{branchOrTagNameOrObjectId}" node 079 writer.setPrimaryType(GitLexicon.OBJECT); 080 addCommitsAsChildren(git, spec, writer, pageSize); 081 } else if (spec.parameterCount() == 2) { 082 // This is a specific commit in the history, via "/commits/{branchOrTagNameOrObjectId}/{objectId}" 083 writer.setPrimaryType(GitLexicon.COMMIT); 084 085 // so we need to show the commit information ... 086 RevWalk walker = new RevWalk(repository); 087 try { 088 String commitId = spec.parameter(1); 089 ObjectId objId = repository.resolve(commitId); 090 RevCommit commit = walker.parseCommit(objId); 091 writer.addProperty(GitLexicon.OBJECT_ID, objId.name()); 092 writer.addProperty(GitLexicon.AUTHOR, authorName(commit)); 093 writer.addProperty(GitLexicon.COMMITTER, commiterName(commit)); 094 writer.addProperty(GitLexicon.COMMITTED, values.dateFrom(commit.getCommitTime())); 095 writer.addProperty(GitLexicon.TITLE, commit.getShortMessage()); 096 writer.addProperty(GitLexicon.TREE, GitTree.referenceToTree(objId, objId.name(), values)); 097 writer.addProperty(GitLexicon.DETAIL, GitCommitDetails.referenceToCommit(objId, values)); 098 // And there are no children 099 } finally { 100 walker.dispose(); 101 } 102 } else { 103 return null; 104 } 105 106 return writer.document(); 107 } 108 109 @Override 110 public Document execute( Repository repository, 111 Git git, 112 CallSpecification spec, 113 PageWriter writer, 114 Values values, 115 PageKey pageKey ) throws GitAPIException, IOException { 116 // List the next page of commits ... 117 addCommitsAsPageOfChildren(git, repository, spec, writer, pageKey); 118 return writer.document(); 119 } 120}