Java tutorial
/********************************************************************************* * The contents of this file are subject to the Common Public Attribution * License Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.openemm.org/cpal1.html. The License is based on the Mozilla * Public License Version 1.1 but Sections 14 and 15 have been added to cover * use of software over a computer network and provide for limited attribution * for the Original Developer. In addition, Exhibit A has been modified to be * consistent with Exhibit B. * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for * the specific language governing rights and limitations under the License. * * The Original Code is OpenEMM. * The Original Developer is the Initial Developer. * The Initial Developer of the Original Code is AGNITAS AG. All portions of * the code written by AGNITAS AG are Copyright (c) 2007 AGNITAS AG. All Rights * Reserved. * * Contributor(s): AGNITAS AG. ********************************************************************************/ package org.agnitas.beans.impl; import java.io.LineNumberReader; import java.io.StringReader; import java.sql.Connection; import java.sql.Timestamp; import java.util.Collection; import java.util.Comparator; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; import java.util.Vector; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.sql.DataSource; import org.agnitas.backend.Mailgun; import org.agnitas.beans.DynamicTag; import org.agnitas.beans.DynamicTagContent; import org.agnitas.beans.MaildropEntry; import org.agnitas.beans.Mailing; import org.agnitas.beans.MailingComponent; import org.agnitas.beans.Mediatype; import org.agnitas.beans.MediatypeEmail; import org.agnitas.beans.TagDetails; import org.agnitas.beans.TrackableLink; import org.agnitas.dao.DynamicTagDao; import org.agnitas.dao.MaildropStatusDao; import org.agnitas.dao.TargetDao; import org.agnitas.target.Target; import org.agnitas.util.AgnTagUtils; import org.agnitas.util.AgnUtils; import org.agnitas.util.SafeString; import org.agnitas.util.TimeoutLRUMap; import org.apache.commons.beanutils.BeanUtils; import org.apache.log4j.Logger; import org.springframework.context.ApplicationContext; import org.springframework.jdbc.datasource.DataSourceUtils; import bsh.Interpreter; /** * * @author Martin Helff, Nicole Serek */ public class MailingImpl extends MailingBaseImpl implements Mailing { private static final transient Logger logger = Logger.getLogger(MailingImpl.class); private static final long serialVersionUID = -6126128329645532973L; protected int mailTemplateID; protected int targetID; protected Map<String, DynamicTag> dynTags = new LinkedHashMap<String, DynamicTag>(); protected Map<String, MailingComponent> components = new LinkedHashMap<String, MailingComponent>(); protected Hashtable<String, MailingComponent> attachments; protected Map<String, TrackableLink> trackableLinks = new LinkedHashMap<String, TrackableLink>(); protected int searchPos; protected int clickActionID; protected int openActionID; protected Set<MaildropEntry> maildropStatus = new LinkedHashSet<MaildropEntry>(); protected Map<Integer, Mediatype> mediatypes = new LinkedHashMap<Integer, Mediatype>(); protected Timestamp creationDate; protected Map<Integer, Target> allowedTargets = null; protected Collection<Integer> targetGroups; protected int maildropID; protected int templateOK; protected boolean isTemplate; protected int targetMode; protected String targetExpression; protected int deleted; protected boolean needsTarget; protected boolean locked; protected boolean archived; /** * mailingType can hold the values 0-3 0: Normal mailing 1: Action-Based 2: * Date-Based 3: Followup Defined in Mailing.java eg. TYPE_NORMAL */ protected int mailingType; @Override public boolean parseTargetExpression(String tExp) { boolean result = true; int posA = 0; int posB = 0; String targetID = null; Integer tmpInt = null; char tmpOp = '&'; this.targetMode = MailingImpl.TARGET_MODE_AND; if (tExp == null) { return result; } if (tExp.indexOf('|') != -1) { this.targetMode = MailingImpl.TARGET_MODE_OR; tmpOp = '|'; } while ((posB = tExp.indexOf(tmpOp, posA)) != -1) { targetID = tExp.substring(posA, posB).trim(); posA = posB + 1; try { tmpInt = new Integer(Integer.parseInt(targetID)); if (this.targetGroups == null) { this.targetGroups = new HashSet<Integer>(); } this.targetGroups.add(tmpInt); } catch (Exception e) { logger.error("parseTargetExpression", e); tmpInt = null; } } if (posA < tExp.length()) { targetID = tExp.substring(posA).trim(); try { tmpInt = new Integer(Integer.parseInt(targetID)); if (this.targetGroups == null) { this.targetGroups = new HashSet<Integer>(); } this.targetGroups.add(tmpInt); } catch (Exception e) { logger.error("parseTargetExpression", e); tmpInt = null; } } return result; } public void updateTargetExpression() { this.targetExpression = this.generateTargetExpression(); } protected String generateTargetExpression() { StringBuffer tmp = new StringBuffer(""); Integer tmpInt = null; boolean isFirst = true; String opTmp = " & "; if (this.targetMode == MailingImpl.TARGET_MODE_OR) { opTmp = " | "; } if (this.targetGroups == null) { return ""; } Iterator<Integer> aIt = this.targetGroups.iterator(); while (aIt.hasNext()) { tmpInt = aIt.next(); if (tmpInt.intValue() != 0) { if (!isFirst) { tmp.append(opTmp); } else { isFirst = false; } tmp.append(tmpInt.toString()); } } return tmp.toString(); } @Override public void addComponent(MailingComponent aComp) { if (components == null) components = new HashMap<String, MailingComponent>(); if (!components.containsKey(aComp.getComponentName())) { components.put(aComp.getComponentName(), aComp); } } private void addComponents(Set<MailingComponent> components) { for (MailingComponent component : components) addComponent(component); } @Override public void addAttachment(MailingComponent aComp) { if (attachments == null) attachments = new Hashtable<String, MailingComponent>(); attachments.put(aComp.getComponentName(), aComp); } @Override public void setTargetID(int tmpid) { targetID = tmpid; } @Override public void setMailTemplateID(int tmpid) { mailTemplateID = tmpid; } @Override public Map<String, DynamicTag> getDynTags() { return dynTags; } @Override public Vector<String> findDynTagsInTemplates(String aTemplate, ApplicationContext con) throws Exception { DynamicTag aktTag = null; Vector<String> addedTags = new Vector<String>(); searchPos = 0; if (aTemplate != null) { while ((aktTag = findNextDynTag(aTemplate, con)) != null) { addDynamicTag(aktTag); addedTags.add(aktTag.getDynName()); } } return addedTags; } public Vector<String> findDynTagsInTemplates(ApplicationContext con) throws Exception { Vector<String> addedTags = new Vector<String>(); MailingComponent tmpComp = null; searchPos = 0; Iterator<MailingComponent> it = this.components.values().iterator(); while (it.hasNext()) { tmpComp = it.next(); if (tmpComp.getType() == MailingComponent.TYPE_TEMPLATE) { addedTags.addAll(this.findDynTagsInTemplates(tmpComp.getEmmBlock(), con)); } } return addedTags; } public Vector<String> scanForComponents(ApplicationContext con) throws Exception { Vector<String> addedTags = new Vector<String>(); MailingComponent tmpComp = null; DynamicTag dyntag = null; DynamicTagContent dyncontent = null; searchPos = 0; Set<MailingComponent> componentsToAdd = new HashSet<MailingComponent>(); Iterator<MailingComponent> itComponents = this.components.values().iterator(); while (itComponents.hasNext()) { tmpComp = itComponents.next(); if (tmpComp.getType() == MailingComponent.TYPE_TEMPLATE) { addedTags.addAll(this.scanForComponents(tmpComp.getEmmBlock(), con, componentsToAdd)); } } addComponents(componentsToAdd); componentsToAdd.clear(); Iterator<DynamicTag> itDynTag = this.dynTags.values().iterator(); while (itDynTag.hasNext()) { dyntag = (DynamicTag) itDynTag.next(); Iterator<DynamicTagContent> it2 = dyntag.getDynContent().values().iterator(); while (it2.hasNext()) { dyncontent = it2.next(); addedTags.addAll(this.scanForComponents(dyncontent.getDynContent(), con, componentsToAdd)); } } addComponents(componentsToAdd); return addedTags; } @Override public Vector<String> scanForLinks(ApplicationContext con) throws Exception { Vector<String> addedLinks = new Vector<String>(); MailingComponent tmpComp = null; DynamicTag dyntag = null; DynamicTagContent dyncontent = null; searchPos = 0; Iterator<MailingComponent> itComponents = this.components.values().iterator(); while (itComponents.hasNext()) { tmpComp = itComponents.next(); if (tmpComp.getType() == MailingComponent.TYPE_TEMPLATE) { addedLinks.addAll(this.scanForLinks(tmpComp.getEmmBlock(), con)); } } Iterator<DynamicTag> itDynTag = this.dynTags.values().iterator(); while (itDynTag.hasNext()) { dyntag = (DynamicTag) itDynTag.next(); Iterator<DynamicTagContent> it2 = dyntag.getDynContent().values().iterator(); while (it2.hasNext()) { dyncontent = it2.next(); addedLinks.addAll(this.scanForLinks(dyncontent.getDynContent(), con)); } } return addedLinks; } @Override public void addDynamicTag(DynamicTag aTag) { if (!this.dynTags.containsKey(aTag.getDynName())) { dynTags.put(aTag.getDynName(), aTag); } DynamicTag dbTag = this.dynTags.get(aTag.getDynName()); if (dbTag.getGroup() != aTag.getGroup()) { dbTag.setGroup(aTag.getGroup()); } } @Override public DynamicTag findNextDynTag(String aTemplate, ApplicationContext con) throws Exception { int valueTagStartPos; int oldPos; DynamicTag aDynTag = null; TagDetails aStartTag = null; TagDetails aEndTag = null; TagDetails aValueTag = null; aStartTag = getOneTag(aTemplate, "agnDYN", searchPos, con); if (aStartTag == null) return null; aStartTag.analyzeParameters(); aStartTag.findTagParameters(); searchPos = aStartTag.getEndPos(); aDynTag = (DynamicTag) con.getBean("DynamicTag"); aDynTag.setCompanyID(companyID); aDynTag.setMailingID(id); aDynTag.setComplex(aStartTag.isComplex()); aDynTag.setDynName(aStartTag.getName()); int group = 0; Map<String, String> params = aStartTag.getTagParameters(); if (params != null) { String gname = (String) params.get("group"); if (gname != null) { DynamicTagDao dao = (DynamicTagDao) con.getBean("DynamicTagDao"); group = dao.getIdForName(this.id, gname); } } aDynTag.setGroup(group); if (aStartTag.isComplex()) { oldPos = searchPos; do { aEndTag = getOneTag(aTemplate, "/agnDYN", searchPos, con); if (aEndTag == null) { LineNumberReader aReader = new LineNumberReader(new StringReader(aTemplate)); aReader.skip(searchPos); throw new Exception("NoEndTag$" + aReader.getLineNumber() + "$" + aStartTag.getName()); } searchPos = aEndTag.getEndPos(); aEndTag.analyzeParameters(); } while (aStartTag.getName().compareTo(aEndTag.getName()) != 0); String valueArea = aTemplate.substring(aStartTag.getEndPos(), aEndTag.getStartPos()); valueTagStartPos = 0; do { aValueTag = getOneTag(valueArea, "agnDVALUE", valueTagStartPos, con); if (aValueTag == null) { LineNumberReader aReader = new LineNumberReader(new StringReader(aTemplate)); aReader.skip(searchPos); throw new Exception("NoValueTag$" + aReader.getLineNumber() + "$" + aStartTag.getName()); } valueTagStartPos = aValueTag.getEndPos(); aValueTag.analyzeParameters(); } while (aStartTag.getName().compareTo(aValueTag.getName()) != 0); searchPos = oldPos; aDynTag.setStartTagStart(aStartTag.getStartPos()); aDynTag.setStartTagEnd(aStartTag.getEndPos()); aDynTag.setValueTagStart(aStartTag.getEndPos() + aValueTag.getStartPos()); aDynTag.setValueTagEnd(aStartTag.getEndPos() + aValueTag.getEndPos()); aDynTag.setEndTagStart(aEndTag.getStartPos()); aDynTag.setEndTagEnd(aEndTag.getEndPos()); } else { aDynTag.setStartTagStart(aStartTag.getStartPos()); aDynTag.setStartTagEnd(aStartTag.getEndPos()); } return aDynTag; } protected TagDetails getOneTag(String aTemplate, String TagName, int startPos, ApplicationContext con) throws Exception { return getOneTag(aTemplate, TagName, startPos, "[", "]", con); } protected TagDetails getOneTag(String aTemplate, String TagName, int startPos, String startMark, String endMark, ApplicationContext con) throws Exception { int posOfDynTag = 0; int endOfDynTag = 0; TagDetails det = (TagDetails) con.getBean("TagDetails"); posOfDynTag = aTemplate.indexOf(startMark + TagName, startPos); // Search // for // next // DYN-Tag if (posOfDynTag == -1) // if not DYN-Tag is found, return null return null; endOfDynTag = aTemplate.indexOf(endMark, posOfDynTag + 7); // Search for // a closing // bracket if (endOfDynTag == -1) // if the Tag-Closing Bracket is missing, throw a // exception throw new Exception("Missing Bracket$" + startPos); endOfDynTag++; det.setStartPos(posOfDynTag); det.setEndPos(endOfDynTag); det.setFullText(aTemplate.substring(posOfDynTag, endOfDynTag)); return det; } private Vector<String> scanForComponents(String aText1, ApplicationContext con, Set<MailingComponent> componentsToAdd) { Vector<String> addComps = new Vector<String>(); String aText = null; String aLink = null; int startMatch = 0; int endMatch = 0; MailingComponent tmpComp = null; if (aText1 == null) { return addComps; } try { aText = aText1.toLowerCase(); Pattern aRegExp = Pattern.compile("https?://[0-9A-Za-z_.+-]+(:[0-9]+)?(/[^ \t\n\r<>\")]*)?"); Matcher aMatch = aRegExp.matcher(aText); while (true) { if (!aMatch.find(endMatch)) { break; } startMatch = aMatch.start(); endMatch = aMatch.end(); if (aText.regionMatches(false, startMatch - 5, "src=\"", 0, 5) || aText.regionMatches(false, startMatch - 4, "src=", 0, 4) || aText.regionMatches(false, startMatch - 11, "background=", 0, 11) || aText.regionMatches(false, startMatch - 12, "background=\"", 0, 12)) { aLink = aText1.substring(startMatch, endMatch); tmpComp = (MailingComponent) con.getBean("MailingComponent"); tmpComp.setCompanyID(companyID); tmpComp.setMailingID(this.id); tmpComp.setComponentName(aLink); tmpComp.setType(MailingComponentImpl.TYPE_IMAGE); if (!components.containsKey(aLink)) { tmpComp.loadContentFromURL(); if (tmpComp.getMimeType().startsWith("image")) { // addComponent(tmpComp); // We will do that later componentsToAdd.add(tmpComp); } } else { tmpComp = (MailingComponent) this.components.get(aLink); } if (tmpComp.getMimeType().startsWith("image")) { addComps.add(aLink); } } } } catch (Exception e) { logger.error("scanForComponents", e); } return addComps; } @Override public Vector<String> scanForLinks(String aText1, ApplicationContext con) { String aLink = null; int start = 0; int end = 0; MailingComponent tmpComp = null; TrackableLink trkLink = null; Vector<String> addedLinks = new Vector<String>(); if (aText1 == null) { return addedLinks; } TagDetails aDetail = (TagDetails) con.getBean("TagDetails"); aDetail.setTagName("agnPROFILE"); aText1 = aText1.replaceAll("\\[agnPROFILE\\]", AgnTagUtils.processTag(aDetail, 0, con, id, mailinglistID, companyID)); aDetail.setTagName("agnUNSUBSCRIBE"); aText1 = aText1.replaceAll("\\[agnUNSUBSCRIBE\\]", AgnTagUtils.processTag(aDetail, 0, con, id, mailinglistID, companyID)); try { if ((aDetail = getFormTag(aText1, "agnFORM", 0, "[", "]", con)) != null) { aDetail.setTagName("agnFORM"); int beginIndex = aDetail.getFullText().indexOf('"') + 1; int endIndex = aDetail.getFullText().indexOf('"', beginIndex); aDetail.setName(aDetail.getFullText().substring(beginIndex, endIndex)); aText1 = aText1.replaceAll("\\[agnFORM name=\".*?\"\\]", AgnTagUtils.processTag(aDetail, 0, con, id, mailinglistID, companyID)); } } catch (Exception e) { logger.error("scanForLinks", e); } try { Pattern aRegExp = Pattern.compile("https?://[0-9A-Za-z_.+-]+(:[0-9]+)?(/[^ \t\n\r<>\")]*)?"); Matcher aMatch = aRegExp.matcher(aText1); while (true) { if (!aMatch.find(end)) { break; } start = aMatch.start(); end = aMatch.end(); try { if ((start == 0) || aText1.regionMatches(false, start - 5, "src=\"", 0, 5) || aText1.regionMatches(false, start - 4, "src=", 0, 4) || aText1.regionMatches(false, start - 11, "background=", 0, 11) || aText1.regionMatches(false, start - 12, "background=\"", 0, 12)) { aLink = aText1.substring(start, end); if (!components.containsKey(aLink) && !trackableLinks.containsKey(aLink)) { tmpComp = (MailingComponent) con.getBean("MailingComponent"); tmpComp.setCompanyID(companyID); tmpComp.setMailingID(id); tmpComp.setComponentName(aLink); tmpComp.setType(MailingComponent.TYPE_IMAGE); tmpComp.loadContentFromURL(); if (!tmpComp.getMimeType().startsWith("image")) { // if(start == 0) { // aLink = aText1.substring(start, end); if (!trackableLinks.containsKey(aLink)) { trkLink = (TrackableLink) con.getBean("TrackableLink"); trkLink.setCompanyID(this.companyID); trkLink.setFullUrl(aLink); trkLink.setMailingID(this.id); trkLink.setUsage(TrackableLink.TRACKABLE_TEXT_HTML); trkLink.setActionID(0); trackableLinks.put(aLink, trkLink); } // } } } addedLinks.add(aLink); } else { aLink = aText1.substring(start, end); if (!trackableLinks.containsKey(aLink)) { trkLink = (TrackableLink) con.getBean("TrackableLink"); trkLink.setCompanyID(this.companyID); trkLink.setFullUrl(aLink); trkLink.setMailingID(this.id); trkLink.setUsage(TrackableLink.TRACKABLE_TEXT_HTML); trkLink.setActionID(0); trackableLinks.put(aLink, trkLink); } addedLinks.add(aLink); } } catch (Exception e) { logger.error("scanForLinks: Error processing link", e); } } } catch (Exception e) { logger.error("scanForLinks: error processing links", e); } return addedLinks; } @Override public java.sql.Timestamp getCreationDate() { return creationDate; } @Override public void setCreationDate(java.sql.Timestamp creationDate) { this.creationDate = creationDate; } @Override public boolean triggerMailing(int maildropStatusID, Hashtable<String, Object> opts, ApplicationContext con) { Mailgun aMailgun = null; DataSource ds = (DataSource) con.getBean("dataSource"); Connection dbCon = DataSourceUtils.getConnection(ds); boolean exitValue = true; try { if (maildropStatusID == 0) { throw new Exception("maildropStatusID is 0"); } aMailgun = (Mailgun) con.getBean("Mailgun"); aMailgun.initializeMailgun(Integer.toString(maildropStatusID)); aMailgun.prepareMailgun(new Hashtable<String, Object>()); aMailgun.executeMailgun(opts); } catch (Exception e) { logger.error("triggerMailing", e); exitValue = false; } DataSourceUtils.releaseConnection(dbCon, ds); return exitValue; } @Override public boolean isWorldMailingSend() { boolean returnValue = false; char status = MaildropEntry.STATUS_WORLD; MaildropEntry drop = null; switch (this.mailingType) { case Mailing.TYPE_ACTIONBASED: status = MaildropEntry.STATUS_ACTIONBASED; break; case Mailing.TYPE_DATEBASED: status = MaildropEntry.STATUS_DATEBASED; break; } Iterator<MaildropEntry> it = this.maildropStatus.iterator(); while (it.hasNext()) { drop = it.next(); if (drop.getStatus() == status) { returnValue = true; } } return returnValue; } @Override public Map<String, MailingComponent> getComponents() { return this.components; } @Override public Map<String, TrackableLink> getTrackableLinks() { return this.trackableLinks; } @Override public int getTargetID() { return targetID; } @Override public boolean sendEventMailing(int customerID, int delayMinutes, String userStatus, Hashtable<String, String> overwrite, ApplicationContext con) { boolean exitValue = true; Mailgun aMailgun = null; TimeoutLRUMap mailgunCache = (TimeoutLRUMap) con.getBean("mailgunCache"); MaildropEntry entry = null; int maildropStatusID = 0; try { aMailgun = (Mailgun) mailgunCache .get(Integer.toString(this.companyID) + "_" + Integer.toString(this.id)); if (aMailgun == null) { Iterator<MaildropEntry> it = this.getMaildropStatus().iterator(); while (it.hasNext()) { entry = it.next(); if (entry.getStatus() == MaildropEntry.STATUS_ACTIONBASED) { maildropStatusID = entry.getId(); } } if (maildropStatusID == 0) { throw new Exception("maildropStatusID is 0"); } aMailgun = (Mailgun) con.getBean("Mailgun"); if (aMailgun == null) { logger.error("Mailgun could not be created: " + this.id); } aMailgun.initializeMailgun(Integer.toString(maildropStatusID)); aMailgun.prepareMailgun(new Hashtable<String, Object>()); mailgunCache.put(Integer.toString(this.companyID) + "_" + Integer.toString(this.id), aMailgun); } if (aMailgun != null) { Hashtable<String, Object> opts = new Hashtable<String, Object>(); opts.put("customer-id", Integer.toString(customerID)); if (overwrite != null) { opts.put("overwrite", overwrite); } java.util.Date aDate = new java.util.Date(); long millis = aDate.getTime(); millis += (delayMinutes * 60000); aDate.setTime(millis); opts.put("send-date", aDate); if (userStatus != null) { opts.put("user-status", userStatus); } aMailgun.executeMailgun(opts); } } catch (Exception e) { logger.error("Fire Campaign-Mail", e); exitValue = false; } return exitValue; } /** * Getter for property mailingType. * * @return Value of property mailingType. */ @Override public int getMailingType() { return this.mailingType; } /** * Setter for property mailingType. * * @param mailingType * New value of property mailingType. */ @Override public void setMailingType(int mailingType) { this.mailingType = mailingType; } @Override public boolean cleanupMaildrop(ApplicationContext con) { Iterator<MaildropEntry> it = this.maildropStatus.iterator(); MaildropEntry entry = null; LinkedList<MaildropEntry> del = new LinkedList<MaildropEntry>(); MaildropStatusDao dao = (MaildropStatusDao) con.getBean("MaildropStatusDao"); while (it.hasNext()) { entry = (MaildropEntry) it.next(); if (entry.getStatus() == 'E' || entry.getStatus() == 'R') { del.add(entry); if (AgnUtils.isOracleDB()) { dao.delete(entry.getId()); } } } it = del.iterator(); while (it.hasNext()) { entry = it.next(); this.maildropStatus.remove(entry); } return true; } @Override public String getPreview(String input, int inputType, int customerID, ApplicationContext con) throws Exception { return getPreview(input, inputType, customerID, false, con); } @Override public String getPreview(String input_org, int inputType, int customerID, boolean overwriteMailtype, ApplicationContext con) throws Exception { DynamicTag aktTag = null; DynamicTag tmpTag = null; DynamicTag contentTag = null; String contentString = null; DynamicTagContent aContent = null; DynamicTagContent aTmpContent = null; Target aTarget = null; int aTargetID = 0; Hashtable<String, DynamicTag> allTags = new Hashtable<String, DynamicTag>(); Hashtable<String, Target> allTargets = new Hashtable<String, Target>(); Interpreter aBsh = null; String input = input_org; TargetDao tDao = (TargetDao) con.getBean("TargetDao"); StringBuffer output = new StringBuffer(this.personalizeText(input, customerID, con)); searchPos = 0; aBsh = AgnUtils.getBshInterpreter(companyID, customerID, con); if (overwriteMailtype) { aBsh.set("mailtype", new Integer(inputType)); } if (aBsh == null) { throw new Exception("error.template.dyntags"); } Iterator<DynamicTag> it = this.dynTags.values().iterator(); while (it.hasNext()) { aktTag = it.next(); tmpTag = (DynamicTag) con.getBean("DynamicTag"); tmpTag.setDynName(aktTag.getDynName()); Map<String, DynamicTagContent> contentMap = aktTag.getDynContent(); if (contentMap != null) { Iterator<DynamicTagContent> it2 = contentMap.values().iterator(); while (it2.hasNext()) { aContent = it2.next(); aTmpContent = (DynamicTagContent) con.getBean("DynamicTagContent"); aTmpContent.setDynName(aContent.getDynName()); aTmpContent.setDynOrder(aContent.getDynOrder()); aTmpContent.setDynContent(this.personalizeText(aContent.getDynContent(), customerID, con)); aTmpContent.setTargetID(aContent.getTargetID()); aTmpContent.setId(aContent.getId()); tmpTag.addContent(aTmpContent); } } allTags.put(aktTag.getDynName(), tmpTag); } aContent = null; this.searchPos = 0; while ((aktTag = findNextDynTag(output.toString(), con)) != null) { searchPos = aktTag.getStartTagStart(); // always search from // beginning of last found // tag if (allTags.containsKey(aktTag.getDynName())) { contentTag = (DynamicTag) allTags.get(aktTag.getDynName()); Map<String, DynamicTagContent> contentMap = contentTag.getDynContent(); contentString = null; // reset always if (contentMap != null) { Iterator<DynamicTagContent> it3 = contentMap.values().iterator(); while (it3.hasNext()) { aContent = it3.next(); aTargetID = aContent.getTargetID(); if (allTargets.containsKey(Integer.toString(aTargetID))) { aTarget = (Target) allTargets.get(Integer.toString(aTargetID)); } else { aTarget = tDao.getTarget(aTargetID, this.companyID); if (aTarget == null) { aTarget = (Target) con.getBean("Target"); aTarget.setCompanyID(this.companyID); aTarget.setId(aTargetID); } allTargets.put(Integer.toString(aTarget.getId()), aTarget); } aTargetID = aTarget.getId(); if (aTargetID == 0) { // Target fits contentString = aContent.getDynContent(); break; // stop processing list of content } else { if (aTarget.isCustomerInGroup(aBsh)) { contentString = aContent.getDynContent(); break; // stop processing list of content } } } } // insert content if found content if (contentString != null) { if (aktTag.isComplex()) { output.delete(aktTag.getEndTagStart(), aktTag.getEndTagEnd()); output.replace(aktTag.getValueTagStart(), aktTag.getValueTagEnd(), contentString); output.delete(aktTag.getStartTagStart(), aktTag.getStartTagEnd()); } else { output.replace(aktTag.getStartTagStart(), aktTag.getStartTagEnd(), contentString); } } else { if (aktTag.isComplex()) { output.delete(aktTag.getStartTagStart(), aktTag.getEndTagEnd()); } else { output.delete(aktTag.getStartTagStart(), aktTag.getStartTagEnd()); } } } else { // dyntag not found in list, throw exception! throw new Exception("error.template.dyntags"); } } if (inputType == MailingImpl.INPUT_TYPE_TEXT) { if (this.getEmailParam().getLinefeed() > 0) { output = new StringBuffer(SafeString.cutLineLength(SafeString.removeHTMLTags(output.toString()), this.getEmailParam().getLinefeed())); } else { output = new StringBuffer(SafeString.removeHTMLTags(output.toString())); } } output = new StringBuffer(this.insertTrackableLinks(output.toString(), customerID, con)); return output.toString(); } /** * Scans a textblock for trackable links and replaces them with encoded * rdir-links. */ public String insertTrackableLinks(String aText1, int customerID, ApplicationContext con) { if (this.trackableLinks == null) { return aText1; } /* * trackableLinks is an unordered HashMap. When there are 2 links in the * Map, where one is part of the other, this could lead to an link * replacement, depending on the map ordering. * * Link 1: http://www.mydomain.de Link 2: * http://www.mydomain.de/path/index.htm * * If Link 1 is returned before Link 2 from the iterator this resulted * in: http://rdir.de/r.html?uid=<uid of Link1>/path/index.htm */ Comparator<String> reverseString = new Comparator<String>() { @Override public int compare(String o1, String o2) { return o2.compareTo(o1); } }; Set<String> sorted = new TreeSet<String>(reverseString); sorted.addAll(this.trackableLinks.keySet()); Iterator<String> i = sorted.iterator(); String aLink = null; int start_link = 0; int end_link = 0; TrackableLink aLinkObj = null; StringBuffer aBuf = new StringBuffer(aText1); boolean isHref = false; if (aText1 == null) { return null; } while (i.hasNext()) { aLink = i.next(); end_link = 0; while ((start_link = aBuf.indexOf(aLink, end_link)) != -1) { end_link = start_link + 1; isHref = false; if (start_link > 5 && (aBuf.substring(start_link - 6, start_link).equalsIgnoreCase("href=\""))) { isHref = true; } if (start_link > 6 && (aBuf.substring(start_link - 7, start_link).equalsIgnoreCase("href=\""))) { isHref = true; } if (aBuf.length() > (start_link + aLink.length())) { if (!(aBuf.charAt(start_link + aLink.length()) == ' ' || aBuf.charAt(start_link + aLink.length()) == '\'' || aBuf.charAt(start_link + aLink.length()) == '"')) { isHref = false; } } if (isHref) { aLinkObj = (TrackableLink) this.trackableLinks.get(aLink); aBuf.replace(start_link, start_link + aLink.length(), aLinkObj.encodeTagStringLinkTracking(con, customerID)); } } } return aBuf.toString(); } @Override public MailingComponent getTemplate(String type) { return (MailingComponent) this.components.get("agn" + type); } @Override public MailingComponent getHtmlTemplate() { return getTemplate("Html"); } @Override public MailingComponent getTextTemplate() { return getTemplate("Text"); } @Override public String personalizeText(String input, int customerID, ApplicationContext con) throws Exception { StringBuffer output = new StringBuffer(input); TagDetails aDetail = null; searchPos = 0; String aValue = null; while ((aDetail = this.getOneTag(output.toString(), "agn", searchPos, con)) != null) { searchPos = aDetail.getStartPos() + 1; aDetail.findTagName(); if (!aDetail.getTagName().equals("agnDYN") && !aDetail.getTagName().equals("agnDVALUE")) { if (!aDetail.findTagParameters()) { throw new Exception("error.personalization_tag_parameter"); } aValue = this.processTag(aDetail, customerID, con); if (aValue != null) { output.replace(aDetail.getStartPos(), aDetail.getEndPos(), aValue); } if (logger.isInfoEnabled()) logger.info("personalizeText: Tag value from DB '" + aValue + "'"); } } return output.toString(); } @Override public boolean checkIfOK() { return true; } /** * Getter for property emailParam. * * @return Value of property emailParam. */ @Override public MediatypeEmail getEmailParam() { return (MediatypeEmail) mediatypes.get(new Integer(0)); } /** * Getter for property targetGroups. * * @return Value of property targetGroups. */ @Override public Collection<Integer> getTargetGroups() { return this.targetGroups; } /** * Setter for property targetGroups. * * @param targetGroups * New value of property targetGroups. */ @Override public void setTargetGroups(Collection<Integer> targetGroups) { this.targetGroups = targetGroups; this.targetExpression = this.generateTargetExpression(); } /** * Setter for property htmlTemplate. * * @param htmlTemplate * New value of property htmlTemplate. */ @Override public void setHtmlTemplate(MailingComponent htmlTemplate) { if (htmlTemplate != null) { this.components.put("agnHtml", htmlTemplate); } } /** * Setter for property dynTags. * * @param dynTags * New value of property dynTags. */ @Override public void setDynTags(Map<String, DynamicTag> dynTags) { this.dynTags = dynTags; } /** * Setter for property dynTags. * * @param trackableLinks */ @Override public void setTrackableLinks(Map<String, TrackableLink> trackableLinks) { this.trackableLinks = trackableLinks; } /** * Setter for property components. * * @param components * New value of property components. */ @Override public void setComponents(Map<String, MailingComponent> components) { this.components = components; } /** * Setter for property textTemplate. * * @param textTemplate */ @Override public void setTextTemplate(MailingComponent textTemplate) { if (textTemplate != null) { this.components.put("agnText", textTemplate); } } /** * Getter for property mailTemplateID. * * @return Value of property mailTemplateID. */ @Override public int getMailTemplateID() { return this.mailTemplateID; } /** * Getter for property templateOK. * * @return Value of property templateOK. */ @Override public int getTemplateOK() { return this.templateOK; } /** * Setter for property templateOK. * * @param templateOK * New value of property templateOK. */ @Override public void setTemplateOK(int templateOK) { this.templateOK = templateOK; } /** * Getter for property isTemplate. * * @return Value of property isTemplate. */ @Override public boolean isIsTemplate() { return this.isTemplate; } /** * Setter for property isTemplate. * * @param isTemplate * New value of property isTemplate. */ @Override public void setIsTemplate(boolean isTemplate) { this.isTemplate = isTemplate; } /** * Getter for property targetMode. * * @return Value of property targetMode. */ @Override public int getTargetMode() { return this.targetMode; } /** * Setter for property targetMode. * * @param targetMode * New value of property targetMode. */ @Override public void setTargetMode(int targetMode) { this.targetMode = targetMode; } /** * Getter for property targetExpression. * * @return Value of property targetExpression. */ @Override public String getTargetExpression() { return this.targetExpression; } /** * Setter for property targetExpression. * * @param targetExpression * New value of property targetExpression. */ @Override public void setTargetExpression(String targetExpression) { this.targetExpression = targetExpression; this.parseTargetExpression(this.targetExpression); } /** * Getter for property mediatypes. * * @return Value of property mediatypes. */ @Override public Map<Integer, Mediatype> getMediatypes() { return this.mediatypes; } /** * Setter for property mediatypes. * * @param mediatypes * New value of property mediatypes. */ @Override public void setMediatypes(Map<Integer, Mediatype> mediatypes) { this.mediatypes = mediatypes; } @Override public void init(int companyID, ApplicationContext con) { MailingComponent comp = null; Mediatype type = null; this.companyID = companyID; comp = (MailingComponent) con.getBean("MailingComponent"); comp.setCompanyID(companyID); comp.setComponentName("agnText"); comp.setType(MailingComponent.TYPE_TEMPLATE); comp.setEmmBlock("[agnDYN name=\"Text-Version\"/]"); comp.setMimeType("text/plain"); this.components.put("agnText", comp); comp = (MailingComponent) con.getBean("MailingComponent"); comp.setCompanyID(companyID); comp.setComponentName("agnHtml"); comp.setType(MailingComponent.TYPE_TEMPLATE); comp.setEmmBlock("[agnDYN name=\"HTML-Version\"/]"); comp.setMimeType("text/html"); this.components.put("agnHtml", comp); type = (Mediatype) con.getBean("MediatypeEmail"); type.setCompanyID(companyID); this.mediatypes.put(new Integer(0), type); } @Override public List<String> cleanupDynTags(Vector<String> keep) { Vector<String> remove = new Vector<String>(); String tmp = null; // first find keys which should be removed Iterator<String> it = this.dynTags.keySet().iterator(); while (it.hasNext()) { tmp = it.next(); if (!keep.contains(tmp)) { remove.add(tmp); } } // now remove them! Enumeration<String> e = remove.elements(); while (e.hasMoreElements()) { dynTags.remove(e.nextElement()); } return remove; } @Override public void cleanupTrackableLinks(Vector<String> keep) { Vector<String> remove = new Vector<String>(); String tmp = null; // first find keys which should be removed Iterator<String> it = this.trackableLinks.keySet().iterator(); while (it.hasNext()) { tmp = it.next(); if (!keep.contains(tmp)) { remove.add(tmp); } } // now remove them! Enumeration<String> e = remove.elements(); while (e.hasMoreElements()) { this.trackableLinks.remove(e.nextElement()); } } @Override public void cleanupMailingComponents(Vector<String> keep) { Vector<String> remove = new Vector<String>(); MailingComponent tmp = null; // first find keys which should be removed Iterator<MailingComponent> it = this.components.values().iterator(); while (it.hasNext()) { tmp = it.next(); if (tmp.getType() == MailingComponent.TYPE_IMAGE && !keep.contains(tmp.getComponentName())) { remove.add(tmp.getComponentName()); } } // now remove them! Enumeration<String> e = remove.elements(); while (e.hasMoreElements()) { this.components.remove(e.nextElement()); } } @Override public DynamicTag getDynamicTagById(int dynId) { DynamicTag tmp = null; Iterator<DynamicTag> it = this.dynTags.values().iterator(); while (it.hasNext()) { tmp = it.next(); if (dynId == tmp.getId()) { return tmp; } } return null; } @Override public TrackableLink getTrackableLinkById(int urlID) { TrackableLink tmp = null; Iterator<TrackableLink> it = this.trackableLinks.values().iterator(); while (it.hasNext()) { tmp = it.next(); if (urlID == tmp.getId()) { return tmp; } } return null; } @Override public Object clone(ApplicationContext con) { Mailing tmpMailing = (Mailing) con.getBean("Mailing"); MailingComponent compOrg = null; MailingComponent compNew = null; TrackableLink linkOrg = null; TrackableLink linkNew = null; DynamicTag tagOrg = null; DynamicTag tagNew = null; DynamicTagContent contentOrg = null; DynamicTagContent contentNew = null; Mediatype emailNew = null; try { // copy components Iterator<MailingComponent> comps = this.components.values().iterator(); while (comps.hasNext()) { compOrg = comps.next(); compNew = (MailingComponent) con.getBean("MailingComponent"); if (compOrg.getBinaryBlock() == null) { compOrg.setBinaryBlock(new byte[1]); } BeanUtils.copyProperties(compNew, compOrg); compNew.setId(0); compNew.setMailingID(0); tmpMailing.addComponent(compNew); } // copy dyntags Iterator<DynamicTag> dyntags = this.dynTags.values().iterator(); while (dyntags.hasNext()) { tagOrg = dyntags.next(); tagNew = (DynamicTag) con.getBean("DynamicTag"); Iterator<DynamicTagContent> contents = tagOrg.getDynContent().values().iterator(); while (contents.hasNext()) { contentOrg = contents.next(); contentNew = (DynamicTagContent) con.getBean("DynamicTagContent"); BeanUtils.copyProperties(contentNew, contentOrg); contentNew.setId(0); contentNew.setDynNameID(0); tagNew.addContent(contentNew); } tagNew.setCompanyID(tagOrg.getCompanyID()); tagNew.setDynName(tagOrg.getDynName()); tmpMailing.addDynamicTag(tagNew); } // copy urls Iterator<TrackableLink> urls = this.trackableLinks.values().iterator(); while (urls.hasNext()) { linkOrg = urls.next(); linkNew = (TrackableLink) con.getBean("TrackableLink"); BeanUtils.copyProperties(linkNew, linkOrg); linkNew.setId(0); linkNew.setMailingID(0); linkNew.setActionID(linkOrg.getActionID()); tmpMailing.getTrackableLinks().put(linkNew.getFullUrl(), linkNew); } // copy emailparam emailNew = (Mediatype) con.getBean("MediatypeEmail"); emailNew.setParam(this.getEmailParam().getParam()); tmpMailing.getMediatypes().put(new Integer(0), emailNew); tmpMailing.setOpenActionID(this.openActionID); tmpMailing.setClickActionID(this.clickActionID); } catch (Exception e) { logger.error("could not copy", e); return null; } return tmpMailing; } @Override public boolean buildDependencies(boolean scanDynTags, ApplicationContext con) throws Exception { return buildDependencies(scanDynTags, null, con); } @Override public boolean buildDependencies(boolean scanDynTags, List<String> dynNamesForDeletion, ApplicationContext con) throws Exception { Vector<String> dynTags = new Vector<String>(); Vector<String> components = new Vector<String>(); Vector<String> links = new Vector<String>(); // scan for Dyntags // in template-components and Mediatype-Params if (scanDynTags) { dynTags.addAll(this.findDynTagsInTemplates(con)); dynTags.addAll(this.findDynTagsInTemplates(this.getEmailParam().getSubject(), con)); dynTags.addAll(this.findDynTagsInTemplates(this.getEmailParam().getReplyAdr(), con)); dynTags.addAll(this.findDynTagsInTemplates(this.getEmailParam().getFromAdr(), con)); List<String> dynNamesList = this.cleanupDynTags(dynTags); if (dynNamesForDeletion != null) dynNamesForDeletion.addAll(dynNamesList); } // scan for Components // in template-components and dyncontent components.addAll(this.scanForComponents(con)); this.cleanupMailingComponents(components); // scan for Links // in template-components and dyncontent links.addAll(this.scanForLinks(con)); // if(AgnUtils.isOracleDB()) { // causes problem with links in OpenEMM this.cleanupTrackableLinks(links); // } return true; } @Override public Map<Integer, Target> getAllowedTargets(ApplicationContext myContext) { if (allowedTargets == null) { TargetDao dao = (TargetDao) myContext.getBean("TargetDao"); allowedTargets = dao.getAllowedTargets(companyID); if (allowedTargets != null) { Target aTarget = (Target) myContext.getBean("Target"); aTarget.setCompanyID(companyID); aTarget.setId(0); aTarget.setTargetName("All Subscribers"); allowedTargets.put(new Integer(0), aTarget); } } return allowedTargets; } private TagDetails getFormTag(String aTemplate, String TagName, int startPos, String startMark, String endMark, ApplicationContext con) throws Exception { int posOfDynTag = 0; int endOfDynTag = 0; TagDetails detail = (TagDetails) con.getBean("TagDetails"); posOfDynTag = aTemplate.indexOf(startMark + TagName, startPos); // Search for next DYN-Tag if (posOfDynTag == -1) {// if not DYN-Tag is found, return null return null; } endOfDynTag = aTemplate.indexOf(endMark, posOfDynTag + 8); // Search for a closing bracket if (endOfDynTag == -1) { // if the Tag-Closing Bracket is missing, throw an exception throw new Exception("Missing Bracket$" + startPos); } endOfDynTag++; detail.setStartPos(posOfDynTag); detail.setEndPos(endOfDynTag); detail.setFullText(aTemplate.substring(posOfDynTag, endOfDynTag)); return detail; } /** * Getter for property maildropStatus. * * @return Value of property maildropStatus. */ @Override public Set<MaildropEntry> getMaildropStatus() { return this.maildropStatus; } /** * Setter for property maildropStatus. * * @param maildropStatus * New value of property maildropStatus. */ @Override public void setMaildropStatus(Set<MaildropEntry> maildropStatus) { this.maildropStatus = maildropStatus; } /** * Getter for property deleted. * * @return Value of property deleted. */ @Override public int getDeleted() { return this.deleted; } /** * Setter for property deleted. * * @param deleted * New value of property deleted. */ @Override public void setDeleted(int deleted) { this.deleted = deleted; } @Override public boolean getNeedsTarget() { return this.needsTarget; } @Override public void setNeedsTarget(boolean needsTarget) { this.needsTarget = needsTarget; } @Override public int getLocked() { return this.locked ? 1 : 0; } @Override public void setLocked(int locked) { this.locked = (locked != 0) ? true : false; } @Override public void setSearchPos(int pos) { searchPos = pos; } @Override public int getArchived() { return this.archived ? 1 : 0; } @Override public void setArchived(int archived) { this.archived = (archived != 0) ? true : false; } @Override public int getOpenActionID() { return openActionID; } @Override public void setOpenActionID(int id) { this.openActionID = id; } @Override public int getClickActionID() { return this.clickActionID; } @Override public void setClickActionID(int id) { this.clickActionID = id; } @Override public String processTag(TagDetails detail, int customerID, ApplicationContext con) { return AgnTagUtils.processTag(detail, customerID, con, id, mailinglistID, companyID); } }