blob: 1e0b5b2ce5778b78763a6369c6d66248c70b7c0c [file] [log] [blame]
Dave Borowitz9de65952012-08-13 16:09:45 -07001// Copyright 2012 Google Inc. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package com.google.gitiles;
16
17import static com.google.common.base.Preconditions.checkNotNull;
18import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
19import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
20import static org.eclipse.jgit.lib.Constants.OBJ_COMMIT;
21import static org.eclipse.jgit.lib.Constants.OBJ_TAG;
22import static org.eclipse.jgit.lib.Constants.OBJ_TREE;
23
24import com.google.common.collect.ImmutableMap;
25import com.google.common.collect.Lists;
26import com.google.gitiles.CommitSoyData.KeySet;
27
28import org.eclipse.jgit.errors.IncorrectObjectTypeException;
29import org.eclipse.jgit.errors.MissingObjectException;
30import org.eclipse.jgit.http.server.ServletUtils;
Dave Borowitzc8a15682013-07-02 14:33:08 -070031import org.eclipse.jgit.lib.Config;
Dave Borowitz9de65952012-08-13 16:09:45 -070032import org.eclipse.jgit.lib.Constants;
33import org.eclipse.jgit.lib.ObjectId;
34import org.eclipse.jgit.lib.Repository;
35import org.eclipse.jgit.revwalk.RevCommit;
36import org.eclipse.jgit.revwalk.RevObject;
37import org.eclipse.jgit.revwalk.RevTag;
38import org.eclipse.jgit.revwalk.RevWalk;
Dave Borowitza03760a2014-01-29 16:17:28 -080039import org.eclipse.jgit.util.GitDateFormatter;
40import org.eclipse.jgit.util.GitDateFormatter.Format;
Dave Borowitz9de65952012-08-13 16:09:45 -070041import org.slf4j.Logger;
42import org.slf4j.LoggerFactory;
43
44import java.io.IOException;
45import java.util.List;
46import java.util.Map;
47
48import javax.servlet.http.HttpServletRequest;
49import javax.servlet.http.HttpServletResponse;
50
51/** Serves an HTML page with detailed information about a ref. */
52public class RevisionServlet extends BaseServlet {
Chad Horohoead23f142012-11-12 09:45:39 -080053 private static final long serialVersionUID = 1L;
Dave Borowitz9de65952012-08-13 16:09:45 -070054 private static final Logger log = LoggerFactory.getLogger(RevisionServlet.class);
55
56 private final Linkifier linkifier;
57
Dave Borowitzc8a15682013-07-02 14:33:08 -070058 public RevisionServlet(Config cfg, Renderer renderer, Linkifier linkifier) {
Dave Borowitz54271462013-11-11 11:43:11 -080059 super(cfg, renderer);
Dave Borowitz9de65952012-08-13 16:09:45 -070060 this.linkifier = checkNotNull(linkifier, "linkifier");
61 }
62
63 @Override
64 protected void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
65 GitilesView view = ViewFilter.getView(req);
66 Repository repo = ServletUtils.getRepository(req);
67
68 RevWalk walk = new RevWalk(repo);
69 try {
Dave Borowitza03760a2014-01-29 16:17:28 -080070 GitDateFormatter df = new GitDateFormatter(Format.DEFAULT);
Dave Borowitz558005d2012-12-20 15:48:08 -080071 List<RevObject> objects = listObjects(walk, view.getRevision());
Dave Borowitz9de65952012-08-13 16:09:45 -070072 List<Map<String, ?>> soyObjects = Lists.newArrayListWithCapacity(objects.size());
73 boolean hasBlob = false;
74
75 // TODO(sop): Allow caching commits by SHA-1 when no S cookie is sent.
76 for (RevObject obj : objects) {
77 try {
78 switch (obj.getType()) {
79 case OBJ_COMMIT:
80 soyObjects.add(ImmutableMap.of(
81 "type", Constants.TYPE_COMMIT,
Dave Borowitz3b086a72013-07-02 15:03:03 -070082 "data", new CommitSoyData()
83 .setLinkifier(linkifier)
84 .setRevWalk(walk)
Dave Borowitzc8a15682013-07-02 14:33:08 -070085 .setArchiveFormat(archiveFormat)
Dave Borowitza03760a2014-01-29 16:17:28 -080086 .toSoyData(req, (RevCommit) obj, KeySet.DETAIL_DIFF_TREE, df)));
Dave Borowitz9de65952012-08-13 16:09:45 -070087 break;
88 case OBJ_TREE:
89 soyObjects.add(ImmutableMap.of(
90 "type", Constants.TYPE_TREE,
91 "data", new TreeSoyData(walk, view).toSoyData(obj)));
92 break;
93 case OBJ_BLOB:
94 soyObjects.add(ImmutableMap.of(
95 "type", Constants.TYPE_BLOB,
96 "data", new BlobSoyData(walk, view).toSoyData(obj)));
97 hasBlob = true;
98 break;
99 case OBJ_TAG:
100 soyObjects.add(ImmutableMap.of(
101 "type", Constants.TYPE_TAG,
Dave Borowitza03760a2014-01-29 16:17:28 -0800102 "data", new TagSoyData(linkifier, req).toSoyData((RevTag) obj, df)));
Dave Borowitz9de65952012-08-13 16:09:45 -0700103 break;
104 default:
Dave Borowitzfd25c3a2013-01-11 14:37:11 -0800105 log.warn("Bad object type for {}: {}", ObjectId.toString(obj.getId()), obj.getType());
Dave Borowitz9de65952012-08-13 16:09:45 -0700106 res.setStatus(SC_NOT_FOUND);
107 return;
108 }
109 } catch (MissingObjectException e) {
110 log.warn("Missing object " + ObjectId.toString(obj.getId()), e);
111 res.setStatus(SC_NOT_FOUND);
112 return;
113 } catch (IncorrectObjectTypeException e) {
114 log.warn("Incorrect object type for " + ObjectId.toString(obj.getId()), e);
115 res.setStatus(SC_NOT_FOUND);
116 return;
117 }
118 }
119
Dave Borowitzb1c628f2013-01-11 11:28:20 -0800120 renderHtml(req, res, "gitiles.revisionDetail", ImmutableMap.of(
Dave Borowitz9de65952012-08-13 16:09:45 -0700121 "title", view.getRevision().getName(),
122 "objects", soyObjects,
123 "hasBlob", hasBlob));
124 } finally {
125 walk.release();
126 }
127 }
128
129 // TODO(dborowitz): Extract this.
Dave Borowitz558005d2012-12-20 15:48:08 -0800130 static List<RevObject> listObjects(RevWalk walk, Revision rev)
Dave Borowitz9de65952012-08-13 16:09:45 -0700131 throws MissingObjectException, IOException {
132 List<RevObject> objects = Lists.newArrayListWithExpectedSize(1);
Dave Borowitz558005d2012-12-20 15:48:08 -0800133 ObjectId id = rev.getId();
134 RevObject cur;
Dave Borowitz9de65952012-08-13 16:09:45 -0700135 while (true) {
Dave Borowitz558005d2012-12-20 15:48:08 -0800136 cur = walk.parseAny(id);
Dave Borowitz9de65952012-08-13 16:09:45 -0700137 objects.add(cur);
Dave Borowitz558005d2012-12-20 15:48:08 -0800138 if (cur.getType() != Constants.OBJ_TAG) {
Dave Borowitz9de65952012-08-13 16:09:45 -0700139 break;
140 }
Dave Borowitz558005d2012-12-20 15:48:08 -0800141 id = ((RevTag) cur).getObject();
142 }
143 if (cur.getType() == Constants.OBJ_COMMIT) {
144 objects.add(walk.parseTree(((RevCommit) cur).getTree()));
Dave Borowitz9de65952012-08-13 16:09:45 -0700145 }
146 return objects;
147 }
148}