HTML emaily v CzechIdM
Jednou z důležitých funkcí CzechIdM je schopnost předávání informací uživatelům pomocí emailu. Většinou se jedná pouze o notifikace, jejichž cílem je předat informaci. Někdy je ale i notifikační email informací určenou k tisku. K tomu se jednoduchý prostý text příliš nehodí, proto jsme do CzechIdM přidali možnost formátovat emaily pomocí HTML tagů.
Změny v emailových šablonách
Emailová šablona pro CzechIdM je obyčejný XML soubor, který obsahuje otagovaná metadata a samotný text emailu. V textu jsou pak použity speciální tagy, které jsou dynamicky doplněny před odesláním zprávy.
<?xml version="1.0" encoding="UTF-8"?> <emailTemplate xmlns="urn:jbpm.org:bcv_emailTemplate-1.0" name="UserRoleApprove"> <language>cs</language> <subject>Schválení přidání role uživateli #{userFullName}</subject> <text> Dobrý den, žádáme Vás o schválení přidělení role "#{roleName}" uživateli "#{userName}". Popis role: #{roleDescription} </text> <hideConfidential>false</hideConfidential> </emailTemplate>
Emailové šablony se ukládají do databáze, ze které si je CzechIdM v případě potřeby načítá. Z pohledu aplikace se pak jedná o Hibernate entity. Tuto entitu jsme rozšířili o atribut Content-Type, který se při načtení šablony propaguje do mailového subsystému.
@Entity @Table(name = "email_templates") public class EmailTemplate extends ViewMainEntity { private static final long serialVersionUID = 1L; ... @Column(name = "language", length = 2, nullable = false) private String language; @Column(name = "content_type", nullable = false) private String contentType; @Column(name = "hideConfidential", nullable = false) private boolean hideConfidential; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } ... }
V případě šablony je pak Content-Type přidán jako další tag v rámci XML souboru. Pokud není uveden, CzechIdM předpokládá “text/plain”. Chceme-li mít šablonu jako HTML (a tedy v ní používat HTML tagy), musíme jako typ uvést “text/html”.
<?xml version="1.0" encoding="UTF-8"?> <emailTemplate xmlns="urn:jbpm.org:bcv_emailTemplate-1.0" name="UserRoleApprove"> <language>cs</language> <subject>Schválení přidání role uživateli #{userFullName}</subject> <contentType>text/html</contentType> <text> Dobrý den,<br/> žádáme Vás o schválení přidělení role <strong>#{roleName}</strong> uživateli <strong>#{userName}</strong>.<br/> Popis role: #{roleDescription}<br/> </text> <hideConfidential>false</hideConfidential> </emailTemplate>
Realizace parseru umožňuje použití jakýchkoli HTML tagů. Pokud jsou uvedeny mezi tagy <text> </text> v šabloně, budou ve výsledné emailové zprávě interpretovány jako HTML značky. Jednoduchou prezentaci výsledku si můžete prohlédnout na obrázku:
Parser pro nové šablony
Do databáze se nové verze šablon nahrávají pomocí utility IdMUploader. Tato utilita parsuje a validuje soubory šablon a ukládá je do samostatné databázové tabulky. Uploader bylo zapotřebí upravit, protože docházelo ke zmatení XML a HTML značek. Takové chování je správné, protože XML umožňuje definici značek vlastních. V tomto případě ale nebylo zrovna žádané. HTML značky byly tedy parsovány také (jako XML) a z výsledné šablony se ztrácely.
Nejjednodušším řešením se ukázalo použití následujícího triku: Celý soubor šablony byl rozparsován a ve vzniklém DOMu byl nalezen výskyt značky “text”. Celý podstrom této značky byl následně z DOMu převeden zpět na XML. Tím došlo k rekonstrukci textu zprávy včetně HTML tagů. O tento proces se stará následující kód.
private void parseData() { Element element = document.getDocumentElement(); NodeList nodeList = element.getChildNodes(); for (int i = 0; i < nodeList.getLength(); i++) { Node node = nodeList.item(i); if ("text".equals(node.getNodeName())) { setText(returnTextNodeChildrenAsString(node)); } ... } ... } private String returnTextNodeChildrenAsString(Node node) { ByteArrayOutputStream out = new ByteArrayOutputStream() try { Transformer transformer = TransformerFactory.newInstance().newTransformer(); transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); Source source = new DOMSource(node); Result target = new StreamResult(out); transformer.transform(source, target); } catch (TransformerException e) { e.printStackTrace(); } String res = out.toString(); return res.replaceAll("<text .*>", "").replaceAll("</text>", ""); }
Závěr
V článku jsme popsali způsob, jakým CzechIdM tvoří emailové zprávy z XML šablon a ukázali jednoduché přidání jejich nové vlastnosti. Text šablon je nyní možné formátovat klasickým HTML. Pokud Vás článek zaujal a chtěli byste se dozvědět o mailovém subsystému v CzechIdM více, neváhejte mne kontaktovat na petr.fiser@bcvsolutions.eu.