From abf87b1049a36892580e121afb3533559a5e2c34 Mon Sep 17 00:00:00 2001 From: Stephan Richter Date: Sun, 3 Aug 2025 13:31:43 +0200 Subject: [PATCH] first step towards alllowing stings as entity ids in TagModule --- .../umbrella/core/api/EntityId.java | 6 +++++ .../umbrella/core/api/TagService.java | 8 +++--- .../umbrella/core/model/LongId.java | 25 +++++++++++++++++++ .../umbrella/core/model/Project.java | 4 +++ .../srsoftware/umbrella/core/model/Task.java | 4 +++ .../umbrella/project/ProjectModule.java | 2 +- .../de/srsoftware/umbrella/tags/SqliteDb.java | 23 +++++++++-------- .../de/srsoftware/umbrella/tags/TagDB.java | 11 ++++---- .../srsoftware/umbrella/tags/TagModule.java | 16 ++++++------ .../srsoftware/umbrella/task/TaskModule.java | 4 +-- 10 files changed, 73 insertions(+), 30 deletions(-) create mode 100644 core/src/main/java/de/srsoftware/umbrella/core/api/EntityId.java create mode 100644 core/src/main/java/de/srsoftware/umbrella/core/model/LongId.java diff --git a/core/src/main/java/de/srsoftware/umbrella/core/api/EntityId.java b/core/src/main/java/de/srsoftware/umbrella/core/api/EntityId.java new file mode 100644 index 0000000..b481ed1 --- /dev/null +++ b/core/src/main/java/de/srsoftware/umbrella/core/api/EntityId.java @@ -0,0 +1,6 @@ +/* © SRSoftware 2025 */ +package de.srsoftware.umbrella.core.api; + +public interface EntityId { + public T unwrap(); +} diff --git a/core/src/main/java/de/srsoftware/umbrella/core/api/TagService.java b/core/src/main/java/de/srsoftware/umbrella/core/api/TagService.java index 4b0e688..a896bbf 100644 --- a/core/src/main/java/de/srsoftware/umbrella/core/api/TagService.java +++ b/core/src/main/java/de/srsoftware/umbrella/core/api/TagService.java @@ -6,11 +6,11 @@ import de.srsoftware.umbrella.core.model.UmbrellaUser; import java.util.Collection; public interface TagService { - void deleteEntity(String task, long taskId); + void deleteEntity(String module, EntityId entityId); - Collection getTags(String module, long entityId, UmbrellaUser user) throws UmbrellaException; + Collection getTags(String module, EntityId entityId, UmbrellaUser user) throws UmbrellaException; - void save(String module, long entityId, Collection userIds, Collection tags); + void save(String module, EntityId entityId, Collection userIds, Collection tags); - String save(String module, long entityId, Collection userIds, String tag); + String save(String module, EntityId entityId, Collection userIds, String tag); } diff --git a/core/src/main/java/de/srsoftware/umbrella/core/model/LongId.java b/core/src/main/java/de/srsoftware/umbrella/core/model/LongId.java new file mode 100644 index 0000000..9686e8b --- /dev/null +++ b/core/src/main/java/de/srsoftware/umbrella/core/model/LongId.java @@ -0,0 +1,25 @@ +/* © SRSoftware 2025 */ +package de.srsoftware.umbrella.core.model; + +import de.srsoftware.umbrella.core.api.EntityId; + +public record LongId(long id) implements EntityId { + + public static LongId of(long id){ + return new LongId(id); + } + + public static LongId of (String stringRepresentation){ + return new LongId(Long.parseLong(stringRepresentation)); + } + + @Override + public Long unwrap() { + return id; + } + + @Override + public String toString() { + return ""+id; + } +} diff --git a/core/src/main/java/de/srsoftware/umbrella/core/model/Project.java b/core/src/main/java/de/srsoftware/umbrella/core/model/Project.java index 2fc8397..54f2429 100644 --- a/core/src/main/java/de/srsoftware/umbrella/core/model/Project.java +++ b/core/src/main/java/de/srsoftware/umbrella/core/model/Project.java @@ -7,6 +7,7 @@ import static de.srsoftware.umbrella.core.Util.mapMarkdown; import static de.srsoftware.umbrella.core.model.Status.PREDEFINED; import de.srsoftware.tools.Mappable; +import de.srsoftware.umbrella.core.api.EntityId; import java.sql.ResultSet; import java.sql.SQLException; import java.util.*; @@ -77,6 +78,9 @@ public class Project implements Mappable { return dirtyFields.contains(field); } + public EntityId entityId(){ + return new LongId(id); + } public Map members(){ return members; diff --git a/core/src/main/java/de/srsoftware/umbrella/core/model/Task.java b/core/src/main/java/de/srsoftware/umbrella/core/model/Task.java index a1f0591..b057d20 100644 --- a/core/src/main/java/de/srsoftware/umbrella/core/model/Task.java +++ b/core/src/main/java/de/srsoftware/umbrella/core/model/Task.java @@ -66,6 +66,10 @@ public class Task implements Mappable { return dueDate; } + public LongId entityId() { + return LongId.of(id); + } + public Double estimatedTime(){ return estimatedTime; } diff --git a/project/src/main/java/de/srsoftware/umbrella/project/ProjectModule.java b/project/src/main/java/de/srsoftware/umbrella/project/ProjectModule.java index 5895e9d..e5d1f22 100644 --- a/project/src/main/java/de/srsoftware/umbrella/project/ProjectModule.java +++ b/project/src/main/java/de/srsoftware/umbrella/project/ProjectModule.java @@ -265,7 +265,7 @@ public class ProjectModule extends BaseHandler implements ProjectService { if (json.has(TAGS) && json.get(TAGS) instanceof JSONArray arr){ var tagList = arr.toList().stream().filter(elem -> elem instanceof String).map(String.class::cast).toList(); - tags.save(PROJECT,prj.id(),null,tagList); + tags.save(PROJECT,prj.entityId(),null,tagList); } return sendContent(ex,prj); diff --git a/tags/src/main/java/de/srsoftware/umbrella/tags/SqliteDb.java b/tags/src/main/java/de/srsoftware/umbrella/tags/SqliteDb.java index c084d4c..7daf54d 100644 --- a/tags/src/main/java/de/srsoftware/umbrella/tags/SqliteDb.java +++ b/tags/src/main/java/de/srsoftware/umbrella/tags/SqliteDb.java @@ -14,6 +14,7 @@ import static java.lang.System.Logger.Level.INFO; import static java.text.MessageFormat.format; import de.srsoftware.tools.jdbc.Query; +import de.srsoftware.umbrella.core.api.EntityId; import de.srsoftware.umbrella.core.exceptions.UmbrellaException; import java.sql.Connection; import java.sql.SQLException; @@ -84,13 +85,13 @@ CREATE TABLE IF NOT EXISTS "{0}" ( } @Override - public String delete(long userId, String module, long entityId, String tag) { + public String delete(long userId, String module, EntityId entity, String tag) { try { Query.delete().from(TABLE_TAGS) - .where(TAG,equal(tag)).where(MODULE,equal(module)).where(ID,equal(entityId)).where(USER_ID,equal(userId)) + .where(TAG,equal(tag)).where(MODULE,equal(module)).where(ID,equal(entity.unwrap())).where(USER_ID,equal(userId)) .execute(db); Query.delete().from(TABLE_TAGS) - .where(TAG,equal(tag)).where(MODULE,equal(module)).where(ID,equal(entityId)).where(USER_ID,isNull()) + .where(TAG,equal(tag)).where(MODULE,equal(module)).where(ID,equal(entity.unwrap())).where(USER_ID,isNull()) .execute(db); return tag; } catch (SQLException e){ @@ -99,10 +100,10 @@ CREATE TABLE IF NOT EXISTS "{0}" ( } @Override - public void deleteEntity(String module, long entityId) { + public void deleteEntity(String module, EntityId entityId) { try { Query.delete().from(TABLE_TAGS) - .where(MODULE,equal(module)).where(ID,equal(entityId)) + .where(MODULE,equal(module)).where(ID,equal(entityId.unwrap())) .execute(db); } catch (SQLException e){ throw new UmbrellaException("Failed to save tags ({0} {1})",module,entityId); @@ -139,12 +140,12 @@ CREATE TABLE IF NOT EXISTS "{0}" ( } @Override - public Set list(long userId, String module, long entityId) { + public Set list(long userId, String module, EntityId entityId) { try { var tags = new HashSet(); - var rs = select(TAG).from(TABLE_TAGS).where(MODULE,equal(module)).where(ID,equal(entityId)).where(USER_ID,equal(userId)).exec(db); + var rs = select(TAG).from(TABLE_TAGS).where(MODULE,equal(module)).where(ID,equal(entityId.unwrap())).where(USER_ID,equal(userId)).exec(db); while (rs.next()) tags.add(rs.getString(1)); - rs = select(TAG).from(TABLE_TAGS).where(MODULE,equal(module)).where(ID,equal(entityId)).where(USER_ID,isNull()).exec(db); + rs = select(TAG).from(TABLE_TAGS).where(MODULE,equal(module)).where(ID,equal(entityId.unwrap())).where(USER_ID,isNull()).exec(db); while (rs.next()) tags.add(rs.getString(1)); rs.close(); return tags; @@ -154,14 +155,14 @@ CREATE TABLE IF NOT EXISTS "{0}" ( } @Override - public void save(Collection userIds, String module, long entityId, Collection tags) { + public void save(Collection userIds, String module, EntityId entityId, Collection tags) { try { var query = replaceInto(TABLE_TAGS,USER_ID,MODULE,ID,TAG); for (var tag : tags) { if (userIds == null) { // tags not assigned to a user are available to all users - query.values(null, module, entityId, tag); + query.values(null, module, entityId.unwrap(), tag); } else for (var userId : userIds) { - query.values(userId,module,entityId,tag); + query.values(userId,module,entityId.unwrap(),tag); } } query.execute(db).close(); diff --git a/tags/src/main/java/de/srsoftware/umbrella/tags/TagDB.java b/tags/src/main/java/de/srsoftware/umbrella/tags/TagDB.java index 56760ff..ca42129 100644 --- a/tags/src/main/java/de/srsoftware/umbrella/tags/TagDB.java +++ b/tags/src/main/java/de/srsoftware/umbrella/tags/TagDB.java @@ -1,19 +1,20 @@ /* © SRSoftware 2025 */ package de.srsoftware.umbrella.tags; +import de.srsoftware.umbrella.core.api.EntityId; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; public interface TagDB { - String delete(long userId, String module, long entityId, String tag); + String delete(long userId, String module, EntityId entityId, String tag); - void deleteEntity(String module, long entityId); + void deleteEntity(String module, EntityId entityId); - Map> getUses(String tag, long id); + Map> getUses(String tag, long userId); - Set list(long userId, String module, long entityId); + Set list(long userId, String module, EntityId entityId); - void save(Collection userIds, String module, long entityId, Collection tags); + void save(Collection userIds, String module, EntityId entityId, Collection tags); } diff --git a/tags/src/main/java/de/srsoftware/umbrella/tags/TagModule.java b/tags/src/main/java/de/srsoftware/umbrella/tags/TagModule.java index e1b4fcc..6152111 100644 --- a/tags/src/main/java/de/srsoftware/umbrella/tags/TagModule.java +++ b/tags/src/main/java/de/srsoftware/umbrella/tags/TagModule.java @@ -15,9 +15,11 @@ import de.srsoftware.configuration.Configuration; import de.srsoftware.tools.Path; import de.srsoftware.tools.SessionToken; import de.srsoftware.umbrella.core.BaseHandler; +import de.srsoftware.umbrella.core.api.EntityId; import de.srsoftware.umbrella.core.api.TagService; import de.srsoftware.umbrella.core.api.UserService; import de.srsoftware.umbrella.core.exceptions.UmbrellaException; +import de.srsoftware.umbrella.core.model.LongId; import de.srsoftware.umbrella.core.model.Token; import de.srsoftware.umbrella.core.model.UmbrellaUser; import java.io.IOException; @@ -35,7 +37,7 @@ public class TagModule extends BaseHandler implements TagService { } @Override - public void deleteEntity(String module, long entityId) { + public void deleteEntity(String module, EntityId entityId) { tagDb.deleteEntity(module,entityId); } @@ -49,7 +51,7 @@ public class TagModule extends BaseHandler implements TagService { var module = path.pop(); if (module == null) throw unprocessable("Module missing in path."); var head = path.pop(); - long entityId = Long.parseLong(head); + var entityId = LongId.of(head); var tag = tagDb.delete(user.get().id(),module,entityId,body(ex)); return sendContent(ex, tag); } catch (NumberFormatException e){ @@ -69,7 +71,7 @@ public class TagModule extends BaseHandler implements TagService { if (module == null) throw unprocessable("Module missing in path."); var head = path.pop(); if (USES.equals(module)) return getTagUses(ex,head,user.get()); - long entityId = Long.parseLong(head); + var entityId = LongId.of(head); return sendContent(ex, getTags(module,entityId,user.get())); } catch (NumberFormatException e){ return sendContent(ex,HTTP_UNPROCESSABLE,"Entity id missing in path."); @@ -98,7 +100,7 @@ public class TagModule extends BaseHandler implements TagService { var module = path.pop(); if (module == null) throw unprocessable("Module missing in path."); var head = path.pop(); - long entityId = Long.parseLong(head); + var entityId = LongId.of(head); var json = json(ex); if (!(json.has(TAG) && json.get(TAG) instanceof String tag)) throw missingFieldException(TAG); List userList = null; @@ -122,17 +124,17 @@ public class TagModule extends BaseHandler implements TagService { } } - public Collection getTags(String module, long entityId, UmbrellaUser user) throws UmbrellaException{ + public Collection getTags(String module, EntityId entityId, UmbrellaUser user) throws UmbrellaException{ return tagDb.list(user.id(),module,entityId); } @Override - public void save(String module, long entityId, Collection userIds, Collection tags) { + public void save(String module, EntityId entityId, Collection userIds, Collection tags) { tagDb.save(userIds,module,entityId,tags); } @Override - public String save(String module, long entityId, Collection userIds, String tag) { + public String save(String module, EntityId entityId, Collection userIds, String tag) { save(module,entityId,userIds,List.of(tag)); return tag; } diff --git a/task/src/main/java/de/srsoftware/umbrella/task/TaskModule.java b/task/src/main/java/de/srsoftware/umbrella/task/TaskModule.java index a50e034..a27d700 100644 --- a/task/src/main/java/de/srsoftware/umbrella/task/TaskModule.java +++ b/task/src/main/java/de/srsoftware/umbrella/task/TaskModule.java @@ -69,7 +69,7 @@ public class TaskModule extends BaseHandler implements TaskService { if (member == null || !member.mayWrite()) throw forbidden("You are not allowed to delete {0}",task.name()); taskDb.delete(task); notes.deleteEntity(TASK,taskId); - tags.deleteEntity(TASK,taskId); + tags.deleteEntity(TASK,LongId.of(taskId)); return sendContent(ex,Map.of(DELETED,taskId)); } @@ -328,7 +328,7 @@ public class TaskModule extends BaseHandler implements TaskService { } if (json.has(TAGS) && json.get(TAGS) instanceof JSONArray arr){ var tagList = arr.toList().stream().filter(e -> e instanceof String).map(String.class::cast).toList(); - tags.save(TASK,task.id(),null,tagList); + tags.save(TASK,task.entityId(),null,tagList); } return sendContent(ex,loadMembers(task)); }