Java tutorial
// Copyright 2014 Palantir Technologies // // 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.palantir.stash.disapprove.servlet; import java.io.IOException; import java.io.Writer; import java.net.URI; import java.sql.SQLException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.json.JSONObject; import org.slf4j.Logger; import com.atlassian.sal.api.auth.LoginUriProvider; import com.atlassian.stash.exception.AuthorisationException; import com.atlassian.stash.nav.NavBuilder; import com.atlassian.stash.pull.PullRequest; import com.atlassian.stash.pull.PullRequestService; import com.atlassian.stash.repository.Repository; import com.atlassian.stash.request.RequestManager; import com.atlassian.stash.user.Permission; import com.atlassian.stash.user.PermissionValidationService; import com.atlassian.stash.user.StashAuthenticationContext; import com.google.common.collect.ImmutableMap; import com.palantir.stash.disapprove.logger.PluginLoggerFactory; import com.palantir.stash.disapprove.persistence.DisapprovalConfiguration; import com.palantir.stash.disapprove.persistence.PersistenceManager; import com.palantir.stash.disapprove.persistence.PullRequestDisapproval; public class DisapprovalServlet extends HttpServlet { private static final long serialVersionUID = 1L; private final LoginUriProvider lup; private final PermissionValidationService permissionValidationService; private final PullRequestService pullRequestService; private final PersistenceManager pm; private final RequestManager rm; private final NavBuilder nb; private final Logger log; public DisapprovalServlet(LoginUriProvider lup, PermissionValidationService permissionValidationService, PullRequestService pullRequestService, PersistenceManager pm, RequestManager rm, NavBuilder nb, PluginLoggerFactory lf) { this.permissionValidationService = permissionValidationService; this.log = lf.getLoggerForThis(this); this.lup = lup; this.pm = pm; this.pullRequestService = pullRequestService; this.rm = rm; this.nb = nb; } @Override protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { final String user = authenticateUser(req, res); if (user == null) { // not logged in, redirect res.sendRedirect(lup.getLoginUri(getUri(req)).toASCIIString()); return; } final String REQ_PARAMS = "repoId(int), prId(long), disapproved(true|false)"; final Integer repoId; final Long prId; try { repoId = Integer.valueOf(req.getParameter("repoId")); prId = Long.valueOf(req.getParameter("prId")); } catch (NumberFormatException e) { throw new IllegalArgumentException("The required paramaters are: " + REQ_PARAMS, e); } final PullRequest pr = pullRequestService.getById(repoId, prId); final Repository repo = pr.getToRef().getRepository(); PullRequestDisapproval prd; DisapprovalConfiguration dc; try { prd = pm.getPullRequestDisapproval(pr); dc = pm.getDisapprovalConfiguration(repo); } catch (SQLException e) { throw new ServletException(e); } boolean oldDisapproval = prd.isDisapproved(); boolean disapproval; String disapproved = req.getParameter("disapproved"); if (disapproved != null && disapproved.equalsIgnoreCase("true")) { disapproval = true; } else if (disapproved != null && disapproved.equalsIgnoreCase("false")) { disapproval = false; } else { throw new IllegalArgumentException("The required parameters are: " + REQ_PARAMS); } Writer w = res.getWriter(); res.setContentType("application/json;charset=UTF-8"); try { processDisapprovalChange(repo, user, prd, oldDisapproval, disapproval); //res.setContentType("text/html;charset=UTF-8"); w.append(new JSONObject(ImmutableMap.of("disapproval", prd.isDisapproved(), "disapprovedBy", prd.getDisapprovedBy(), "enabledForRepo", dc.isEnabled())).toString()); } catch (IllegalStateException e) { w.append(new JSONObject(ImmutableMap.of("error", e.getMessage())).toString()); res.setStatus(401); } finally { w.close(); } } @Override public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { final String user = authenticateUser(req, res); if (user == null) { // not logged in, redirect res.sendRedirect(lup.getLoginUri(getUri(req)).toASCIIString()); return; } final String URL_FORMAT = "BASE_URL/REPO_ID"; final String pathInfo = req.getPathInfo(); final String[] parts = pathInfo.split("/"); if (parts.length != 5) { throw new IllegalArgumentException("The format of the URL is " + URL_FORMAT); } final Integer repoId; final Long prId; try { repoId = Integer.valueOf(parts[3]); prId = Long.valueOf(parts[4]); } catch (NumberFormatException e) { throw new IllegalArgumentException("The format of the URL is " + URL_FORMAT, e); } final PullRequest pr = pullRequestService.getById(repoId, prId); if (pr == null) { throw new IllegalArgumentException("No PR found for repo id " + repoId + " pr id " + prId.toString()); } PullRequestDisapproval prd; DisapprovalConfiguration dc; try { prd = pm.getPullRequestDisapproval(pr); dc = pm.getDisapprovalConfiguration(pr.getToRef().getRepository()); } catch (SQLException e) { throw new ServletException(e); } try { Writer w = res.getWriter(); //res.setContentType("text/html;charset=UTF-8"); res.setContentType("application/json;charset=UTF-8"); w.append(new JSONObject(ImmutableMap.of("disapproval", prd.isDisapproved(), "disapprovedBy", prd.getDisapprovedBy(), "enabledForRepo", dc.isEnabled())).toString()); } finally { res.getWriter().close(); } } private String authenticateUser(HttpServletRequest req, HttpServletResponse res) throws IOException { try { permissionValidationService.validateAuthenticated(); } catch (AuthorisationException notLoggedInException) { log.debug("User not logged in", notLoggedInException); return null; } StashAuthenticationContext ac = rm.getRequestContext().getAuthenticationContext(); final String user = ac.getCurrentUser().getName(); log.debug("User {} logged in", user); return user; } private void processDisapprovalChange(final Repository repo, final String user, PullRequestDisapproval prd, boolean oldDisapproval, boolean disapproval) throws IOException { if (disapproval) { // we are setting disapproval if (oldDisapproval) { // disapproval already set, do nothing log.warn("PR already disapproved by " + prd.getDisapprovedBy()); return; } prd.setDisapprovedBy(user); prd.setDisapproved(true); prd.save(); log.info("PR has been disapproved by " + user); pullRequestService.addComment(prd.getRepositoryId(), prd.getPullRequestId(), getCommentTextDisapproval(user)); return; } // unsetting disapproval if (!oldDisapproval) { log.warn("PR is not disapproved"); return; } if (!user.equalsIgnoreCase(prd.getDisapprovedBy())) { // TODO: is user an admin? try { permissionValidationService.validateForRepository(repo, Permission.REPO_ADMIN); } catch (AuthorisationException e) { throw new IllegalStateException("User " + user + " is not able to remove disapproval set by user " + prd.getDisapprovedBy()); } } prd.setDisapproved(false); prd.setDisapprovedBy("None"); prd.save(); log.info("PR is no longer disapproved"); try { pullRequestService.addComment(prd.getRepositoryId(), prd.getPullRequestId(), getCommentTextRemoveDisapproval(user)); assert (true); } catch (Exception e) { e.printStackTrace(); } } private URI getUri(HttpServletRequest req) { StringBuffer builder = req.getRequestURL(); if (req.getQueryString() != null) { builder.append("?"); builder.append(req.getQueryString()); } return URI.create(builder.toString()); } private String getCommentTextDisapproval(String user) { //final String HTML = "<span style=\"color: #AA0000;\">_</span> Pull request disapproved"; final String disapprovalFace = nb.buildAbsolute() + "/plugins/servlet/disapproval/static-content/disapprovalface.png"; final String IMAGE = "![_](" + disapprovalFace + ") Pull request disapproved"; return IMAGE.replace("__USER__", user); } private String getCommentTextRemoveDisapproval(String user) { final String undisapprovalface = nb.buildAbsolute() + "/plugins/servlet/disapproval/static-content/undisapprovalface.png"; final String IMAGE = "![( )](" + undisapprovalface + ") Pull request disapproval removed"; return IMAGE.replace("__USER__", user); } }