changes the way how to deal with child entities + adds component lead

Thu, 15 Oct 2020 13:31:52 +0200

author
Mike Becker <universe@uap-core.de>
date
Thu, 15 Oct 2020 13:31:52 +0200
changeset 128
947d0f6a6a83
parent 127
6105ee2cceaf
child 129
a09d5c59351a

changes the way how to deal with child entities + adds component lead

setup/postgres/psql_create_tables.sql file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/dao/ChildEntityDao.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/dao/ComponentDao.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/dao/DataAccessObjects.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/dao/GenericDao.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/dao/IssueDao.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/dao/ProjectDao.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/dao/RootEntityDao.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/dao/UserDao.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/dao/VersionDao.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/dao/postgres/PGComponentDao.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/dao/postgres/PGDataAccessObjects.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/dao/postgres/PGIssueDao.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/dao/postgres/PGProjectDao.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/dao/postgres/PGUserDao.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/dao/postgres/PGVersionDao.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/entities/Version.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/modules/ProjectsModule.java file | annotate | diff | comparison | revisions
src/main/webapp/WEB-INF/jsp/version-form.jsp file | annotate | diff | comparison | revisions
     1.1 --- a/setup/postgres/psql_create_tables.sql	Thu Oct 15 12:27:05 2020 +0200
     1.2 +++ b/setup/postgres/psql_create_tables.sql	Thu Oct 15 13:31:52 2020 +0200
     1.3 @@ -40,7 +40,8 @@
     1.4      name            varchar(20)     not null,
     1.5      color           char(6)         not null default '000000',
     1.6      ordinal         integer         not null default 0,
     1.7 -    description     text
     1.8 +    description     text,
     1.9 +    lead            integer         references lpit_user(userid)
    1.10  );
    1.11  
    1.12  create type issue_status as enum (
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/src/main/java/de/uapcore/lightpit/dao/ChildEntityDao.java	Thu Oct 15 13:31:52 2020 +0200
     2.3 @@ -0,0 +1,116 @@
     2.4 +/*
     2.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     2.6 + *
     2.7 + * Copyright 2018 Mike Becker. All rights reserved.
     2.8 + *
     2.9 + * Redistribution and use in source and binary forms, with or without
    2.10 + * modification, are permitted provided that the following conditions are met:
    2.11 + *
    2.12 + *   1. Redistributions of source code must retain the above copyright
    2.13 + *      notice, this list of conditions and the following disclaimer.
    2.14 + *
    2.15 + *   2. Redistributions in binary form must reproduce the above copyright
    2.16 + *      notice, this list of conditions and the following disclaimer in the
    2.17 + *      documentation and/or other materials provided with the distribution.
    2.18 + *
    2.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    2.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    2.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    2.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    2.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    2.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    2.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    2.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    2.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    2.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    2.29 + * POSSIBILITY OF SUCH DAMAGE.
    2.30 + *
    2.31 + */
    2.32 +package de.uapcore.lightpit.dao;
    2.33 +
    2.34 +import java.sql.SQLException;
    2.35 +import java.util.List;
    2.36 +
    2.37 +public interface ChildEntityDao<T, P> {
    2.38 +
    2.39 +    /**
    2.40 +     * Lists all entities being a child of the specified parent.
    2.41 +     * @param parent the parent
    2.42 +     * @return the list of child instances
    2.43 +     * @throws SQLException on any kind of SQL errors
    2.44 +     */
    2.45 +    List<T> list(P parent) throws SQLException;
    2.46 +
    2.47 +    /**
    2.48 +     * Finds an entity by its integer ID.
    2.49 +     * It is not guaranteed that referenced entities are automatically joined.
    2.50 +     *
    2.51 +     * @param id the id
    2.52 +     * @return the enity or null if there is no such entity
    2.53 +     * @throws SQLException on any kind of SQL errors
    2.54 +     */
    2.55 +    T find(int id) throws SQLException;
    2.56 +
    2.57 +    /**
    2.58 +     * Inserts an instance into database.
    2.59 +     * It is not guaranteed that generated fields will be updated in the instance.
    2.60 +     *
    2.61 +     * @param instance the instance to insert
    2.62 +     * @param parent a reference to the parent
    2.63 +     * @throws SQLException on any kind of SQL errors
    2.64 +     */
    2.65 +    void save(T instance, P parent) throws SQLException;
    2.66 +
    2.67 +    /**
    2.68 +     * Updates an instance in the database.
    2.69 +     *
    2.70 +     * @param instance the instance to insert
    2.71 +     * @return true if an instance has been updated, false if no instance with the specified ID was found
    2.72 +     * @throws SQLException on any kind of SQL errors
    2.73 +     */
    2.74 +    boolean update(T instance) throws SQLException;
    2.75 +
    2.76 +    /**
    2.77 +     * Updates an instance in the database changing the parent.
    2.78 +     * This operation is not supported by default.
    2.79 +     *
    2.80 +     * @param instance the instance to insert
    2.81 +     * @param newParent a reference to the new parent
    2.82 +     * @return true if an instance has been updated, false if no instance with the specified ID was found
    2.83 +     * @throws SQLException on any kind of SQL errors
    2.84 +     * @see #isChangingParentSupported()
    2.85 +     */
    2.86 +    default boolean update(T instance, P newParent) throws SQLException {
    2.87 +        throw new UnsupportedOperationException();
    2.88 +    }
    2.89 +
    2.90 +    /**
    2.91 +     * Returns true if changing the parent is supported by this DAO.
    2.92 +     * This method must return true, if {@link #update(Object, Object)} is implemented.
    2.93 +     * @return true, if changing the parent is supported
    2.94 +     */
    2.95 +    default boolean isChangingParentSupported() {
    2.96 +        return false;
    2.97 +    }
    2.98 +
    2.99 +    /**
   2.100 +     * Inserts or updates an instance in the database.
   2.101 +     * Tries an update first and if that fails, performs a save.
   2.102 +     * If changing a parent is not supported by this DAO,
   2.103 +     * specifying an alternate parent for an existing instance has no effect.
   2.104 +     *
   2.105 +     * @param instance the instance to insert or update
   2.106 +     * @param parent a reference to the parent
   2.107 +     * @throws SQLException on any kind of SQL errors
   2.108 +     * @see #update(Object)
   2.109 +     * @see #update(Object, Object)
   2.110 +     * @see #save(Object, Object)
   2.111 +     */
   2.112 +    default void saveOrUpdate(T instance, P parent) throws SQLException {
   2.113 +        if (isChangingParentSupported()) {
   2.114 +            if (!update(instance, parent)) save(instance, parent);
   2.115 +        } else {
   2.116 +            if (!update(instance)) save(instance, parent);
   2.117 +        }
   2.118 +    }
   2.119 +}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/main/java/de/uapcore/lightpit/dao/ComponentDao.java	Thu Oct 15 13:31:52 2020 +0200
     3.3 @@ -0,0 +1,36 @@
     3.4 +/*
     3.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3.6 + *
     3.7 + * Copyright 2018 Mike Becker. All rights reserved.
     3.8 + *
     3.9 + * Redistribution and use in source and binary forms, with or without
    3.10 + * modification, are permitted provided that the following conditions are met:
    3.11 + *
    3.12 + *   1. Redistributions of source code must retain the above copyright
    3.13 + *      notice, this list of conditions and the following disclaimer.
    3.14 + *
    3.15 + *   2. Redistributions in binary form must reproduce the above copyright
    3.16 + *      notice, this list of conditions and the following disclaimer in the
    3.17 + *      documentation and/or other materials provided with the distribution.
    3.18 + *
    3.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    3.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    3.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    3.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    3.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    3.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    3.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    3.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    3.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    3.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    3.29 + * POSSIBILITY OF SUCH DAMAGE.
    3.30 + *
    3.31 + */
    3.32 +package de.uapcore.lightpit.dao;
    3.33 +
    3.34 +import de.uapcore.lightpit.entities.Component;
    3.35 +import de.uapcore.lightpit.entities.Project;
    3.36 +
    3.37 +public interface ComponentDao extends ChildEntityDao<Component, Project> {
    3.38 +
    3.39 +}
     4.1 --- a/src/main/java/de/uapcore/lightpit/dao/DataAccessObjects.java	Thu Oct 15 12:27:05 2020 +0200
     4.2 +++ b/src/main/java/de/uapcore/lightpit/dao/DataAccessObjects.java	Thu Oct 15 13:31:52 2020 +0200
     4.3 @@ -35,5 +35,7 @@
     4.4  
     4.5      VersionDao getVersionDao();
     4.6  
     4.7 +    ComponentDao getComponentDao();
     4.8 +
     4.9      IssueDao getIssueDao();
    4.10  }
     5.1 --- a/src/main/java/de/uapcore/lightpit/dao/GenericDao.java	Thu Oct 15 12:27:05 2020 +0200
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,75 +0,0 @@
     5.4 -/*
     5.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     5.6 - *
     5.7 - * Copyright 2018 Mike Becker. All rights reserved.
     5.8 - *
     5.9 - * Redistribution and use in source and binary forms, with or without
    5.10 - * modification, are permitted provided that the following conditions are met:
    5.11 - *
    5.12 - *   1. Redistributions of source code must retain the above copyright
    5.13 - *      notice, this list of conditions and the following disclaimer.
    5.14 - *
    5.15 - *   2. Redistributions in binary form must reproduce the above copyright
    5.16 - *      notice, this list of conditions and the following disclaimer in the
    5.17 - *      documentation and/or other materials provided with the distribution.
    5.18 - *
    5.19 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    5.20 - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    5.21 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    5.22 - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    5.23 - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    5.24 - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    5.25 - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    5.26 - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    5.27 - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    5.28 - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    5.29 - * POSSIBILITY OF SUCH DAMAGE.
    5.30 - *
    5.31 - */
    5.32 -package de.uapcore.lightpit.dao;
    5.33 -
    5.34 -import java.sql.SQLException;
    5.35 -
    5.36 -public interface GenericDao<T> {
    5.37 -
    5.38 -    /**
    5.39 -     * Finds an entity by its integer ID.
    5.40 -     * It is not guaranteed that referenced entities are automatically joined.
    5.41 -     *
    5.42 -     * @param id the id
    5.43 -     * @return the enity or null if there is no such entity
    5.44 -     * @throws SQLException on any kind of SQL errors
    5.45 -     */
    5.46 -    T find(int id) throws SQLException;
    5.47 -
    5.48 -    /**
    5.49 -     * Inserts an instance into database.
    5.50 -     * It is not guaranteed that generated fields will be updated in the instance.
    5.51 -     *
    5.52 -     * @param instance the instance to insert
    5.53 -     * @throws SQLException on any kind of SQL errors
    5.54 -     */
    5.55 -    void save(T instance) throws SQLException;
    5.56 -
    5.57 -    /**
    5.58 -     * Updates an instance in the database.
    5.59 -     *
    5.60 -     * @param instance the instance to insert
    5.61 -     * @return true if an instance has been updated, false if no instance with the specified ID was found
    5.62 -     * @throws SQLException on any kind of SQL errors
    5.63 -     */
    5.64 -    boolean update(T instance) throws SQLException;
    5.65 -
    5.66 -    /**
    5.67 -     * Inserts or updates an instance in the database.
    5.68 -     * Tries an update first and if that fails, performs a save.
    5.69 -     *
    5.70 -     * @param instance the instance to insert or update
    5.71 -     * @throws SQLException on any kind of SQL errors
    5.72 -     * @see #update(Object)
    5.73 -     * @see #save(Object)
    5.74 -     */
    5.75 -    default void saveOrUpdate(T instance) throws SQLException {
    5.76 -        if (!update(instance)) save(instance);
    5.77 -    }
    5.78 -}
     6.1 --- a/src/main/java/de/uapcore/lightpit/dao/IssueDao.java	Thu Oct 15 12:27:05 2020 +0200
     6.2 +++ b/src/main/java/de/uapcore/lightpit/dao/IssueDao.java	Thu Oct 15 13:31:52 2020 +0200
     6.3 @@ -36,18 +36,7 @@
     6.4  import java.sql.SQLException;
     6.5  import java.util.List;
     6.6  
     6.7 -public interface IssueDao extends GenericDao<Issue> {
     6.8 -
     6.9 -    /**
    6.10 -     * Lists all issues for the specified project.
    6.11 -     * This is not guaranteed to contain version information.
    6.12 -     * Use {@link #joinVersionInformation(Issue)} to obtain this information for a specific issue.
    6.13 -     *
    6.14 -     * @param project the project
    6.15 -     * @return a list of issues
    6.16 -     * @throws SQLException on any kind of SQL error
    6.17 -     */
    6.18 -    List<Issue> list(Project project) throws SQLException;
    6.19 +public interface IssueDao extends ChildEntityDao<Issue, Project> {
    6.20  
    6.21      /**
    6.22       * Lists all issues that are somehow related to the specified version.
    6.23 @@ -82,11 +71,12 @@
    6.24       * Implementations of this DAO must guarantee that the generated ID is stored in the instance.
    6.25       *
    6.26       * @param instance the instance to insert
    6.27 +     * @param project the parent project
    6.28       * @throws SQLException on any kind of SQL error
    6.29       * @see Issue#setId(int)
    6.30       */
    6.31      @Override
    6.32 -    void save(Issue instance) throws SQLException;
    6.33 +    void save(Issue instance, Project project) throws SQLException;
    6.34  
    6.35      /**
    6.36       * Retrieves the affected, scheduled and resolved versions for the specified issue.
     7.1 --- a/src/main/java/de/uapcore/lightpit/dao/ProjectDao.java	Thu Oct 15 12:27:05 2020 +0200
     7.2 +++ b/src/main/java/de/uapcore/lightpit/dao/ProjectDao.java	Thu Oct 15 13:31:52 2020 +0200
     7.3 @@ -32,10 +32,7 @@
     7.4  import de.uapcore.lightpit.entities.Project;
     7.5  
     7.6  import java.sql.SQLException;
     7.7 -import java.util.List;
     7.8  
     7.9 -public interface ProjectDao extends GenericDao<Project> {
    7.10 -    List<Project> list() throws SQLException;
    7.11 -
    7.12 +public interface ProjectDao extends RootEntityDao<Project> {
    7.13      IssueSummary getIssueSummary(Project project) throws SQLException;
    7.14  }
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/src/main/java/de/uapcore/lightpit/dao/RootEntityDao.java	Thu Oct 15 13:31:52 2020 +0200
     8.3 @@ -0,0 +1,83 @@
     8.4 +/*
     8.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     8.6 + *
     8.7 + * Copyright 2018 Mike Becker. All rights reserved.
     8.8 + *
     8.9 + * Redistribution and use in source and binary forms, with or without
    8.10 + * modification, are permitted provided that the following conditions are met:
    8.11 + *
    8.12 + *   1. Redistributions of source code must retain the above copyright
    8.13 + *      notice, this list of conditions and the following disclaimer.
    8.14 + *
    8.15 + *   2. Redistributions in binary form must reproduce the above copyright
    8.16 + *      notice, this list of conditions and the following disclaimer in the
    8.17 + *      documentation and/or other materials provided with the distribution.
    8.18 + *
    8.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    8.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    8.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    8.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    8.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    8.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    8.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    8.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    8.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    8.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    8.29 + * POSSIBILITY OF SUCH DAMAGE.
    8.30 + *
    8.31 + */
    8.32 +package de.uapcore.lightpit.dao;
    8.33 +
    8.34 +import java.sql.SQLException;
    8.35 +import java.util.List;
    8.36 +
    8.37 +public interface RootEntityDao<T> {
    8.38 +
    8.39 +    /**
    8.40 +     * Lists all entities.
    8.41 +     * @return a list of all entities
    8.42 +     * @throws SQLException on any kind of SQL errors
    8.43 +     */
    8.44 +    List<T> list() throws SQLException;
    8.45 +
    8.46 +    /**
    8.47 +     * Finds an entity by its integer ID.
    8.48 +     * It is not guaranteed that referenced entities are automatically joined.
    8.49 +     *
    8.50 +     * @param id the id
    8.51 +     * @return the enity or null if there is no such entity
    8.52 +     * @throws SQLException on any kind of SQL errors
    8.53 +     */
    8.54 +    T find(int id) throws SQLException;
    8.55 +
    8.56 +    /**
    8.57 +     * Inserts an instance into database.
    8.58 +     * It is not guaranteed that generated fields will be updated in the instance.
    8.59 +     *
    8.60 +     * @param instance the instance to insert
    8.61 +     * @throws SQLException on any kind of SQL errors
    8.62 +     */
    8.63 +    void save(T instance) throws SQLException;
    8.64 +
    8.65 +    /**
    8.66 +     * Updates an instance in the database.
    8.67 +     *
    8.68 +     * @param instance the instance to insert
    8.69 +     * @return true if an instance has been updated, false if no instance with the specified ID was found
    8.70 +     * @throws SQLException on any kind of SQL errors
    8.71 +     */
    8.72 +    boolean update(T instance) throws SQLException;
    8.73 +
    8.74 +    /**
    8.75 +     * Inserts or updates an instance in the database.
    8.76 +     * Tries an update first and if that fails, performs a save.
    8.77 +     *
    8.78 +     * @param instance the instance to insert or update
    8.79 +     * @throws SQLException on any kind of SQL errors
    8.80 +     * @see #update(Object)
    8.81 +     * @see #save(Object)
    8.82 +     */
    8.83 +    default void saveOrUpdate(T instance) throws SQLException {
    8.84 +        if (!update(instance)) save(instance);
    8.85 +    }
    8.86 +}
     9.1 --- a/src/main/java/de/uapcore/lightpit/dao/UserDao.java	Thu Oct 15 12:27:05 2020 +0200
     9.2 +++ b/src/main/java/de/uapcore/lightpit/dao/UserDao.java	Thu Oct 15 13:31:52 2020 +0200
     9.3 @@ -31,12 +31,9 @@
     9.4  import de.uapcore.lightpit.entities.User;
     9.5  
     9.6  import java.sql.SQLException;
     9.7 -import java.util.List;
     9.8  import java.util.Optional;
     9.9  
    9.10 -public interface UserDao extends GenericDao<User> {
    9.11 -
    9.12 -    List<User> list() throws SQLException;
    9.13 +public interface UserDao extends RootEntityDao<User> {
    9.14  
    9.15      /**
    9.16       * Tries to find a user by their username.
    10.1 --- a/src/main/java/de/uapcore/lightpit/dao/VersionDao.java	Thu Oct 15 12:27:05 2020 +0200
    10.2 +++ b/src/main/java/de/uapcore/lightpit/dao/VersionDao.java	Thu Oct 15 13:31:52 2020 +0200
    10.3 @@ -31,17 +31,5 @@
    10.4  import de.uapcore.lightpit.entities.Project;
    10.5  import de.uapcore.lightpit.entities.Version;
    10.6  
    10.7 -import java.sql.SQLException;
    10.8 -import java.util.List;
    10.9 -
   10.10 -public interface VersionDao extends GenericDao<Version> {
   10.11 -
   10.12 -    /**
   10.13 -     * Lists all versions for the specified project.
   10.14 -     *
   10.15 -     * @param project the project
   10.16 -     * @return a list of versions
   10.17 -     * @throws SQLException on any kind of SQL error
   10.18 -     */
   10.19 -    List<Version> list(Project project) throws SQLException;
   10.20 +public interface VersionDao extends ChildEntityDao<Version, Project> {
   10.21  }
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/src/main/java/de/uapcore/lightpit/dao/postgres/PGComponentDao.java	Thu Oct 15 13:31:52 2020 +0200
    11.3 @@ -0,0 +1,139 @@
    11.4 +/*
    11.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    11.6 + *
    11.7 + * Copyright 2018 Mike Becker. All rights reserved.
    11.8 + *
    11.9 + * Redistribution and use in source and binary forms, with or without
   11.10 + * modification, are permitted provided that the following conditions are met:
   11.11 + *
   11.12 + *   1. Redistributions of source code must retain the above copyright
   11.13 + *      notice, this list of conditions and the following disclaimer.
   11.14 + *
   11.15 + *   2. Redistributions in binary form must reproduce the above copyright
   11.16 + *      notice, this list of conditions and the following disclaimer in the
   11.17 + *      documentation and/or other materials provided with the distribution.
   11.18 + *
   11.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   11.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   11.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   11.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
   11.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   11.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   11.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   11.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   11.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   11.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   11.29 + * POSSIBILITY OF SUCH DAMAGE.
   11.30 + *
   11.31 + */
   11.32 +package de.uapcore.lightpit.dao.postgres;
   11.33 +
   11.34 +import de.uapcore.lightpit.dao.ComponentDao;
   11.35 +import de.uapcore.lightpit.dao.Functions;
   11.36 +import de.uapcore.lightpit.entities.Component;
   11.37 +import de.uapcore.lightpit.entities.Project;
   11.38 +import de.uapcore.lightpit.entities.User;
   11.39 +import de.uapcore.lightpit.types.WebColor;
   11.40 +
   11.41 +import java.sql.Connection;
   11.42 +import java.sql.PreparedStatement;
   11.43 +import java.sql.ResultSet;
   11.44 +import java.sql.SQLException;
   11.45 +import java.util.ArrayList;
   11.46 +import java.util.List;
   11.47 +import java.util.Objects;
   11.48 +
   11.49 +public final class PGComponentDao implements ComponentDao {
   11.50 +
   11.51 +    private final PreparedStatement insert, update, list, find;
   11.52 +
   11.53 +    public PGComponentDao(Connection connection) throws SQLException {
   11.54 +        list = connection.prepareStatement(
   11.55 +                "select id, name, color, ordinal, description, " +
   11.56 +                        "userid, username, givenname, lastname, mail " +
   11.57 +                        "from lpit_component " +
   11.58 +                        "left join lpit_user on lead = userid " +
   11.59 +                        "where project = ? " +
   11.60 +                        "order by ordinal desc, lower(name) desc");
   11.61 +
   11.62 +        find = connection.prepareStatement(
   11.63 +                "select id, name, color, ordinal, description, " +
   11.64 +                        "userid, username, givenname, lastname, mail " +
   11.65 +                        "from lpit_component " +
   11.66 +                        "left join lpit_user on lead = userid " +
   11.67 +                        "where id = ? ");
   11.68 +
   11.69 +        insert = connection.prepareStatement(
   11.70 +                "insert into lpit_component (project, name, color, ordinal, description, lead) values (?, ?, ?, ?, ?, ?)"
   11.71 +        );
   11.72 +
   11.73 +        update = connection.prepareStatement(
   11.74 +                "update lpit_component set name = ?, color = ?, ordinal = ?, description = ?, lead = ? where id = ?"
   11.75 +        );
   11.76 +    }
   11.77 +
   11.78 +    private static Component mapColumns(ResultSet result) throws SQLException {
   11.79 +        final var component = new Component(result.getInt("id"));
   11.80 +        component.setName(result.getString("name"));
   11.81 +        try {
   11.82 +            component.setColor(new WebColor(result.getString("color")));
   11.83 +        } catch (IllegalArgumentException ex) {
   11.84 +            // if someone tempered with the database we default the color to black
   11.85 +            component.setColor(new WebColor("000000"));
   11.86 +        }
   11.87 +        component.setOrdinal(result.getInt("ordinal"));
   11.88 +        component.setDescription(result.getString("description"));
   11.89 +        component.setLead(PGUserDao.mapColumns(result));
   11.90 +        return component;
   11.91 +    }
   11.92 +
   11.93 +    @Override
   11.94 +    public void save(Component instance, Project project) throws SQLException {
   11.95 +        Objects.requireNonNull(instance.getName());
   11.96 +        insert.setInt(1, project.getId());
   11.97 +        insert.setString(2, instance.getName());
   11.98 +        insert.setString(3, instance.getColor().getHex());
   11.99 +        insert.setInt(4, instance.getOrdinal());
  11.100 +        Functions.setStringOrNull(insert, 5, instance.getDescription());
  11.101 +        Functions.setForeignKeyOrNull(insert, 6, instance.getLead(), User::getId);
  11.102 +        insert.executeUpdate();
  11.103 +    }
  11.104 +
  11.105 +    @Override
  11.106 +    public boolean update(Component instance) throws SQLException {
  11.107 +        if (instance.getId() < 0) return false;
  11.108 +        Objects.requireNonNull(instance.getName());
  11.109 +        Objects.requireNonNull(instance.getColor());
  11.110 +        update.setString(1, instance.getName());
  11.111 +        update.setString(2, instance.getColor().getHex());
  11.112 +        update.setInt(3, instance.getOrdinal());
  11.113 +        Functions.setStringOrNull(update, 4, instance.getDescription());
  11.114 +        Functions.setForeignKeyOrNull(update, 5, instance.getLead(), User::getId);
  11.115 +        update.setInt(6, instance.getId());
  11.116 +        return update.executeUpdate() > 0;
  11.117 +    }
  11.118 +
  11.119 +    @Override
  11.120 +    public List<Component> list(Project project) throws SQLException {
  11.121 +        list.setInt(1, project.getId());
  11.122 +        List<Component> components = new ArrayList<>();
  11.123 +        try (var result = list.executeQuery()) {
  11.124 +            while (result.next()) {
  11.125 +                components.add(mapColumns(result));
  11.126 +            }
  11.127 +        }
  11.128 +        return components;
  11.129 +    }
  11.130 +
  11.131 +    @Override
  11.132 +    public Component find(int id) throws SQLException {
  11.133 +        find.setInt(1, id);
  11.134 +        try (var result = find.executeQuery()) {
  11.135 +            if (result.next()) {
  11.136 +                return mapColumns(result);
  11.137 +            } else {
  11.138 +                return null;
  11.139 +            }
  11.140 +        }
  11.141 +    }
  11.142 +}
    12.1 --- a/src/main/java/de/uapcore/lightpit/dao/postgres/PGDataAccessObjects.java	Thu Oct 15 12:27:05 2020 +0200
    12.2 +++ b/src/main/java/de/uapcore/lightpit/dao/postgres/PGDataAccessObjects.java	Thu Oct 15 13:31:52 2020 +0200
    12.3 @@ -38,12 +38,14 @@
    12.4      private final UserDao userDao;
    12.5      private final ProjectDao projectDao;
    12.6      private final VersionDao versionDao;
    12.7 +    private final ComponentDao componentDao;
    12.8      private final IssueDao issueDao;
    12.9  
   12.10      public PGDataAccessObjects(Connection connection) throws SQLException {
   12.11          userDao = new PGUserDao(connection);
   12.12          projectDao = new PGProjectDao(connection);
   12.13          versionDao = new PGVersionDao(connection);
   12.14 +        componentDao = new PGComponentDao(connection);
   12.15          issueDao = new PGIssueDao(connection);
   12.16      }
   12.17  
   12.18 @@ -58,6 +60,11 @@
   12.19      }
   12.20  
   12.21      @Override
   12.22 +    public ComponentDao getComponentDao() {
   12.23 +        return componentDao;
   12.24 +    }
   12.25 +
   12.26 +    @Override
   12.27      public VersionDao getVersionDao() {
   12.28          return versionDao;
   12.29      }
    13.1 --- a/src/main/java/de/uapcore/lightpit/dao/postgres/PGIssueDao.java	Thu Oct 15 12:27:05 2020 +0200
    13.2 +++ b/src/main/java/de/uapcore/lightpit/dao/postgres/PGIssueDao.java	Thu Oct 15 13:31:52 2020 +0200
    13.3 @@ -120,20 +120,6 @@
    13.4          );
    13.5      }
    13.6  
    13.7 -    private User obtainUser(ResultSet result) throws SQLException {
    13.8 -        final int id = result.getInt("userid");
    13.9 -        if (id != 0) {
   13.10 -            final var user = new User(id);
   13.11 -            user.setUsername(result.getString("username"));
   13.12 -            user.setGivenname(result.getString("givenname"));
   13.13 -            user.setLastname(result.getString("lastname"));
   13.14 -            user.setMail(result.getString("mail"));
   13.15 -            return user;
   13.16 -        } else {
   13.17 -            return null;
   13.18 -        }
   13.19 -    }
   13.20 -
   13.21      private Issue mapColumns(ResultSet result) throws SQLException {
   13.22          final var project = new Project(result.getInt("project"));
   13.23          project.setName(result.getString("projectname"));
   13.24 @@ -143,7 +129,7 @@
   13.25          issue.setCategory(IssueCategory.valueOf(result.getString("category")));
   13.26          issue.setSubject(result.getString("subject"));
   13.27          issue.setDescription(result.getString("description"));
   13.28 -        issue.setAssignee(obtainUser(result));
   13.29 +        issue.setAssignee(PGUserDao.mapColumns(result));
   13.30          issue.setCreated(result.getTimestamp("created"));
   13.31          issue.setUpdated(result.getTimestamp("updated"));
   13.32          issue.setEta(result.getDate("eta"));
   13.33 @@ -176,9 +162,9 @@
   13.34      }
   13.35  
   13.36      @Override
   13.37 -    public void save(Issue instance) throws SQLException {
   13.38 +    public void save(Issue instance, Project project) throws SQLException {
   13.39          Objects.requireNonNull(instance.getSubject());
   13.40 -        Objects.requireNonNull(instance.getProject());
   13.41 +        instance.setProject(project);
   13.42          insert.setInt(1, instance.getProject().getId());
   13.43          insert.setString(2, instance.getStatus().name());
   13.44          insert.setString(3, instance.getCategory().name());
   13.45 @@ -275,7 +261,7 @@
   13.46                  comment.setUpdated(result.getTimestamp("updated"));
   13.47                  comment.setUpdateCount(result.getInt("updatecount"));
   13.48                  comment.setComment(result.getString("comment"));
   13.49 -                comment.setAuthor(obtainUser(result));
   13.50 +                comment.setAuthor(PGUserDao.mapColumns(result));
   13.51                  comments.add(comment);
   13.52              }
   13.53          }
    14.1 --- a/src/main/java/de/uapcore/lightpit/dao/postgres/PGProjectDao.java	Thu Oct 15 12:27:05 2020 +0200
    14.2 +++ b/src/main/java/de/uapcore/lightpit/dao/postgres/PGProjectDao.java	Thu Oct 15 13:31:52 2020 +0200
    14.3 @@ -85,16 +85,7 @@
    14.4          proj.setName(result.getString("name"));
    14.5          proj.setDescription(result.getString("description"));
    14.6          proj.setRepoUrl(result.getString("repourl"));
    14.7 -
    14.8 -        final int id = result.getInt("userid");
    14.9 -        if (id != 0) {
   14.10 -            final var user = new User(id);
   14.11 -            user.setUsername(result.getString("username"));
   14.12 -            user.setGivenname(result.getString("givenname"));
   14.13 -            user.setLastname(result.getString("lastname"));
   14.14 -            user.setMail(result.getString("mail"));
   14.15 -            proj.setOwner(user);
   14.16 -        }
   14.17 +        proj.setOwner(PGUserDao.mapColumns(result));
   14.18  
   14.19          return proj;
   14.20      }
    15.1 --- a/src/main/java/de/uapcore/lightpit/dao/postgres/PGUserDao.java	Thu Oct 15 12:27:05 2020 +0200
    15.2 +++ b/src/main/java/de/uapcore/lightpit/dao/postgres/PGUserDao.java	Thu Oct 15 13:31:52 2020 +0200
    15.3 @@ -63,7 +63,7 @@
    15.4          update = connection.prepareStatement("update lpit_user set lastname = ?, givenname = ?, mail = ? where userid = ?");
    15.5      }
    15.6  
    15.7 -    private User mapColumns(ResultSet result) throws SQLException {
    15.8 +    static User mapColumns(ResultSet result) throws SQLException {
    15.9          final int id = result.getInt("userid");
   15.10          if (id == 0) return null;
   15.11          final var user = new User(id);
    16.1 --- a/src/main/java/de/uapcore/lightpit/dao/postgres/PGVersionDao.java	Thu Oct 15 12:27:05 2020 +0200
    16.2 +++ b/src/main/java/de/uapcore/lightpit/dao/postgres/PGVersionDao.java	Thu Oct 15 13:31:52 2020 +0200
    16.3 @@ -47,16 +47,14 @@
    16.4  
    16.5      public PGVersionDao(Connection connection) throws SQLException {
    16.6          list = connection.prepareStatement(
    16.7 -                "select versionid, project, p.name as projectname, v.name, ordinal, status " +
    16.8 -                        "from lpit_version v " +
    16.9 -                        "join lpit_project p on v.project = p.projectid " +
   16.10 +                "select versionid, project, name, ordinal, status " +
   16.11 +                        "from lpit_version " +
   16.12                          "where project = ? " +
   16.13 -                        "order by ordinal desc, lower(v.name) desc");
   16.14 +                        "order by ordinal desc, lower(name) desc");
   16.15  
   16.16          find = connection.prepareStatement(
   16.17 -                "select versionid, project, p.name as projectname, v.name, ordinal, status " +
   16.18 -                        "from lpit_version  v " +
   16.19 -                        "join lpit_project p on v.project = p.projectid " +
   16.20 +                "select versionid, project, name, ordinal, status " +
   16.21 +                        "from lpit_version  " +
   16.22                          "where versionid = ?");
   16.23  
   16.24          insert = connection.prepareStatement(
   16.25 @@ -68,10 +66,7 @@
   16.26      }
   16.27  
   16.28      private Version mapColumns(ResultSet result) throws SQLException {
   16.29 -        final var project = new Project(result.getInt("project"));
   16.30 -        project.setName(result.getString("projectname"));
   16.31          final var version = new Version(result.getInt("versionid"));
   16.32 -        version.setProject(project);
   16.33          version.setName(result.getString("name"));
   16.34          version.setOrdinal(result.getInt("ordinal"));
   16.35          version.setStatus(VersionStatus.valueOf(result.getString("status")));
   16.36 @@ -79,10 +74,9 @@
   16.37      }
   16.38  
   16.39      @Override
   16.40 -    public void save(Version instance) throws SQLException {
   16.41 +    public void save(Version instance, Project project) throws SQLException {
   16.42          Objects.requireNonNull(instance.getName());
   16.43 -        Objects.requireNonNull(instance.getProject());
   16.44 -        insert.setInt(1, instance.getProject().getId());
   16.45 +        insert.setInt(1, project.getId());
   16.46          insert.setString(2, instance.getName());
   16.47          insert.setInt(3, instance.getOrdinal());
   16.48          insert.setString(4, instance.getStatus().name());
   16.49 @@ -106,9 +100,7 @@
   16.50          List<Version> versions = new ArrayList<>();
   16.51          try (var result = list.executeQuery()) {
   16.52              while (result.next()) {
   16.53 -                final var v = mapColumns(result);
   16.54 -                v.setProject(project);
   16.55 -                versions.add(v);
   16.56 +                versions.add(mapColumns(result));
   16.57              }
   16.58          }
   16.59          return versions;
    17.1 --- a/src/main/java/de/uapcore/lightpit/entities/Version.java	Thu Oct 15 12:27:05 2020 +0200
    17.2 +++ b/src/main/java/de/uapcore/lightpit/entities/Version.java	Thu Oct 15 13:31:52 2020 +0200
    17.3 @@ -33,7 +33,6 @@
    17.4  public final class Version implements Comparable<Version> {
    17.5  
    17.6      private final int id;
    17.7 -    private Project project;
    17.8      private String name;
    17.9      /**
   17.10       * If we do not want versions to be ordered lexicographically we may specify an order.
   17.11 @@ -49,14 +48,6 @@
   17.12          return id;
   17.13      }
   17.14  
   17.15 -    public void setProject(Project project) {
   17.16 -        this.project = project;
   17.17 -    }
   17.18 -
   17.19 -    public Project getProject() {
   17.20 -        return project;
   17.21 -    }
   17.22 -
   17.23      public String getName() {
   17.24          return name;
   17.25      }
    18.1 --- a/src/main/java/de/uapcore/lightpit/modules/ProjectsModule.java	Thu Oct 15 12:27:05 2020 +0200
    18.2 +++ b/src/main/java/de/uapcore/lightpit/modules/ProjectsModule.java	Thu Oct 15 13:31:52 2020 +0200
    18.3 @@ -238,13 +238,7 @@
    18.4              return ResponseType.NONE;
    18.5          }
    18.6  
    18.7 -        if (viewModel.getVersionFilter() == null) {
    18.8 -            final var version = new Version(-1);
    18.9 -            version.setProject(viewModel.getProjectInfo().getProject());
   18.10 -            viewModel.setVersion(version);
   18.11 -        } else {
   18.12 -            viewModel.setVersion(viewModel.getVersionFilter());
   18.13 -        }
   18.14 +        viewModel.setVersion(Optional.ofNullable(viewModel.getVersionFilter()).orElse(new Version(-1)));
   18.15  
   18.16          return forwardView(req, viewModel, "version-form");
   18.17      }
   18.18 @@ -254,15 +248,14 @@
   18.19  
   18.20          var version = new Version(-1);
   18.21          try {
   18.22 +            final var project = new Project(getParameter(req, Integer.class, "pid").orElseThrow());
   18.23              version = new Version(getParameter(req, Integer.class, "id").orElseThrow());
   18.24 -            version.setProject(new Project(getParameter(req, Integer.class, "pid").orElseThrow()));
   18.25              version.setName(getParameter(req, String.class, "name").orElseThrow());
   18.26              getParameter(req, Integer.class, "ordinal").ifPresent(version::setOrdinal);
   18.27              version.setStatus(VersionStatus.valueOf(getParameter(req, String.class, "status").orElseThrow()));
   18.28 -            dao.getVersionDao().saveOrUpdate(version);
   18.29 +            dao.getVersionDao().saveOrUpdate(version, project);
   18.30  
   18.31 -            // specifying the pid parameter will purposely reset the session selected version!
   18.32 -            setRedirectLocation(req, "./projects/versions?pid=" + version.getProject().getId());
   18.33 +            setRedirectLocation(req, "./projects/versions?pid=" + project.getId());
   18.34              setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL);
   18.35          } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) {
   18.36              LOG.warn("Form validation failure: {}", ex.getMessage());
   18.37 @@ -332,7 +325,7 @@
   18.38                              stream.map(Version::new).collect(Collectors.toList())
   18.39                      ).ifPresent(issue::setResolvedVersions);
   18.40  
   18.41 -            dao.getIssueDao().saveOrUpdate(issue);
   18.42 +            dao.getIssueDao().saveOrUpdate(issue, issue.getProject());
   18.43  
   18.44              // specifying the issue parameter keeps the edited issue as menu item
   18.45              setRedirectLocation(req, "./projects/view?pid=" + issue.getProject().getId());
    19.1 --- a/src/main/webapp/WEB-INF/jsp/version-form.jsp	Thu Oct 15 12:27:05 2020 +0200
    19.2 +++ b/src/main/webapp/WEB-INF/jsp/version-form.jsp	Thu Oct 15 13:31:52 2020 +0200
    19.3 @@ -30,6 +30,7 @@
    19.4  
    19.5  <jsp:useBean id="viewmodel" type="de.uapcore.lightpit.viewmodel.VersionEditView" scope="request" />
    19.6  <c:set var="version" scope="page" value="${viewmodel.version}"/>
    19.7 +<c:set var="project" scope="page" value="${viewmodel.projectInfo.project}"/>
    19.8  
    19.9  <form action="./projects/versions/commit" method="post">
   19.10      <table class="formtable" style="width: 35ch">
   19.11 @@ -41,8 +42,8 @@
   19.12          <tr>
   19.13              <th><fmt:message key="version.project"/></th>
   19.14              <td>
   19.15 -                <c:out value="${version.project.name}" />
   19.16 -                <input type="hidden" name="pid" value="${version.project.id}" />
   19.17 +                <c:out value="${project.name}" />
   19.18 +                <input type="hidden" name="pid" value="${project.id}" />
   19.19              </td>
   19.20          </tr>
   19.21          <tr>
   19.22 @@ -72,7 +73,7 @@
   19.23          <tr>
   19.24              <td colspan="2">
   19.25                  <input type="hidden" name="id" value="${version.id}"/>
   19.26 -                <a href="./projects/versions?pid=${version.project.id}" class="button">
   19.27 +                <a href="./projects/versions?pid=${project.id}" class="button">
   19.28                      <fmt:message bundle="${lightpit_bundle}" key="button.cancel"/>
   19.29                  </a>
   19.30                  <button type="submit"><fmt:message bundle="${lightpit_bundle}" key="button.okay"/></button>

mercurial