From cd931b12b3e57524c6336819c28422331de75f34 Mon Sep 17 00:00:00 2001 From: Maximilian Steinert <71747937+iradraconis@users.noreply.github.com> Date: Sat, 26 Oct 2024 14:16:09 +0200 Subject: [PATCH 1/8] adds endpoint for retrieving email-templates incl. placeholders completes #2055 --- .../io/rest/v6/TemplatesEndpointLocalV6.java | 4 +- .../io/rest/v6/TemplatesEndpointV6.java | 113 +++++++++++++++++- .../jlawyer/services/SystemManagement.java | 51 +++++++- .../services/SystemManagementLocal.java | 7 ++ 4 files changed, 169 insertions(+), 6 deletions(-) diff --git a/j-lawyer-server/j-lawyer-io/src/java/org/jlawyer/io/rest/v6/TemplatesEndpointLocalV6.java b/j-lawyer-server/j-lawyer-io/src/java/org/jlawyer/io/rest/v6/TemplatesEndpointLocalV6.java index 6ae5a1408..95571ce23 100644 --- a/j-lawyer-server/j-lawyer-io/src/java/org/jlawyer/io/rest/v6/TemplatesEndpointLocalV6.java +++ b/j-lawyer-server/j-lawyer-io/src/java/org/jlawyer/io/rest/v6/TemplatesEndpointLocalV6.java @@ -664,6 +664,7 @@ You should also get your employer (if you work as a programmer) or school, package org.jlawyer.io.rest.v6; import java.util.List; +import java.util.Map; import javax.ejb.Local; import javax.ws.rs.core.Response; import org.jlawyer.io.rest.v6.pojo.RestfulPlaceholderV6; @@ -682,5 +683,6 @@ public interface TemplatesEndpointLocalV6 { Response getPlaceHoldersForTemplate(String folder, String template, String caseId); Response addDocumentFromTemplate(String caseId, String fileName, String templateFolder, String template, List placeHolderValues) throws Exception; - + + Response getEmailTemplates(String caseId); } diff --git a/j-lawyer-server/j-lawyer-io/src/java/org/jlawyer/io/rest/v6/TemplatesEndpointV6.java b/j-lawyer-server/j-lawyer-io/src/java/org/jlawyer/io/rest/v6/TemplatesEndpointV6.java index 3af11dc7f..5d4df881f 100644 --- a/j-lawyer-server/j-lawyer-io/src/java/org/jlawyer/io/rest/v6/TemplatesEndpointV6.java +++ b/j-lawyer-server/j-lawyer-io/src/java/org/jlawyer/io/rest/v6/TemplatesEndpointV6.java @@ -674,7 +674,9 @@ You should also get your employer (if you work as a programmer) or school, import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import javax.annotation.security.RolesAllowed; import javax.ejb.Stateless; import javax.naming.InitialContext; @@ -690,7 +692,12 @@ You should also get your employer (if you work as a programmer) or school, import org.jlawyer.data.tree.GenericNode; import org.jlawyer.io.rest.v1.pojo.RestfulDocumentV1; import org.jlawyer.io.rest.v6.pojo.RestfulPlaceholderV6; - +import java.io.ByteArrayInputStream; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.xml.parsers.DocumentBuilderFactory; +import org.w3c.dom.Document; /** * * http://localhost:8080/j-lawyer-io/rest/cases/list @@ -904,4 +911,108 @@ public Response addDocumentFromTemplate(@PathParam("caseId") String caseId, @Pat } } + @Override + @GET + @Path("email/{caseId}") + @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8") + @RolesAllowed({"loginRole"}) + public Response getEmailTemplates(@PathParam("caseId") String caseId) { + try { + InitialContext ic = new InitialContext(); + SystemManagementLocal system = (SystemManagementLocal) ic.lookup(LOOKUP_SYSMAN); + ArchiveFileServiceLocal caseService = (ArchiveFileServiceLocal) ic.lookup(LOOKUP_CASESVC); + + ArchiveFileBean aFile = caseService.getArchiveFile(caseId); + if (aFile == null) { + log.error("Case not found: " + caseId); + return Response.status(Response.Status.NOT_FOUND) + .entity("Case not found: " + caseId) + .build(); + } + + List templates = system.getTemplatesByPath(SystemManagementLocal.TEMPLATE_TYPE_EMAIL, "/"); + List> resultList = new ArrayList<>(); + + // Get case parties + List parties = new ArrayList<>(); + List addresses = caseService.getInvolvementDetailsForCase(caseId); + for (ArchiveFileAddressesBean aab : addresses) { + parties.add(new PartiesTriplet(aab.getAddressKey(), aab.getReferenceType(), aab)); + } + + for (String templateName : templates) { + Map template = new LinkedHashMap<>(); + template.put("name", templateName); + + try { + String content = system.getTemplateContent(SystemManagementLocal.TEMPLATE_TYPE_EMAIL, "/", templateName); + + // XML parsen + Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder() + .parse(new ByteArrayInputStream(content.getBytes("UTF-8"))); + + // Subject und Body CDATA extrahieren + String subject = doc.getElementsByTagName("subject").item(0).getTextContent(); + String body = doc.getElementsByTagName("body").item(0).getTextContent(); + + // Originale Version speichern + template.put("originalSubject", subject.trim()); + template.put("originalBody", body); + + // Platzhalter aus Subject und Body sammeln + Set placeholders = new HashSet<>(); + Matcher m = Pattern.compile("\\{\\{([^}]+)\\}\\}").matcher(subject + body); + while (m.find()) { + placeholders.add(m.group(1)); + } + + // Platzhalter-Map erstellen und füllen + HashMap placeholderMap = new HashMap<>(); + for (String placeholder : placeholders) { + placeholderMap.put("{{" + placeholder + "}}", ""); + } + + // Platzhalter mit Werten füllen + placeholderMap = system.getPlaceHolderValues( + placeholderMap, aFile, parties, "", null, new HashMap<>(), + system.getUser(aFile.getLawyer()), + system.getUser(aFile.getAssistant()), + null, null, null, null, null, null, null + ); + + // Platzhalter-Werte-Map erstellen + Map placeholderValues = new LinkedHashMap<>(); + for (String placeholder : placeholders) { + String fullPlaceholder = "{{" + placeholder + "}}"; + Object value = placeholderMap.get(fullPlaceholder); + placeholderValues.put(placeholder, value != null ? value.toString() : ""); + } + template.put("placeholderValues", placeholderValues); + + // Platzhalter ersetzen + for (Map.Entry entry : placeholderMap.entrySet()) { + if (entry.getValue() != null) { + subject = subject.replace(entry.getKey(), entry.getValue().toString()); + body = body.replace(entry.getKey(), entry.getValue().toString()); + } + } + + template.put("subject", subject.trim()); + template.put("body", body); + + } catch (Exception e) { + log.error("Error processing template " + templateName, e); + template.put("error", e.getMessage()); + } + + resultList.add(template); + } + + return Response.ok(resultList).build(); + + } catch (Exception ex) { + log.error("Cannot get email templates for case " + caseId, ex); + return Response.serverError().build(); + } + } } diff --git a/j-lawyer-server/j-lawyer-server-ejb/src/java/com/jdimension/jlawyer/services/SystemManagement.java b/j-lawyer-server/j-lawyer-server-ejb/src/java/com/jdimension/jlawyer/services/SystemManagement.java index fc37c96e5..2fa57f1b1 100644 --- a/j-lawyer-server/j-lawyer-server-ejb/src/java/com/jdimension/jlawyer/services/SystemManagement.java +++ b/j-lawyer-server/j-lawyer-server-ejb/src/java/com/jdimension/jlawyer/services/SystemManagement.java @@ -700,6 +700,7 @@ import java.util.HashMap; import java.util.Hashtable; import java.util.List; +import java.util.Map; import java.util.Properties; import javax.annotation.Resource; import javax.annotation.security.PermitAll; @@ -995,10 +996,13 @@ public void removeOptionGroup(String id) { } private String getTypedFolderName(int templateType) { - if (templateType == SystemManagementRemote.TEMPLATE_TYPE_HEAD) { - return "letterheads"; - } else { - return "templates"; + switch(templateType) { + case SystemManagementLocal.TEMPLATE_TYPE_HEAD: + return "letterheads"; + case SystemManagementLocal.TEMPLATE_TYPE_EMAIL: + return "emailtemplates"; + default: + return "templates"; } } @@ -2548,5 +2552,44 @@ public List importSheets(byte[] odsData, List sheetNames return importer.importSheets(sheetNames, dryRun); } + + // eMail Templates + @Override + public String getTemplateContent(int templateType, String folder, String templateName) throws Exception { + String localBaseDir = this.getTemplatesBaseDir(templateType, folder); + String templatePath = localBaseDir + File.separator + templateName; + + File templateFile = new File(templatePath); + if (!templateFile.exists()) { + throw new Exception("Template not found: " + templatePath); + } + + return new String(ServerFileUtils.readFile(templateFile), "UTF-8"); + } + + @Override + public String fillPlaceholdersInContent(String content, HashMap placeholders) throws Exception { + if (content == null || placeholders == null) { + return content; + } + String result = content; + for (Map.Entry entry : placeholders.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue(); + + if (value != null) { + if (!key.startsWith("{{")) { + key = "{{" + key; + } + if (!key.endsWith("}}")) { + key = key + "}}"; + } + + result = result.replace(key, value.toString()); + } + } + + return result; + } } diff --git a/j-lawyer-server/j-lawyer-server-ejb/src/java/com/jdimension/jlawyer/services/SystemManagementLocal.java b/j-lawyer-server/j-lawyer-server-ejb/src/java/com/jdimension/jlawyer/services/SystemManagementLocal.java index d2c2c730d..4ac33a2dd 100644 --- a/j-lawyer-server/j-lawyer-server-ejb/src/java/com/jdimension/jlawyer/services/SystemManagementLocal.java +++ b/j-lawyer-server/j-lawyer-server-ejb/src/java/com/jdimension/jlawyer/services/SystemManagementLocal.java @@ -688,6 +688,7 @@ public interface SystemManagementLocal { public static final int TEMPLATE_TYPE_BODY=10; public static final int TEMPLATE_TYPE_HEAD=20; + public static final int TEMPLATE_TYPE_EMAIL=30; public String getServerVersion(); public void statusMail(String subject, String body); @@ -734,4 +735,10 @@ public interface SystemManagementLocal { HashMap getPlaceHolderValuesUnrestricted(HashMap placeHolders, ArchiveFileBean aFile, List selectedParties, String dictateSign, GenericCalculationTable calculationTable, HashMap formsPlaceHolderValues, AppUserBean caseLawyer, AppUserBean caseAssistant, AppUserBean author, Invoice invoice, AppUserBean invoiceSender, GenericCalculationTable invoiceTable, GenericCalculationTable timesheetsTable, byte[] giroCode, String ingoText) throws Exception; DocumentNameTemplate getDefaultDocumentNameTemplate() throws Exception; + + String getTemplateContent(int templateType, String folder, String templateName) throws Exception; + + String fillPlaceholdersInContent(String content, HashMap placeholders) throws Exception; + + } From 760bdeb5309f9f05ea67662f6633e156fe5d546e Mon Sep 17 00:00:00 2001 From: Maximilian Steinert <71747937+iradraconis@users.noreply.github.com> Date: Sat, 26 Oct 2024 21:51:40 +0200 Subject: [PATCH 2/8] adds undo/redo when writing eMails - fixes #2605 --- .../jlawyer/client/mail/HtmlEditorPanel.java | 61 ++++++++++++++++++- .../jlawyer/client/mail/TextEditorPanel.java | 51 +++++++++++++++- 2 files changed, 110 insertions(+), 2 deletions(-) diff --git a/j-lawyer-client/src/com/jdimension/jlawyer/client/mail/HtmlEditorPanel.java b/j-lawyer-client/src/com/jdimension/jlawyer/client/mail/HtmlEditorPanel.java index 60b027199..1311b9e03 100755 --- a/j-lawyer-client/src/com/jdimension/jlawyer/client/mail/HtmlEditorPanel.java +++ b/j-lawyer-client/src/com/jdimension/jlawyer/client/mail/HtmlEditorPanel.java @@ -666,10 +666,17 @@ import com.jdimension.jlawyer.server.utils.ContentTypes; import java.awt.Component; import java.awt.Container; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; +import javax.swing.AbstractAction; import javax.swing.JButton; import javax.swing.JComboBox; +import javax.swing.JComponent; import javax.swing.JEditorPane; +import javax.swing.KeyStroke; import org.apache.log4j.Logger; +import javax.swing.undo.UndoManager; /** * @@ -677,6 +684,7 @@ */ public class HtmlEditorPanel extends javax.swing.JPanel implements EditorImplementation { + private final UndoManager undoManager; private static final Logger log=Logger.getLogger(HtmlEditorPanel.class.getName()); /** @@ -684,7 +692,9 @@ public class HtmlEditorPanel extends javax.swing.JPanel implements EditorImpleme */ public HtmlEditorPanel() { initComponents(); - } + + undoManager = new UndoManager(); + setupUndoRedoForEditorPane(htmlPane); } /** * This method is called from within the constructor to initialize the form. @@ -822,5 +832,54 @@ private boolean insertToEditorPane(Container c, String t, int pos) { } return false; } + + private void setupUndoRedoForEditorPane(Container container) { + for (Component comp : container.getComponents()) { + if (comp instanceof JEditorPane) { + JEditorPane editorPane = (JEditorPane) comp; + editorPane.getDocument().addUndoableEditListener(e -> undoManager.addEdit(e.getEdit())); + + // Setup key bindings for undo + KeyStroke undoKeystroke = KeyStroke.getKeyStroke( + KeyEvent.VK_Z, + Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx() + ); + + // Setup key bindings for redo + KeyStroke redoKeystroke = KeyStroke.getKeyStroke( + KeyEvent.VK_Y, + Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx() + ); + + editorPane.getInputMap(JComponent.WHEN_FOCUSED).put(undoKeystroke, "Undo"); + editorPane.getActionMap().put("Undo", new AbstractAction("Undo") { + @Override + public void actionPerformed(ActionEvent evt) { + if (undoManager.canUndo()) { + undoManager.undo(); + } + } + }); + + editorPane.getInputMap(JComponent.WHEN_FOCUSED).put(redoKeystroke, "Redo"); + editorPane.getActionMap().put("Redo", new AbstractAction("Redo") { + @Override + public void actionPerformed(ActionEvent evt) { + if (undoManager.canRedo()) { + undoManager.redo(); + } + } + }); + + break; // Found the editor pane, no need to continue + } else if (comp instanceof Container) { + setupUndoRedoForEditorPane((Container) comp); + } + } + } + + public UndoManager getUndoManager() { + return undoManager; + } } diff --git a/j-lawyer-client/src/com/jdimension/jlawyer/client/mail/TextEditorPanel.java b/j-lawyer-client/src/com/jdimension/jlawyer/client/mail/TextEditorPanel.java index c0e8e24da..18c6e0d37 100755 --- a/j-lawyer-client/src/com/jdimension/jlawyer/client/mail/TextEditorPanel.java +++ b/j-lawyer-client/src/com/jdimension/jlawyer/client/mail/TextEditorPanel.java @@ -664,20 +664,64 @@ package com.jdimension.jlawyer.client.mail; import com.jdimension.jlawyer.server.utils.ContentTypes; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; +import javax.swing.AbstractAction; +import javax.swing.JComponent; import javax.swing.KeyStroke; +import javax.swing.undo.UndoManager; /** * * @author Kutschke */ public class TextEditorPanel extends javax.swing.JPanel implements EditorImplementation { - + + private final UndoManager undoManager; + /** * Creates new form TextEditorPanel */ public TextEditorPanel() { initComponents(); + // Initialize UndoManager + undoManager = new UndoManager(); + taText.getDocument().addUndoableEditListener(e -> undoManager.addEdit(e.getEdit())); + + // Setup key bindings for undo + KeyStroke undoKeystroke = KeyStroke.getKeyStroke( + KeyEvent.VK_Z, + Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx() + ); + + // Setup key bindings for redo + KeyStroke redoKeystroke = KeyStroke.getKeyStroke( + KeyEvent.VK_Y, + Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx() + ); + + taText.getInputMap(JComponent.WHEN_FOCUSED).put(undoKeystroke, "Undo"); + taText.getActionMap().put("Undo", new AbstractAction("Undo") { + @Override + public void actionPerformed(ActionEvent evt) { + if (undoManager.canUndo()) { + undoManager.undo(); + } + } + }); + + taText.getInputMap(JComponent.WHEN_FOCUSED).put(redoKeystroke, "Redo"); + taText.getActionMap().put("Redo", new AbstractAction("Redo") { + @Override + public void actionPerformed(ActionEvent evt) { + if (undoManager.canRedo()) { + undoManager.redo(); + } + } + }); + // this is required because the scroll pane was stealing those key strokes from its jtextarea, making it impossible to scroll using the keys this.jScrollPane2.getInputMap().put(KeyStroke.getKeyStroke("UP"), "none"); this.jScrollPane2.getInputMap().put(KeyStroke.getKeyStroke("DOWN"), "none"); @@ -764,4 +808,9 @@ public String getSelectedText() { public void insert(String t, int pos) { this.taText.insert(t, pos); } + + + public UndoManager getUndoManager() { + return undoManager; + } } From 66950af17fc9343ab2af360b514e1483df755600 Mon Sep 17 00:00:00 2001 From: Maximilian Steinert <71747937+iradraconis@users.noreply.github.com> Date: Sun, 27 Oct 2024 11:53:47 +0100 Subject: [PATCH 3/8] Add REST endpoints for email templates: - GET /email/templates returns list of available templates - GET /email/{caseId}/{templateName} returns template with filled placeholders Refactor email template endpoints: - Split existing getEmailTemplates into two dedicated endpoints - Simplify template list to return only template names - Improve response structure by including placeholder values separately --- .../io/rest/v6/TemplatesEndpointLocalV6.java | 4 +- .../io/rest/v6/TemplatesEndpointV6.java | 154 ++++++++++-------- 2 files changed, 85 insertions(+), 73 deletions(-) diff --git a/j-lawyer-server/j-lawyer-io/src/java/org/jlawyer/io/rest/v6/TemplatesEndpointLocalV6.java b/j-lawyer-server/j-lawyer-io/src/java/org/jlawyer/io/rest/v6/TemplatesEndpointLocalV6.java index 95571ce23..6de1f29d2 100644 --- a/j-lawyer-server/j-lawyer-io/src/java/org/jlawyer/io/rest/v6/TemplatesEndpointLocalV6.java +++ b/j-lawyer-server/j-lawyer-io/src/java/org/jlawyer/io/rest/v6/TemplatesEndpointLocalV6.java @@ -684,5 +684,7 @@ public interface TemplatesEndpointLocalV6 { Response addDocumentFromTemplate(String caseId, String fileName, String templateFolder, String template, List placeHolderValues) throws Exception; - Response getEmailTemplates(String caseId); + Response listEmailTemplates(); + + Response getEmailTemplate(String caseId, String templateName); } diff --git a/j-lawyer-server/j-lawyer-io/src/java/org/jlawyer/io/rest/v6/TemplatesEndpointV6.java b/j-lawyer-server/j-lawyer-io/src/java/org/jlawyer/io/rest/v6/TemplatesEndpointV6.java index 5d4df881f..b5c2ef6da 100644 --- a/j-lawyer-server/j-lawyer-io/src/java/org/jlawyer/io/rest/v6/TemplatesEndpointV6.java +++ b/j-lawyer-server/j-lawyer-io/src/java/org/jlawyer/io/rest/v6/TemplatesEndpointV6.java @@ -913,10 +913,37 @@ public Response addDocumentFromTemplate(@PathParam("caseId") String caseId, @Pat @Override @GET - @Path("email/{caseId}") + @Path("email/templates") @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8") @RolesAllowed({"loginRole"}) - public Response getEmailTemplates(@PathParam("caseId") String caseId) { + public Response listEmailTemplates() { + try { + InitialContext ic = new InitialContext(); + SystemManagementLocal system = (SystemManagementLocal) ic.lookup(LOOKUP_SYSMAN); + + List templates = system.getTemplatesByPath(SystemManagementLocal.TEMPLATE_TYPE_EMAIL, "/"); + List> resultList = new ArrayList<>(); + + for (String templateName : templates) { + Map template = new LinkedHashMap<>(); + template.put("name", templateName); + resultList.add(template); + } + + return Response.ok(resultList).build(); + + } catch (Exception ex) { + log.error("Cannot list email templates", ex); + return Response.serverError().build(); + } + } + + @Override + @GET + @Path("email/{caseId}/{templateName}") + @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8") + @RolesAllowed({"loginRole"}) + public Response getEmailTemplate(@PathParam("caseId") String caseId, @PathParam("templateName") String templateName) { try { InitialContext ic = new InitialContext(); SystemManagementLocal system = (SystemManagementLocal) ic.lookup(LOOKUP_SYSMAN); @@ -924,95 +951,78 @@ public Response getEmailTemplates(@PathParam("caseId") String caseId) { ArchiveFileBean aFile = caseService.getArchiveFile(caseId); if (aFile == null) { - log.error("Case not found: " + caseId); return Response.status(Response.Status.NOT_FOUND) .entity("Case not found: " + caseId) .build(); } - List templates = system.getTemplatesByPath(SystemManagementLocal.TEMPLATE_TYPE_EMAIL, "/"); - List> resultList = new ArrayList<>(); + String content = system.getTemplateContent(SystemManagementLocal.TEMPLATE_TYPE_EMAIL, "/", templateName); + Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder() + .parse(new ByteArrayInputStream(content.getBytes("UTF-8"))); + + String subject = doc.getElementsByTagName("subject").item(0).getTextContent(); + String body = doc.getElementsByTagName("body").item(0).getTextContent(); - // Get case parties + // Originale Version speichern + Map result = new LinkedHashMap<>(); + result.put("name", templateName); + result.put("originalSubject", subject.trim()); + result.put("originalBody", body); + + // Platzhalter sammeln und füllen List parties = new ArrayList<>(); List addresses = caseService.getInvolvementDetailsForCase(caseId); for (ArchiveFileAddressesBean aab : addresses) { parties.add(new PartiesTriplet(aab.getAddressKey(), aab.getReferenceType(), aab)); } - for (String templateName : templates) { - Map template = new LinkedHashMap<>(); - template.put("name", templateName); + // Platzhalter aus Subject und Body sammeln + Set placeholders = new HashSet<>(); + Matcher m = Pattern.compile("\\{\\{([^}]+)\\}\\}").matcher(subject + body); + while (m.find()) { + placeholders.add(m.group(1)); + } - try { - String content = system.getTemplateContent(SystemManagementLocal.TEMPLATE_TYPE_EMAIL, "/", templateName); - - // XML parsen - Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder() - .parse(new ByteArrayInputStream(content.getBytes("UTF-8"))); - - // Subject und Body CDATA extrahieren - String subject = doc.getElementsByTagName("subject").item(0).getTextContent(); - String body = doc.getElementsByTagName("body").item(0).getTextContent(); - - // Originale Version speichern - template.put("originalSubject", subject.trim()); - template.put("originalBody", body); - - // Platzhalter aus Subject und Body sammeln - Set placeholders = new HashSet<>(); - Matcher m = Pattern.compile("\\{\\{([^}]+)\\}\\}").matcher(subject + body); - while (m.find()) { - placeholders.add(m.group(1)); - } - - // Platzhalter-Map erstellen und füllen - HashMap placeholderMap = new HashMap<>(); - for (String placeholder : placeholders) { - placeholderMap.put("{{" + placeholder + "}}", ""); - } - - // Platzhalter mit Werten füllen - placeholderMap = system.getPlaceHolderValues( - placeholderMap, aFile, parties, "", null, new HashMap<>(), - system.getUser(aFile.getLawyer()), - system.getUser(aFile.getAssistant()), - null, null, null, null, null, null, null - ); - - // Platzhalter-Werte-Map erstellen - Map placeholderValues = new LinkedHashMap<>(); - for (String placeholder : placeholders) { - String fullPlaceholder = "{{" + placeholder + "}}"; - Object value = placeholderMap.get(fullPlaceholder); - placeholderValues.put(placeholder, value != null ? value.toString() : ""); - } - template.put("placeholderValues", placeholderValues); - - // Platzhalter ersetzen - for (Map.Entry entry : placeholderMap.entrySet()) { - if (entry.getValue() != null) { - subject = subject.replace(entry.getKey(), entry.getValue().toString()); - body = body.replace(entry.getKey(), entry.getValue().toString()); - } - } - - template.put("subject", subject.trim()); - template.put("body", body); - - } catch (Exception e) { - log.error("Error processing template " + templateName, e); - template.put("error", e.getMessage()); - } + // Platzhalter-Map erstellen und füllen + HashMap placeholderMap = new HashMap<>(); + for (String placeholder : placeholders) { + placeholderMap.put("{{" + placeholder + "}}", ""); + } - resultList.add(template); + // Platzhalter mit Werten füllen + placeholderMap = system.getPlaceHolderValues( + placeholderMap, aFile, parties, "", null, new HashMap<>(), + system.getUser(aFile.getLawyer()), + system.getUser(aFile.getAssistant()), + null, null, null, null, null, null, null + ); + + // Platzhalter-Werte-Map erstellen + Map placeholderValues = new LinkedHashMap<>(); + for (String placeholder : placeholders) { + String fullPlaceholder = "{{" + placeholder + "}}"; + Object value = placeholderMap.get(fullPlaceholder); + placeholderValues.put(placeholder, value != null ? value.toString() : ""); } + result.put("placeholderValues", placeholderValues); - return Response.ok(resultList).build(); + // Gefüllte Version + for (Map.Entry entry : placeholderMap.entrySet()) { + if (entry.getValue() != null) { + subject = subject.replace(entry.getKey(), entry.getValue().toString()); + body = body.replace(entry.getKey(), entry.getValue().toString()); + } + } + + result.put("subject", subject.trim()); + result.put("body", body); + + return Response.ok(result).build(); } catch (Exception ex) { - log.error("Cannot get email templates for case " + caseId, ex); + log.error("Cannot get email template " + templateName + " for case " + caseId, ex); return Response.serverError().build(); } } + } From b2b2ccf87021b5e7f64a9622c6ef7036146db8ed Mon Sep 17 00:00:00 2001 From: Maximilian Steinert <71747937+iradraconis@users.noreply.github.com> Date: Sun, 27 Oct 2024 12:05:28 +0100 Subject: [PATCH 4/8] Add Swagger documentation for email template endpoints: - Document template list endpoint with response codes - Document template detail endpoint with parameters and responses --- .../io/rest/v6/TemplatesEndpointV6.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/j-lawyer-server/j-lawyer-io/src/java/org/jlawyer/io/rest/v6/TemplatesEndpointV6.java b/j-lawyer-server/j-lawyer-io/src/java/org/jlawyer/io/rest/v6/TemplatesEndpointV6.java index b5c2ef6da..45c92d208 100644 --- a/j-lawyer-server/j-lawyer-io/src/java/org/jlawyer/io/rest/v6/TemplatesEndpointV6.java +++ b/j-lawyer-server/j-lawyer-io/src/java/org/jlawyer/io/rest/v6/TemplatesEndpointV6.java @@ -911,6 +911,15 @@ public Response addDocumentFromTemplate(@PathParam("caseId") String caseId, @Pat } } + /** + * Lists all available email templates. + * + * @return List of available email templates with their names + * @response 200 List of templates successfully retrieved + * @response 401 User not authorized + * @response 403 User not authenticated + * @response 500 Server error while retrieving templates + */ @Override @GET @Path("email/templates") @@ -938,6 +947,18 @@ public Response listEmailTemplates() { } } + /** + * Returns a specific email template with all placeholders filled with case data. + * + * @param caseId The ID of the case to fill placeholders from + * @param templateName Name of the template to retrieve + * @return Email template with original content, filled content and placeholder values + * @response 200 Template successfully retrieved with filled placeholders + * @response 401 User not authorized + * @response 403 User not authenticated + * @response 404 Case or template not found + * @response 500 Server error while processing template + */ @Override @GET @Path("email/{caseId}/{templateName}") From 7abb96dd977997d9aabf0c7c6ded81350506aad7 Mon Sep 17 00:00:00 2001 From: j-dimension Date: Sun, 27 Oct 2024 20:31:30 +0100 Subject: [PATCH 5/8] use dedicated service for retrieving email template names. issue #2623 --- .../java/org/jlawyer/io/rest/v6/TemplatesEndpointV6.java | 8 +++++--- .../jlawyer/services/IntegrationServiceLocal.java | 3 +++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/j-lawyer-server/j-lawyer-io/src/java/org/jlawyer/io/rest/v6/TemplatesEndpointV6.java b/j-lawyer-server/j-lawyer-io/src/java/org/jlawyer/io/rest/v6/TemplatesEndpointV6.java index 45c92d208..f87cc09be 100644 --- a/j-lawyer-server/j-lawyer-io/src/java/org/jlawyer/io/rest/v6/TemplatesEndpointV6.java +++ b/j-lawyer-server/j-lawyer-io/src/java/org/jlawyer/io/rest/v6/TemplatesEndpointV6.java @@ -670,6 +670,7 @@ You should also get your employer (if you work as a programmer) or school, import com.jdimension.jlawyer.services.ArchiveFileServiceLocal; import com.jdimension.jlawyer.services.FormsServiceLocal; import com.jdimension.jlawyer.pojo.PartiesTriplet; +import com.jdimension.jlawyer.services.IntegrationServiceLocal; import com.jdimension.jlawyer.services.SystemManagementLocal; import java.util.ArrayList; import java.util.Collections; @@ -712,6 +713,7 @@ public class TemplatesEndpointV6 implements TemplatesEndpointLocalV6 { private static final String LOOKUP_SYSMAN="java:global/j-lawyer-server/j-lawyer-server-ejb/SystemManagement!com.jdimension.jlawyer.services.SystemManagementLocal"; private static final String LOOKUP_CASESVC="java:global/j-lawyer-server/j-lawyer-server-ejb/ArchiveFileService!com.jdimension.jlawyer.services.ArchiveFileServiceLocal"; private static final String LOOKUP_FORMSSVC="java:global/j-lawyer-server/j-lawyer-server-ejb/FormsService!com.jdimension.jlawyer.services.FormsServiceLocal"; + private static final String LOOKUP_INTEGRATIONSVC="java:global/j-lawyer-server/j-lawyer-server-ejb/IntegrationService!com.jdimension.jlawyer.services.IntegrationServiceLocal"; /** * Returns the folder structure holding document templates. @@ -922,15 +924,15 @@ public Response addDocumentFromTemplate(@PathParam("caseId") String caseId, @Pat */ @Override @GET - @Path("email/templates") + @Path("email") @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8") @RolesAllowed({"loginRole"}) public Response listEmailTemplates() { try { InitialContext ic = new InitialContext(); - SystemManagementLocal system = (SystemManagementLocal) ic.lookup(LOOKUP_SYSMAN); + IntegrationServiceLocal intSvc = (IntegrationServiceLocal) ic.lookup(LOOKUP_INTEGRATIONSVC); - List templates = system.getTemplatesByPath(SystemManagementLocal.TEMPLATE_TYPE_EMAIL, "/"); + Collection templates = intSvc.getAllEmailTemplateNames(); List> resultList = new ArrayList<>(); for (String templateName : templates) { diff --git a/j-lawyer-server/j-lawyer-server-ejb/src/java/com/jdimension/jlawyer/services/IntegrationServiceLocal.java b/j-lawyer-server/j-lawyer-server-ejb/src/java/com/jdimension/jlawyer/services/IntegrationServiceLocal.java index 4d8658b46..705029c75 100644 --- a/j-lawyer-server/j-lawyer-server-ejb/src/java/com/jdimension/jlawyer/services/IntegrationServiceLocal.java +++ b/j-lawyer-server/j-lawyer-server-ejb/src/java/com/jdimension/jlawyer/services/IntegrationServiceLocal.java @@ -663,6 +663,7 @@ */ package com.jdimension.jlawyer.services; +import java.util.Collection; import javax.ejb.Local; /** @@ -672,4 +673,6 @@ @Local public interface IntegrationServiceLocal { + Collection getAllEmailTemplateNames(); + } From c716cb91b960e6ef9fd48d71229ed532fe23273e Mon Sep 17 00:00:00 2001 From: j-dimension Date: Sun, 27 Oct 2024 23:09:14 +0100 Subject: [PATCH 6/8] - added support for lawyer / assistant / author placeholders - added support for forms placeholders - added mimetype to output, so that a client can determine whether it deals with plain text or HTML - refactored code to use existing logic / avoid duplication - issue #2623 --- .../io/rest/v6/TemplatesEndpointLocalV6.java | 3 +- .../io/rest/v6/TemplatesEndpointV6.java | 310 ++++++++++-------- .../jlawyer/services/AddressService.java | 1 - .../services/IntegrationServiceLocal.java | 2 + 4 files changed, 169 insertions(+), 147 deletions(-) diff --git a/j-lawyer-server/j-lawyer-io/src/java/org/jlawyer/io/rest/v6/TemplatesEndpointLocalV6.java b/j-lawyer-server/j-lawyer-io/src/java/org/jlawyer/io/rest/v6/TemplatesEndpointLocalV6.java index 6de1f29d2..17a042ba8 100644 --- a/j-lawyer-server/j-lawyer-io/src/java/org/jlawyer/io/rest/v6/TemplatesEndpointLocalV6.java +++ b/j-lawyer-server/j-lawyer-io/src/java/org/jlawyer/io/rest/v6/TemplatesEndpointLocalV6.java @@ -664,7 +664,6 @@ You should also get your employer (if you work as a programmer) or school, package org.jlawyer.io.rest.v6; import java.util.List; -import java.util.Map; import javax.ejb.Local; import javax.ws.rs.core.Response; import org.jlawyer.io.rest.v6.pojo.RestfulPlaceholderV6; @@ -686,5 +685,5 @@ public interface TemplatesEndpointLocalV6 { Response listEmailTemplates(); - Response getEmailTemplate(String caseId, String templateName); + Response getEmailFromTemplate(String templateName, String caseId); } diff --git a/j-lawyer-server/j-lawyer-io/src/java/org/jlawyer/io/rest/v6/TemplatesEndpointV6.java b/j-lawyer-server/j-lawyer-io/src/java/org/jlawyer/io/rest/v6/TemplatesEndpointV6.java index f87cc09be..1141bed2f 100644 --- a/j-lawyer-server/j-lawyer-io/src/java/org/jlawyer/io/rest/v6/TemplatesEndpointV6.java +++ b/j-lawyer-server/j-lawyer-io/src/java/org/jlawyer/io/rest/v6/TemplatesEndpointV6.java @@ -663,15 +663,19 @@ You should also get your employer (if you work as a programmer) or school, */ package org.jlawyer.io.rest.v6; +import com.jdimension.jlawyer.documents.CommonTemplatesUtil; +import com.jdimension.jlawyer.email.EmailTemplate; import com.jdimension.jlawyer.persistence.AppUserBean; import com.jdimension.jlawyer.persistence.ArchiveFileAddressesBean; import com.jdimension.jlawyer.persistence.ArchiveFileBean; import com.jdimension.jlawyer.persistence.ArchiveFileDocumentsBean; +import com.jdimension.jlawyer.persistence.PartyTypeBean; import com.jdimension.jlawyer.services.ArchiveFileServiceLocal; import com.jdimension.jlawyer.services.FormsServiceLocal; import com.jdimension.jlawyer.pojo.PartiesTriplet; import com.jdimension.jlawyer.services.IntegrationServiceLocal; import com.jdimension.jlawyer.services.SystemManagementLocal; +import java.security.Principal; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -693,12 +697,10 @@ You should also get your employer (if you work as a programmer) or school, import org.jlawyer.data.tree.GenericNode; import org.jlawyer.io.rest.v1.pojo.RestfulDocumentV1; import org.jlawyer.io.rest.v6.pojo.RestfulPlaceholderV6; -import java.io.ByteArrayInputStream; import java.util.*; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import javax.xml.parsers.DocumentBuilderFactory; -import org.w3c.dom.Document; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.SecurityContext; + /** * * http://localhost:8080/j-lawyer-io/rest/cases/list @@ -710,30 +712,33 @@ You should also get your employer (if you work as a programmer) or school, public class TemplatesEndpointV6 implements TemplatesEndpointLocalV6 { private static final Logger log = Logger.getLogger(TemplatesEndpointV6.class.getName()); - private static final String LOOKUP_SYSMAN="java:global/j-lawyer-server/j-lawyer-server-ejb/SystemManagement!com.jdimension.jlawyer.services.SystemManagementLocal"; - private static final String LOOKUP_CASESVC="java:global/j-lawyer-server/j-lawyer-server-ejb/ArchiveFileService!com.jdimension.jlawyer.services.ArchiveFileServiceLocal"; - private static final String LOOKUP_FORMSSVC="java:global/j-lawyer-server/j-lawyer-server-ejb/FormsService!com.jdimension.jlawyer.services.FormsServiceLocal"; - private static final String LOOKUP_INTEGRATIONSVC="java:global/j-lawyer-server/j-lawyer-server-ejb/IntegrationService!com.jdimension.jlawyer.services.IntegrationServiceLocal"; - + private static final String LOOKUP_SYSMAN = "java:global/j-lawyer-server/j-lawyer-server-ejb/SystemManagement!com.jdimension.jlawyer.services.SystemManagementLocal"; + private static final String LOOKUP_CASESVC = "java:global/j-lawyer-server/j-lawyer-server-ejb/ArchiveFileService!com.jdimension.jlawyer.services.ArchiveFileServiceLocal"; + private static final String LOOKUP_FORMSSVC = "java:global/j-lawyer-server/j-lawyer-server-ejb/FormsService!com.jdimension.jlawyer.services.FormsServiceLocal"; + private static final String LOOKUP_INTEGRATIONSVC = "java:global/j-lawyer-server/j-lawyer-server-ejb/IntegrationService!com.jdimension.jlawyer.services.IntegrationServiceLocal"; + + @Context + private SecurityContext securityContext; + /** * Returns the folder structure holding document templates. - * + * * @return entire folder structure for document templates * @response 401 User not authorized * @response 403 User not authenticated */ @Override @GET - @Produces(MediaType.APPLICATION_JSON+";charset=utf-8") + @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8") @Path("/documents/folders") @RolesAllowed({"loginRole"}) public Response getTemplateFolders() { try { InitialContext ic = new InitialContext(); SystemManagementLocal system = (SystemManagementLocal) ic.lookup(LOOKUP_SYSMAN); - GenericNode rootNode=system.getAllTemplatesTree(SystemManagementLocal.TEMPLATE_TYPE_BODY); - String baseDir=system.getTemplatesBaseDir(SystemManagementLocal.TEMPLATE_TYPE_BODY); - ArrayList nodeIds=new ArrayList<>(); + GenericNode rootNode = system.getAllTemplatesTree(SystemManagementLocal.TEMPLATE_TYPE_BODY); + String baseDir = system.getTemplatesBaseDir(SystemManagementLocal.TEMPLATE_TYPE_BODY); + ArrayList nodeIds = new ArrayList<>(); collectFolders(rootNode, baseDir, nodeIds); Collections.sort(nodeIds, String.CASE_INSENSITIVE_ORDER); return Response.ok(nodeIds).build(); @@ -744,12 +749,13 @@ public Response getTemplateFolders() { } private void collectFolders(Object startNode, String stripPrefix, ArrayList resultList) { - GenericNode node=(GenericNode)startNode; - String id=node.getId(); - if(id.startsWith(stripPrefix)) - id=id.replace(stripPrefix, "/"); + GenericNode node = (GenericNode) startNode; + String id = node.getId(); + if (id.startsWith(stripPrefix)) { + id = id.replace(stripPrefix, "/"); + } resultList.add(id); - for(GenericNode c: node.getChildren()) { + for (GenericNode c : node.getChildren()) { collectFolders(c, stripPrefix, resultList); } } @@ -763,15 +769,15 @@ private void collectFolders(Object startNode, String stripPrefix, ArrayList resultList=system.getTemplatesByPath(SystemManagementLocal.TEMPLATE_TYPE_BODY, folder); + + List resultList = system.getTemplatesByPath(SystemManagementLocal.TEMPLATE_TYPE_BODY, folder); Collections.sort(resultList, String.CASE_INSENSITIVE_ORDER); return Response.ok(resultList).build(); } catch (Exception ex) { @@ -781,7 +787,9 @@ public Response getTemplatesInFolder(@PathParam("folder") String folder) { } /** - * Returns all placeholders keys for a given template in a given folder, using the given case. Case is needed to resolve potential forms placeholders (AKA Falldaten). + * Returns all placeholders keys for a given template in a given folder, + * using the given case. Case is needed to resolve potential forms + * placeholders (AKA Falldaten). * * @param folder the folder hierarchy starting with / * @param template the file name of the template @@ -791,20 +799,20 @@ public Response getTemplatesInFolder(@PathParam("folder") String folder) { */ @Override @GET - @Produces(MediaType.APPLICATION_JSON+";charset=utf-8") + @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8") @Path("/documents/{folder}/{template}/{caseId}") @RolesAllowed({"loginRole"}) public Response getPlaceHoldersForTemplate(@PathParam("folder") String folder, @PathParam("template") String template, @PathParam("caseId") String caseId) { try { InitialContext ic = new InitialContext(); SystemManagementLocal system = (SystemManagementLocal) ic.lookup(LOOKUP_SYSMAN); - - List resultList=system.getPlaceHoldersForTemplate(SystemManagementLocal.TEMPLATE_TYPE_BODY, folder, template, caseId); + + List resultList = system.getPlaceHoldersForTemplate(SystemManagementLocal.TEMPLATE_TYPE_BODY, folder, template, caseId); Collections.sort(resultList, String.CASE_INSENSITIVE_ORDER); - Object[] oArray=resultList.stream().filter(ph -> !ph.startsWith("[[")).toArray(); - String[] resultArray=new String[oArray.length]; - for(int i=0;i !ph.startsWith("[[")).toArray(); + String[] resultArray = new String[oArray.length]; + for (int i = 0; i < oArray.length; i++) { + resultArray[i] = oArray[i].toString(); } return Response.ok(resultArray).build(); } catch (Exception ex) { @@ -814,86 +822,92 @@ public Response getPlaceHoldersForTemplate(@PathParam("folder") String folder, @ } /** - * Creates a new document based on a template.Any place holders are automatically populated, but a client may override them. Invoice creation not supported. + * Creates a new document based on a template.Any place holders are + * automatically populated, but a client may override them. Invoice creation + * not supported. * * @param caseId the id of the case - * @param fileName file name of the document to be created, without file extension (server will enforce same extension as template) + * @param fileName file name of the document to be created, without file + * extension (server will enforce same extension as template) * @param folder the template folder hierarchy starting with / * @param template the file name of the template - * @param placeHolderValues key-value pairs holding placeholder values, used for overriding defaults / existing values + * @param placeHolderValues key-value pairs holding placeholder values, used + * for overriding defaults / existing values * @response 401 User not authorized * @response 403 User not authenticated */ @Override @PUT - @Produces(MediaType.APPLICATION_JSON+";charset=utf-8") + @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8") @Path("/documents/{folder}/{template}/{caseId}/{fileName}") @RolesAllowed({"loginRole"}) public Response addDocumentFromTemplate(@PathParam("caseId") String caseId, @PathParam("fileName") String fileName, @PathParam("folder") String folder, @PathParam("template") String template, List placeHolderValues) throws Exception { - - if(folder==null || "".equals(folder)) - folder="/"; - - if(!folder.startsWith("/")) - folder="/" + folder; - + + if (folder == null || "".equals(folder)) { + folder = "/"; + } + + if (!folder.startsWith("/")) { + folder = "/" + folder; + } + try { InitialContext ic = new InitialContext(); ArchiveFileServiceLocal casesvc = (ArchiveFileServiceLocal) ic.lookup(LOOKUP_CASESVC); - + SystemManagementLocal system = (SystemManagementLocal) ic.lookup(LOOKUP_SYSMAN); - List placeHoldersInTemplate=system.getPlaceHoldersForTemplate(SystemManagementLocal.TEMPLATE_TYPE_BODY, folder, template, caseId); + List placeHoldersInTemplate = system.getPlaceHoldersForTemplate(SystemManagementLocal.TEMPLATE_TYPE_BODY, folder, template, caseId); Collections.sort(placeHoldersInTemplate, String.CASE_INSENSITIVE_ORDER); - Object[] placeHoldersInTemplateArray=placeHoldersInTemplate.stream().filter(ph -> !ph.startsWith("[[")).toArray(); - HashMap placeHoldersInTemplateMap=new HashMap<>(); - for(Object o: placeHoldersInTemplateArray) { + Object[] placeHoldersInTemplateArray = placeHoldersInTemplate.stream().filter(ph -> !ph.startsWith("[[")).toArray(); + HashMap placeHoldersInTemplateMap = new HashMap<>(); + for (Object o : placeHoldersInTemplateArray) { placeHoldersInTemplateMap.put(o.toString(), ""); } - - ArchiveFileBean aFile=casesvc.getArchiveFile(caseId); - if(aFile==null) { + + ArchiveFileBean aFile = casesvc.getArchiveFile(caseId); + if (aFile == null) { log.error("can not create document with template " + template + " in folder " + folder + " for case " + caseId + " - case does not exist"); return Response.serverError().build(); } - + FormsServiceLocal forms = (FormsServiceLocal) ic.lookup(LOOKUP_FORMSSVC); - HashMap formsPlaceHolders=forms.getPlaceHolderValuesForCase(caseId); - - List parties=new ArrayList<>(); - List aabList=casesvc.getInvolvementDetailsForCase(caseId); - for(ArchiveFileAddressesBean aab: aabList) { - PartiesTriplet pt=new PartiesTriplet(aab.getAddressKey(), aab.getReferenceType(), aab); + HashMap formsPlaceHolders = forms.getPlaceHolderValuesForCase(caseId); + + List parties = new ArrayList<>(); + List aabList = casesvc.getInvolvementDetailsForCase(caseId); + for (ArchiveFileAddressesBean aab : aabList) { + PartiesTriplet pt = new PartiesTriplet(aab.getAddressKey(), aab.getReferenceType(), aab); parties.add(pt); } //placeHoldersInTemplateMap = system.getPlaceHolderValues(placeHoldersInTemplateMap, aFile, parties, "", null, formsPlaceHolders, system.getUser(aFile.getLawyer()), system.getUser(aFile.getAssistant()), system.getUser(context.getCallerPrincipal().getName())); - - AppUserBean userLawyer=null; + + AppUserBean userLawyer = null; try { - userLawyer=system.getUser(aFile.getLawyer()); + userLawyer = system.getUser(aFile.getLawyer()); } catch (Throwable t) { log.warn("Unable to find lawyer " + aFile.getLawyer(), t); } - AppUserBean userAssistant=null; + AppUserBean userAssistant = null; try { - userAssistant=system.getUser(aFile.getAssistant()); + userAssistant = system.getUser(aFile.getAssistant()); } catch (Throwable t) { log.warn("Unable to find assistant " + aFile.getLawyer(), t); } - - + placeHoldersInTemplateMap = system.getPlaceHolderValues(placeHoldersInTemplateMap, aFile, parties, "", null, formsPlaceHolders, userLawyer, userAssistant, null, null, null, null, null, null, null); - - - for(RestfulPlaceholderV6 rph: placeHolderValues) { - String key=rph.getPlaceHolderKey(); - if(!key.startsWith("{{")) - key="{{"+key; - if(!key.endsWith("}}")) - key=key+"}}"; + + for (RestfulPlaceholderV6 rph : placeHolderValues) { + String key = rph.getPlaceHolderKey(); + if (!key.startsWith("{{")) { + key = "{{" + key; + } + if (!key.endsWith("}}")) { + key = key + "}}"; + } placeHoldersInTemplateMap.put(key, rph.getPlaceHolderValue()); } - ArchiveFileDocumentsBean newDoc=casesvc.addDocumentFromTemplate(caseId, fileName, null, folder, template, placeHoldersInTemplateMap, "", null); - RestfulDocumentV1 rdoc=new RestfulDocumentV1(); + ArchiveFileDocumentsBean newDoc = casesvc.addDocumentFromTemplate(caseId, fileName, null, folder, template, placeHoldersInTemplateMap, "", null); + RestfulDocumentV1 rdoc = new RestfulDocumentV1(); rdoc.setCreationDate(newDoc.getCreationDate()); rdoc.setChangeDate(newDoc.getChangeDate()); rdoc.setFavorite(rdoc.isFavorite()); @@ -905,7 +919,7 @@ public Response addDocumentFromTemplate(@PathParam("caseId") String caseId, @Pat rdoc.setSize(newDoc.getSize()); rdoc.setHighlight1(newDoc.getHighlight1()); rdoc.setHighlight2(newDoc.getHighlight2()); - + return Response.ok(rdoc).build(); } catch (Exception ex) { log.error("can not create document with template " + template + " in folder " + folder + " for case " + caseId, ex); @@ -914,17 +928,17 @@ public Response addDocumentFromTemplate(@PathParam("caseId") String caseId, @Pat } /** - * Lists all available email templates. - * - * @return List of available email templates with their names - * @response 200 List of templates successfully retrieved - * @response 401 User not authorized - * @response 403 User not authenticated - * @response 500 Server error while retrieving templates - */ + * Lists all available email templates. + * + * @return List of available email templates with their names + * @response 200 List of templates successfully retrieved + * @response 401 User not authorized + * @response 403 User not authenticated + * @response 500 Server error while retrieving templates + */ @Override @GET - @Path("email") + @Path("email") @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8") @RolesAllowed({"loginRole"}) public Response listEmailTemplates() { @@ -950,47 +964,77 @@ public Response listEmailTemplates() { } /** - * Returns a specific email template with all placeholders filled with case data. - * - * @param caseId The ID of the case to fill placeholders from - * @param templateName Name of the template to retrieve - * @return Email template with original content, filled content and placeholder values - * @response 200 Template successfully retrieved with filled placeholders - * @response 401 User not authorized - * @response 403 User not authenticated - * @response 404 Case or template not found - * @response 500 Server error while processing template - */ + * Returns a specific email template with all placeholders filled with case + * data. Default parties will be used. + * + * @param caseId The ID of the case to fill placeholders from + * @param templateName Name of the template to retrieve + * @return Email template with original content, filled content and + * placeholder values + * @response 200 Template successfully retrieved with filled placeholders + * @response 401 User not authorized + * @response 403 User not authenticated + * @response 404 Case or template not found + * @response 500 Server error while processing template + */ @Override @GET - @Path("email/{caseId}/{templateName}") + @Path("email/{templateName}/{caseId}") @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8") @RolesAllowed({"loginRole"}) - public Response getEmailTemplate(@PathParam("caseId") String caseId, @PathParam("templateName") String templateName) { + public Response getEmailFromTemplate(@PathParam("templateName") String templateName, @PathParam("caseId") String caseId) { try { InitialContext ic = new InitialContext(); SystemManagementLocal system = (SystemManagementLocal) ic.lookup(LOOKUP_SYSMAN); ArchiveFileServiceLocal caseService = (ArchiveFileServiceLocal) ic.lookup(LOOKUP_CASESVC); + IntegrationServiceLocal intSvc = (IntegrationServiceLocal) ic.lookup(LOOKUP_INTEGRATIONSVC); + + Principal principal = securityContext.getUserPrincipal(); + + AppUserBean author = null; + if (principal != null) { + author = system.getUser(principal.getName()); + } + + EmailTemplate tpl = intSvc.getEmailTemplate(templateName); ArchiveFileBean aFile = caseService.getArchiveFile(caseId); if (aFile == null) { return Response.status(Response.Status.NOT_FOUND) - .entity("Case not found: " + caseId) - .build(); + .entity("Case not found: " + caseId) + .build(); } - String content = system.getTemplateContent(SystemManagementLocal.TEMPLATE_TYPE_EMAIL, "/", templateName); - Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder() - .parse(new ByteArrayInputStream(content.getBytes("UTF-8"))); + List allPartyTypes = system.getPartyTypes(); + List allPartyTypesPlaceholders = new ArrayList<>(); + for (PartyTypeBean ptb : allPartyTypes) { + allPartyTypesPlaceholders.add(ptb.getPlaceHolder()); + } - String subject = doc.getElementsByTagName("subject").item(0).getTextContent(); - String body = doc.getElementsByTagName("body").item(0).getTextContent(); + FormsServiceLocal forms = (FormsServiceLocal) ic.lookup(LOOKUP_FORMSSVC); + Collection formPlaceHolders = forms.getPlaceHoldersForCase(caseId); + HashMap formPlaceHolderValues = forms.getPlaceHolderValuesForCase(caseId); + + // get a list of placeholders + ArrayList placeHolderNames = CommonTemplatesUtil.getPlaceHoldersInTemplate(tpl.getSubject(), allPartyTypesPlaceholders, formPlaceHolders); + HashMap ht = new HashMap<>(); + for (String ph : placeHolderNames) { + ht.put(ph, ""); + } - // Originale Version speichern - Map result = new LinkedHashMap<>(); - result.put("name", templateName); - result.put("originalSubject", subject.trim()); - result.put("originalBody", body); + // get user objects for this case + AppUserBean caseLawyer = null; + AppUserBean caseAssistant = null; + try { + caseLawyer = system.getUser(aFile.getLawyer()); + } catch (Exception ex) { + log.warn("Unable to load lawyer with id " + aFile.getLawyer()); + } + try { + caseAssistant = system.getUser(aFile.getAssistant()); + } catch (Exception ex) { + log.warn("Unable to load assistant with id " + aFile.getAssistant()); + } // Platzhalter sammeln und füllen List parties = new ArrayList<>(); @@ -999,46 +1043,24 @@ public Response getEmailTemplate(@PathParam("caseId") String caseId, @PathParam( parties.add(new PartiesTriplet(aab.getAddressKey(), aab.getReferenceType(), aab)); } - // Platzhalter aus Subject und Body sammeln - Set placeholders = new HashSet<>(); - Matcher m = Pattern.compile("\\{\\{([^}]+)\\}\\}").matcher(subject + body); - while (m.find()) { - placeholders.add(m.group(1)); - } + // get all placeholder values for the given set of placeholders + HashMap htValues = system.getPlaceHolderValues(ht, aFile, parties, "", null, formPlaceHolderValues, caseLawyer, caseAssistant, author, null, null, null, null, null, null); + String subject = CommonTemplatesUtil.replacePlaceHolders(tpl.getSubject(), htValues); - // Platzhalter-Map erstellen und füllen - HashMap placeholderMap = new HashMap<>(); - for (String placeholder : placeholders) { - placeholderMap.put("{{" + placeholder + "}}", ""); + placeHolderNames = CommonTemplatesUtil.getPlaceHoldersInTemplate(tpl.getBody(), allPartyTypesPlaceholders, formPlaceHolders); + ht = new HashMap<>(); + for (String ph : placeHolderNames) { + ht.put(ph, ""); } + htValues = system.getPlaceHolderValues(ht, aFile, parties, "", null, formPlaceHolderValues, caseLawyer, caseAssistant, author, null, null, null, null, null, null); - // Platzhalter mit Werten füllen - placeholderMap = system.getPlaceHolderValues( - placeholderMap, aFile, parties, "", null, new HashMap<>(), - system.getUser(aFile.getLawyer()), - system.getUser(aFile.getAssistant()), - null, null, null, null, null, null, null - ); - - // Platzhalter-Werte-Map erstellen - Map placeholderValues = new LinkedHashMap<>(); - for (String placeholder : placeholders) { - String fullPlaceholder = "{{" + placeholder + "}}"; - Object value = placeholderMap.get(fullPlaceholder); - placeholderValues.put(placeholder, value != null ? value.toString() : ""); - } - result.put("placeholderValues", placeholderValues); - - // Gefüllte Version - for (Map.Entry entry : placeholderMap.entrySet()) { - if (entry.getValue() != null) { - subject = subject.replace(entry.getKey(), entry.getValue().toString()); - body = body.replace(entry.getKey(), entry.getValue().toString()); - } - } + htValues.put("{{CLOUD_LINK}}", ""); + String body = CommonTemplatesUtil.replacePlaceHolders(tpl.getBody(), htValues); + Map result = new LinkedHashMap<>(); result.put("subject", subject.trim()); result.put("body", body); + result.put("mimeType", tpl.getFormat()); return Response.ok(result).build(); @@ -1047,5 +1069,5 @@ public Response getEmailTemplate(@PathParam("caseId") String caseId, @PathParam( return Response.serverError().build(); } } - + } diff --git a/j-lawyer-server/j-lawyer-server-ejb/src/java/com/jdimension/jlawyer/services/AddressService.java b/j-lawyer-server/j-lawyer-server-ejb/src/java/com/jdimension/jlawyer/services/AddressService.java index 96eebd554..41208f70f 100644 --- a/j-lawyer-server/j-lawyer-server-ejb/src/java/com/jdimension/jlawyer/services/AddressService.java +++ b/j-lawyer-server/j-lawyer-server-ejb/src/java/com/jdimension/jlawyer/services/AddressService.java @@ -680,7 +680,6 @@ import java.util.Collection; import java.util.Date; import java.util.HashMap; -import java.util.Hashtable; import java.util.List; import java.util.Map; import javax.annotation.Resource; diff --git a/j-lawyer-server/j-lawyer-server-ejb/src/java/com/jdimension/jlawyer/services/IntegrationServiceLocal.java b/j-lawyer-server/j-lawyer-server-ejb/src/java/com/jdimension/jlawyer/services/IntegrationServiceLocal.java index 705029c75..bd6038bb2 100644 --- a/j-lawyer-server/j-lawyer-server-ejb/src/java/com/jdimension/jlawyer/services/IntegrationServiceLocal.java +++ b/j-lawyer-server/j-lawyer-server-ejb/src/java/com/jdimension/jlawyer/services/IntegrationServiceLocal.java @@ -663,6 +663,7 @@ */ package com.jdimension.jlawyer.services; +import com.jdimension.jlawyer.email.EmailTemplate; import java.util.Collection; import javax.ejb.Local; @@ -674,5 +675,6 @@ public interface IntegrationServiceLocal { Collection getAllEmailTemplateNames(); + EmailTemplate getEmailTemplate(String fileName) throws Exception; } From 113880cf53f3cb3826d7878e74671f7060228aca Mon Sep 17 00:00:00 2001 From: j-dimension Date: Sun, 27 Oct 2024 23:13:42 +0100 Subject: [PATCH 7/8] reverted unused methods. issue #2623 --- .../jlawyer/services/SystemManagement.java | 51 ++----------------- .../services/SystemManagementLocal.java | 6 --- 2 files changed, 4 insertions(+), 53 deletions(-) diff --git a/j-lawyer-server/j-lawyer-server-ejb/src/java/com/jdimension/jlawyer/services/SystemManagement.java b/j-lawyer-server/j-lawyer-server-ejb/src/java/com/jdimension/jlawyer/services/SystemManagement.java index 2fa57f1b1..581b9e3be 100644 --- a/j-lawyer-server/j-lawyer-server-ejb/src/java/com/jdimension/jlawyer/services/SystemManagement.java +++ b/j-lawyer-server/j-lawyer-server-ejb/src/java/com/jdimension/jlawyer/services/SystemManagement.java @@ -996,13 +996,10 @@ public void removeOptionGroup(String id) { } private String getTypedFolderName(int templateType) { - switch(templateType) { - case SystemManagementLocal.TEMPLATE_TYPE_HEAD: - return "letterheads"; - case SystemManagementLocal.TEMPLATE_TYPE_EMAIL: - return "emailtemplates"; - default: - return "templates"; + if (templateType == SystemManagementRemote.TEMPLATE_TYPE_HEAD) { + return "letterheads"; + } else { + return "templates"; } } @@ -2552,44 +2549,4 @@ public List importSheets(byte[] odsData, List sheetNames return importer.importSheets(sheetNames, dryRun); } - - // eMail Templates - @Override - public String getTemplateContent(int templateType, String folder, String templateName) throws Exception { - String localBaseDir = this.getTemplatesBaseDir(templateType, folder); - String templatePath = localBaseDir + File.separator + templateName; - - File templateFile = new File(templatePath); - if (!templateFile.exists()) { - throw new Exception("Template not found: " + templatePath); - } - - return new String(ServerFileUtils.readFile(templateFile), "UTF-8"); - } - - @Override - public String fillPlaceholdersInContent(String content, HashMap placeholders) throws Exception { - if (content == null || placeholders == null) { - return content; - } - - String result = content; - for (Map.Entry entry : placeholders.entrySet()) { - String key = entry.getKey(); - Object value = entry.getValue(); - - if (value != null) { - if (!key.startsWith("{{")) { - key = "{{" + key; - } - if (!key.endsWith("}}")) { - key = key + "}}"; - } - - result = result.replace(key, value.toString()); - } - } - - return result; - } } diff --git a/j-lawyer-server/j-lawyer-server-ejb/src/java/com/jdimension/jlawyer/services/SystemManagementLocal.java b/j-lawyer-server/j-lawyer-server-ejb/src/java/com/jdimension/jlawyer/services/SystemManagementLocal.java index 4ac33a2dd..269b197ad 100644 --- a/j-lawyer-server/j-lawyer-server-ejb/src/java/com/jdimension/jlawyer/services/SystemManagementLocal.java +++ b/j-lawyer-server/j-lawyer-server-ejb/src/java/com/jdimension/jlawyer/services/SystemManagementLocal.java @@ -688,7 +688,6 @@ public interface SystemManagementLocal { public static final int TEMPLATE_TYPE_BODY=10; public static final int TEMPLATE_TYPE_HEAD=20; - public static final int TEMPLATE_TYPE_EMAIL=30; public String getServerVersion(); public void statusMail(String subject, String body); @@ -736,9 +735,4 @@ public interface SystemManagementLocal { DocumentNameTemplate getDefaultDocumentNameTemplate() throws Exception; - String getTemplateContent(int templateType, String folder, String templateName) throws Exception; - - String fillPlaceholdersInContent(String content, HashMap placeholders) throws Exception; - - } From 5aca71fd79a8010a06556fabc3c7c6a1c100ac12 Mon Sep 17 00:00:00 2001 From: j-dimension Date: Sun, 27 Oct 2024 23:17:13 +0100 Subject: [PATCH 8/8] code cleanup. issue #2623 --- .../java/com/jdimension/jlawyer/services/SystemManagement.java | 1 - 1 file changed, 1 deletion(-) diff --git a/j-lawyer-server/j-lawyer-server-ejb/src/java/com/jdimension/jlawyer/services/SystemManagement.java b/j-lawyer-server/j-lawyer-server-ejb/src/java/com/jdimension/jlawyer/services/SystemManagement.java index 581b9e3be..b570debc8 100644 --- a/j-lawyer-server/j-lawyer-server-ejb/src/java/com/jdimension/jlawyer/services/SystemManagement.java +++ b/j-lawyer-server/j-lawyer-server-ejb/src/java/com/jdimension/jlawyer/services/SystemManagement.java @@ -700,7 +700,6 @@ import java.util.HashMap; import java.util.Hashtable; import java.util.List; -import java.util.Map; import java.util.Properties; import javax.annotation.Resource; import javax.annotation.security.PermitAll;