src/main/java/de/uapcore/lightpit/modules/ProjectsModule.java

Fri, 22 May 2020 17:26:27 +0200

author
Mike Becker <universe@uap-core.de>
date
Fri, 22 May 2020 17:26:27 +0200
changeset 74
91d1fc2a3a14
parent 71
dca186d3911f
child 75
33b6843fdf8a
permissions
-rw-r--r--

removes that dynamic_fragment bullshit

     1 /*
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3  *
     4  * Copyright 2018 Mike Becker. All rights reserved.
     5  *
     6  * Redistribution and use in source and binary forms, with or without
     7  * modification, are permitted provided that the following conditions are met:
     8  *
     9  *   1. Redistributions of source code must retain the above copyright
    10  *      notice, this list of conditions and the following disclaimer.
    11  *
    12  *   2. Redistributions in binary form must reproduce the above copyright
    13  *      notice, this list of conditions and the following disclaimer in the
    14  *      documentation and/or other materials provided with the distribution.
    15  *
    16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    26  * POSSIBILITY OF SUCH DAMAGE.
    27  *
    28  */
    29 package de.uapcore.lightpit.modules;
    32 import de.uapcore.lightpit.*;
    33 import de.uapcore.lightpit.dao.DataAccessObjects;
    34 import de.uapcore.lightpit.entities.*;
    35 import org.slf4j.Logger;
    36 import org.slf4j.LoggerFactory;
    38 import javax.servlet.annotation.WebServlet;
    39 import javax.servlet.http.HttpServletRequest;
    40 import javax.servlet.http.HttpServletResponse;
    41 import java.io.IOException;
    42 import java.sql.SQLException;
    43 import java.util.ArrayList;
    44 import java.util.List;
    45 import java.util.NoSuchElementException;
    46 import java.util.Optional;
    48 import static de.uapcore.lightpit.Functions.fqn;
    50 @LightPITModule(
    51         bundleBaseName = "localization.projects",
    52         modulePath = "projects",
    53         defaultPriority = 20
    54 )
    55 @WebServlet(
    56         name = "ProjectsModule",
    57         urlPatterns = "/projects/*"
    58 )
    59 public final class ProjectsModule extends AbstractLightPITServlet {
    61     private static final Logger LOG = LoggerFactory.getLogger(ProjectsModule.class);
    63     public static final String SESSION_ATTR_SELECTED_PROJECT = fqn(ProjectsModule.class, "selected-project");
    65     private Project getSelectedProject(HttpServletRequest req, DataAccessObjects dao) throws SQLException {
    66         final var projectDao = dao.getProjectDao();
    67         final var session = req.getSession();
    68         final var projectSelection = getParameter(req, Integer.class, "pid");
    69         final Project selectedProject;
    70         if (projectSelection.isPresent()) {
    71             selectedProject = projectDao.find(projectSelection.get());
    72         } else {
    73             final var sessionProject = (Project) session.getAttribute(SESSION_ATTR_SELECTED_PROJECT);
    74             selectedProject = sessionProject == null ? null : projectDao.find(sessionProject.getId());
    75         }
    76         session.setAttribute(SESSION_ATTR_SELECTED_PROJECT, selectedProject);
    77         return selectedProject;
    78     }
    81     /**
    82      * Creates the breadcrumb menu.
    83      *
    84      * @param level           the current active level
    85      * @param selectedProject the selected project, if any, or null
    86      * @return a dynamic breadcrumb menu trying to display as many levels as possible
    87      */
    88     private List<MenuEntry> getBreadcrumbs(int level,
    89                                            Project selectedProject) {
    90         MenuEntry entry;
    92         final var breadcrumbs = new ArrayList<MenuEntry>();
    93         entry = new MenuEntry(new ResourceKey("localization.projects", "menuLabel"),
    94                 "projects/", 0);
    95         breadcrumbs.add(entry);
    96         if (level == 0) entry.setActive(true);
    98         if (selectedProject == null)
    99             return breadcrumbs;
   101         entry = new MenuEntry(selectedProject.getName(),
   102                 "projects/view?pid=" + selectedProject.getId(), 1);
   103         if (level == 1) entry.setActive(true);
   105         breadcrumbs.add(entry);
   106         return breadcrumbs;
   107     }
   109     @RequestMapping(method = HttpMethod.GET)
   110     public ResponseType index(HttpServletRequest req, DataAccessObjects dao) throws SQLException {
   112         final var projectList = dao.getProjectDao().list();
   113         req.setAttribute("projects", projectList);
   114         setContentPage(req, "projects");
   115         setStylesheet(req, "projects");
   117         final var selectedProject = getSelectedProject(req, dao);
   118         setBreadcrumbs(req, getBreadcrumbs(0, selectedProject));
   120         return ResponseType.HTML;
   121     }
   123     private void configureEditForm(HttpServletRequest req, DataAccessObjects dao, Optional<Project> project) throws SQLException {
   124         if (project.isPresent()) {
   125             req.setAttribute("project", project.get());
   126             setBreadcrumbs(req, getBreadcrumbs(1, project.get()));
   127         } else {
   128             req.setAttribute("project", new Project(-1));
   129             setBreadcrumbs(req, getBreadcrumbs(0, null));
   130         }
   132         req.setAttribute("users", dao.getUserDao().list());
   133         setContentPage(req, "project-form");
   134     }
   136     @RequestMapping(requestPath = "edit", method = HttpMethod.GET)
   137     public ResponseType edit(HttpServletRequest req, DataAccessObjects dao) throws SQLException {
   139         Optional<Project> project = findByParameter(req, Integer.class, "id", dao.getProjectDao()::find);
   140         configureEditForm(req, dao, project);
   141         if (project.isPresent()) {
   142             req.getSession().setAttribute(SESSION_ATTR_SELECTED_PROJECT, project.get());
   143         }
   145         return ResponseType.HTML;
   146     }
   148     @RequestMapping(requestPath = "commit", method = HttpMethod.POST)
   149     public ResponseType commit(HttpServletRequest req, DataAccessObjects dao) throws SQLException {
   151         Project project = null;
   152         try {
   153             project = new Project(getParameter(req, Integer.class, "id").orElseThrow());
   154             project.setName(getParameter(req, String.class, "name").orElseThrow());
   155             getParameter(req, String.class, "description").ifPresent(project::setDescription);
   156             getParameter(req, String.class, "repoUrl").ifPresent(project::setRepoUrl);
   157             getParameter(req, Integer.class, "owner").map(
   158                     ownerId -> ownerId >= 0 ? new User(ownerId) : null
   159             ).ifPresent(project::setOwner);
   161             dao.getProjectDao().saveOrUpdate(project);
   163             setRedirectLocation(req, "./projects/");
   164             setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL);
   165             LOG.debug("Successfully updated project {}", project.getName());
   166         } catch (NoSuchElementException | NumberFormatException | SQLException ex) {
   167             // TODO: set request attribute with error text
   168             LOG.warn("Form validation failure: {}", ex.getMessage());
   169             LOG.debug("Details:", ex);
   170             configureEditForm(req, dao, Optional.ofNullable(project));
   171         }
   173         return ResponseType.HTML;
   174     }
   176     @RequestMapping(requestPath = "view", method = HttpMethod.GET)
   177     public ResponseType view(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws IOException, SQLException {
   178         final var selectedProject = getSelectedProject(req, dao);
   179         if (selectedProject == null) {
   180             resp.sendError(HttpServletResponse.SC_FORBIDDEN);
   181             return ResponseType.NONE;
   182         }
   184         req.setAttribute("versions", dao.getVersionDao().list(selectedProject));
   185         req.setAttribute("issues", dao.getIssueDao().list(selectedProject));
   187         // TODO: add more levels depending on last visited location
   188         setBreadcrumbs(req, getBreadcrumbs(1, selectedProject));
   190         setContentPage(req, "project-details");
   192         return ResponseType.HTML;
   193     }
   195     private void configureEditVersionForm(HttpServletRequest req, Optional<Version> version, Project selectedProject) {
   196         req.setAttribute("version", version.orElse(new Version(-1, selectedProject)));
   197         req.setAttribute("versionStatusEnum", VersionStatus.values());
   199         setContentPage(req, "version-form");
   200     }
   202     @RequestMapping(requestPath = "versions/edit", method = HttpMethod.GET)
   203     public ResponseType editVersion(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws IOException, SQLException {
   204         final var selectedProject = getSelectedProject(req, dao);
   205         if (selectedProject == null) {
   206             resp.sendError(HttpServletResponse.SC_FORBIDDEN);
   207             return ResponseType.NONE;
   208         }
   210         configureEditVersionForm(req,
   211                 findByParameter(req, Integer.class, "id", dao.getVersionDao()::find),
   212                 selectedProject);
   214         return ResponseType.HTML;
   215     }
   217     @RequestMapping(requestPath = "versions/commit", method = HttpMethod.POST)
   218     public ResponseType commitVersion(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws IOException, SQLException {
   219         final var selectedProject = getSelectedProject(req, dao);
   220         if (selectedProject == null) {
   221             resp.sendError(HttpServletResponse.SC_FORBIDDEN);
   222             return ResponseType.NONE;
   223         }
   225         Version version = null;
   226         try {
   227             version = new Version(getParameter(req, Integer.class, "id").orElseThrow(), selectedProject);
   228             version.setName(getParameter(req, String.class, "name").orElseThrow());
   229             getParameter(req, Integer.class, "ordinal").ifPresent(version::setOrdinal);
   230             version.setStatus(VersionStatus.valueOf(getParameter(req, String.class, "status").orElseThrow()));
   231             dao.getVersionDao().saveOrUpdate(version);
   233             setRedirectLocation(req, "./projects/versions/");
   234             setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL);
   235             LOG.debug("Successfully updated version {} for project {}", version.getName(), selectedProject.getName());
   236         } catch (NoSuchElementException | NumberFormatException | SQLException ex) {
   237             // TODO: set request attribute with error text
   238             LOG.warn("Form validation failure: {}", ex.getMessage());
   239             LOG.debug("Details:", ex);
   240             configureEditVersionForm(req, Optional.ofNullable(version), selectedProject);
   241         }
   243         return ResponseType.HTML;
   244     }
   246     private void configureEditIssueForm(HttpServletRequest req, DataAccessObjects dao, Optional<Issue> issue, Project selectedProject) throws SQLException {
   248         req.setAttribute("issue", issue.orElse(new Issue(-1, selectedProject)));
   249         req.setAttribute("issueStatusEnum", IssueStatus.values());
   250         req.setAttribute("issueCategoryEnum", IssueCategory.values());
   251         req.setAttribute("versions", dao.getVersionDao().list(selectedProject));
   253         setContentPage(req, "issue-form");
   254     }
   256     @RequestMapping(requestPath = "issues/edit", method = HttpMethod.GET)
   257     public ResponseType editIssue(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws IOException, SQLException {
   258         final var selectedProject = getSelectedProject(req, dao);
   259         if (selectedProject == null) {
   260             resp.sendError(HttpServletResponse.SC_FORBIDDEN);
   261             return ResponseType.NONE;
   262         }
   264         configureEditIssueForm(req, dao,
   265                 findByParameter(req, Integer.class, "id", dao.getIssueDao()::find),
   266                 selectedProject);
   268         return ResponseType.HTML;
   269     }
   271     @RequestMapping(requestPath = "issues/commit", method = HttpMethod.POST)
   272     public ResponseType commitIssue(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws IOException, SQLException {
   273         final var selectedProject = getSelectedProject(req, dao);
   274         if (selectedProject == null) {
   275             resp.sendError(HttpServletResponse.SC_FORBIDDEN);
   276             return ResponseType.NONE;
   277         }
   279         Issue issue = null;
   280         try {
   281             issue = new Issue(getParameter(req, Integer.class, "id").orElseThrow(), selectedProject);
   283             // TODO: implement
   285             dao.getIssueDao().saveOrUpdate(issue);
   287             setRedirectLocation(req, "./projects/issues/");
   288             setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL);
   289             LOG.debug("Successfully updated issue {} for project {}", issue.getId(), selectedProject.getName());
   290         } catch (NoSuchElementException | NumberFormatException | SQLException ex) {
   291             // TODO: set request attribute with error text
   292             LOG.warn("Form validation failure: {}", ex.getMessage());
   293             LOG.debug("Details:", ex);
   294             configureEditIssueForm(req, dao, Optional.ofNullable(issue), selectedProject);
   295         }
   297         return ResponseType.HTML;
   298     }
   299 }

mercurial