blob: c22d6270a9709bb2be880cf0f2381a0bff3889cc [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;
Dave Borowitzc8a15682013-07-02 14:33:08 -070018
Dave Borowitz9de65952012-08-13 16:09:45 -070019import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
Dave Borowitzc8a15682013-07-02 14:33:08 -070020
Dave Borowitz9de65952012-08-13 16:09:45 -070021import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
22import static org.eclipse.jgit.lib.Constants.OBJ_COMMIT;
23import static org.eclipse.jgit.lib.Constants.OBJ_TAG;
24import static org.eclipse.jgit.lib.Constants.OBJ_TREE;
25
26import com.google.common.collect.ImmutableMap;
27import com.google.common.collect.Lists;
28import com.google.gitiles.CommitSoyData.KeySet;
29
30import org.eclipse.jgit.errors.IncorrectObjectTypeException;
31import org.eclipse.jgit.errors.MissingObjectException;
32import org.eclipse.jgit.http.server.ServletUtils;
Dave Borowitzc8a15682013-07-02 14:33:08 -070033import org.eclipse.jgit.lib.Config;
Dave Borowitz9de65952012-08-13 16:09:45 -070034import org.eclipse.jgit.lib.Constants;
35import org.eclipse.jgit.lib.ObjectId;
36import org.eclipse.jgit.lib.Repository;
37import org.eclipse.jgit.revwalk.RevCommit;
38import org.eclipse.jgit.revwalk.RevObject;
39import org.eclipse.jgit.revwalk.RevTag;
40import org.eclipse.jgit.revwalk.RevWalk;
41import 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;
Dave Borowitzc8a15682013-07-02 14:33:08 -070057 private final ArchiveFormat archiveFormat;
Dave Borowitz9de65952012-08-13 16:09:45 -070058
Dave Borowitzc8a15682013-07-02 14:33:08 -070059 public RevisionServlet(Config cfg, Renderer renderer, Linkifier linkifier) {
Dave Borowitz9de65952012-08-13 16:09:45 -070060 super(renderer);
61 this.linkifier = checkNotNull(linkifier, "linkifier");
Dave Borowitzc8a15682013-07-02 14:33:08 -070062 this.archiveFormat = ArchiveFormat.getDefault(checkNotNull(cfg, "cfg"));
Dave Borowitz9de65952012-08-13 16:09:45 -070063 }
64
65 @Override
66 protected void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
67 GitilesView view = ViewFilter.getView(req);
68 Repository repo = ServletUtils.getRepository(req);
69
70 RevWalk walk = new RevWalk(repo);
71 try {
Dave Borowitz558005d2012-12-20 15:48:08 -080072 List<RevObject> objects = listObjects(walk, view.getRevision());
Dave Borowitz9de65952012-08-13 16:09:45 -070073 List<Map<String, ?>> soyObjects = Lists.newArrayListWithCapacity(objects.size());
74 boolean hasBlob = false;
75
76 // TODO(sop): Allow caching commits by SHA-1 when no S cookie is sent.
77 for (RevObject obj : objects) {
78 try {
79 switch (obj.getType()) {
80 case OBJ_COMMIT:
81 soyObjects.add(ImmutableMap.of(
82 "type", Constants.TYPE_COMMIT,
Dave Borowitz3b086a72013-07-02 15:03:03 -070083 "data", new CommitSoyData()
84 .setLinkifier(linkifier)
85 .setRevWalk(walk)
Dave Borowitzc8a15682013-07-02 14:33:08 -070086 .setArchiveFormat(archiveFormat)
Dave Borowitz3b086a72013-07-02 15:03:03 -070087 .toSoyData(req, (RevCommit) obj, KeySet.DETAIL_DIFF_TREE)));
Dave Borowitz9de65952012-08-13 16:09:45 -070088 break;
89 case OBJ_TREE:
90 soyObjects.add(ImmutableMap.of(
91 "type", Constants.TYPE_TREE,
92 "data", new TreeSoyData(walk, view).toSoyData(obj)));
93 break;
94 case OBJ_BLOB:
95 soyObjects.add(ImmutableMap.of(
96 "type", Constants.TYPE_BLOB,
97 "data", new BlobSoyData(walk, view).toSoyData(obj)));
98 hasBlob = true;
99 break;
100 case OBJ_TAG:
101 soyObjects.add(ImmutableMap.of(
102 "type", Constants.TYPE_TAG,
103 "data", new TagSoyData(linkifier, req).toSoyData((RevTag) obj)));
104 break;
105 default:
Dave Borowitzfd25c3a2013-01-11 14:37:11 -0800106 log.warn("Bad object type for {}: {}", ObjectId.toString(obj.getId()), obj.getType());
Dave Borowitz9de65952012-08-13 16:09:45 -0700107 res.setStatus(SC_NOT_FOUND);
108 return;
109 }
110 } catch (MissingObjectException e) {
111 log.warn("Missing object " + ObjectId.toString(obj.getId()), e);
112 res.setStatus(SC_NOT_FOUND);
113 return;
114 } catch (IncorrectObjectTypeException e) {
115 log.warn("Incorrect object type for " + ObjectId.toString(obj.getId()), e);
116 res.setStatus(SC_NOT_FOUND);
117 return;
118 }
119 }
120
Dave Borowitzb1c628f2013-01-11 11:28:20 -0800121 renderHtml(req, res, "gitiles.revisionDetail", ImmutableMap.of(
Dave Borowitz9de65952012-08-13 16:09:45 -0700122 "title", view.getRevision().getName(),
123 "objects", soyObjects,
124 "hasBlob", hasBlob));
125 } finally {
126 walk.release();
127 }
128 }
129
130 // TODO(dborowitz): Extract this.
Dave Borowitz558005d2012-12-20 15:48:08 -0800131 static List<RevObject> listObjects(RevWalk walk, Revision rev)
Dave Borowitz9de65952012-08-13 16:09:45 -0700132 throws MissingObjectException, IOException {
133 List<RevObject> objects = Lists.newArrayListWithExpectedSize(1);
Dave Borowitz558005d2012-12-20 15:48:08 -0800134 ObjectId id = rev.getId();
135 RevObject cur;
Dave Borowitz9de65952012-08-13 16:09:45 -0700136 while (true) {
Dave Borowitz558005d2012-12-20 15:48:08 -0800137 cur = walk.parseAny(id);
Dave Borowitz9de65952012-08-13 16:09:45 -0700138 objects.add(cur);
Dave Borowitz558005d2012-12-20 15:48:08 -0800139 if (cur.getType() != Constants.OBJ_TAG) {
Dave Borowitz9de65952012-08-13 16:09:45 -0700140 break;
141 }
Dave Borowitz558005d2012-12-20 15:48:08 -0800142 id = ((RevTag) cur).getObject();
143 }
144 if (cur.getType() == Constants.OBJ_COMMIT) {
145 objects.add(walk.parseTree(((RevCommit) cur).getTree()));
Dave Borowitz9de65952012-08-13 16:09:45 -0700146 }
147 return objects;
148 }
149}