/* * * Copyright 2013 Entando S.r.l. (http://www.entando.com) All rights reserved. * * This file is part of Entando software. * Entando is a free software; * You can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) as published by the Free Software Foundation; version 2. * * See the file License for the specific language governing permissions * and limitations under the License * * * * Copyright 2013 Entando S.r.l. (http://www.entando.com) All rights reserved. * */ package com.agiletec.plugins.jpnewsletter.aps.system.services.newsletter.parse; import java.io.StringReader; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Map.Entry; import org.jdom.CDATA; import org.jdom.Document; import org.jdom.Element; import org.jdom.input.SAXBuilder; import org.jdom.output.Format; import org.jdom.output.XMLOutputter; import com.agiletec.aps.system.ApsSystemUtils; import com.agiletec.aps.system.exception.ApsSystemException; import com.agiletec.aps.util.DateConverter; import com.agiletec.plugins.jpnewsletter.aps.system.services.newsletter.model.NewsletterConfig; import com.agiletec.plugins.jpnewsletter.aps.system.services.newsletter.model.NewsletterContentType; /* <newsletterConfig> <scheduler active="true" onlyOwner="false" delayHours="24" start="01/03/2007 11:08" /> <subscriptions allAttributeName="newsletter_allContents"> <descr> mappa delle corrispondeze tra attributo buleano 'sottoscrizione categoria newsletter' di profilo utente e categoria di contenuto/tematismo-newsletter </descr> <subscription categoryCode="food" attributeName="newsletter_food" /> <subscription categoryCode="travel" attributeName="newsletter_travel" /> ...... </subscriptions> <contentTypes> <contentType code="NWL" defaultModel="1" htmlModel="2" /> <contentType code="FOO" defaultModel="21" htmlModel="22" /> ....... </contentTypes> <mail senderCode="CODE1" mailAttrName="email" alsoHtml="true" unsubscriptionPage="newsletter_unsubscribe" > <subject><![CDATA[Oggetto della mail]]></subject> <htmlHeader><![CDATA[ <br />Header html della mail<br /> ]]></htmlHeader> <htmlFooter><![CDATA[ <br />Footer html della mail<br /> ]]></htmlFooter> <htmlSeparator><![CDATA[ Separatore html tra contenuti ]]></htmlSeparator> <textHeader><![CDATA[ Header text della mail ]]></textHeader> <textFooter><![CDATA[ Footer text della mail ]]></textFooter> <textSeparator><![CDATA[ Separatore text tra contenuti ]]></textSeparator> <subscriberHtmlFooter><![CDATA[Clicca sul link per cancellare la sottoscrizione <a href="{unsubscribeLink}" >CONFERMA</a></body></html>]]></htmlFooter> <subscriberTextFooter><![CDATA[Clicca sul link per cancellare la sottoscrizione <a href="{unsubscribeLink}" >CONFERMA</a>]]></textFooter> <subscription pageCode="newsletter_terminatereg" tokenValidityDays="90" > <subject><![CDATA[Conferma la sottoscrizione al servizio di Newsletter]]></subject> <htmlBody><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="it"> <head></head> <body><p>Clicca sul link per confermare <a href="{subscribeLink}" >***CONFERMA***</a></p> </body></html>]]></htmlBody> <textBody><![CDATA[Clicca sul link per confermare <a href="{subscribeLink}" >***CONFERMA***</a>]]></textBody> </subscription> </mail> </newsletterConfig> */ /** * Classe DOM delegata alle operazioni di lettura/scrittura della configurazione del servizio di newsletter. * * @author E.Santoboni, E.Mezzano */ public class NewsletterConfigDOM { /** * Extract the newsletter configuration from an xml. * @param xml The xml containing the configuration. * @return The newsletter configuration. * @throws ApsSystemException In case of parsing errors. */ public NewsletterConfig extractConfig(String xml) throws ApsSystemException { NewsletterConfig config = new NewsletterConfig(); Element root = this.getRootElement(xml); this.extractScheduler(root, config); this.extractSubscriptions(root, config); this.extractContentTypes(root, config); this.extractMailConfig(root, config); return config; } /** * Create an xml containing the newsletter configuration. * @param config The newsletter configuration. * @return The xml containing the configuration. * @throws ApsSystemException In case of errors. */ public String createConfigXml(NewsletterConfig config) throws ApsSystemException { Element root = this.createConfigElement(config); Document doc = new Document(root); XMLOutputter out = new XMLOutputter(); Format format = Format.getPrettyFormat(); format.setIndent("\t"); out.setFormat(format); String xml = out.outputString(doc); return xml; } private void extractScheduler(Element root, NewsletterConfig config) { Element schedulerElement = root.getChild(SCHEDULER_ELEM); String active = schedulerElement.getAttributeValue(SCHEDULER_ACTIVE_ATTR); config.setActive(active != null && active.equalsIgnoreCase("true")); String onlyOwner = schedulerElement.getAttributeValue(SCHEDULER_ONLYOWNER_ATTR); config.setOnlyOwner(onlyOwner != null && onlyOwner.equalsIgnoreCase("true")); String delayHours = schedulerElement.getAttributeValue(SCHEDULER_DELAYHOURS_ATTR); int hours = 1; if (delayHours != null && delayHours.length()>0) { hours = Integer.parseInt(delayHours); } config.setHoursDelay(hours); String start = schedulerElement.getAttributeValue(SCHEDULER_START_ATTR); if (start!=null && start.length()>0) { config.setStartScheduler(DateConverter.parseDate(start, SCHEDULER_STARTDATE_CONFIG_PATTERN)); } else { config.setStartScheduler(new Date()); } } /** * Estrae la parte di configurazione relativa alle sottoscrizioni, mappante le relazioni tra categorie e relativo attributo del profilo. * @param root L'elemento radice contenente il sottoelemento relativo alle sottoscrizioni. * @param config La configurazione del servizio newsletter. */ private void extractSubscriptions(Element root, NewsletterConfig config) { Element subscriptionsElem = root.getChild(SUBSCRIPTIONS_ELEM); String allContentsAttribute = subscriptionsElem.getAttributeValue(SUBSCRIPTIONS_ALL_ATTR); allContentsAttribute = (allContentsAttribute != null && allContentsAttribute.trim().length() > 0) ? allContentsAttribute.trim() : null; config.setAllContentsAttributeName(allContentsAttribute); List<Element> subscriptionElems = subscriptionsElem.getChildren(SUBSCRIPTION_CHILD); if (null != subscriptionElems) { for (int i=0; i<subscriptionElems.size(); i++) { Element subscriptionElem = (Element) subscriptionElems.get(i); String categoryCode = subscriptionElem.getAttributeValue(SUBSCRIPTION_CATEGORYCODE_ATTR); String attributeName = subscriptionElem.getAttributeValue(SUBSCRIPTION_ATTRIBUTENAME_ATTR); config.addSubscription(categoryCode, attributeName); } } } /** * Estrae la parte di configurazione relativa ai tipi di contenuto, contenente i modelli utilizzati per i tipi di contenuto notificabili. * @param root L'elemento radice contenente il sottoelemento relativo ai tipi di contenuto. * @param config La configurazione del servizio newsletter. */ private void extractContentTypes(Element root, NewsletterConfig config) { Element contentTypesElem = root.getChild(CONTENTTYPES_ELEM); if (null != contentTypesElem) { List<Element> contentTypeElements = contentTypesElem.getChildren(CONTENTTYPE_CHILD); if (null != contentTypeElements) { for (int i=0; i<contentTypeElements.size(); i++) { Element contentTypeElem = contentTypeElements.get(i); config.addContentType(this.extractContentType(contentTypeElem)); } } } } /** * Estrae la parte di configurazione relativa alla mail. * @param root L'elemento radice contenente il sottoelemento relativo alle mail. * @param config La configurazione del servizio newsletter. */ private void extractMailConfig(Element root, NewsletterConfig config) { Element mailElem = root.getChild(MAIL_ELEM); String alsoHtml = mailElem.getAttributeValue(MAIL_ALSOHTML_ATTR); config.setAlsoHtml(alsoHtml != null && "true".equalsIgnoreCase(alsoHtml)); String senderCode = mailElem.getAttributeValue(MAIL_SENDERCODE_ATTR); config.setSenderCode(senderCode); String mailAttrName = mailElem.getAttributeValue(MAIL_MAILATTRNAME_ATTR); config.setMailAttrName(mailAttrName); String unsubscriptionPage = mailElem.getAttributeValue(MAIL_UNSUBSCRIPTIONPAGE_ATTR); config.setUnsubscriptionPageCode(unsubscriptionPage); config.setSubject(mailElem.getChildText(MAIL_SUBJECT_CHILD)); config.setHtmlHeader(mailElem.getChildText(MAIL_HTML_HEADER_CHILD)); config.setHtmlFooter(mailElem.getChildText(MAIL_HTML_FOOTER_CHILD)); config.setHtmlSeparator(mailElem.getChildText(MAIL_HTML_SEPARATOR_CHILD)); config.setTextHeader(mailElem.getChildText(MAIL_TEXT_HEADER_CHILD)); config.setTextFooter(mailElem.getChildText(MAIL_TEXT_FOOTER_CHILD)); config.setTextSeparator(mailElem.getChildText(MAIL_TEXT_SEPARATOR_CHILD)); config.setSubscribersHtmlFooter(mailElem.getChildText(MAIL_SUBSCRIBER_HTML_FOOTER_CHILD)); config.setSubscribersTextFooter(mailElem.getChildText(MAIL_SUBSCRIBER_TEXT_FOOTER_CHILD)); Element subscriptionElem = mailElem.getChild(MAIL_SUBSCRIPTION_CHILD); if (subscriptionElem!=null) { String pageCode = subscriptionElem.getAttributeValue(MAIL_SUBSCRIPTION_PAGECODE_ATTR); config.setSubscriptionPageCode(pageCode); String tokenValidity = subscriptionElem.getAttributeValue(MAIL_SUBSCRIPTION_TOKENVALIDITY_ATTR); config.setSubscriptionTokenValidityDays(Integer.parseInt(tokenValidity)); config.setSubscriptionSubject(subscriptionElem.getChildText(MAIL_SUBSCRIPTION_SUBJECT_CHILD)); config.setSubscriptionHtmlBody(subscriptionElem.getChildText(MAIL_SUBSCRIPTION_HTML_CHILD)); config.setSubscriptionTextBody(subscriptionElem.getChildText(MAIL_SUBSCRIPTION_TEXT_CHILD)); } } /** * Estrae la parte di configurazione relativa ad un singolo tipo di contenuto. * @param contentTypeElem L'elemento contenente la configurazione di un singolo tipo di contenuto. * @return La configurazione del tipo di contenuto. */ protected NewsletterContentType extractContentType(Element contentTypeElem) { NewsletterContentType contentType = new NewsletterContentType(); String contentTypeCode = contentTypeElem.getAttributeValue(CONTENTTYPE_CODE_ATTR); contentType.setContentTypeCode(contentTypeCode); String defaultModel = contentTypeElem.getAttributeValue(CONTENTTYPE_DEFMODEL_ATTR); contentType.setSimpleTextModel(Integer.parseInt(defaultModel)); String htmlModel = contentTypeElem.getAttributeValue(CONTENTTYPE_HTMLMODEL_ATTR); if (htmlModel!=null && htmlModel.length()>0) { contentType.setHtmlModel(Integer.parseInt(htmlModel)); } return contentType; } /** * Crea l'elemento della configurazione del servizio di newsletter. * @param config La configurazione del servizio newsletter. * @return L'elemento della configurazione del servizio di newsletter. */ private Element createConfigElement(NewsletterConfig config) { Element configElem = new Element(ROOT); Element shcedulerElem = this.createSchedulerElement(config); configElem.addContent(shcedulerElem); Element subscriptionsElem = this.createSubscriptionsElement(config); configElem.addContent(subscriptionsElem); Element contentTypesElem = this.createContentTypesElement(config); configElem.addContent(contentTypesElem); Element mailElem = this.createMailElement(config); configElem.addContent(mailElem); return configElem; } /** * Crea l'elemento della configurazione relativa alle sottoscrizioni. * @param config La configurazione del servizio newsletter. * @return L'elemento di configurazione relativo alle sottoscrizioni. */ private Element createSubscriptionsElement(NewsletterConfig config) { Element subscriptionsElem = new Element(SUBSCRIPTIONS_ELEM); String allContentsAttribute = config.getAllContentsAttributeName(); allContentsAttribute = allContentsAttribute != null ? allContentsAttribute.trim() : ""; subscriptionsElem.setAttribute(SUBSCRIPTIONS_ALL_ATTR, allContentsAttribute); Iterator subscriptionsIter = config.getSubscriptions().entrySet().iterator(); while (subscriptionsIter.hasNext()) { Entry subscriptionEntry = (Entry) subscriptionsIter.next(); Element subscriptionChild = new Element(SUBSCRIPTION_CHILD); String categoryCode = (String) subscriptionEntry.getKey(); subscriptionChild.setAttribute(SUBSCRIPTION_CATEGORYCODE_ATTR, categoryCode); String attributeName = (String) subscriptionEntry.getValue(); subscriptionChild.setAttribute(SUBSCRIPTION_ATTRIBUTENAME_ATTR, attributeName); subscriptionsElem.addContent(subscriptionChild); } return subscriptionsElem; } private Element createSchedulerElement(NewsletterConfig config) { Element schedulerElement = new Element(SCHEDULER_ELEM); schedulerElement.setAttribute(SCHEDULER_ACTIVE_ATTR, String.valueOf(config.isActive())); schedulerElement.setAttribute(SCHEDULER_ONLYOWNER_ATTR, String.valueOf(config.isOnlyOwner())); schedulerElement.setAttribute(SCHEDULER_DELAYHOURS_ATTR, String.valueOf(config.getHoursDelay())); schedulerElement.setAttribute(SCHEDULER_START_ATTR, DateConverter.getFormattedDate(config.getStartScheduler(), SCHEDULER_STARTDATE_CONFIG_PATTERN)); return schedulerElement; } /** * Crea l'elemento della configurazione relativa ai tipi di contenuto. * @param config La configurazione del servizio newsletter. * @return L'elemento di configurazione relativo ai tipi di contenuto. */ protected Element createContentTypesElement(NewsletterConfig config) { Element contentTypesElem = new Element(CONTENTTYPES_ELEM); Iterator<NewsletterContentType> contentTypesIter = config.getContentTypes().values().iterator(); while (contentTypesIter.hasNext()) { NewsletterContentType contentType = contentTypesIter.next(); Element contentTypeChild = new Element(CONTENTTYPE_CHILD); contentTypeChild.setAttribute(CONTENTTYPE_CODE_ATTR, contentType.getContentTypeCode()); String textModel = String.valueOf(contentType.getSimpleTextModel()); contentTypeChild.setAttribute(CONTENTTYPE_DEFMODEL_ATTR, textModel); String htmlModel = String.valueOf(contentType.getHtmlModel()); contentTypeChild.setAttribute(CONTENTTYPE_HTMLMODEL_ATTR, htmlModel); contentTypesElem.addContent(contentTypeChild); } return contentTypesElem; } /** * Crea l'elemento della configurazione relativa alle mail. * @param config La configurazione del servizio newsletter. * @return L'elemento di configurazione relativo alle mail. */ private Element createMailElement(NewsletterConfig config) { Element mailElem = new Element(MAIL_ELEM); mailElem.setAttribute(MAIL_ALSOHTML_ATTR, String.valueOf(config.isAlsoHtml())); mailElem.setAttribute(MAIL_SENDERCODE_ATTR, config.getSenderCode()); mailElem.setAttribute(MAIL_MAILATTRNAME_ATTR, config.getMailAttrName()); mailElem.setAttribute(MAIL_UNSUBSCRIPTIONPAGE_ATTR, config.getUnsubscriptionPageCode()); Element subject = new Element(MAIL_SUBJECT_CHILD); subject.addContent(new CDATA(config.getSubject())); mailElem.addContent(subject); Element htmlHeader = new Element(MAIL_HTML_HEADER_CHILD); htmlHeader.addContent(new CDATA(config.getHtmlHeader())); mailElem.addContent(htmlHeader); Element htmlFooter = new Element(MAIL_HTML_FOOTER_CHILD); htmlFooter.addContent(new CDATA(config.getHtmlFooter())); mailElem.addContent(htmlFooter); Element htmlSeparator = new Element(MAIL_HTML_SEPARATOR_CHILD); htmlSeparator.addContent(new CDATA(config.getHtmlSeparator())); mailElem.addContent(htmlSeparator); Element textHeader = new Element(MAIL_TEXT_HEADER_CHILD); textHeader.addContent(new CDATA(config.getTextHeader())); mailElem.addContent(textHeader); Element textFooter = new Element(MAIL_TEXT_FOOTER_CHILD); textFooter.addContent(new CDATA(config.getTextFooter())); mailElem.addContent(textFooter); Element textSeparator = new Element(MAIL_TEXT_SEPARATOR_CHILD); textSeparator.addContent(new CDATA(config.getTextSeparator())); mailElem.addContent(textSeparator); Element subscribersHtmlFooter = new Element(MAIL_SUBSCRIBER_HTML_FOOTER_CHILD); subscribersHtmlFooter.addContent(new CDATA(config.getSubscribersHtmlFooter())); mailElem.addContent(subscribersHtmlFooter); Element subscribersTextFooter = new Element(MAIL_SUBSCRIBER_TEXT_FOOTER_CHILD); subscribersTextFooter.addContent(new CDATA(config.getSubscribersTextFooter())); mailElem.addContent(subscribersTextFooter); Element subscriptionElem = new Element(MAIL_SUBSCRIPTION_CHILD); subscriptionElem.setAttribute(MAIL_SUBSCRIPTION_PAGECODE_ATTR, config.getSubscriptionPageCode()); subscriptionElem.setAttribute(MAIL_SUBSCRIPTION_TOKENVALIDITY_ATTR, String.valueOf(config.getSubscriptionTokenValidityDays())); Element subscriptionSubject = new Element(MAIL_SUBSCRIPTION_SUBJECT_CHILD); subscriptionSubject.addContent(new CDATA(config.getSubscriptionSubject())); subscriptionElem.addContent(subscriptionSubject); Element subscriptionTextBody = new Element(MAIL_SUBSCRIPTION_HTML_CHILD); subscriptionTextBody.addContent(new CDATA(config.getSubscriptionHtmlBody())); subscriptionElem.addContent(subscriptionTextBody); Element subscriptionHtmlBody = new Element(MAIL_SUBSCRIPTION_TEXT_CHILD); subscriptionHtmlBody.addContent(new CDATA(config.getSubscriptionTextBody())); subscriptionElem.addContent(subscriptionHtmlBody); mailElem.addContent(subscriptionElem); return mailElem; } /** * Returns the Xml element from a given text. * @param xmlText The text containing an Xml. * @return The Xml element from a given text. * @throws ApsSystemException In case of parsing exceptions. */ private Element getRootElement(String xmlText) throws ApsSystemException { SAXBuilder builder = new SAXBuilder(); builder.setValidation(false); StringReader reader = new StringReader(xmlText); Element root = null; try { Document doc = builder.build(reader); root = doc.getRootElement(); } catch (Throwable t) { ApsSystemUtils.getLogger().error("Error parsing xml: " + t.getMessage()); throw new ApsSystemException("Error parsing xml", t); } return root; } private static final String ROOT = "newsletterConfig"; private static final String SCHEDULER_ELEM = "scheduler"; private static final String SCHEDULER_ACTIVE_ATTR = "active"; private static final String SCHEDULER_ONLYOWNER_ATTR = "onlyOwner"; private static final String SCHEDULER_DELAYHOURS_ATTR = "delayHours"; private static final String SCHEDULER_START_ATTR = "start"; private static final String SUBSCRIPTIONS_ELEM = "subscriptions"; private static final String SUBSCRIPTIONS_ALL_ATTR = "allAttributeName"; private static final String SUBSCRIPTION_CHILD = "subscription"; private static final String SUBSCRIPTION_CATEGORYCODE_ATTR = "categoryCode"; private static final String SUBSCRIPTION_ATTRIBUTENAME_ATTR = "attributeName"; protected static final String CONTENTTYPES_ELEM = "contentTypes"; protected static final String CONTENTTYPE_CHILD = "contentType"; protected static final String CONTENTTYPE_CODE_ATTR = "code"; protected static final String CONTENTTYPE_DEFMODEL_ATTR = "defaultModel"; protected static final String CONTENTTYPE_HTMLMODEL_ATTR = "htmlModel"; private static final String MAIL_ELEM = "mail"; private static final String MAIL_ALSOHTML_ATTR = "alsoHtml"; private static final String MAIL_SENDERCODE_ATTR = "senderCode"; private static final String MAIL_MAILATTRNAME_ATTR = "mailAttrName"; private static final String MAIL_UNSUBSCRIPTIONPAGE_ATTR = "unsubscriptionPage"; private static final String MAIL_SUBJECT_CHILD = "subject"; private static final String MAIL_HTML_HEADER_CHILD = "htmlHeader"; private static final String MAIL_HTML_FOOTER_CHILD = "htmlFooter"; private static final String MAIL_HTML_SEPARATOR_CHILD = "htmlSeparator"; private static final String MAIL_TEXT_HEADER_CHILD = "textHeader"; private static final String MAIL_TEXT_FOOTER_CHILD = "textFooter"; private static final String MAIL_TEXT_SEPARATOR_CHILD = "textSeparator"; private static final String MAIL_SUBSCRIBER_HTML_FOOTER_CHILD = "subscriberHtmlFooter"; private static final String MAIL_SUBSCRIBER_TEXT_FOOTER_CHILD = "subscriberTextFooter"; private static final String MAIL_SUBSCRIPTION_CHILD = "subscription"; private static final String MAIL_SUBSCRIPTION_PAGECODE_ATTR = "pageCode"; private static final String MAIL_SUBSCRIPTION_TOKENVALIDITY_ATTR = "tokenValidityDays"; private static final String MAIL_SUBSCRIPTION_SUBJECT_CHILD = "subject"; private static final String MAIL_SUBSCRIPTION_HTML_CHILD = "htmlBody"; private static final String MAIL_SUBSCRIPTION_TEXT_CHILD = "textBody"; private static final String SCHEDULER_STARTDATE_CONFIG_PATTERN = "dd/MM/yyyy HH:mm"; }