/********************************************************************************* * 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.web; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.sql.DataSource; import org.agnitas.beans.Mailinglist; import org.agnitas.beans.factory.MailinglistFactory; import org.agnitas.beans.impl.MailinglistImpl; import org.agnitas.beans.impl.PaginatedListImpl; import org.agnitas.dao.*; import org.agnitas.target.Target; import org.agnitas.util.AgnUtils; import org.agnitas.web.forms.StrutsFormBase; import org.apache.commons.lang.StringUtils; 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 org.displaytag.pagination.PaginatedList; import org.springframework.context.ApplicationContext; import org.springframework.jdbc.core.JdbcTemplate; public class MailinglistAction extends StrutsActionBase { public static final int ACTION_MAILINGLIST_RECIPIENTS_DELETE = ACTION_LAST + 3; public static final int ACTION_MAILINGLIST_RECIPIENTS_CONFIRM_DELETE = ACTION_LAST + 4; public static final int ACTION_MAILINGLIST_RECIPIENTS_DELETE_YES = ACTION_LAST + 5; protected MailingDao mailingDao; protected TargetDao targetDao; protected BindingEntryDao bindingEntryDao; protected MailinglistFactory mailinglistFactory; protected MailinglistDao mailinglistDao; protected RecipientDao recipientDao; protected DataSource dataSource; class MListCompare implements Comparator { public int compare (Object o1, Object o2) { Mailinglist m1 = (Mailinglist) o1, m2 = (Mailinglist) o2; return m2.getId () - m1.getId (); } } // --------------------------------------------------------- Public Methods /** * Process the specified HTTP request, and create the corresponding HTTP * response (or forward to another web component that will create it). * Return an <code>ActionForward</code> instance describing where and how * control should be forwarded, or <code>null</code> if the response has * already been completed. * <br><br> * ACTION_LIST: initializes columns width list if necessary. Forwards to "list". * <br><br> * ACTION_VIEW: loads data of chosen mailinglist into form and forwards to mailinglist view page. * <br><br> * ACTION_NEW: resets mailinglist id property of form. Forwards to page of creation new mailinglist entry. * <br><br> * ACTION_SAVE: if there is no mailinglist with the same name - creates new mailinglist or updates existing * mailinglist in database. Sets the ID of mailinglist into form. If the "targetID" parameter of request is * set - creates bindings of created mailinglist to recipients matching the target group with that ID. * Forwards to view page. * <br><br> * ACTION_CONFIRM_DELETE: loads the mailinglist into form. If mailinglist is not used by any of the mailings - * forwards to delete-confirmation page, otherwise shows error and forwards to "list" * <br><br> * ACTION_DELETE: deletes bindings of recipients associated with chosen mailinglist from database. Deletes * mailinglist entry from database. Forwards to list. * <br><br> * ACTION_MAILINGLIST_RECIPIENTS_DELETE: resets recipients deletion options. Forwards to page with choosing * options for deletion of mailinglist recipients. * <br><br> * ACTION_MAILINGLIST_RECIPIENTS_CONFIRM_DELETE: forwards to mailinglist-recipients deletion confirmation-page. * <br><br> * ACTION_MAILINGLIST_RECIPIENTS_DELETE_YES: deletes recipients bindings of current mailinglist. Deletes recipients * which were assigned only to current mailinglist. During deletion considers two form-properties set by user: * notAdminsAndTest (if true - removes all but admin- and test-recipients, if false - removes all recipients), * onlyActive (if true - removes only recipients with "active"-status in this mailinglist, if false - doesn't * cares about the status during deletion) * <br><br> * Any other ACTION_* would cause a forward to "list" * <br><br> * If forward is "list" - initializes columns width list for the table; loads list of mailinglists to request. * * @param form data for the action filled by the jsp * @param req request from jsp. * @param res response * @param mapping The ActionMapping used to select this instance * @exception IOException if an input/output error occurs * @exception ServletException if a servlet exception occurs * @return destination */ public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { MailinglistForm aForm=null; ActionMessages errors = new ActionMessages(); ActionMessages messages = new ActionMessages(); ActionForward destination=null; if(!AgnUtils.isUserLoggedIn(req)) { return mapping.findForward("logon"); } if(form!=null) { aForm=(MailinglistForm)form; } else { aForm=new MailinglistForm(); } AgnUtils.logger().info("Action: "+aForm.getAction()); if(AgnUtils.parameterNotEmpty(req, "delete")) { aForm.setAction(ACTION_CONFIRM_DELETE); } try { switch(aForm.getAction()) { case MailinglistAction.ACTION_LIST: if(allowed("mailinglist.show", req)) { if ( aForm.getColumnwidthsList() == null) { aForm.setColumnwidthsList(getInitializedColumnWidthList(4)); } destination=mapping.findForward("list"); } else { errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("error.permissionDenied")); } break; case MailinglistAction.ACTION_VIEW: if(allowed("mailinglist.show", req)) { loadMailinglist(aForm, req); aForm.setAction(MailinglistAction.ACTION_SAVE); destination=mapping.findForward("view"); } else { errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("error.permissionDenied")); } break; case MailinglistAction.ACTION_NEW: if(allowed("mailinglist.new", req)) { aForm.setMailinglistID(0); aForm.setAction(MailinglistAction.ACTION_SAVE); destination=mapping.findForward("view"); messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("default.changes_saved")); } else { errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("error.permissionDenied")); } break; case MailinglistAction.ACTION_SAVE: if(allowed("mailinglist.change", req) && AgnUtils.parameterNotEmpty(req, "save")) { String targetId = req.getParameter( "targetID" ); if(req.getParameter("save")!=null) { if (!mailingChangedToExisting(aForm, req)) { saveMailinglist(aForm, req); if (StringUtils.isNotEmpty(targetId)) { // create MailingList from Target createMailingListFromTarget(targetId, req, aForm); if (aForm.getColumnwidthsList() == null) { aForm.setColumnwidthsList(getInitializedColumnWidthList(4)); } // FIXME the result is ignored. Unnecessary call? // getMailinglist(req, aForm); } messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("default.changes_saved")); } else { errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("error.mailinglist.duplicate", aForm.getShortname())); } // Always go back to overview destination = mapping.findForward("view"); aForm.setAction(MailinglistAction.ACTION_SAVE); } } else { errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("error.permissionDenied")); } break; case MailinglistAction.ACTION_CONFIRM_DELETE: if(allowed("mailinglist.delete", req)) { loadMailinglist(aForm, req); List mlids=mailingDao.getMailingsForMLID(getCompanyID(req), aForm.getMailinglistID()); if(mlids.size() > 0) { errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("error.mailinglist.cannot_delete")); //aForm.setAction(MailinglistAction.ACTION_SAVE); // FIXME the result is ignored. Unnecessary call? // getMailinglist(req, aForm); destination=mapping.findForward("list"); } else { aForm.setAction(MailinglistAction.ACTION_DELETE); destination=mapping.findForward("delete"); } } else { errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("error.permissionDenied")); } break; case MailinglistAction.ACTION_DELETE: if(allowed("mailinglist.delete", req)) { deleteMailinglist(aForm, req); aForm.setAction(MailinglistAction.ACTION_LIST); // FIXME the result is ignored. Unnecessary call? // getMailinglist(req, aForm); destination=mapping.findForward("list"); messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("default.changes_saved")); } else { errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("error.permissionDenied")); } break; case ACTION_MAILINGLIST_RECIPIENTS_DELETE: { aForm.setAction(ACTION_MAILINGLIST_RECIPIENTS_CONFIRM_DELETE); aForm.setActiveOnly(false); aForm.setNotAdminsAndTest(false); return mapping.findForward("recipients_delete"); } case ACTION_MAILINGLIST_RECIPIENTS_CONFIRM_DELETE: { aForm.setAction(ACTION_MAILINGLIST_RECIPIENTS_DELETE_YES); return mapping.findForward("confirm_recipients_delete"); } case ACTION_MAILINGLIST_RECIPIENTS_DELETE_YES: { if(!allowed("mailinglist.recipients.delete",req)){ errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("error.permissionDenied")); saveErrors(req, errors); return mapping.findForward("failure"); } aForm.setAction(ACTION_VIEW); Mailinglist mlist = mailinglistDao.getMailinglist(aForm.getMailinglistID(), AgnUtils.getCompanyID(req)); aForm.setDescription(mlist.getDescription()); aForm.setShortname(mlist.getShortname()); boolean onlyActive = aForm.isActiveOnly(); boolean notAdminsAndTest = aForm.isNotAdminsAndTest(); String tmpTable = recipientDao.createTmpTableByMailinglistID(AgnUtils.getCompanyID(req), aForm.getMailinglistID()); recipientDao.deleteRecipientsBindings(aForm.getMailinglistID(), AgnUtils.getCompanyID(req), onlyActive, notAdminsAndTest); recipientDao.deleteAllNoBindings(AgnUtils.getCompanyID(req), tmpTable); messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("mailinglist.recipients.deleted")); saveMessages(req, messages); return mapping.findForward("view"); } default: if(allowed("mailinglist.show", req)) { if ( aForm.getColumnwidthsList() == null) { aForm.setColumnwidthsList(getInitializedColumnWidthList(4)); } aForm.setAction(MailinglistAction.ACTION_LIST); destination=mapping.findForward("list"); } else { errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("error.permissionDenied")); } } } catch (Exception e) { AgnUtils.logger().error("execute: "+e+"\n"+AgnUtils.getStackTrace(e)); errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("error.exception")); } if(destination != null && "list".equals(destination.getName())) { if ( aForm.getColumnwidthsList() == null) aForm.setColumnwidthsList(getInitializedColumnWidthList(4)); try { setNumberOfRows(req,(StrutsFormBase)form); req.setAttribute("mailinglistList",getMailinglist(req, aForm)); } catch (Exception e) { AgnUtils.logger().error("getMailinglistList: "+e+"\n"+AgnUtils.getStackTrace(e)); errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("error.exception")); } } if (!errors.isEmpty()) { saveErrors(req, errors); } // Report any message (non-errors) we have discovered if(!messages.isEmpty()) { saveMessages(req, messages); } return destination; } /** * creates a mailingList from a given Target * @param req * @param form */ private void createMailingListFromTarget( String targetIdString, HttpServletRequest req, MailinglistForm form ) { Integer targetId = Integer.valueOf( targetIdString ); if ( targetId == null ) { return; } Target target = targetDao.getTarget( targetId, getCompanyID( req ) ); if ( target != null ) { bindingEntryDao.addTargetsToMailinglist(getCompanyID(req), form.getMailinglistID(), target); } } /** * Sets attributes for mailingslists request. * @deprecated replaced by getMailinglistList */ protected void list(MailinglistForm aForm, HttpServletRequest req) { List mlist = mailinglistDao.getMailinglists(this.getCompanyID(req)); Object[] temp = mlist.toArray (); ArrayList alist; Arrays.sort (temp, new MListCompare ()); alist = new ArrayList (temp.length); for (int n = 0; n < temp.length; ++n) { alist.add (temp[n]); } req.setAttribute("mailinglists", alist); } /** * Loads mailingslist. */ protected void loadMailinglist(MailinglistForm aForm, HttpServletRequest req) { Mailinglist aMailinglist=mailinglistDao.getMailinglist(aForm.getMailinglistID(), this.getCompanyID(req)); if(aMailinglist!=null) { aForm.setShortname(aMailinglist.getShortname()); aForm.setDescription(aMailinglist.getDescription()); AgnUtils.userlogger().info(AgnUtils.getAdmin(req).getUsername() + ": do load mailinglist " + aMailinglist.getShortname()); } else if(aForm.getMailinglistID() != 0) { AgnUtils.logger().warn("loadMailinglist: could not load mailinglist: "+aForm.getMailinglistID()); } } /** * Saves mailinglist. */ protected boolean saveMailinglist(MailinglistForm aForm, HttpServletRequest req) { Mailinglist aMailinglist=mailinglistDao.getMailinglist(aForm.getMailinglistID(), this.getCompanyID(req)); boolean is_new=false; if(aMailinglist==null) { aForm.setMailinglistID(0); aMailinglist=mailinglistFactory.newMailinglist(); aMailinglist.setCompanyID(this.getCompanyID(req)); is_new=true; } aMailinglist.setShortname(aForm.getShortname()); aMailinglist.setDescription(aForm.getDescription()); mailinglistDao.saveMailinglist(aMailinglist); aForm.setMailinglistID(aMailinglist.getId()); AgnUtils.logger().info("saveMailinglist: save mailinglist id: "+aMailinglist.getId()); if (is_new){ AgnUtils.userlogger().info(AgnUtils.getAdmin(req).getUsername() + ": create mailinglist " + aMailinglist.getShortname()); }else{ AgnUtils.userlogger().info(AgnUtils.getAdmin(req).getUsername() + ": edit mailinglist " + aMailinglist.getShortname()); } return is_new; } /** * Removes mailinglist. */ protected void deleteMailinglist(MailinglistForm aForm, HttpServletRequest req) { if(aForm.getMailinglistID()!=0) { Mailinglist aMailinglist=mailinglistDao.getMailinglist(aForm.getMailinglistID(), this.getCompanyID(req)); if(aMailinglist!=null) { mailinglistDao.deleteBindings(aMailinglist.getId(), aMailinglist.getCompanyID()); mailinglistDao.deleteMailinglist(aForm.getMailinglistID(), this.getCompanyID(req)); AgnUtils.userlogger().info(AgnUtils.getAdmin(req).getUsername() + ": delete mailinglist " + aMailinglist.getShortname()); } } } /** * Load Mailing lists from database into paginated list. */ public PaginatedList getMailinglist(HttpServletRequest request, MailinglistForm aForm ) throws IllegalAccessException, InstantiationException { ApplicationContext aContext= getWebApplicationContext(); JdbcTemplate aTemplate=new JdbcTemplate( dataSource); List<Integer> charColumns = Arrays.asList(new Integer[]{1,2 }); String direction = request.getParameter("dir"); String sort = getSort(request, aForm); String sortForQuery = StringUtils.isEmpty(sort) ? "shortname" : sort; String upperSort = "upper( " + sortForQuery + " )"; int rownums = aForm.getNumberofRows() >= 0 ? aForm.getNumberofRows() : 0; if( direction == null ) { direction = aForm.getOrder(); } else { aForm.setOrder(direction); } String pageStr = request.getParameter("page"); if ( pageStr == null || "".equals(pageStr.trim()) ) { if ( aForm.getPage() == null || "".equals(aForm.getPage().trim())) { aForm.setPage("1"); } pageStr = aForm.getPage(); } else { aForm.setPage(pageStr); } if( aForm.isNumberOfRowsChanged() ) { aForm.setPage("1"); aForm.setNumberOfRowsChanged(false); pageStr = "1"; } String sqlStatement = "SELECT mailinglist_id, shortname, description "; String sqlStatementFrompart = " FROM mailinglist_tbl WHERE company_id="+AgnUtils.getCompanyID(request); String orderBypart = " ORDER BY "+ upperSort +" "+direction; int totalRows = aTemplate.queryForInt("SELECT count(mailinglist_id) " + sqlStatementFrompart ); Integer page = Integer.parseInt(pageStr); page = AgnUtils.getValidPageNumber(totalRows, page, rownums); aForm.setPage(page.toString()); int offset = ( page - 1) * rownums; if( AgnUtils.isOracleDB() ) { sqlStatement += ", rownum r"; sqlStatement = "SELECT * FROM (" + sqlStatement + sqlStatementFrompart + orderBypart + ") WHERE r between " + (offset+1) + " and " + ( offset+ rownums ); } if ( AgnUtils.isMySQLDB()) { sqlStatement = sqlStatement + sqlStatementFrompart + orderBypart + " LIMIT " + offset + " , " + rownums; } List<Map> tmpList = aTemplate.queryForList(sqlStatement); List<Mailinglist> result = new ArrayList<Mailinglist>(); for(Map row:tmpList) { Mailinglist newBean = new MailinglistImpl(); newBean.setId(((Number)row.get("MAILINGLIST_ID")).intValue()); newBean.setShortname((String) row.get("SHORTNAME")); newBean.setDescription((String) row.get("DESCRIPTION")); result.add(newBean); } PaginatedListImpl paginatedList = new PaginatedListImpl(result, totalRows, rownums, page, sort, direction ); return paginatedList; } protected String getSort(HttpServletRequest request, StrutsFormBase aForm) { String sort = request.getParameter("sort"); if( sort == null ) { sort = aForm.getSort(); } else { aForm.setSort(sort); } return sort; } private boolean mailingChangedToExisting(MailinglistForm aForm, HttpServletRequest request) { int mailinglistID = aForm.getMailinglistID(); if (mailinglistID != 0) { Mailinglist mailinglist = mailinglistDao.getMailinglist(mailinglistID, AgnUtils.getCompanyID(request)); if (mailinglist != null && mailinglist.getShortname().equals(aForm.getShortname())){ return false; } } return mailinglistDao.mailinglistExists(aForm.getShortname(), AgnUtils.getCompanyID(request)); } public void setMailingDao(MailingDao mailingDao) { this.mailingDao = mailingDao; } public void setTargetDao(TargetDao targetDao) { this.targetDao = targetDao; } public void setBindingEntryDao(BindingEntryDao bindingEntryDao) { this.bindingEntryDao = bindingEntryDao; } public void setMailinglistDao(MailinglistDao mailinglistDao) { this.mailinglistDao = mailinglistDao; } public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } public void setMailinglistFactory(MailinglistFactory mailinglistFactory) { this.mailinglistFactory = mailinglistFactory; } public void setRecipientDao(RecipientDao recipientDao) { this.recipientDao = recipientDao; } }