blob: 949fbabd0f1dbd85593cb8a589d00ccb40c3faf3 [file] [log] [blame]
Dave Borowitzba9c1182013-03-13 14:16:43 -07001// Copyright 2013 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 javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
18import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
19
Dave Borowitz54271462013-11-11 11:43:11 -080020import com.google.common.base.Joiner;
21import com.google.common.collect.ImmutableMap;
22import com.google.gson.reflect.TypeToken;
Dave Borowitzba9c1182013-03-13 14:16:43 -070023
24import org.eclipse.jgit.api.Git;
25import org.eclipse.jgit.api.NameRevCommand;
26import org.eclipse.jgit.api.errors.GitAPIException;
27import org.eclipse.jgit.errors.AmbiguousObjectException;
28import org.eclipse.jgit.errors.RevisionSyntaxException;
29import org.eclipse.jgit.http.server.ServletUtils;
30import org.eclipse.jgit.lib.Constants;
31import org.eclipse.jgit.lib.ObjectId;
32import org.eclipse.jgit.lib.Repository;
33
Dave Borowitz54271462013-11-11 11:43:11 -080034import java.io.IOException;
Dave Borowitz673d1982014-05-02 12:30:49 -070035import java.io.Writer;
Dave Borowitz54271462013-11-11 11:43:11 -080036import java.util.List;
37import java.util.Map;
38
39import javax.servlet.http.HttpServletRequest;
40import javax.servlet.http.HttpServletResponse;
Dave Borowitzba9c1182013-03-13 14:16:43 -070041
42/** Serves an API result describing an object. */
43public class DescribeServlet extends BaseServlet {
44 private static final long serialVersionUID = 1L;
45
46 private static final String ALL_PARAM = "all";
47 private static final String CONTAINS_PARAM = "contains";
48 private static final String TAGS_PARAM = "tags";
49
50 private static boolean getBooleanParam(GitilesView view, String name) {
51 List<String> values = view.getParameters().get(name);
52 return !values.isEmpty()
Dave Borowitz27058932014-12-03 15:44:46 -080053 && (values.get(0).isEmpty() || values.get(0).equals("1"));
Dave Borowitzba9c1182013-03-13 14:16:43 -070054 }
55
Dave Borowitz8d6d6872014-03-16 15:18:14 -070056 protected DescribeServlet(GitilesAccess.Factory accessFactory) {
57 super(null, accessFactory);
Dave Borowitzba9c1182013-03-13 14:16:43 -070058 }
59
60 @Override
61 protected void doGetText(HttpServletRequest req, HttpServletResponse res)
62 throws IOException {
63 String name = describe(ServletUtils.getRepository(req), ViewFilter.getView(req), req, res);
64 if (name == null) {
65 return;
66 }
Dave Borowitz673d1982014-05-02 12:30:49 -070067 Writer out = startRenderText(req, res);
Dave Borowitzba9c1182013-03-13 14:16:43 -070068 out.write(RefServlet.sanitizeRefForText(name));
69 out.close();
70 }
71
72 @Override
73 protected void doGetJson(HttpServletRequest req, HttpServletResponse res)
74 throws IOException {
75 String name = describe(ServletUtils.getRepository(req), ViewFilter.getView(req), req, res);
76 if (name == null) {
77 return;
78 }
79 renderJson(req, res,
80 ImmutableMap.of(ViewFilter.getView(req).getPathPart(), name),
81 new TypeToken<Map<String, String>>() {}.getType());
82 }
83
84 private ObjectId resolve(Repository repo, GitilesView view, HttpServletRequest req,
85 HttpServletResponse res) throws IOException {
86 String rev = view.getPathPart();
87 try {
88 return repo.resolve(rev);
89 } catch (RevisionSyntaxException e) {
90 renderTextError(req, res, SC_BAD_REQUEST,
91 "Invalid revision syntax: " + RefServlet.sanitizeRefForText(rev));
92 return null;
93 } catch (AmbiguousObjectException e) {
94 renderTextError(req, res, SC_BAD_REQUEST, String.format(
95 "Ambiguous short SHA-1 %s (%s)",
96 e.getAbbreviatedObjectId(), Joiner.on(", ").join(e.getCandidates())));
97 return null;
98 }
99 }
100
101 private String describe(Repository repo, GitilesView view, HttpServletRequest req,
102 HttpServletResponse res) throws IOException {
103 if (!getBooleanParam(view, CONTAINS_PARAM)) {
104 res.setStatus(SC_BAD_REQUEST);
105 return null;
106 }
107 ObjectId id = resolve(repo, view, req, res);
108 if (id == null) {
109 return null;
110 }
Dave Borowitzba9c1182013-03-13 14:16:43 -0700111 String name;
Dave Borowitzc35311d2015-08-10 11:21:51 -0400112 try (Git git = new Git(repo)) {
113 NameRevCommand cmd = nameRevCommand(git, id, req, res);
114 if (cmd == null) {
115 return null;
116 }
Dave Borowitzba9c1182013-03-13 14:16:43 -0700117 name = cmd.call().get(id);
118 } catch (GitAPIException e) {
119 throw new IOException(e);
120 }
121 if (name == null) {
122 res.setStatus(SC_NOT_FOUND);
123 return null;
124 }
125 return name;
126 }
127
Dave Borowitzc35311d2015-08-10 11:21:51 -0400128 private NameRevCommand nameRevCommand(Git git, ObjectId id,
129 HttpServletRequest req, HttpServletResponse res) throws IOException {
Dave Borowitzba9c1182013-03-13 14:16:43 -0700130 GitilesView view = ViewFilter.getView(req);
Dave Borowitzc35311d2015-08-10 11:21:51 -0400131 NameRevCommand cmd = git.nameRev();
Dave Borowitzba9c1182013-03-13 14:16:43 -0700132 boolean all = getBooleanParam(view, ALL_PARAM);
133 boolean tags = getBooleanParam(view, TAGS_PARAM);
134 if (all && tags) {
135 renderTextError(req, res, SC_BAD_REQUEST, "Cannot specify both \"all\" and \"tags\"");
136 return null;
137 }
138 if (all) {
139 cmd.addPrefix(Constants.R_REFS);
140 } else if (tags) {
141 cmd.addPrefix(Constants.R_TAGS);
142 } else {
143 cmd.addAnnotatedTags();
144 }
145 cmd.add(id);
146 return cmd;
147 }
148}