blob: 83f6acb8d53e5a86ed031a87007181c53f0d9c29 [file] [log] [blame]
// Copyright (C) 2012 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.googlesource.gerrit.plugins.branchnetwork.canvas;
import com.google.gerrit.common.data.GitwebType;
import com.google.gerrit.entities.Project;
import com.google.gerrit.extensions.annotations.PluginCanonicalWebUrl;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.config.GitwebConfig;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.permissions.ProjectPermission;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.net.URL;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.Repository;
@Singleton
public class GitGraphServlet extends HttpServlet {
private static final long serialVersionUID = -822406714154950673L;
private static final int PROGRESS_BAR_WIDTH = 208;
private static final int PROGRESS_BAR_HEIGHT = 13;
private String canonicalPath;
private GitRepositoryManager repoManager;
private GitwebConfig gitWebConfig;
private String pluginCanonicalWebUrl;
private final Provider<CurrentUser> user;
private final PermissionBackend permissionBackend;
@Inject
public GitGraphServlet(
@PluginCanonicalWebUrl String url,
GitwebConfig gitWebConfig,
final GitRepositoryManager repoManager,
Provider<CurrentUser> user,
PermissionBackend permissionBackend)
throws MalformedURLException {
this.canonicalPath = new URL(url).getPath();
this.pluginCanonicalWebUrl = url.substring(0, url.length() - (canonicalPath.length() - 1));
this.repoManager = repoManager;
this.gitWebConfig = gitWebConfig;
this.user = user;
this.permissionBackend = permissionBackend;
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
try {
String repoName = req.getParameter("p");
if (repoName == null) {
resp.sendRedirect("Documentation/index.html");
return;
}
boolean naked = req.getParameter("naked") != null;
int width = getParam(req, "width", 920);
int height = getParam(req, "height", 600);
if (repoName.endsWith(".git")) {
repoName = repoName.substring(0, repoName.length() - 4);
}
final Project.NameKey nameKey = Project.nameKey(repoName);
try {
permissionBackend.user(user.get()).project(nameKey).check(ProjectPermission.ACCESS);
} catch (AuthException | PermissionBackendException e) {
resp.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
Repository repo = null;
try {
repo = repoManager.openRepository(nameKey);
} catch (RepositoryNotFoundException e) {
getServletContext().log("Cannot open repository", e);
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
} finally {
if (repo != null) {
repo.close();
}
}
String networkMetaUrl = String.format("%1$snetwork_meta/%2$s/", canonicalPath, repoName);
String networkDataChunkUrl =
String.format("%1$snetwork_data_chunk/%2$s/?nethash=", canonicalPath, repoName);
GitwebType type = gitWebConfig.getGitwebType();
if (type == null) {
out.println("<html>ERROR: invalid gitweb configuration</html>");
} else {
String commitUrlPattern =
gitWebConfig.getUrl()
+ type.getRevision()
.replaceAll("\\$\\{project\\}", repoName)
.replaceAll("\\$\\{commit\\}", "{2}");
String projectPattern =
gitWebConfig.getUrl() + type.getProject().replaceAll("\\$\\{project\\}", repoName);
commitUrlPattern =
(commitUrlPattern.startsWith("/")
? commitUrlPattern
: pluginCanonicalWebUrl + commitUrlPattern);
projectPattern =
(projectPattern.startsWith("/")
? projectPattern
: pluginCanonicalWebUrl + projectPattern);
String header =
"<html>\n"
+ "<head>\n"
+ "<style type=\"text/css\">\n"
+ "div#progress\n"
+ "{\n"
+ "position:absolute;\n"
+ "left:"
+ (width - PROGRESS_BAR_WIDTH) / 2
+ "px;\n"
+ "top:"
+ (height - PROGRESS_BAR_HEIGHT) / 2
+ "px;\n"
+ "z-index:-1;\n"
+ "}\n"
+ "div#graph\n"
+ "{\n"
+ "position:absolute;\n"
+ "left:0px;\n"
+ "top:0px;\n"
+ "z-index:0;\n"
+ "}\n"
+ "</style>\n"
+ "</head>\n"
+ "<body>\n"
+ "<div id=\"progress\" >"
+ "<img src=\""
+ canonicalPath
+ "static/progress_bar.gif\" />"
+ "</div>"
+ "<div id=\"graph\">";
String javaScript =
"<script type=\"text/javascript\" src=\""
+ canonicalPath
+ "static/jquery-1.4.2.min.js\"></script>\n"
+ "<script type=\"text/javascript\" src=\""
+ canonicalPath
+ "static/network.js\"></script>\n"
+ "<script type=\"text/javascript\">"
+ "$(document).ready( function() {\n"
+ "new NetworkCanvas('network-canvas', "
+ width
+ ", "
+ height
+ " , null, null, null,\n"
+ "'"
+ commitUrlPattern
+ "',\n"
+ "'"
+ projectPattern
+ "',\n"
+ "'"
+ networkMetaUrl
+ "',\n"
+ "'"
+ networkDataChunkUrl
+ "');\n"
+ "});\n"
+ "</script>\n";
String canvas =
"<canvas id=\"network-canvas\" width=\""
+ width
+ "\" height=\""
+ height
+ "\" style=\"cursor: default; \"></canvas>";
String footer = "</div>" + "</body>\n" + "</html>\n";
out.println(naked ? (javaScript + canvas) : (header + javaScript + canvas + footer));
}
} finally {
out.close();
}
}
private int getParam(HttpServletRequest req, String name, int defValue) {
String value = req.getParameter(name);
if (value != null) {
return Integer.parseInt(value);
} else {
return defValue;
}
}
}