blob: 845399e60e6618639a12324cdfa163d1f8ce8c2f [file] [log] [blame]
// Copyright (C) 2013 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.github.wizard;
import com.google.gerrit.server.IdentifiedUser;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import com.googlesource.gerrit.plugins.github.GitHubConfig;
import com.googlesource.gerrit.plugins.github.GitHubConfig.NextPage;
import com.googlesource.gerrit.plugins.github.oauth.GitHubLogin;
import com.googlesource.gerrit.plugins.github.oauth.ScopedProvider;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.http.HttpStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Singleton
public class VelocityControllerServlet extends HttpServlet {
private static final long serialVersionUID = 5565594120346641704L;
private static final Logger log = LoggerFactory.getLogger(VelocityControllerServlet.class);
private static final String CONTROLLER_PACKAGE =
VelocityControllerServlet.class.getPackage().getName();
private final ScopedProvider<GitHubLogin> loginProvider;
private final Provider<IdentifiedUser> userProvider;
private final Injector injector;
private final Provider<ControllerErrors> errorsProvider;
private final GitHubConfig githubConfig;
@Inject
public VelocityControllerServlet(
final ScopedProvider<GitHubLogin> loginProvider,
Provider<IdentifiedUser> userProvider,
final Injector injector,
Provider<ControllerErrors> errorsProvider,
GitHubConfig githubConfig) {
this.loginProvider = loginProvider;
this.userProvider = userProvider;
this.injector = injector;
this.errorsProvider = errorsProvider;
this.githubConfig = githubConfig;
}
@SuppressWarnings("unchecked")
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String controllerName;
VelocityController controller;
controllerName = getControllerClassName(req);
try {
Class<? extends VelocityController> controllerClass =
(Class<? extends VelocityController>)
Class.forName(CONTROLLER_PACKAGE + "." + controllerName + "Controller");
controller = injector.getInstance(controllerClass);
} catch (ClassNotFoundException e) {
log.debug("Cannot find any controller for servlet " + req.getServletPath());
redirectToNextStep(req, resp);
return;
}
GitHubLogin hubLogin = loginProvider.get(req);
IdentifiedUser user = userProvider.get();
WrappedResponse wrappedResp = new WrappedResponse(resp);
controller.doAction(user, hubLogin, req, wrappedResp, errorsProvider.get());
if (wrappedResp.getStatus() == 0 || wrappedResp.getStatus() == HttpStatus.SC_OK) {
redirectToNextStep(req, resp);
}
}
private String getControllerClassName(HttpServletRequest req) {
String reqServletName;
StringBuilder controllerName = new StringBuilder();
reqServletName = req.getPathInfo();
reqServletName = trimFromChar(reqServletName, '/');
reqServletName = trimUpToChar(reqServletName, '.');
String[] controllerNameParts = reqServletName.split("-");
for (String namePart : controllerNameParts) {
controllerName.append(Character.toUpperCase(namePart.charAt(0)) + namePart.substring(1));
}
return controllerName.toString();
}
private String trimUpToChar(String string, char ch) {
if (string.indexOf(ch) >= 0) {
return string.substring(0, string.indexOf(ch));
}
return string;
}
private String trimFromChar(String string, char ch) {
if (string.lastIndexOf(ch) >= 0) {
return string.substring(string.lastIndexOf(ch) + 1);
}
return string;
}
private void redirectToNextStep(HttpServletRequest req, HttpServletResponse resp)
throws IOException, ServletException {
String sourceUri = req.getPathInfo();
int pathPos = sourceUri.lastIndexOf('/') + 1;
String sourcePage = sourceUri.substring(pathPos);
String sourcePath = sourceUri.substring(0, pathPos);
int queryStringStart = sourcePage.indexOf('?');
if (queryStringStart > 0) {
sourcePage = sourcePage.substring(0, queryStringStart);
}
NextPage nextPage = githubConfig.getNextPage(sourcePage);
if (nextPage != null) {
if (nextPage.redirect) {
resp.sendRedirect(nextPageURL(sourcePath, nextPage));
} else {
RequestDispatcher requestDispatcher =
req.getRequestDispatcher(nextPageURL(sourcePath, nextPage));
req.setAttribute("destUrl", nextPage.uri);
requestDispatcher.forward(req, resp);
}
}
}
private String nextPageURL(String sourcePath, NextPage nextPage) {
return nextPage.uri.startsWith("/") ? nextPage.uri : sourcePath + nextPage.uri;
}
}