overhauling constants, working on translations

Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
2026-01-15 13:58:50 +01:00
parent 669853352e
commit 0d1cdd35d1
103 changed files with 2161 additions and 1207 deletions

View File

@@ -4,7 +4,6 @@ package de.srsoftware.umbrella.time;
public class Constants {
private Constants(){}
public static final String CHILDREN = "children";
public static final String CLOSED = "closed";
public static final String CONFIG_DATABASE = "umbrella.modules.time.database";
public static final String DOCUMENTS = "documents";
@@ -14,8 +13,6 @@ public class Constants {
public static final String TABLE_TASK_TIMES = "task_times";
public static final String TABLE_TIMES = "times";
public static final String TASK_ID = "task_id";
public static final String TASKS = "tasks";
public static final String TIME_ID = "time_id";
public static final String TIMES = "times";
public static final String TRACK_TASK = "track_task";

View File

@@ -4,10 +4,13 @@ package de.srsoftware.umbrella.time;
import static de.srsoftware.tools.jdbc.Condition.*;
import static de.srsoftware.tools.jdbc.Query.*;
import static de.srsoftware.tools.jdbc.Query.SelectQuery.ALL;
import static de.srsoftware.umbrella.core.Constants.*;
import static de.srsoftware.umbrella.core.Errors.*;
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.databaseException;
import static de.srsoftware.umbrella.core.constants.Field.*;
import static de.srsoftware.umbrella.core.constants.Field.TIME_ID;
import static de.srsoftware.umbrella.core.constants.Text.TIME_WITH_ID;
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.*;
import static de.srsoftware.umbrella.core.model.Time.State.Complete;
import static de.srsoftware.umbrella.core.model.Translatable.t;
import static de.srsoftware.umbrella.time.Constants.*;
import static java.text.MessageFormat.format;
@@ -50,7 +53,7 @@ CREATE TABLE IF NOT EXISTS {0} (
stmt.execute();
stmt.close();
} catch (SQLException e) {
throw databaseException(FAILED_TO_CREATE_TABLE,TABLE_TASK_TIMES).causedBy(e);
throw failedToCreateTable(TABLE_TASK_TIMES).causedBy(e);
}
}
@@ -65,13 +68,13 @@ CREATE TABLE IF NOT EXISTS {0} (
{6} TIMESTAMP,
{7} INT NOT NULL DEFAULT {8}
)""";
sql = format(sql,TABLE_TIMES,ID,USER_ID,SUBJECT,DESCRIPTION,START_TIME,END_TIME,STATE, Time.State.Started.code());
sql = format(sql,TABLE_TIMES, ID, USER_ID, SUBJECT, DESCRIPTION,START_TIME, END_TIME, STATE, Time.State.Started.code());
try {
var stmt = db.prepareStatement(sql);
stmt.execute();
stmt.close();
} catch (SQLException e) {
throw databaseException(FAILED_TO_CREATE_TABLE,TABLE_TIMES).causedBy(e);
throw failedToCreateTable(TABLE_TIMES).causedBy(e);
}
}
@@ -84,7 +87,7 @@ CREATE TABLE IF NOT EXISTS {0} (
db.setAutoCommit(false);
return timeId;
} catch (SQLException e) {
throw databaseException(FAILED_TO_DROP_ENTITY,"time "+timeId).causedBy(e);
throw failedToDropObject(t(TIME_WITH_ID, ID,timeId)).causedBy(e);
}
}
@@ -93,7 +96,7 @@ CREATE TABLE IF NOT EXISTS {0} (
try {
var query = select(ALL).from(TABLE_TIMES).where(USER_ID,equal(userId));
if (fulltext) {
for (var key : keys) query.where(format("CONCAT({0},\" \",{1})",SUBJECT,DESCRIPTION),like("%"+key+"%"));
for (var key : keys) query.where(format("CONCAT({0},\" \",{1})", SUBJECT, DESCRIPTION),like("%"+key+"%"));
} else {
for (var key : keys) query.where(SUBJECT,like("%"+key+"%"));
}
@@ -106,7 +109,7 @@ CREATE TABLE IF NOT EXISTS {0} (
rs.close();
return times;
} catch (Exception e) {
throw databaseException(FAILED_TO_SEARCH_DB,TABLE_TIMES).causedBy(e);
throw failedToSearchDb(t(TIMES)).causedBy(e);
}
}
@@ -133,7 +136,7 @@ CREATE TABLE IF NOT EXISTS {0} (
rs.close();
return times;
} catch (Exception e) {
throw databaseException(FAILED_TO_LIST_ENTITIES,TIMES).causedBy(e);
throw databaseException(FAILED_TO_LIST_ENTITIES, TYPE,TIMES).causedBy(e);
}
}
@@ -157,7 +160,7 @@ CREATE TABLE IF NOT EXISTS {0} (
rs.close();
return times;
} catch (SQLException e) {
throw databaseException(FAILED_TO_LIST_ENTITIES,TIMES).causedBy(e);
throw databaseException(FAILED_TO_LIST_ENTITIES, TYPE,TIMES).causedBy(e);
}
}
@@ -172,10 +175,10 @@ CREATE TABLE IF NOT EXISTS {0} (
rs = select(ALL).from(TABLE_TASK_TIMES).where(TIME_ID,equal(timeId)).exec(db);
while (rs.next()) time.taskIds().add(rs.getLong(TASK_ID));
rs.close();
if (time == null) throw UmbrellaException.notFound("No time found with id = {0}",timeId);
if (time == null) throw notFound("No time found with id = {id}", ID,timeId);
return time;
} catch (SQLException e) {
throw databaseException(FAILED_TO_LIST_ENTITIES,TIMES).causedBy(e);
throw databaseException(FAILED_TO_LIST_ENTITIES, TYPE,TIMES).causedBy(e);
}
}
@@ -199,7 +202,7 @@ CREATE TABLE IF NOT EXISTS {0} (
query.execute(db).close();
return track;
} catch (SQLException e){
throw databaseException(FAILED_TO_STORE_ENTITY,"time").causedBy(e);
throw failedToStoreObject("time").causedBy(e);
}
}
@@ -213,7 +216,7 @@ CREATE TABLE IF NOT EXISTS {0} (
.apply(timeState.code())
.close();
} catch (SQLException e) {
throw databaseException(FAILED_TO_UPDATE_ENTITY,TIMES).causedBy(e);
throw databaseException(FAILED_TO_UPDATE_OBJECT, OBJECT,TIMES).causedBy(e);
}
}
}

View File

@@ -2,13 +2,17 @@
package de.srsoftware.umbrella.time;
import static de.srsoftware.umbrella.core.ConnectionProvider.connect;
import static de.srsoftware.umbrella.core.Constants.*;
import static de.srsoftware.umbrella.core.Errors.FAILED_TO_LOAD_OBJECT_BY_ID;
import static de.srsoftware.umbrella.core.ModuleRegistry.*;
import static de.srsoftware.umbrella.core.Paths.*;
import static de.srsoftware.umbrella.core.Util.mapValues;
import static de.srsoftware.umbrella.core.constants.Field.*;
import static de.srsoftware.umbrella.core.constants.Field.TASKS;
import static de.srsoftware.umbrella.core.constants.Path.*;
import static de.srsoftware.umbrella.core.constants.Text.TIME_WITH_ID;
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.*;
import static de.srsoftware.umbrella.core.model.Time.State.Open;
import static de.srsoftware.umbrella.core.model.Time.State.Started;
import static de.srsoftware.umbrella.core.model.Translatable.t;
import static de.srsoftware.umbrella.time.Constants.*;
import com.sun.net.httpserver.HttpExchange;
@@ -18,6 +22,7 @@ import de.srsoftware.tools.SessionToken;
import de.srsoftware.umbrella.core.BaseHandler;
import de.srsoftware.umbrella.core.ModuleRegistry;
import de.srsoftware.umbrella.core.api.*;
import de.srsoftware.umbrella.core.constants.Text;
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
import de.srsoftware.umbrella.core.model.*;
import java.io.IOException;
@@ -31,7 +36,7 @@ public class TimeModule extends BaseHandler implements TimeService {
public TimeModule( Configuration config) throws UmbrellaException {
super();
var dbFile = config.get(CONFIG_DATABASE).orElseThrow(() -> missingFieldException(CONFIG_DATABASE));
var dbFile = config.get(CONFIG_DATABASE).orElseThrow(() -> missingField(CONFIG_DATABASE));
timeDb = new SqliteDb(connect(dbFile));
ModuleRegistry.add(this);
}
@@ -59,7 +64,7 @@ public class TimeModule extends BaseHandler implements TimeService {
var timeId = Long.parseLong(head);
return deleteTime(user.get(),timeId,ex);
} catch (NumberFormatException e){
return send(ex,invalidFieldException(TIME_ID,"long value"));
return send(ex,invalidField(TIME_ID,"long value"));
} catch (UmbrellaException e){
return send(ex,e);
}
@@ -98,7 +103,7 @@ public class TimeModule extends BaseHandler implements TimeService {
var timeId = Long.parseLong(head);
return patchTime(user.get(), timeId, ex);
} catch (NumberFormatException e) {
return send(ex, invalidFieldException(TIME_ID, "long value"));
return send(ex, invalidField(TIME_ID, "long value"));
}
} catch (UmbrellaException e){
return send(ex,e);
@@ -143,10 +148,10 @@ public class TimeModule extends BaseHandler implements TimeService {
throw unprocessable("Expected two time ids as body");
}
var time1 = timeDb.load(id1);
if (time1.userId() != user.id()) throw forbidden("You are not owner of time {0}",time1.id());
if (time1.userId() != user.id()) throw notAmember(t(TIME_WITH_ID, ID, time1.id()));
if (time1.state() != Open) throw forbidden("Time is not editable");
var time2 = timeDb.load(id2);
if (time2.userId() != user.id()) throw forbidden("You are not owner of time {0}",time2.id());
if (time2.userId() != user.id()) throw forbidden("You are not owner of time {id}", ID,time2.id());
if (time2.state() != Open) throw forbidden("Time is not editable");
if (time1.start() > time2.start()) {
@@ -196,16 +201,16 @@ public class TimeModule extends BaseHandler implements TimeService {
private boolean getStartedTime(UmbrellaUser user, HttpExchange ex) throws IOException {
var startedTime = getStartedTime(user);
if (startedTime.isPresent()) return sendContent(ex,startedTime.get());
return send(ex,UmbrellaException.notFound("no started time"));
return send(ex, UmbrellaException.notFound("no started time"));
}
private boolean listTimes(HttpExchange ex, UmbrellaUser user) throws IOException, UmbrellaException {
var json = json(ex);
if (!(json.has(COMPANY_ID) && json.get(COMPANY_ID) instanceof Number cid)) throw missingFieldException(COMPANY_ID);
if (!(json.has(COMPANY_ID) && json.get(COMPANY_ID) instanceof Number cid)) throw missingField(COMPANY_ID);
var companyId = cid.longValue();
var company = companyService().get(companyId);
if (!companyService().membership(companyId,user.id())) throw forbidden("You are mot a member of company {0}",company.name());
if (!(json.has(PROJECT_ID) && json.get(PROJECT_ID) instanceof Number pid)) throw missingFieldException(PROJECT_ID);
if (!companyService().membership(companyId,user.id())) throw notAmember(company.name());
if (!(json.has(PROJECT_ID) && json.get(PROJECT_ID) instanceof Number pid)) throw missingField(PROJECT_ID);
long projectId = pid.longValue();
Map<Long,Task> tasksOfProject = taskService().listProjectTasks(projectId);
@@ -235,12 +240,12 @@ public class TimeModule extends BaseHandler implements TimeService {
private boolean patchTimes(UmbrellaUser user, HttpExchange ex) throws IOException {
var json = json(ex);
if (!json.has(IDS) || !(json.get(IDS) instanceof JSONArray ids)) throw missingFieldException(IDS);
if (!json.has(IDS) || !(json.get(IDS) instanceof JSONArray ids)) throw missingField(IDS);
var times = new HashSet<Time>();
for (var o : ids.toList()){
if (!(o instanceof Number id)) throw unprocessable("IDS list contains {0}, which is not a valid ID!",o);
if (!(o instanceof Number id)) throw unprocessable("IDS list contains {object}, which is not a valid ID!", OBJECT,o);
var time = timeDb.load(id.longValue());
if (!accessible(time,user)) throw forbidden("Time list contains id ({0}) of time ({1}) which you are not allowed to edit!",o,time.subject());
if (!accessible(time,user)) throw forbidden("Time list contains id ({id}) of time ({object}) which you are not allowed to edit!", ID,o, OBJECT,time.subject());
times.add(time);
}
for (var time : times) timeDb.save(time.patch(json));
@@ -249,7 +254,7 @@ public class TimeModule extends BaseHandler implements TimeService {
private boolean postSearch(HttpExchange ex, UmbrellaUser user) throws IOException {
var json = json(ex);
if (!(json.has(KEY) && json.get(KEY) instanceof String key)) throw missingFieldException(KEY);
if (!(json.has(KEY) && json.get(KEY) instanceof String key)) throw missingField(KEY);
var keys = Arrays.asList(key.split(" "));
var fulltext = json.has(FULLTEXT) && json.get(FULLTEXT) instanceof Boolean val && val;
var notes = timeDb.find(user.id(),keys,fulltext);
@@ -283,14 +288,14 @@ public class TimeModule extends BaseHandler implements TimeService {
}
private boolean trackTask(UmbrellaUser user, Path path, HttpExchange ex) throws IOException {
if (path.empty()) throw missingFieldException(TASK_ID);
if (path.empty()) throw missingField(TASK_ID);
Task task;
try {
var taskId = Long.parseLong(path.pop());
task = taskService().load(List.of(taskId)).get(taskId);
if (task == null) throw UmbrellaException.notFound("Failed to load task with id = {0}",taskId);
if (task == null) throw UmbrellaException.notFound(FAILED_TO_LOAD_OBJECT_BY_ID, OBJECT,t(Text.TASK), ID,taskId);
} catch (NumberFormatException e) {
throw invalidFieldException(TASK_ID,"long value");
throw invalidField(TASK_ID,"long value");
}
long now;