From e614880d71bfc869739bbc83a126e252872f6494 Mon Sep 17 00:00:00 2001 From: Stephan Richter Date: Mon, 27 Jul 2026 09:22:50 +0200 Subject: [PATCH] refactoring objects in preparation for: refactoring journal database to contain object ids for: querying journal for objects --- .../umbrella/messagebus/events/Event.java | 15 +++++--- .../umbrella/messagebus/events/ItemEvent.java | 4 ++ .../messagebus/events/ProjectEvent.java | 5 +++ .../messagebus/events/TransactionEvent.java | 5 +++ .../umbrella/messagebus/events/WikiEvent.java | 4 ++ .../srsoftware/umbrella/core/model/Item.java | 37 +++++++------------ .../umbrella/core/model/ObjectWithId.java | 30 +++++++++++++++ .../umbrella/core/model/Project.java | 30 ++++++--------- .../umbrella/core/model/Transaction.java | 17 +++------ .../umbrella/core/model/WikiPage.java | 13 ++----- .../srsoftware/umbrella/journal/SqliteDb.java | 11 +++--- 11 files changed, 97 insertions(+), 74 deletions(-) create mode 100644 core/src/main/java/de/srsoftware/umbrella/core/model/ObjectWithId.java diff --git a/bus/src/main/java/de/srsoftware/umbrella/messagebus/events/Event.java b/bus/src/main/java/de/srsoftware/umbrella/messagebus/events/Event.java index 09b68d86..56a7650f 100644 --- a/bus/src/main/java/de/srsoftware/umbrella/messagebus/events/Event.java +++ b/bus/src/main/java/de/srsoftware/umbrella/messagebus/events/Event.java @@ -6,6 +6,7 @@ import static java.util.Optional.*; import de.srsoftware.tools.Diff; import de.srsoftware.tools.Mappable; +import de.srsoftware.umbrella.core.model.ObjectWithId; import de.srsoftware.umbrella.core.model.Translatable; import de.srsoftware.umbrella.core.model.UmbrellaUser; import java.util.Collection; @@ -14,15 +15,15 @@ import java.util.Map; import java.util.Optional; import org.json.JSONObject; -public abstract class Event { +public abstract class Event { public enum EventType { CREATE, MEMBER_ADDED, UPDATE, DELETE; - } + } private final UmbrellaUser initiator; private final String module; private final Payload payload; @@ -39,10 +40,10 @@ public abstract class Event { public Event(UmbrellaUser initiator, String module, Payload payload, Map oldData){ this.initiator = initiator; - this.module = module; - this.payload = payload; + this.module = module; + this.payload = payload; this.eventType = EventType.UPDATE; - this.oldData = oldData; + this.oldData = oldData; } public abstract Collection audience(); @@ -98,6 +99,10 @@ public abstract class Event { return module; } + public long objectId() { + return payload.id(); + }; + protected Map oldData() { return oldData; } diff --git a/bus/src/main/java/de/srsoftware/umbrella/messagebus/events/ItemEvent.java b/bus/src/main/java/de/srsoftware/umbrella/messagebus/events/ItemEvent.java index 9f886933..727582f8 100644 --- a/bus/src/main/java/de/srsoftware/umbrella/messagebus/events/ItemEvent.java +++ b/bus/src/main/java/de/srsoftware/umbrella/messagebus/events/ItemEvent.java @@ -36,6 +36,10 @@ public class ItemEvent extends Event{ return t("{user} added \"{item}\" to \"{location}\"", USER,initiator().name(), ITEM, payload().name(), LOCATION, loc); } + @Override + public long objectId() { + return payload().id(); + } @Override public Translatable subject() { diff --git a/bus/src/main/java/de/srsoftware/umbrella/messagebus/events/ProjectEvent.java b/bus/src/main/java/de/srsoftware/umbrella/messagebus/events/ProjectEvent.java index 78534b3a..0113f962 100644 --- a/bus/src/main/java/de/srsoftware/umbrella/messagebus/events/ProjectEvent.java +++ b/bus/src/main/java/de/srsoftware/umbrella/messagebus/events/ProjectEvent.java @@ -78,6 +78,11 @@ public class ProjectEvent extends Event{ return t("You can view/edit this project at {base_url}/project/{id}/view",ID,payload().id()); } + @Override + public long objectId() { + return payload().id(); + } + @Override public Translatable subject() { return switch (eventType()){ diff --git a/bus/src/main/java/de/srsoftware/umbrella/messagebus/events/TransactionEvent.java b/bus/src/main/java/de/srsoftware/umbrella/messagebus/events/TransactionEvent.java index ec30ea3c..00d9f7b4 100644 --- a/bus/src/main/java/de/srsoftware/umbrella/messagebus/events/TransactionEvent.java +++ b/bus/src/main/java/de/srsoftware/umbrella/messagebus/events/TransactionEvent.java @@ -62,6 +62,11 @@ public class TransactionEvent extends Event { return t("You can view/edit this transaction at {base_url}/account/{id}", ID, payload().accountId()); } + @Override + public long objectId() { + return payload().id(); + } + @Override public Translatable subject() { var user = initiator().name(); diff --git a/bus/src/main/java/de/srsoftware/umbrella/messagebus/events/WikiEvent.java b/bus/src/main/java/de/srsoftware/umbrella/messagebus/events/WikiEvent.java index 2a6c5b91..d4e9240c 100644 --- a/bus/src/main/java/de/srsoftware/umbrella/messagebus/events/WikiEvent.java +++ b/bus/src/main/java/de/srsoftware/umbrella/messagebus/events/WikiEvent.java @@ -68,6 +68,10 @@ public class WikiEvent extends Event{ return t("You can view/edit this wiki page at {base_url}/wiki/{id}/view",ID,payload().id()); } + @Override + public long objectId() { + return payload().id(); + } @Override public Translatable subject() { diff --git a/core/src/main/java/de/srsoftware/umbrella/core/model/Item.java b/core/src/main/java/de/srsoftware/umbrella/core/model/Item.java index e7fbc43e..657eedef 100644 --- a/core/src/main/java/de/srsoftware/umbrella/core/model/Item.java +++ b/core/src/main/java/de/srsoftware/umbrella/core/model/Item.java @@ -4,7 +4,6 @@ package de.srsoftware.umbrella.core.model; import static de.srsoftware.umbrella.core.Util.mapMarkdown; import static de.srsoftware.umbrella.core.constants.Field.*; -import de.srsoftware.tools.Mappable; import de.srsoftware.umbrella.core.api.Owner; import de.srsoftware.umbrella.core.constants.Field; import java.sql.ResultSet; @@ -12,16 +11,16 @@ import java.sql.SQLException; import java.util.*; import org.json.JSONObject; -public class Item implements Mappable { - private long id, ownerNumber; // id is the database key, number the owner-relative id - private Owner owner; +public class Item extends ObjectWithId { + private long ownerNumber; // id is the database key, number the owner-relative id + private final Owner owner; private String code, description, name; private Location location; - private Collection properties; - private Set dirtyFields = new HashSet<>(); + private final Collection properties; + private final Set dirtyFields = new HashSet<>(); public Item(long id, Owner owner, long ownerNumber, Location location, String code, String name, String description) { - this.id = id; + super(id); this.owner = owner; this.ownerNumber = ownerNumber; this.location = location; @@ -48,15 +47,6 @@ public class Item implements Mappable { return !dirtyFields.isEmpty(); } - public long id(){ - return id; - } - - public Item id(long newVal) { - id = newVal; - return this; - } - public Location location(){ return location; } @@ -121,14 +111,13 @@ public class Item implements Mappable { @Override public Map toMap() { - var map = new HashMap(); - map.put(OWNER,owner.toMap()); - map.put(ID,id); - map.put(LOCATION,location.toMap()); - map.put(Field.CODE,code); - map.put(NAME,name); - map.put(DESCRIPTION,mapMarkdown(description)); - map.put(OWNER_NUMBER,ownerNumber); + var map = super.map( + OWNER,owner.toMap(), + LOCATION,location.toMap(), + Field.CODE,code, + NAME,name, + DESCRIPTION,mapMarkdown(description), + OWNER_NUMBER,ownerNumber); if (properties != null) map.put(PROPERTIES,properties.stream().map(Property::toMap).toList()); return map; } diff --git a/core/src/main/java/de/srsoftware/umbrella/core/model/ObjectWithId.java b/core/src/main/java/de/srsoftware/umbrella/core/model/ObjectWithId.java new file mode 100644 index 00000000..9bb8fd18 --- /dev/null +++ b/core/src/main/java/de/srsoftware/umbrella/core/model/ObjectWithId.java @@ -0,0 +1,30 @@ +package de.srsoftware.umbrella.core.model; + +import de.srsoftware.tools.Mappable; +import de.srsoftware.umbrella.core.constants.Field; + +import java.security.InvalidParameterException; +import java.time.LocalDate; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public abstract class ObjectWithId implements Mappable { + private final long id; + + public ObjectWithId(long id){ + this.id = id; + } + + public long id(){ + return id; + } + + protected Map map(Object ... keysAndValues) { + if (keysAndValues.length % 2 != 0) throw new InvalidParameterException("Expected even number of keys and parameters!"); + var map = new HashMap(); + map.put(Field.ID,id); + for (var idx = 0; idx members; private final Collection allowedStates; private boolean showClosed; private Long companyId; private int status; private String name; - private final long id; private String description; private final Set dirtyFields = new HashSet<>(); private final Map tagColors = new HashMap<>(); public Project(long id, String name, String description, int status, Long companyId, boolean showClosed, Map members, Collection allowedStates) { - this.id = id; + super(id); this.name = name; this.description = description; this.status = status; @@ -67,10 +65,6 @@ public class Project implements Mappable { return members.containsKey(user.id()); } - public long id(){ - return id; - } - public boolean isDirty() { return !dirtyFields.isEmpty(); } @@ -126,23 +120,21 @@ public class Project implements Mappable { @Override public Map toMap() { - var map = new HashMap(); var memberMap = new HashMap>(); if (members != null) for (var entry : members.entrySet()){ memberMap.put(entry.getKey(),entry.getValue().toMap()); } - map.put(ID,id); - map.put(NAME,name); - map.put(DESCRIPTION,mapMarkdown(description)); - map.put(STATUS,status); - map.put(COMPANY_ID,companyId); - map.put(SHOW_CLOSED,showClosed); - map.put(MEMBERS,memberMap); var stateMap = new HashMap(); for (var state : allowedStates) stateMap.put(state.code(),state.name()); - map.put(Field.ALLOWED_STATES,stateMap); - map.put(TAG_COLORS,tagColors); - return map; + return super.map( + NAME,name, + DESCRIPTION,mapMarkdown(description), + STATUS,status, + COMPANY_ID,companyId, + SHOW_CLOSED,showClosed, + MEMBERS,memberMap, + Field.ALLOWED_STATES,stateMap, + TAG_COLORS,tagColors); } @Override diff --git a/core/src/main/java/de/srsoftware/umbrella/core/model/Transaction.java b/core/src/main/java/de/srsoftware/umbrella/core/model/Transaction.java index 45a29223..1fae3dd4 100644 --- a/core/src/main/java/de/srsoftware/umbrella/core/model/Transaction.java +++ b/core/src/main/java/de/srsoftware/umbrella/core/model/Transaction.java @@ -14,17 +14,17 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; -public class Transaction implements Mappable { - private long accountId, id; +public class Transaction extends ObjectWithId { + private final long accountId; private LocalDateTime date; private IdOrString source, destination; private double amount; private String purpose; - private Set tags; - private HashSet dirtyFields = new HashSet<>(); + private final Set tags; + private final HashSet dirtyFields = new HashSet<>(); public Transaction(long id, long accountId, LocalDateTime date, IdOrString source, IdOrString destination, double amount, String purpose, Set tags){ - this.id = id; + super(id); this.accountId = accountId; this.date = date; this.source = source; @@ -77,10 +77,6 @@ public class Transaction implements Mappable { return this; } - public long id(){ - return id; - } - public boolean isDirty(){ return !dirtyFields.isEmpty(); } @@ -123,8 +119,7 @@ public class Transaction implements Mappable { @Override public Map toMap() { - return Map.of( - Field.ID, id, + return super.map( Field.ACCOUNT, accountId, Field.DATE, date.toLocalDate(), Field.SOURCE, source.toMap(), diff --git a/core/src/main/java/de/srsoftware/umbrella/core/model/WikiPage.java b/core/src/main/java/de/srsoftware/umbrella/core/model/WikiPage.java index 745b3859..49c0b93d 100644 --- a/core/src/main/java/de/srsoftware/umbrella/core/model/WikiPage.java +++ b/core/src/main/java/de/srsoftware/umbrella/core/model/WikiPage.java @@ -10,16 +10,14 @@ import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.*; import static de.srsoftware.umbrella.core.model.Translatable.t; import static java.lang.String.join; -import de.srsoftware.tools.Mappable; import de.srsoftware.umbrella.core.api.UserService; import java.sql.ResultSet; import java.sql.SQLException; import java.util.*; import org.json.JSONObject; -public class WikiPage implements Mappable { +public class WikiPage extends ObjectWithId { - private final long id; private String title; private int version; private final Set versions = new TreeSet<>(); @@ -29,7 +27,7 @@ public class WikiPage implements Mappable { private boolean guestAllowed = false; public WikiPage(long id, String title, int version, String content) { - this.id = id; + super(id); this.version = version; this.content = content; this.title = title; @@ -60,10 +58,6 @@ public class WikiPage implements Mappable { dirtyFields.add(GUEST_ALLOWED); } - public long id(){ - return id; - } - public boolean isDirty(String field) { return dirtyFields.contains(field); } @@ -146,8 +140,7 @@ public class WikiPage implements Mappable { var memberMap = new HashMap>(); for (var entry : members.entrySet()) memberMap.put(entry.getKey(),entry.getValue().toMap()); - return Map.of( - ID,id, + return map( CONTENT,mapMarkdown(content), GUEST_ALLOWED,guestAllowed, MEMBERS,memberMap, diff --git a/journal/src/main/java/de/srsoftware/umbrella/journal/SqliteDb.java b/journal/src/main/java/de/srsoftware/umbrella/journal/SqliteDb.java index 77bfa0a0..785c0ce9 100644 --- a/journal/src/main/java/de/srsoftware/umbrella/journal/SqliteDb.java +++ b/journal/src/main/java/de/srsoftware/umbrella/journal/SqliteDb.java @@ -38,11 +38,12 @@ public class SqliteDb extends BaseDb implements JournalDb{ {2} LONG NOT NULL, {3} INTEGER, {4} VARCHAR(255) NOT NULL, - {5} VARCHAR(16) NOT NULL, - {6} TEXT + {5} VARCHAR(255), + {6} VARCHAR(16) NOT NULL, + {7} TEXT ); """; - sql = format(sql,TABLE_JOURNAL,ID,TIMESTAMP,USER_ID,MODULE,ACTION,DESCRIPTION); + sql = format(sql,TABLE_JOURNAL,ID,TIMESTAMP,USER_ID,MODULE,ENTITY_ID,ACTION,DESCRIPTION); try { db.prepareStatement(sql).execute(); } catch (SQLException e) { @@ -54,8 +55,8 @@ public class SqliteDb extends BaseDb implements JournalDb{ public void logEvent(Event event) { try { var timestamp = LocalDateTime.now().toEpochSecond(ZoneOffset.UTC); - insertInto(TABLE_JOURNAL,TIMESTAMP,USER_ID,MODULE,ACTION,DESCRIPTION) - .values(timestamp,event.initiator().id(), event.module(), event.eventType(), event.describe()) + insertInto(TABLE_JOURNAL,TIMESTAMP,USER_ID,MODULE,ENTITY_ID,ACTION,DESCRIPTION) + .values(timestamp,event.initiator().id(), event.module(), event.objectId(), event.eventType(), event.describe()) .execute(db).close(); } catch (SQLException e) { throw databaseException(ERROR_WRITE_EVENT,event.eventType(),event.initiator().name());