blob: d065a450a067a886adda9e673b7fd8ba52104f43 [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;
Dave Borowitz01551272014-03-16 13:43:16 -070025import com.google.common.collect.ImmutableSet;
Dave Borowitz9de65952012-08-13 16:09:45 -070026import com.google.common.collect.Lists;
Dave Borowitz01551272014-03-16 13:43:16 -070027import com.google.gitiles.CommitData.Field;
Dave Borowitz90d1db92014-03-16 14:16:15 -070028import com.google.gitiles.CommitJsonData.Commit;
Dave Borowitz2b2f34b2014-04-29 16:47:20 -070029import com.google.gitiles.DateFormatter.Format;
Dave Borowitz9de65952012-08-13 16:09:45 -070030
31import org.eclipse.jgit.errors.IncorrectObjectTypeException;
32import org.eclipse.jgit.errors.MissingObjectException;
33import org.eclipse.jgit.http.server.ServletUtils;
34import 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 {
Dave Borowitz90d1db92014-03-16 14:16:15 -070053 private static final ImmutableSet<Field> COMMIT_SOY_FIELDS =
54 Field.setOf(CommitSoyData.DEFAULT_FIELDS, Field.DIFF_TREE);
55 private static final ImmutableSet<Field> COMMIT_JSON_FIELDS =
56 Field.setOf(CommitJsonData.DEFAULT_FIELDS, Field.DIFF_TREE);
Dave Borowitz01551272014-03-16 13:43:16 -070057
Chad Horohoead23f142012-11-12 09:45:39 -080058 private static final long serialVersionUID = 1L;
Dave Borowitz9de65952012-08-13 16:09:45 -070059 private static final Logger log = LoggerFactory.getLogger(RevisionServlet.class);
60
61 private final Linkifier linkifier;
62
Dave Borowitzded109a2014-03-03 15:25:39 -050063 public RevisionServlet(GitilesAccess.Factory accessFactory, Renderer renderer,
Dave Borowitz2b2f34b2014-04-29 16:47:20 -070064 Linkifier linkifier) {
Dave Borowitz8d6d6872014-03-16 15:18:14 -070065 super(renderer, accessFactory);
Dave Borowitz9de65952012-08-13 16:09:45 -070066 this.linkifier = checkNotNull(linkifier, "linkifier");
67 }
68
69 @Override
Dave Borowitz90d1db92014-03-16 14:16:15 -070070 protected void doGetHtml(HttpServletRequest req, HttpServletResponse res) throws IOException {
Dave Borowitz9de65952012-08-13 16:09:45 -070071 GitilesView view = ViewFilter.getView(req);
72 Repository repo = ServletUtils.getRepository(req);
Dave Borowitz2b2f34b2014-04-29 16:47:20 -070073 GitilesAccess access = getAccess(req);
Dave Borowitz9de65952012-08-13 16:09:45 -070074
75 RevWalk walk = new RevWalk(repo);
76 try {
Dave Borowitz2b2f34b2014-04-29 16:47:20 -070077 DateFormatter df = new DateFormatter(access, Format.DEFAULT);
Dave Borowitz558005d2012-12-20 15:48:08 -080078 List<RevObject> objects = listObjects(walk, view.getRevision());
Dave Borowitz9de65952012-08-13 16:09:45 -070079 List<Map<String, ?>> soyObjects = Lists.newArrayListWithCapacity(objects.size());
80 boolean hasBlob = false;
81
82 // TODO(sop): Allow caching commits by SHA-1 when no S cookie is sent.
83 for (RevObject obj : objects) {
84 try {
85 switch (obj.getType()) {
86 case OBJ_COMMIT:
87 soyObjects.add(ImmutableMap.of(
88 "type", Constants.TYPE_COMMIT,
Dave Borowitz3b086a72013-07-02 15:03:03 -070089 "data", new CommitSoyData()
90 .setLinkifier(linkifier)
91 .setRevWalk(walk)
Dave Borowitz2b2f34b2014-04-29 16:47:20 -070092 .setArchiveFormat(getArchiveFormat(access))
Dave Borowitz90d1db92014-03-16 14:16:15 -070093 .toSoyData(req, (RevCommit) obj, COMMIT_SOY_FIELDS, df)));
Dave Borowitz9de65952012-08-13 16:09:45 -070094 break;
95 case OBJ_TREE:
96 soyObjects.add(ImmutableMap.of(
97 "type", Constants.TYPE_TREE,
Dave Borowitz6e797482014-05-01 11:10:01 -070098 "data", new TreeSoyData(walk.getObjectReader(), view).toSoyData(obj)));
Dave Borowitz9de65952012-08-13 16:09:45 -070099 break;
100 case OBJ_BLOB:
101 soyObjects.add(ImmutableMap.of(
102 "type", Constants.TYPE_BLOB,
Dave Borowitz6e797482014-05-01 11:10:01 -0700103 "data", new BlobSoyData(walk.getObjectReader(), view).toSoyData(obj)));
Dave Borowitz9de65952012-08-13 16:09:45 -0700104 hasBlob = true;
105 break;
106 case OBJ_TAG:
107 soyObjects.add(ImmutableMap.of(
108 "type", Constants.TYPE_TAG,
Dave Borowitza03760a2014-01-29 16:17:28 -0800109 "data", new TagSoyData(linkifier, req).toSoyData((RevTag) obj, df)));
Dave Borowitz9de65952012-08-13 16:09:45 -0700110 break;
111 default:
Dave Borowitzfd25c3a2013-01-11 14:37:11 -0800112 log.warn("Bad object type for {}: {}", ObjectId.toString(obj.getId()), obj.getType());
Dave Borowitz9de65952012-08-13 16:09:45 -0700113 res.setStatus(SC_NOT_FOUND);
114 return;
115 }
116 } catch (MissingObjectException e) {
117 log.warn("Missing object " + ObjectId.toString(obj.getId()), e);
118 res.setStatus(SC_NOT_FOUND);
119 return;
120 } catch (IncorrectObjectTypeException e) {
121 log.warn("Incorrect object type for " + ObjectId.toString(obj.getId()), e);
122 res.setStatus(SC_NOT_FOUND);
123 return;
124 }
125 }
126
Dave Borowitzb1c628f2013-01-11 11:28:20 -0800127 renderHtml(req, res, "gitiles.revisionDetail", ImmutableMap.of(
Dave Borowitz9de65952012-08-13 16:09:45 -0700128 "title", view.getRevision().getName(),
129 "objects", soyObjects,
130 "hasBlob", hasBlob));
131 } finally {
132 walk.release();
133 }
134 }
135
Dave Borowitz90d1db92014-03-16 14:16:15 -0700136 @Override
137 protected void doGetJson(HttpServletRequest req, HttpServletResponse res) throws IOException {
138 GitilesView view = ViewFilter.getView(req);
139 Repository repo = ServletUtils.getRepository(req);
140
141 RevWalk walk = new RevWalk(repo);
142 try {
Dave Borowitz2b2f34b2014-04-29 16:47:20 -0700143 DateFormatter df = new DateFormatter(getAccess(req), Format.DEFAULT);
Dave Borowitz90d1db92014-03-16 14:16:15 -0700144 RevObject obj = walk.parseAny(view.getRevision().getId());
145 switch (obj.getType()) {
146 case OBJ_COMMIT:
147 renderJson(req, res, new CommitJsonData()
148 .setRevWalk(walk)
149 .toJsonData(req, (RevCommit) obj, COMMIT_JSON_FIELDS, df),
150 Commit.class);
151 break;
152 default:
153 // TODO(dborowitz): Support showing other types.
154 res.setStatus(SC_NOT_FOUND);
155 break;
156 }
157 } finally {
158 walk.release();
159 }
160 }
161
Dave Borowitz9de65952012-08-13 16:09:45 -0700162 // TODO(dborowitz): Extract this.
Dave Borowitz558005d2012-12-20 15:48:08 -0800163 static List<RevObject> listObjects(RevWalk walk, Revision rev)
Dave Borowitz9de65952012-08-13 16:09:45 -0700164 throws MissingObjectException, IOException {
165 List<RevObject> objects = Lists.newArrayListWithExpectedSize(1);
Dave Borowitz558005d2012-12-20 15:48:08 -0800166 ObjectId id = rev.getId();
167 RevObject cur;
Dave Borowitz9de65952012-08-13 16:09:45 -0700168 while (true) {
Dave Borowitz558005d2012-12-20 15:48:08 -0800169 cur = walk.parseAny(id);
Dave Borowitz9de65952012-08-13 16:09:45 -0700170 objects.add(cur);
Dave Borowitz558005d2012-12-20 15:48:08 -0800171 if (cur.getType() != Constants.OBJ_TAG) {
Dave Borowitz9de65952012-08-13 16:09:45 -0700172 break;
173 }
Dave Borowitz558005d2012-12-20 15:48:08 -0800174 id = ((RevTag) cur).getObject();
175 }
176 if (cur.getType() == Constants.OBJ_COMMIT) {
177 objects.add(walk.parseTree(((RevCommit) cur).getTree()));
Dave Borowitz9de65952012-08-13 16:09:45 -0700178 }
179 return objects;
180 }
181}