blob: 40777a005d62d85090d3aadb320ce8ac8cf54be7 [file] [log] [blame]
Dave Borowitz6d9bc5a2013-06-19 09:12:52 -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_NOT_FOUND;
18import static javax.servlet.http.HttpServletResponse.SC_OK;
19
Dave Borowitzded109a2014-03-03 15:25:39 -050020import com.google.common.base.Optional;
Dave Borowitzfc417942014-04-09 07:54:42 -070021import com.google.common.base.Strings;
Dave Borowitzded109a2014-03-03 15:25:39 -050022
Dave Borowitz6d9bc5a2013-06-19 09:12:52 -070023import org.eclipse.jgit.api.ArchiveCommand;
24import org.eclipse.jgit.api.errors.GitAPIException;
Dave Borowitz6d9bc5a2013-06-19 09:12:52 -070025import org.eclipse.jgit.errors.IncorrectObjectTypeException;
26import org.eclipse.jgit.http.server.ServletUtils;
Dave Borowitz5051e672013-11-11 11:09:40 -080027import org.eclipse.jgit.lib.FileMode;
28import org.eclipse.jgit.lib.ObjectId;
Dave Borowitz6d9bc5a2013-06-19 09:12:52 -070029import org.eclipse.jgit.lib.Repository;
Dave Borowitz5051e672013-11-11 11:09:40 -080030import org.eclipse.jgit.revwalk.RevTree;
Dave Borowitz6d9bc5a2013-06-19 09:12:52 -070031import org.eclipse.jgit.revwalk.RevWalk;
Dave Borowitz5051e672013-11-11 11:09:40 -080032import org.eclipse.jgit.treewalk.TreeWalk;
Dave Borowitz6d9bc5a2013-06-19 09:12:52 -070033
34import java.io.IOException;
Dave Borowitz6d9bc5a2013-06-19 09:12:52 -070035
36import javax.servlet.ServletException;
37import javax.servlet.http.HttpServletRequest;
38import javax.servlet.http.HttpServletResponse;
39
40public class ArchiveServlet extends BaseServlet {
41 private static final long serialVersionUID = 1L;
42
Dave Borowitzded109a2014-03-03 15:25:39 -050043 public ArchiveServlet(GitilesAccess.Factory accessFactory) {
Dave Borowitz8d6d6872014-03-16 15:18:14 -070044 super(null, accessFactory);
Dave Borowitz6d9bc5a2013-06-19 09:12:52 -070045 }
46
47 @Override
48 protected void doGet(HttpServletRequest req, HttpServletResponse res)
49 throws IOException, ServletException {
50 GitilesView view = ViewFilter.getView(req);
51 Revision rev = view.getRevision();
52 Repository repo = ServletUtils.getRepository(req);
53
Dave Borowitz5051e672013-11-11 11:09:40 -080054 ObjectId treeId = getTree(view, repo, rev);
55 if (treeId.equals(ObjectId.zeroId())) {
Dave Borowitz6d9bc5a2013-06-19 09:12:52 -070056 res.sendError(SC_NOT_FOUND);
57 return;
Dave Borowitz6d9bc5a2013-06-19 09:12:52 -070058 }
59
Dave Borowitzded109a2014-03-03 15:25:39 -050060 Optional<ArchiveFormat> format = ArchiveFormat.byExtension(
Dave Borowitz8d6d6872014-03-16 15:18:14 -070061 view.getExtension(), getAccess(req).getConfig());
Dave Borowitzded109a2014-03-03 15:25:39 -050062 if (!format.isPresent()) {
63 res.setStatus(SC_NOT_FOUND);
64 return;
65 }
Dave Borowitz6d9bc5a2013-06-19 09:12:52 -070066 String filename = getFilename(view, rev, view.getExtension());
Dave Borowitzded109a2014-03-03 15:25:39 -050067 setDownloadHeaders(res, filename, format.get().getMimeType());
Dave Borowitz6d9bc5a2013-06-19 09:12:52 -070068 res.setStatus(SC_OK);
69
70 try {
71 new ArchiveCommand(repo)
Dave Borowitz36eb26d2014-04-19 16:42:32 -070072 .setFormat(format.get().getRegisteredName())
Dave Borowitz5051e672013-11-11 11:09:40 -080073 .setTree(treeId)
Dave Borowitz6d9bc5a2013-06-19 09:12:52 -070074 .setOutputStream(res.getOutputStream())
75 .call();
76 } catch (GitAPIException e) {
77 throw new IOException(e);
78 }
79 }
80
Dave Borowitz5051e672013-11-11 11:09:40 -080081 private ObjectId getTree(GitilesView view, Repository repo, Revision rev) throws IOException {
82 RevWalk rw = new RevWalk(repo);
83 try {
84 RevTree tree = rw.parseTree(rev.getId());
Dave Borowitzfc417942014-04-09 07:54:42 -070085 if (Strings.isNullOrEmpty(view.getPathPart())) {
Dave Borowitz5051e672013-11-11 11:09:40 -080086 return tree;
87 }
88 TreeWalk tw = TreeWalk.forPath(rw.getObjectReader(), view.getPathPart(), tree);
Dave Borowitzfc417942014-04-09 07:54:42 -070089 if (tw == null || tw.getFileMode(0) != FileMode.TREE) {
Dave Borowitz5051e672013-11-11 11:09:40 -080090 return ObjectId.zeroId();
91 }
92 return tw.getObjectId(0);
93 } catch (IncorrectObjectTypeException e) {
94 return ObjectId.zeroId();
95 } finally {
96 rw.release();
97 }
98 }
99
Dave Borowitz6d9bc5a2013-06-19 09:12:52 -0700100 private String getFilename(GitilesView view, Revision rev, String ext) {
Dave Borowitz5051e672013-11-11 11:09:40 -0800101 StringBuilder sb = new StringBuilder()
Dave Borowitz6d9bc5a2013-06-19 09:12:52 -0700102 .append(Paths.basename(view.getRepositoryName()))
103 .append('-')
Dave Borowitz5051e672013-11-11 11:09:40 -0800104 .append(rev.getName());
105 if (view.getPathPart() != null) {
106 sb.append('-')
107 .append(view.getPathPart().replace('/', '-'));
108 }
109 return sb.append(ext)
Dave Borowitz6d9bc5a2013-06-19 09:12:52 -0700110 .toString();
111 }
112}