From cfde218d32cf7715a4ddff1057bd99b631ed1828 Mon Sep 17 00:00:00 2001 From: jendib Date: Sun, 13 Sep 2015 23:54:06 +0200 Subject: [PATCH] #23: Tag tree (server) --- .../com/sismics/docs/core/dao/jpa/TagDao.java | 7 +++-- .../sismics/docs/core/dao/jpa/dto/TagDto.java | 23 +++++++++++++++ .../docs/core/dao/jpa/dto/TagStatDto.java | 2 +- .../com/sismics/docs/core/model/jpa/Tag.java | 25 ++++++++++++++++ .../src/main/resources/config.properties | 2 +- .../resources/db/update/dbupdate-002-0.sql | 2 ++ docs-web/src/dev/resources/config.properties | 2 +- .../docs/rest/resource/TagResource.java | 29 +++++++++++++++++-- docs-web/src/prod/resources/config.properties | 2 +- .../src/stress/resources/config.properties | 2 +- .../sismics/docs/rest/TestTagResource.java | 6 +++- 11 files changed, 91 insertions(+), 11 deletions(-) create mode 100644 docs-core/src/main/resources/db/update/dbupdate-002-0.sql diff --git a/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/TagDao.java b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/TagDao.java index da108dd9..dbff4438 100644 --- a/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/TagDao.java +++ b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/TagDao.java @@ -103,7 +103,7 @@ public class TagDao { @SuppressWarnings("unchecked") public List getByDocumentId(String documentId, String userId) { EntityManager em = ThreadLocalContext.get().getEntityManager(); - StringBuilder sb = new StringBuilder("select t.TAG_ID_C, t.TAG_NAME_C, t.TAG_COLOR_C from T_DOCUMENT_TAG dt "); + StringBuilder sb = new StringBuilder("select t.TAG_ID_C, t.TAG_NAME_C, t.TAG_COLOR_C, t.TAG_IDPARENT_C from T_DOCUMENT_TAG dt "); sb.append(" join T_TAG t on t.TAG_ID_C = dt.DOT_IDTAG_C "); sb.append(" where dt.DOT_IDDOCUMENT_C = :documentId and t.TAG_DELETEDATE_D is null "); sb.append(" and t.TAG_IDUSER_C = :userId and dt.DOT_DELETEDATE_D is null "); @@ -123,6 +123,7 @@ public class TagDao { tagDto.setId((String) o[i++]); tagDto.setName((String) o[i++]); tagDto.setColor((String) o[i++]); + tagDto.setParentId((String) o[i++]); tagDtoList.add(tagDto); } return tagDtoList; @@ -137,7 +138,7 @@ public class TagDao { @SuppressWarnings("unchecked") public List getStats(String userId) { EntityManager em = ThreadLocalContext.get().getEntityManager(); - StringBuilder sb = new StringBuilder("select t.TAG_ID_C, t.TAG_NAME_C, t.TAG_COLOR_C, count(d.DOC_ID_C) "); + StringBuilder sb = new StringBuilder("select t.TAG_ID_C, t.TAG_NAME_C, t.TAG_COLOR_C, t.TAG_IDPARENT_C, count(d.DOC_ID_C) "); sb.append(" from T_TAG t "); sb.append(" left join T_DOCUMENT_TAG dt on t.TAG_ID_C = dt.DOT_IDTAG_C and dt.DOT_DELETEDATE_D is null "); sb.append(" left join T_DOCUMENT d on d.DOC_ID_C = dt.DOT_IDDOCUMENT_C and d.DOC_DELETEDATE_D is null and d.DOC_IDUSER_C = :userId "); @@ -158,6 +159,7 @@ public class TagDao { tagDto.setId((String) o[i++]); tagDto.setName((String) o[i++]); tagDto.setColor((String) o[i++]); + tagDto.setParentId((String) o[i++]); tagDto.setCount(((Number) o[i++]).intValue()); tagStatDtoList.add(tagDto); } @@ -281,6 +283,7 @@ public class TagDao { // Update the tag tagFromDb.setName(tag.getName()); tagFromDb.setColor(tag.getColor()); + tagFromDb.setParentId(tag.getParentId()); // Create audit log AuditLogUtil.create(tagFromDb, AuditLogType.UPDATE); diff --git a/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/dto/TagDto.java b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/dto/TagDto.java index 343acd90..6666015d 100644 --- a/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/dto/TagDto.java +++ b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/dto/TagDto.java @@ -23,6 +23,11 @@ public class TagDto { * Color. */ private String color; + + /** + * Parent ID. + */ + private String parentId; /** * Getter of id. @@ -77,4 +82,22 @@ public class TagDto { public void setColor(String color) { this.color = color; } + + /** + * Getter of parentId. + * + * @return the parentId + */ + public String getParentId() { + return parentId; + } + + /** + * Setter of parentId. + * + * @param color parentId + */ + public void setParentId(String parentId) { + this.parentId = parentId; + } } diff --git a/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/dto/TagStatDto.java b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/dto/TagStatDto.java index cb54a7d7..03b0e76c 100644 --- a/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/dto/TagStatDto.java +++ b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/dto/TagStatDto.java @@ -2,7 +2,7 @@ package com.sismics.docs.core.dao.jpa.dto; /** - * Tag DTO. + * Tag stat DTO. * * @author bgamard */ diff --git a/docs-core/src/main/java/com/sismics/docs/core/model/jpa/Tag.java b/docs-core/src/main/java/com/sismics/docs/core/model/jpa/Tag.java index 70fcba4c..e556c7d2 100644 --- a/docs-core/src/main/java/com/sismics/docs/core/model/jpa/Tag.java +++ b/docs-core/src/main/java/com/sismics/docs/core/model/jpa/Tag.java @@ -39,6 +39,12 @@ public class Tag implements Loggable { @Column(name = "TAG_IDUSER_C", nullable = false, length = 36) private String userId; + /** + * User ID. + */ + @Column(name = "TAG_IDPARENT_C", length = 36) + private String parentId; + /** * Creation date. */ @@ -165,12 +171,31 @@ public class Tag implements Loggable { public void setDeleteDate(Date deleteDate) { this.deleteDate = deleteDate; } + + /** + * Getter of parentId. + * + * @return parentId + */ + public String getParentId() { + return parentId; + } + + /** + * Setter of parentId. + * + * @param parentId parentId + */ + public void setParentId(String parentId) { + this.parentId = parentId; + } @Override public String toString() { return MoreObjects.toStringHelper(this) .add("id", id) .add("name", name) + .add("parentId", parentId) .toString(); } diff --git a/docs-core/src/main/resources/config.properties b/docs-core/src/main/resources/config.properties index 9484a82d..d8b90e8b 100644 --- a/docs-core/src/main/resources/config.properties +++ b/docs-core/src/main/resources/config.properties @@ -1 +1 @@ -db.version=1 \ No newline at end of file +db.version=2 \ No newline at end of file diff --git a/docs-core/src/main/resources/db/update/dbupdate-002-0.sql b/docs-core/src/main/resources/db/update/dbupdate-002-0.sql new file mode 100644 index 00000000..14551cf3 --- /dev/null +++ b/docs-core/src/main/resources/db/update/dbupdate-002-0.sql @@ -0,0 +1,2 @@ +alter table T_TAG add column TAG_IDPARENT_C varchar(36); +update T_CONFIG set CFG_VALUE_C = '2' where CFG_ID_C = 'DB_VERSION'; diff --git a/docs-web/src/dev/resources/config.properties b/docs-web/src/dev/resources/config.properties index f2362d2f..87577f48 100644 --- a/docs-web/src/dev/resources/config.properties +++ b/docs-web/src/dev/resources/config.properties @@ -1,3 +1,3 @@ api.current_version=${project.version} api.min_version=1.0 -db.version=1 \ No newline at end of file +db.version=2 \ No newline at end of file diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/TagResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/TagResource.java index 05b8cc4b..1ec03fd3 100644 --- a/docs-web/src/main/java/com/sismics/docs/rest/resource/TagResource.java +++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/TagResource.java @@ -22,6 +22,7 @@ import com.sismics.docs.core.dao.jpa.dto.TagStatDto; import com.sismics.docs.core.model.jpa.Tag; import com.sismics.rest.exception.ClientException; import com.sismics.rest.exception.ForbiddenClientException; +import com.sismics.rest.util.JsonUtil; import com.sismics.rest.util.ValidationUtil; /** @@ -50,7 +51,8 @@ public class TagResource extends BaseResource { items.add(Json.createObjectBuilder() .add("id", tag.getId()) .add("name", tag.getName()) - .add("color", tag.getColor())); + .add("color", tag.getColor()) + .add("parent", JsonUtil.nullable(tag.getParentId()))); } JsonObjectBuilder response = Json.createObjectBuilder() @@ -96,7 +98,8 @@ public class TagResource extends BaseResource { @PUT public Response add( @FormParam("name") String name, - @FormParam("color") String color) { + @FormParam("color") String color, + @FormParam("parent") String parentId) { if (!authenticate()) { throw new ForbiddenClientException(); } @@ -117,11 +120,20 @@ public class TagResource extends BaseResource { throw new ClientException("AlreadyExistingTag", MessageFormat.format("Tag already exists: {0}", name)); } + // Check the parent + if (parentId != null) { + Tag parentTag = tagDao.getByTagId(principal.getId(), parentId); + if (parentTag == null) { + throw new ClientException("ParentNotFound", MessageFormat.format("Parent not found: {0}", parentId)); + } + } + // Create the tag tag = new Tag(); tag.setName(name); tag.setColor(color); tag.setUserId(principal.getId()); + tag.setParentId(parentId); String id = tagDao.create(tag); JsonObjectBuilder response = Json.createObjectBuilder() @@ -140,7 +152,8 @@ public class TagResource extends BaseResource { public Response update( @PathParam("id") String id, @FormParam("name") String name, - @FormParam("color") String color) { + @FormParam("color") String color, + @FormParam("parent") String parentId) { if (!authenticate()) { throw new ForbiddenClientException(); } @@ -161,6 +174,14 @@ public class TagResource extends BaseResource { throw new ClientException("TagNotFound", MessageFormat.format("Tag not found: {0}", id)); } + // Check the parent + if (parentId != null) { + Tag parentTag = tagDao.getByTagId(principal.getId(), parentId); + if (parentTag == null) { + throw new ClientException("ParentNotFound", MessageFormat.format("Parent not found: {0}", parentId)); + } + } + // Check for name duplicate Tag tagDuplicate = tagDao.getByName(principal.getId(), name); if (tagDuplicate != null && !tagDuplicate.getId().equals(id)) { @@ -174,6 +195,8 @@ public class TagResource extends BaseResource { if (!StringUtils.isEmpty(color)) { tag.setColor(color); } + // Parent tag is always updated to have the possibility to delete it + tag.setParentId(parentId); tagDao.update(tag); diff --git a/docs-web/src/prod/resources/config.properties b/docs-web/src/prod/resources/config.properties index f2362d2f..87577f48 100644 --- a/docs-web/src/prod/resources/config.properties +++ b/docs-web/src/prod/resources/config.properties @@ -1,3 +1,3 @@ api.current_version=${project.version} api.min_version=1.0 -db.version=1 \ No newline at end of file +db.version=2 \ No newline at end of file diff --git a/docs-web/src/stress/resources/config.properties b/docs-web/src/stress/resources/config.properties index f2362d2f..87577f48 100644 --- a/docs-web/src/stress/resources/config.properties +++ b/docs-web/src/stress/resources/config.properties @@ -1,3 +1,3 @@ api.current_version=${project.version} api.min_version=1.0 -db.version=1 \ No newline at end of file +db.version=2 \ No newline at end of file diff --git a/docs-web/src/test/java/com/sismics/docs/rest/TestTagResource.java b/docs-web/src/test/java/com/sismics/docs/rest/TestTagResource.java index b9fa0532..3094879a 100644 --- a/docs-web/src/test/java/com/sismics/docs/rest/TestTagResource.java +++ b/docs-web/src/test/java/com/sismics/docs/rest/TestTagResource.java @@ -2,6 +2,7 @@ package com.sismics.docs.rest; import javax.json.JsonArray; import javax.json.JsonObject; +import javax.json.JsonValue; import javax.ws.rs.client.Entity; import javax.ws.rs.core.Form; import javax.ws.rs.core.Response; @@ -44,7 +45,8 @@ public class TestTagResource extends BaseJerseyTest { .cookie(TokenBasedSecurityFilter.COOKIE_NAME, tag1Token) .put(Entity.form(new Form() .param("name", "Tag4") - .param("color", "#00ff00")), JsonObject.class); + .param("color", "#00ff00") + .param("parent", tag3Id)), JsonObject.class); String tag4Id = json.getString("id"); Assert.assertNotNull(tag4Id); @@ -129,6 +131,7 @@ public class TestTagResource extends BaseJerseyTest { Assert.assertTrue(tags.size() > 0); Assert.assertEquals("Tag4", tags.getJsonObject(1).getString("name")); Assert.assertEquals("#00ff00", tags.getJsonObject(1).getString("color")); + Assert.assertEquals(tag3Id, tags.getJsonObject(1).getString("parent")); // Update a tag json = target().path("/tag/" + tag4Id).request() @@ -146,6 +149,7 @@ public class TestTagResource extends BaseJerseyTest { Assert.assertTrue(tags.size() > 0); Assert.assertEquals("UpdatedName", tags.getJsonObject(1).getString("name")); Assert.assertEquals("#0000ff", tags.getJsonObject(1).getString("color")); + Assert.assertEquals(JsonValue.NULL, tags.getJsonObject(1).get("parent")); // Deletes a tag target().path("/tag/" + tag4Id).request()