introduced ModuleRegistry to easy inter-module dependencies

This commit is contained in:
2025-08-09 13:43:10 +02:00
parent 1d569b4962
commit 5d506ac0f9
25 changed files with 347 additions and 255 deletions

View File

@@ -42,10 +42,8 @@ import de.srsoftware.tools.Path;
import de.srsoftware.tools.SessionToken;
import de.srsoftware.tools.Tuple;
import de.srsoftware.umbrella.core.BaseHandler;
import de.srsoftware.umbrella.core.api.CompanyService;
import de.srsoftware.umbrella.core.api.PostBox;
import de.srsoftware.umbrella.core.api.Translator;
import de.srsoftware.umbrella.core.api.UserService;
import de.srsoftware.umbrella.core.ModuleRegistry;
import de.srsoftware.umbrella.core.api.*;
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
import de.srsoftware.umbrella.core.model.*;
import de.srsoftware.umbrella.documents.model.*;
@@ -61,32 +59,26 @@ import java.util.stream.Stream;
import org.json.JSONArray;
import org.json.JSONObject;
public class DocumentApi extends BaseHandler {
public class DocumentApi extends BaseHandler implements DocumentService {
private static final Predicate<de.srsoftware.document.api.Document> ZUGFERD_FILTER = document -> document.id().equals("Zugferd");
private final DocumentRegistry registry = new DocumentRegistry();
private final CompanyService companies;
private final Configuration config;
private final DocumentDb db;
private final UserService users;
private final Translator translator;
private final PostBox messages;
private final ModuleRegistry modules;
public DocumentApi(CompanyService companyService, Translator translator, Configuration config) throws UmbrellaException {
public DocumentApi(ModuleRegistry registry, Configuration config) throws UmbrellaException {
this.config = config;
this.translator = translator;
var dbFile = config.get(CONFIG_DATABASE).orElseThrow(() -> missingFieldException(CONFIG_DATABASE));
db = new SqliteDb(connect(dbFile));
companies = companyService;
users = companyService.userService();
messages = users.postBox();
modules = registry.add(this);
Optional<String> templates = config.get(CONFIG_TEMPLATES);
if (templates.isEmpty()) throw missingFieldException(CONFIG_TEMPLATES);
registry.add(new DocumentDirectory(new File(templates.get())));
registry.add(new TemplateProcessor(), new LatexFactory(), new WeasyFactory(), new ZugferdFactory());
this.registry.add(new DocumentDirectory(new File(templates.get())));
this.registry.add(new TemplateProcessor(), new LatexFactory(), new WeasyFactory(), new ZugferdFactory());
registry.documents().forEach(d -> LOG.log(DEBUG,"found template: {0}",d));
this.registry.documents().forEach(d -> LOG.log(DEBUG,"found template: {0}",d));
}
@Override
@@ -94,7 +86,7 @@ public class DocumentApi extends BaseHandler {
addCors(ex);
try {
Optional<Token> token = SessionToken.from(ex).map(Token::of);
var user = users.loadUser(token);
var user = modules.userService().loadUser(token);
if (user.isEmpty()) return unauthorized(ex);
var head = path.pop();
long docId = Long.parseLong(head);
@@ -113,7 +105,7 @@ public class DocumentApi extends BaseHandler {
private boolean deleteDocument(HttpExchange ex, long docId, UmbrellaUser user) throws IOException, UmbrellaException {
var doc = db.loadDoc(docId);
var companyId = doc.companyId();
if (!companies.membership(companyId,user.id())) throw forbidden("You are mot a member of company {0}",doc.companyId());
if (!modules.companyService().membership(companyId,user.id())) throw forbidden("You are mot a member of company {0}",doc.companyId());
if (doc.state() != NEW) throw new UmbrellaException(HTTP_BAD_REQUEST,"This document has already been sent");
return sendContent(ex,db.deleteDoc(docId));
}
@@ -121,7 +113,7 @@ public class DocumentApi extends BaseHandler {
private boolean deletePosition(HttpExchange ex, long docId, UmbrellaUser user) throws UmbrellaException, IOException {
var doc = db.loadDoc(docId);
var companyId = doc.companyId();
if (!companies.membership(companyId,user.id())) throw forbidden("You are mot a member of company {0}",doc.companyId());
if (!modules.companyService().membership(companyId,user.id())) throw forbidden("You are mot a member of company {0}",doc.companyId());
if (doc.state() != NEW) throw new UmbrellaException(HTTP_BAD_REQUEST,"This document has already been sent");
var json = json(ex);
if (!(json.has(POSITION) && json.get(POSITION) instanceof Number number)) throw missingFieldException(POSITION);
@@ -134,7 +126,7 @@ public class DocumentApi extends BaseHandler {
addCors(ex);
try {
Optional<Token> token = SessionToken.from(ex).map(Token::of);
var user = users.loadUser(token);
var user = modules.userService().loadUser(token);
if (user.isEmpty()) return unauthorized(ex);
var head = path.pop();
return switch (head){
@@ -165,7 +157,7 @@ public class DocumentApi extends BaseHandler {
addCors(ex);
try {
Optional<Token> token = SessionToken.from(ex).map(Token::of);
var user = users.loadUser(token);
var user = modules.userService().loadUser(token);
if (user.isEmpty()) return unauthorized(ex);
var head = path.pop();
var docId = Long.parseLong(head);
@@ -187,7 +179,7 @@ public class DocumentApi extends BaseHandler {
addCors(ex);
try {
Optional<Token> token = SessionToken.from(ex).map(Token::of);
var user = users.loadUser(token);
var user = modules.userService().loadUser(token);
if (user.isEmpty()) return unauthorized(ex);
var head = path.pop();
return switch (head){
@@ -219,7 +211,7 @@ public class DocumentApi extends BaseHandler {
var attachment = new Attachment(doc.number()+".pdf",rendered.mimeType(),rendered.bytes());
var message = new Message(user,subject,content,null,List.of(attachment));
var envelope = new Envelope(message,new User(doc.customer().shortName(),new EmailAddress(email),doc.customer().language()));
messages.send(envelope);
modules.postBox().send(envelope);
db.save(doc.set(SENT));
return ok(ex);
}
@@ -244,8 +236,8 @@ public class DocumentApi extends BaseHandler {
private Tuple<Document,Company> getDocument(long docId, UmbrellaUser user) throws UmbrellaException {
var doc = db.loadDoc(docId);
var companyId = doc.companyId();
var company = companies.get(companyId);
if (!companies.membership(companyId,user.id())) throw forbidden("You are mot a member of company {0}",company.name());
var company = modules.companyService().get(companyId);
if (!modules.companyService().membership(companyId,user.id())) throw forbidden("You are mot a member of company {0}",company.name());
return Tuple.of(doc,company);
}
@@ -364,7 +356,7 @@ public class DocumentApi extends BaseHandler {
.filter(filter)
.findAny();
if (optDoc.isEmpty()) throw UmbrellaException.notFound("Cannot render {0} {1}: Missing template \"{2}\"",type,document.number(),template);
Function<String,String> translate = text -> translator.translate(user.language(),text);
Function<String,String> translate = text -> modules.translator().translate(user.language(),text);
var pdfData = new HashMap<String,Object>();
pdfData.put(FIELD_DOCUMENT,document.renderToMap());
pdfData.put("translate",translate);
@@ -413,8 +405,8 @@ public class DocumentApi extends BaseHandler {
var json = json(ex);
if (!json.has(COMPANY)) throw missingFieldException(COMPANY);
long companyId = json.getLong(COMPANY);
var company = companies.get(companyId);
if (!companies.membership(companyId,user.id())) throw forbidden("You are mot a member of company {0}",company);
var company = modules.companyService().get(companyId);
if (!modules.companyService().membership(companyId,user.id())) throw forbidden("You are mot a member of company {0}",company);
var docs = db.listDocs(companyId);
var map = new HashMap<Long,Object>();
for (var entry : docs.entrySet()) map.put(entry.getKey(),entry.getValue().summary());
@@ -459,8 +451,8 @@ public class DocumentApi extends BaseHandler {
if (!(json.has(SENDER) && json.get(SENDER) instanceof JSONObject senderData)) throw missingFieldException(SENDER);
if (!senderData.has(FIELD_COMPANY) || !(senderData.get(FIELD_COMPANY) instanceof Number companyId)) throw missingFieldException(FIELD_COMPANY);
var company = companies.get(companyId.longValue());
if (!companies.membership(companyId.longValue(),user.id())) throw forbidden("You are mot a member of company {0}",company);
var company = modules.companyService().get(companyId.longValue());
if (!modules.companyService().membership(companyId.longValue(),user.id())) throw forbidden("You are mot a member of company {0}",company);
if (!json.has(FIELD_CUSTOMER) || !(json.get(FIELD_CUSTOMER) instanceof JSONObject customerData)) throw missingFieldException(FIELD_CUSTOMER);
if (!json.has(FIELD_TYPE) || !(json.get(FIELD_TYPE) instanceof Number docTypeId)) throw missingFieldException(FIELD_TYPE);
@@ -506,8 +498,8 @@ public class DocumentApi extends BaseHandler {
private boolean postTemplateList(HttpExchange ex, UmbrellaUser user) throws UmbrellaException, IOException {
var json = json(ex);
if (!(json.has(COMPANY) && json.get(COMPANY) instanceof Number companyId)) throw missingFieldException(COMPANY);
var company = companies.get(companyId.longValue());
if (!companies.membership(companyId.longValue(),user.id())) throw forbidden("You are not a member of {0}",company.name());
var company = modules.companyService().get(companyId.longValue());
if (!modules.companyService().membership(companyId.longValue(),user.id())) throw forbidden("You are not a member of {0}",company.name());
var templates = db.getCompanyTemplates(companyId.longValue());
return sendContent(ex,templates.stream().map(Template::toMap));
}