/********************************************************************************* * 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) 2009 AGNITAS AG. All Rights * Reserved. * * Contributor(s): AGNITAS AG. ********************************************************************************/ package org.agnitas.cms.web; import org.agnitas.beans.DynamicTag; import org.agnitas.beans.Mailing; import org.agnitas.beans.impl.MailingImpl; import org.agnitas.cms.beans.CmsTargetGroup; import org.agnitas.cms.dao.CmsMailingDao; import org.agnitas.cms.utils.CMLocationsUtils; import org.agnitas.cms.utils.ClassicTemplateGenerator; import org.agnitas.cms.utils.CmsUtils; import org.agnitas.cms.utils.TagUtils; import org.agnitas.cms.utils.dataaccess.CMTemplateManager; import org.agnitas.cms.utils.dataaccess.ContentModuleManager; import org.agnitas.cms.web.forms.CmsMailingContentForm; import org.agnitas.cms.webservices.generated.CMTemplate; import org.agnitas.cms.webservices.generated.ContentModule; import org.agnitas.cms.webservices.generated.ContentModuleLocation; import org.agnitas.util.AgnUtils; import org.agnitas.web.MailingContentAction; import org.apache.struts.action.ActionErrors; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionMessage; import org.apache.struts.action.ActionMessages; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Vector; /** * @author Vyacheslav Stepanov */ public class CmsMailingContentAction extends MailingContentAction { public static final int ACTION_CMS_EDITOR = ACTION_LAST + 50; public static final int ACTION_SAVE_CMS_DATA = ACTION_LAST + 51; public static final int ACTION_ADD_CM = ACTION_LAST + 52; public static final int ACTION_REMOVE_CM = ACTION_LAST + 53; public static final int ACTION_SHOW_TEXT_VERSION = ACTION_LAST + 54; public static final int ACTION_SAVE_CMS_TEXT_VERSION = ACTION_LAST + 55; public static final int ACTION_CHANGE_CATEGORY = ACTION_LAST + 56; public static final int CM_LIST_SIZE = 5; private CmsMailingDao cmsMailingDao; private ClassicTemplateGenerator classicTemplateGenerator; public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse res) throws IOException, ServletException { ActionForward actualDestination = super.execute(mapping, form, request, res); CmsMailingContentForm aForm = null; ActionMessages errors = new ActionMessages(); ActionForward destination = null; aForm = (CmsMailingContentForm) form; AgnUtils.logger().info("Action: " + aForm.getAction()); if(!allowed("cms.mailing_content_management", request)) { errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("error.permissionDenied")); saveErrors(request, errors); return actualDestination; } if(hasParameterStartsWith(request, "addCM")) { aForm.setAction(CmsMailingContentAction.ACTION_ADD_CM); } if(hasParameterStartsWith(request, "removeCM")) { aForm.setAction(CmsMailingContentAction.ACTION_REMOVE_CM); } if(AgnUtils.parameterNotEmpty(request, "show")) { aForm.setAction(CmsMailingContentAction.ACTION_CHANGE_CATEGORY); } try { final int adminId = AgnUtils.getAdmin(request).getAdminID(); switch(aForm.getAction()) { // if mailing has CMS model - show CMS content edit page case CmsMailingContentAction.ACTION_VIEW_CONTENT: { // Get test recipients for preview panel drop down list. // Impossible to do separation of layers (in order not to get dao from applicationContext object) // until MailingContentAction is refactored so that it will not access applicationContext object Map<Integer, String> testRecipients = recipientDao.getAdminAndTestRecipientsDescription( aForm.getCompanyID(request), aForm.getMailingID()); aForm.setTestRecipients(testRecipients); // try to find assigned template CMTemplate template = getTemplateManager(request) .getCMTemplateForMailing(aForm.getMailingID()); // if no assigned template found - try to find assigned CMs if(template == null) { List<Integer> assignedCms = getContentModuleManager(request) .getAssignedCMsForMailing(aForm.getMailingID()); if(!assignedCms.isEmpty()) { destination = mapping.findForward("cms_content_editor"); errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("cms.NoTemplateAssigned")); } } else { destination = mapping.findForward("cms_content_editor"); } break; } case CmsMailingContentAction.ACTION_CMS_EDITOR: { aForm.resetCmsData(); loadAllContentModules(aForm, request); errors.add(loadEditor(aForm, request)); aForm.setAction(CmsMailingContentAction.ACTION_SAVE_CMS_DATA); aForm.setAllCategories(getContentModuleManager(request).getAllCMCategories(AgnUtils.getCompanyID(request))); destination = mapping.findForward("cms_editor_frame"); break; } case CmsMailingContentAction.ACTION_SAVE_CMS_DATA: { if(!request.getParameterMap().isEmpty()) { saveCmAssignments(aForm, request); saveLocations(aForm, request, true); final int mailingId = aForm.getMailingID(); classicTemplateGenerator.generate(mailingId, request, false); } String cmEditId = request.getParameter("cmToEdit"); String phForNewCM = request.getParameter("phForNewCM"); if(cmEditId != null && !cmEditId.isEmpty() && !"0".equals(cmEditId)) { destination = new ActionForward(mapping.findForward("edit_cm").getPath() + "&contentModuleId=" + cmEditId + "&mailingId=" + aForm.getMailingID(), true); } else if(phForNewCM != null && !phForNewCM.isEmpty()) { destination = new ActionForward(mapping.findForward("new_cm").getPath() + "&mailingId=" + aForm.getMailingID() + "&phName=" + phForNewCM + "&createForMailing=true", true); } else { aForm.setAction(CmsMailingContentAction.ACTION_SAVE_CMS_DATA); destination = mapping.findForward("cms_editor_frame"); } break; } case CmsMailingContentAction.ACTION_ADD_CM: { saveLocations(aForm, request, false); errors = addContentModule(aForm, request); aForm.setAction(CmsMailingContentAction.ACTION_SAVE_CMS_DATA); destination = mapping.findForward("cms_editor_frame"); break; } case CmsMailingContentAction.ACTION_REMOVE_CM: { saveLocations(aForm, request, false); removeContentModule(aForm, request); aForm.setAction(CmsMailingContentAction.ACTION_SAVE_CMS_DATA); destination = mapping.findForward("cms_editor_frame"); break; } case CmsMailingContentAction.ACTION_CHANGE_CATEGORY: { saveLocations(aForm, request, false); aForm.setAction(CmsMailingContentAction.ACTION_SAVE_CMS_DATA); destination = mapping.findForward("cms_editor_frame"); break; } case CmsMailingContentAction.ACTION_SHOW_TEXT_VERSION: { //Do some thing final CMTemplateManager manager = CmsUtils .getCMTemplateManager(getApplicationContext(request)); aForm.setTextVersion(manager.getTextVersion(adminId)); aForm.setAction(CmsMailingContentAction.ACTION_SAVE_CMS_TEXT_VERSION); aForm.setWorldMailingSend(isWorldMailingSend(aForm.getMailingID(),request)); destination = mapping.findForward("text_editor"); break; } case CmsMailingContentAction.ACTION_SAVE_CMS_TEXT_VERSION: { //save text content final int mailingId = aForm.getMailingID(); final int companyId = aForm.getCompanyID(request); final CMTemplateManager manager = CmsUtils .getCMTemplateManager(getApplicationContext(request)); manager.saveTextVersion(adminId, aForm.getTextVersion()); classicTemplateGenerator.generate(mailingId, request); aForm.setAction(CmsMailingContentAction.ACTION_SAVE_CMS_DATA); destination = mapping.findForward("cms_content_editor"); break; } } } catch(Exception e) { AgnUtils.logger().error("execute: " + e + "\n" + AgnUtils.getStackTrace(e)); errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("error.exception")); } if(destination != null && "cms_editor_frame".equals(destination.getName())) { aForm.setAvailableContentModules(getAllContentModulesList(aForm)); request.setAttribute("availableCmCount", aForm.getAvailableContentModules().size()); } // Report any errors we have discovered back to the original form if(!errors.isEmpty()) { saveErrors(request, errors); } if(destination == null) { return actualDestination; } else { return destination; } } private boolean hasParameterStartsWith(HttpServletRequest request, String startStr) { Enumeration parameterNames = request.getParameterNames(); while(parameterNames.hasMoreElements()) { String parameterName = (String) parameterNames.nextElement(); if(parameterName.startsWith(startStr)) { return true; } } return false; } private boolean isWorldMailingSend(int mailingID,HttpServletRequest request){ Mailing aMailing=mailingDao.getMailing(mailingID, this.getCompanyID(request)); return aMailing.isWorldMailingSend(); } private String getParameterValueFromName(HttpServletRequest request, String startStr) { Enumeration parameterNames = request.getParameterNames(); while(parameterNames.hasMoreElements()) { String parameterName = (String) parameterNames.nextElement(); if(parameterName.startsWith(startStr) && parameterName.endsWith(".x")) { int delimiterIndex = parameterName.indexOf("_"); if(delimiterIndex == -1) { return null; } return parameterName .substring(delimiterIndex + 1, parameterName.length() - 2); } } return null; } private void saveCmAssignments(CmsMailingContentForm aForm, HttpServletRequest request) { List<Integer> oldAssignedCMs = getContentModuleManager(request). getAssignedCMsForMailing(aForm.getMailingID()); Set<Integer> newAssignedCMs = aForm.getContentModules().keySet(); List<Integer> cmsToAssign = new ArrayList<Integer>(); List<Integer> cmsToDeassign = new ArrayList<Integer>(); for(Integer cmId : newAssignedCMs) { if(!oldAssignedCMs.contains(cmId)) { cmsToAssign.add(cmId); } } for(Integer cmId : oldAssignedCMs) { if(!newAssignedCMs.contains(cmId)) { cmsToDeassign.add(cmId); } } getContentModuleManager(request) .addMailingBindingToContentModules(cmsToAssign, aForm.getMailingID()); getContentModuleManager(request). removeMailingBindingFromContentModules(cmsToDeassign, aForm.getMailingID()); } private void removeContentModule(CmsMailingContentForm aForm, HttpServletRequest request) { Integer cmId = Integer.valueOf(getParameterValueFromName(request, "removeCM")); aForm.getContentModules().remove(cmId); ContentModuleLocation location = CMLocationsUtils .getLocationForCMId(aForm.getContentModuleLocations(), cmId); aForm.getContentModuleLocations().remove(location); refreshLocations(aForm); } private ActionMessages addContentModule(CmsMailingContentForm aForm, HttpServletRequest request) { ActionErrors errors = new ActionErrors(); String[] placeholders = aForm.getPlaceholders(); List<ContentModuleLocation> cmLocations = aForm.getContentModuleLocations(); if(cmLocations.size() >= placeholders.length) { errors.add("global", new ActionMessage("error.cant.add.cm")); return errors; } int cmId = Integer.valueOf(getParameterValueFromName(request, "addCM")); String cmContent = TagUtils.generateContentModuleContent(cmId, false, getApplicationContext(request)); cmContent = CmsUtils.appendImageURLsWithSystemUrl(cmContent); aForm.getContentModules().put(cmId, cmContent); refreshLocations(aForm); return errors; } private void refreshLocations(CmsMailingContentForm aForm) { List<ContentModuleLocation> validLocations = CMLocationsUtils.createValidLocations( aForm.getContentModuleLocations(), aForm.getContentModules().keySet(), aForm.getPlaceholders(), aForm.getCmTemplateId(), aForm.getMailingID()); aForm.setContentModuleLocations(validLocations); } private List<ContentModule> getAllContentModulesList(CmsMailingContentForm aForm) { List<ContentModule> resultList = new ArrayList<ContentModule>(); Set<Integer> assignedCmIds = aForm.getContentModules().keySet(); for(ContentModule contentModule : aForm.getAllContentModules()) { if(!assignedCmIds.contains(contentModule.getId())) { if (aForm.getCategoryToShow() == 0 || aForm.getCategoryToShow() > 0 && aForm.getCategoryToShow() == contentModule.getCategoryId()) { resultList.add(contentModule); } } } return resultList; } private void loadAllContentModules(CmsMailingContentForm aForm, HttpServletRequest request) { aForm.setAllContentModules(getContentModuleManager(request).getContentModulesForMailing(aForm.getMailingID())); } private void saveLocations(CmsMailingContentForm aForm, HttpServletRequest request, boolean storeToDB) { Map<Integer, String> modules = aForm.getContentModules(); for(Integer cmId : modules.keySet()) { ContentModuleLocation location = CMLocationsUtils.getLocationForCMId( aForm.getContentModuleLocations(), cmId); if(location == null) { continue; } String phName = request.getParameter("cm." + cmId + ".ph_name"); int phOrder = Integer .parseInt(request.getParameter("cm." + cmId + ".order_in_ph")); int targetId = Integer.parseInt(request.getParameter("cm_target." + cmId)); location.setDynName(phName); location.setOrder(phOrder); location.setTargetGroupId(targetId); } if(storeToDB) { getContentModuleManager(request).removeCMLocationsForMailing(aForm.getMailingID()); getContentModuleManager(request).addCMLocations(aForm.getContentModuleLocations()); } } private ActionMessages loadEditor(CmsMailingContentForm aForm, HttpServletRequest request) { // load template data CMTemplate template = getTemplateManager(request) .getCMTemplateForMailing(aForm.getMailingID()); String templateContent = CmsUtils.getDefaultCMTemplate(); String templateHead = ""; int templateId = 0; if(template != null) { try { templateContent = new String(template.getContent(), "UTF-8"); templateContent = CmsUtils.appendImageURLsWithSystemUrl(templateContent); } catch(UnsupportedEncodingException e) { AgnUtils.logger().warn("Wrong charset name", e); } templateHead = getTemplateHead(templateContent); templateContent = getTemplateBody(templateContent); templateId = template.getId(); } aForm.setCmTemplateId(templateId); aForm.setTemplateHead(templateHead); // find dyn tags in template body ActionMessages errors = FindDynTags(aForm, request, templateContent); if(!errors.isEmpty()) { return errors; } // generate content modules content loadContentModules(aForm, request); // load and fix if necessary modules locations loadCMLocations(aForm, templateId, request); // load target groups loadTargetGroups(aForm, request); return new ActionMessages(); } private void loadCMLocations(CmsMailingContentForm aForm, int templateId, HttpServletRequest req) { List<ContentModuleLocation> locations = getContentModuleManager(req). getCMLocationsForMailingId(aForm.getMailingID()); List<ContentModuleLocation> validLocations = CMLocationsUtils.createValidLocations(locations, aForm.getContentModules().keySet(), aForm.getPlaceholders(), templateId, aForm.getMailingID()); aForm.setContentModuleLocations(validLocations); } private void loadContentModules(CmsMailingContentForm aForm, HttpServletRequest req) { List<ContentModule> moduleList = getContentModuleManager(req). getContentModulesForMailing(aForm.getMailingID()); Map<Integer, String> contentMap = new HashMap<Integer, String>(); for(ContentModule contentModule : moduleList) { String cmContent = TagUtils .generateContentModuleContent(contentModule.getId(), false, getApplicationContext(req)); cmContent = CmsUtils.appendImageURLsWithSystemUrl(cmContent); contentMap.put(contentModule.getId(), cmContent); } aForm.setContentModules(contentMap); } private ActionMessages FindDynTags(CmsMailingContentForm aForm, HttpServletRequest request, String templateContent) { ActionMessages errors = new ActionMessages(); MailingImpl tmpMailing = new MailingImpl(); tmpMailing.setCompanyID(AgnUtils.getCompanyID(request)); tmpMailing.setDynTags(new HashMap()); try { Vector dynTags = tmpMailing .findDynTagsInTemplates(templateContent, getApplicationContext(request)); for(Object dynObject : dynTags) { String dynName = (String) dynObject; DynamicTag dynTag = (DynamicTag) tmpMailing.getDynTags().get(dynName); int tagStart = -1; int tagEnd = -1; if(dynTag.getStartTagEnd() > 0) { tagStart = dynTag.getStartTagStart(); tagEnd = dynTag.getStartTagEnd(); } else if(dynTag.getValueTagEnd() > 0) { tagStart = dynTag.getValueTagStart(); tagEnd = dynTag.getValueTagEnd(); } if(tagStart > -1 && tagEnd > -1) { String tagReplacer = generatePlaceholderHtml(dynName); int shift = tagReplacer.length() - (tagEnd - tagStart); adjustTagsPositions(tmpMailing.getDynTags(), shift); templateContent = templateContent.substring(0, tagStart) + tagReplacer + templateContent.substring(tagEnd); } } aForm.setTemplateBody(templateContent); if(!dynTags.isEmpty()) { aForm.setPlaceholders((String[]) dynTags.toArray(new String[0])); } } catch(Exception e) { AgnUtils.logger().error("Error during dyn tags parsing: " + e + "\n" + AgnUtils.getStackTrace(e)); errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("error.template.dyntags")); } return errors; } private void adjustTagsPositions(Map dynTags, int shift) { for(Object tag : dynTags.keySet()) { DynamicTag dynTag = (DynamicTag) dynTags.get(tag); if(dynTag.getStartTagEnd() > 0) { dynTag.setStartTagStart(dynTag.getStartTagStart() + shift); dynTag.setStartTagEnd(dynTag.getStartTagEnd() + shift); } if(dynTag.getValueTagEnd() > 0) { dynTag.setValueTagStart(dynTag.getValueTagStart() + shift); dynTag.setValueTagEnd(dynTag.getValueTagEnd() + shift); } } } private void loadTargetGroups(CmsMailingContentForm aForm, HttpServletRequest request) { Map<Integer, CmsTargetGroup> targetGroups = cmsMailingDao.getTargetGroups(AgnUtils.getCompanyID(request)); aForm.setTargetGroups(targetGroups); } private String getTemplateHead(String template) { return getTagContent(template, "head"); } private String getTemplateBody(String template) { String body = getTagContent(template, "body"); if(body.length() == 0) { return template; } return body; } private String getTagContent(String content, String tagName) { int headStart = content.indexOf("<" + tagName + ">"); if(headStart == -1) { headStart = content.indexOf("<" + tagName.toUpperCase() + ">"); } int headEnd = content.indexOf("</" + tagName + ">"); if(headEnd == -1) { headEnd = content.indexOf("</" + tagName.toUpperCase() + ">"); } if(headStart != -1 && headEnd != -1 && headEnd > headStart) { return content.substring(headStart + tagName.length() + 2, headEnd); } else { return ""; } } private String generatePlaceholderHtml(String name) { return "<table id=\"table.placeholder." + name + "\"class=\"placeholder\">\n" + " <tbody id=\"placeholder." + name + "\">\n" + " <tr>\n" + " <td id=\"name.placeholder." + name + "\" class=\"placeholder-headline\">" + name + "</td>\n" + " </tr>\n" + " </tbody>\n" + "</table>"; } private CMTemplateManager getTemplateManager(HttpServletRequest req) { return CmsUtils.getCMTemplateManager(getApplicationContext(req)); } private ContentModuleManager getContentModuleManager(HttpServletRequest req) { return CmsUtils.getContentModuleManager(getApplicationContext(req)); } public void setCmsMailingDao(CmsMailingDao cmsMailingDao) { this.cmsMailingDao = cmsMailingDao; } public void setClassicTemplateGenerator(ClassicTemplateGenerator classicTemplateGenerator) { this.classicTemplateGenerator = classicTemplateGenerator; } }