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.web; import java.io.IOException; import java.util.AbstractMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.sql.DataSource; import org.agnitas.beans.BindingEntry; import org.agnitas.beans.Company; import org.agnitas.beans.ProfileField; import org.agnitas.beans.Recipient; import org.agnitas.beans.factory.BindingEntryFactory; import org.agnitas.beans.factory.RecipientFactory; import org.agnitas.dao.MailinglistDao; import org.agnitas.dao.RecipientDao; import org.agnitas.dao.TargetDao; import org.agnitas.service.ColumnInfoService; import org.agnitas.service.RecipientBeanQueryWorker; import org.agnitas.service.RecipientQueryBuilder; import org.agnitas.target.TargetNodeFactory; import org.agnitas.target.TargetRepresentationFactory; import org.agnitas.target.impl.TargetNodeDate; import org.agnitas.target.impl.TargetNodeNumeric; import org.agnitas.target.impl.TargetNodeString; import org.agnitas.util.AgnUtils; import org.agnitas.util.CaseInsensitiveMap; import org.agnitas.util.SqlPreparedStatementManager; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; 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 org.displaytag.pagination.PaginatedList; import org.springframework.jdbc.core.JdbcTemplate; /** * Handles all actions on recipients profile. */ public class RecipientAction extends StrutsActionBase { private static final transient Logger logger = Logger.getLogger(RecipientAction.class); public static final String COLUMN_GENDER = "gender"; public static final String COLUMN_FIRSTNAME = "firstname"; public static final String COLUMN_LASTNAME = "lastname"; public static final String FUTURE_TASK = "GET_RECIPIENT_LIST"; public static final String DUMMY_RECIPIENT_FIELD = "dummy-recipient-field"; public static final int ACTION_SEARCH = ACTION_LAST + 1; public static final int ACTION_OVERVIEW_START = ACTION_LAST + 2; public static final int ACTION_VIEW_WITHOUT_LOAD = ACTION_LAST + 3; public static final int ORG_ACTION_LAST = ACTION_LAST + 3; protected AbstractMap<String, Future> futureHolder = null; protected MailinglistDao mailinglistDao; protected TargetDao targetDao; protected RecipientDao recipientDao; protected TargetRepresentationFactory targetRepresentationFactory; protected TargetNodeFactory targetNodeFactory; protected ExecutorService executorService; protected RecipientQueryBuilder recipientQueryBuilder; protected ColumnInfoService columnInfoService; protected RecipientFactory recipientFactory; protected BindingEntryFactory bindingEntryFactory; protected DataSource dataSource; // --------------------------------------------------------- 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 the list of columns-widths according to number of columns selected by user;<br> * checks if the number of selected columns is less or equal than max-value (currently 8):<br> * - if max value exceeded - puts error to page and restores the list of selected columns from previous time<br> * - if the selected column number <= max-value - stores the current selection to be used for future calls<br> * forwards to list. * <br><br> * ACTION_VIEW: loads recipient to form, puts list of mailinglists to request and forwards to "view" * <br><br> * ACTION_SAVE: If the request parameter "cancel.x" is set - just forwards to "list". In other case saves * changed or new recipient to the database; also saves the recipient bindings to mailinglists * <br><br> * ACTION_NEW: if the request parameter "cancel.x" is set - just forwards to "list", otherwise forwards * to the page where user can fill the data for a new recipient * <br><br> * ACTION_CONFIRM_DELETE: loads recipient into form and forwards to jsp with confirmation about deletion * of current recipient * <br><br> * ACTION_DELETE: if the request parameter "kill" is set - removes the recipient from database (otherwise * returns to previous page) * <br><br> * ACTION_VIEW_WITHOUT_LOAD: forwards to view page without loading the recipient data from DB. * Used as input page for struts-action in struts-config.xml. If the error occurs while saving the recipient - * this action is used (as we don't need to load recipient data again) * <br><br> * Any other ACTION_* would cause a forward to "list" * <br><br> * If the destination is "list" - calls a FutureHolder to get the list of recipients. While FutureHolder is running * destination is "loading". After FutureHolder is finished destination is "list". * * @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 specified in struts-config.xml to forward to next jsp */ @Override public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { // Validate the request parameters specified by the user RecipientForm aForm = null; ActionMessages errors = new ActionErrors(); ActionMessages messages = new ActionMessages(); ActionForward destination = null; if (!AgnUtils.isUserLoggedIn(req)) { return mapping.findForward("logon"); } if (form != null) { aForm = (RecipientForm) form; } else { aForm = new RecipientForm(); } this.updateRecipientFormProperties(req, aForm); if (aForm.getDelete().isSelected()) { aForm.setAction(ACTION_CONFIRM_DELETE); } if (aForm.getAction() == ACTION_LIST) { String[] selectedFields = aForm.getSelectedFields(); if (selectedFields != null && selectedFields.length > 0) { aForm.setSelectedFields((String[]) ArrayUtils.removeElement(selectedFields, DUMMY_RECIPIENT_FIELD)); } } try { switch (aForm.getAction()) { case ACTION_LIST: if (allowed("recipient.show", req)) { destination = mapping.findForward("list"); int length = aForm.getSelectedFields().length; if (aForm.getColumnwidthsList() == null) { aForm.setColumnwidthsList(getInitializedColumnWidthList(length + 1)); } if (length > 8) { aForm.setSelectedFields(aForm.getSelectedFieldsOld()); errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("error.maximum.recipient.columns")); aForm.addErrors(errors); } else { aForm.setSelectedFieldsOld(aForm.getSelectedFields()); } } else { errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("error.permissionDenied")); } break; case ACTION_VIEW: if (allowed("recipient.show", req)) { if (req.getParameter("recipientID") != null) { loadRecipient(aForm, req); aForm.setAction(RecipientAction.ACTION_SAVE); } else { loadDefaults(aForm, req); aForm.setAction(RecipientAction.ACTION_NEW); } req.setAttribute("mailinglists", mailinglistDao.getMailinglists(AgnUtils.getCompanyID(req))); destination = mapping.findForward("view"); } else { errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("error.permissionDenied")); } break; case ACTION_SAVE: if (allowed("recipient.change", req)) { if (req.getParameter("cancel.x") == null) { saveRecipient(aForm, req); aForm.setAction(RecipientAction.ACTION_LIST); messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("default.changes_saved")); aForm.setMessages(new ActionMessages(messages)); } destination = mapping.findForward("list"); } else { errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("error.permissionDenied")); } break; case ACTION_NEW: if (allowed("recipient.new", req)) { if (req.getParameter("cancel.x") == null) { aForm.setRecipientID(0); if (saveRecipient(aForm, req)) { aForm.setAction(RecipientAction.ACTION_LIST); destination = mapping.findForward("list"); messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("default.changes_saved")); aForm.setMessages(new ActionMessages(messages)); } else { errors.add("NewRecipient", new ActionMessage("error.subscriber.insert_in_db_error")); aForm.setAction(RecipientAction.ACTION_VIEW); destination = mapping.findForward("view"); } req.setAttribute("mailinglists", mailinglistDao.getMailinglists(AgnUtils.getCompanyID(req))); } else { destination = mapping.findForward("list"); } } else { errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("error.permissionDenied")); } break; case ACTION_CONFIRM_DELETE: if (allowed("recipient.delete", req)) { loadRecipient(aForm, req); destination = mapping.findForward("delete"); } else { errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("error.permissionDenied")); } break; case ACTION_DELETE: if (allowed("recipient.delete", req)) { if (req.getParameter("kill") != null) { deleteRecipient(aForm, req); aForm.setAction(RecipientAction.ACTION_LIST); destination = mapping.findForward("list"); messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("default.changes_saved")); aForm.setMessages(new ActionMessages(messages)); } } else { errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("error.permissionDenied")); } break; case ACTION_VIEW_WITHOUT_LOAD: if (allowed("recipient.show", req)) { req.setAttribute("mailinglists", mailinglistDao.getMailinglists(AgnUtils.getCompanyID(req))); destination = mapping.findForward("view"); aForm.setAction(RecipientAction.ACTION_SAVE); } else { errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("error.permissionDenied")); } break; default: aForm.setAction(RecipientAction.ACTION_LIST); if (allowed("recipient.show", req)) { destination = mapping.findForward("list"); if (aForm.getColumnwidthsList() == null) { int length = aForm.getSelectedFields().length; aForm.setColumnwidthsList(getInitializedColumnWidthList(length + 1)); } } 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())) { try { Map<String, String> fieldsMap = getRecipientFieldsNames(AgnUtils.getCompanyID(req), aForm.getAdminId()); Set<String> recipientDbColumns = fieldsMap.keySet(); req.setAttribute("fieldsMap", fieldsMap); setNumberOfRows(req, aForm); destination = mapping.findForward("loading"); String key = FUTURE_TASK + "@" + req.getSession(false).getId(); if (!futureHolder.containsKey(key)) { Future<PaginatedList> recipientListFuture = getRecipientListFuture(req, aForm, recipientDbColumns); futureHolder.put(key, recipientListFuture); } if (futureHolder.containsKey(key) && futureHolder.get(key).isDone()) { req.setAttribute("recipientList", futureHolder.get(key).get()); req.setAttribute("mailinglists", mailinglistDao.getMailinglists(AgnUtils.getCompanyID(req))); req.setAttribute("targets", targetDao.getTargets(AgnUtils.getCompanyID(req))); destination = mapping.findForward("list"); PaginatedList resultingList = (PaginatedList) futureHolder.get(key).get(); if (resultingList == null) { aForm.setDeactivatePagination(false); errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("error.errorneous_recipient_search")); } else { aForm.setAll(resultingList.getFullListSize()); messages.add(aForm.getMessages()); aForm.setMessages(null); errors.add(aForm.getErrors()); aForm.resetErrors(); } aForm.setRefreshMillis(RecipientForm.DEFAULT_REFRESH_MILLIS); futureHolder.remove(key); } else { if (aForm.getRefreshMillis() < 1000) { // raise the refresh time aForm.setRefreshMillis(aForm.getRefreshMillis() + 50); } aForm.setError(false); } } catch (Exception e) { AgnUtils.logger().error("recipientList: " + e + "\n" + AgnUtils.getStackTrace(e)); errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("error.exception")); aForm.setError(true); // do not refresh when an error has been occurred } if (aForm.isDeactivatePagination()) { Company company = AgnUtils.getCompany(req); int maxRecipients = company.getMaxRecipients(); errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("recipient.search.max_recipients", maxRecipients)); } } // this is a hack for the recipient-search / recipient overview. if (destination != null && "list".equals(destination.getName())) { // check if we are in search-mode if (!aForm.isOverview()) { // check if it is the last element in filter if (aForm.getNumTargetNodes() == 0 && aForm.getListID() == 0 && aForm.getTargetID() == 0 && aForm.getUser_type().equals("E") && aForm.getUser_status() == 0) { aForm.setAction(7); destination = mapping.findForward("search"); } } } // Report any errors we have discovered back to the original form if (!errors.isEmpty()) { saveErrors(req, errors); // return new ActionForward(mapping.getForward()); } // Report any message (non-errors) we have discovered if (!messages.isEmpty()) { saveMessages(req, messages); } return destination; } /** * Loads recipient data into a form. Uses recipientID property of aForm to identify the customer. * * @param aForm form to put recipient data into * @param req HTTP request */ protected void loadRecipient(RecipientForm aForm, HttpServletRequest req) { Map data = null; Iterator i = null; int companyID = this.getCompanyID(req); data = recipientDao.getCustomerDataFromDb(companyID, aForm.getRecipientID()); i = data.keySet().iterator(); while (i.hasNext()) { String key = (String) i.next(); if (key.equals("gender")) { try { aForm.setGender(Integer.parseInt((String) data.get("gender"))); } catch (Exception e) { aForm.setGender(2); } } else if (key.equals("title")) { aForm.setTitle((String) data.get(key)); } else if (key.equals("firstname")) { aForm.setFirstname((String) data.get(key)); } else if (key.equals("lastname")) { aForm.setLastname((String) data.get(key)); } else if (key.equals("email")) { aForm.setEmail((String) data.get(key)); } else if (key.equals("mailtype")) { try { aForm.setMailtype(Integer.parseInt((String) data.get("mailtype"))); } catch (Exception e) { aForm.setMailtype(1); } } else { aForm.setColumn(key, data.get(key)); } } AgnUtils.userlogger() .info(AgnUtils.getAdmin(req).getUsername() + ": do load recipient " + aForm.getRecipientID()); } /** * Loads recipient columns list for specific admin (identified by adminID property of form) and puts it to form. * * @param aForm form * @param req HTTP request */ protected void loadDefaults(RecipientForm aForm, HttpServletRequest req) { Map tmp = null; aForm.clearColumns(); try { List<ProfileField> list = columnInfoService.getColumnInfos(this.getCompanyID(req), aForm.getAdminId()); for (ProfileField profileField : list) { aForm.setColumn(profileField.getColumn(), profileField.getDefaultValue()); } } catch (Exception e) { } } /** * Saves recipient bindings to mailinglists set by user on view-page.<br> * The bindings-data is taken from recipientForm. * * @param recipientForm form * @param request HTTP request */ protected void saveBindings(RecipientForm recipientForm, HttpServletRequest request) { int companyID = getCompanyID(request); int customerID = recipientForm.getRecipientID(); Map customerMailingLists = null; Map<Integer, Map<Integer, BindingEntry>> bindings = recipientForm.getAllBindings(); Iterator<Integer> bindingsKeyIterator = bindings.keySet().iterator(); customerMailingLists = recipientDao.getAllMailingLists(customerID, companyID); while (bindingsKeyIterator.hasNext()) { Integer bindingsKey = bindingsKeyIterator.next(); Map<Integer, BindingEntry> mailing = bindings.get(bindingsKey); Iterator<Integer> bindingEntryKeyIterator = mailing.keySet().iterator(); while (bindingEntryKeyIterator.hasNext()) { Integer bindingEntryKey = bindingEntryKeyIterator.next(); BindingEntry bindingEntry = mailing.get(bindingEntryKey); if (bindingEntry.getUserStatus() != 0) { bindingEntry.setCustomerID(customerID); // this should be removed after refactoring of BindingEntry class if (bindingEntry.getBindingEntryDao() == null) { bindingEntry.setBindingEntryDao(bindingEntryFactory.getBindingEntryDao()); } if (!bindingEntry.saveBindingInDB(companyID, customerMailingLists)) { AgnUtils.logger().error("saveBindings: Binding could not be saved"); } } } } } /** * If customerID of aForm is not 0 - saves changed recipient to DB<br> * If customerID is 0 - creates new recipient in DB (before that checks if max number of recipients is reached)<br> * Recipient data is taken from form properties.<br> * Also invokes method for saving recipient bindings to mailinglists. * * @param aForm form * @param req HTTP request */ protected boolean saveRecipient(RecipientForm aForm, HttpServletRequest req) { Recipient cust = recipientFactory.newRecipient(); Map data = null; Map column = null; Iterator i = null; int companyID = aForm.getCompanyID(req); cust.setCompanyID(this.getCompanyID(req)); if (aForm.getRecipientID() != 0) { cust.setCustomerID(aForm.getRecipientID()); data = recipientDao.getCustomerDataFromDb(companyID, cust.getCustomerID()); column = aForm.getColumnMap(); i = column.keySet().iterator(); while (i.hasNext()) { String key = (String) i.next(); String value = (String) column.get(key); data.put(key, value); } data.put("gender", new Integer(aForm.getGender()).toString()); data.put("title", aForm.getTitle()); data.put("firstname", aForm.getFirstname()); data.put("lastname", aForm.getLastname()); data.put("email", aForm.getEmail()); data.put("mailtype", new Integer(aForm.getMailtype()).toString()); storeSpecificFields(aForm, data); cust.setCustParameters(data); recipientDao.updateInDB(cust); AgnUtils.userlogger() .info(AgnUtils.getAdmin(req).getUsername() + ": edit recipient " + cust.getCustomerID()); } else { if (recipientDao.mayAdd(companyID, 1) == false) { return false; } data = recipientDao.getCustomerDataFromDb(companyID, aForm.getRecipientID()); column = aForm.getColumnMap(); i = column.keySet().iterator(); while (i.hasNext()) { String key = (String) i.next(); String value = (String) column.get(key); data.put(key, value); } data.put("gender", new Integer(aForm.getGender()).toString()); data.put("title", aForm.getTitle()); data.put("firstname", aForm.getFirstname()); data.put("lastname", aForm.getLastname()); data.put("email", aForm.getEmail()); data.put("mailtype", new Integer(aForm.getMailtype()).toString()); storeSpecificFields(aForm, data); cust.setCustParameters(data); cust.setCustomerID(recipientDao.insertNewCust(cust)); aForm.setRecipientID(cust.getCustomerID()); AgnUtils.userlogger() .info(AgnUtils.getAdmin(req).getUsername() + ": create recipient " + cust.getCustomerID()); } aForm.setRecipientID(cust.getCustomerID()); saveBindings(aForm, req); updateCustBindingsFromAdminReq(cust, req); return true; } /** * Method for storing specific fields of recipient. Can be overridden in subclass. For OpenEMM the method * currently doesn't do anything. * * @param aForm current form * @param customerFields the map of recipients fields which will be later used for saving recipient to DB */ protected void storeSpecificFields(RecipientForm aForm, Map<String, String> customerFields) { } /** * Gets the list of recipient fields * * @param companyId current company ID * @return recipient fields in a form of map: column -> column-shortname * @throws Exception if the exception happens in columnInfoService class */ protected Map<String, String> getRecipientFieldsNames(int companyId, int adminId) throws Exception { CaseInsensitiveMap<ProfileField> columnInfoMap = columnInfoService.getColumnInfoMap(companyId, adminId); Map<String, String> fieldsMap = new LinkedHashMap<String, String>(); // we need predefined oreder for default columns: gender, firstname, lastname. fieldsMap.put(COLUMN_GENDER, columnInfoMap.get(COLUMN_GENDER).getShortname()); fieldsMap.put(COLUMN_FIRSTNAME, columnInfoMap.get(COLUMN_FIRSTNAME).getShortname()); fieldsMap.put(COLUMN_LASTNAME, columnInfoMap.get(COLUMN_LASTNAME).getShortname()); columnInfoMap.remove(COLUMN_GENDER); columnInfoMap.remove(COLUMN_FIRSTNAME); columnInfoMap.remove(COLUMN_LASTNAME); // put the rest of columns to the map for (String column : columnInfoMap.keySet()) { fieldsMap.put(column, columnInfoMap.get(column).getShortname()); } return fieldsMap; } /** * Updates customer bindings with the data taken from request * * @param cust recipient bean * @param req HTTP request holding parameters for binding entries */ @Deprecated public boolean updateCustBindingsFromAdminReq(Recipient cust, HttpServletRequest req) { String aKey = null; String newKey = null; String aParam = null; int aMailinglistID; int oldSubStatus, newSubStatus; String tmpUT = null; String tmpOrgUT = null; Iterator aEnum = req.getParameterMap().keySet().iterator(); BindingEntry bindingEntry = bindingEntryFactory.newBindingEntry(); while (aEnum.hasNext()) { aKey = (String) aEnum.next(); if (aKey.startsWith("AGN_0_ORG_MT")) { oldSubStatus = Integer.parseInt((String) req.getParameter(aKey)); aMailinglistID = Integer.parseInt(aKey.substring(12)); newKey = "AGN_0_MTYPE" + aMailinglistID; aParam = (String) req.getParameter(newKey); if (aParam != null) { newSubStatus = 1; } else { newSubStatus = 0; } newKey = "AGN_0_MLUT" + aMailinglistID; tmpUT = (String) req.getParameter(newKey); newKey = "AGN_0_ORG_UT" + aMailinglistID; tmpOrgUT = (String) req.getParameter(newKey); if ((newSubStatus != oldSubStatus) || (tmpUT.compareTo(tmpOrgUT) != 0)) { bindingEntry.setMediaType(0); bindingEntry.setCustomerID(cust.getCustomerID()); bindingEntry.setMailinglistID(aMailinglistID); bindingEntry.setUserType(tmpUT); if (newSubStatus == 0) { // Opt-Out bindingEntry.setUserStatus(BindingEntry.USER_STATUS_ADMINOUT); // bindingEntry.setUserRemark("Opt-Out by ADMIN"); } else { // Opt-In bindingEntry.setUserStatus(BindingEntry.USER_STATUS_ACTIVE); // bindingEntry.setUserRemark("Opt-In by ADMIN"); } if (bindingEntry.updateBindingInDB(cust.getCompanyID()) == false) { // bindingEntry.setUserType(BindingEntry.USER_TYPE_WORLD); // Bei Neu-Eintrag durch User entsprechenden Typ setzen if (newSubStatus == 1) { bindingEntry.insertNewBindingInDB(cust.getCompanyID()); } } } } } return true; } /** * Removes recipient from a database. The ID of recipient is taken from form property recipientID. * * @param aForm form * @param req HTTP request */ protected void deleteRecipient(RecipientForm aForm, HttpServletRequest req) { int companyID = this.getCompanyID(req); recipientDao.deleteCustomerDataFromDb(companyID, aForm.getRecipientID()); AgnUtils.userlogger() .info(AgnUtils.getAdmin(req).getUsername() + ": delete recipient " + aForm.getRecipientID()); } /** * Get a list of recipients according to filters user selected: mailinglist, target group, recipient status, * recipient type, advanced search parameters, selected columns to show. * * @param request HTTP request * @param aForm recipient form * @return the Future containing the paginated list of matching recipient * @throws Exception */ public Future<PaginatedList> getRecipientListFuture(HttpServletRequest request, RecipientForm aForm, Set<String> recipientDbColumns) throws Exception { SqlPreparedStatementManager sqlStatementManagerForCount = recipientQueryBuilder.getSQLStatement(request, aForm, targetRepresentationFactory, targetNodeFactory, false, true); String countStatement = sqlStatementManagerForCount.getPreparedSqlString().replaceAll("cust[.]bind", "bind") .replace("lower(cust.email)", "cust.email"); if (logger.isInfoEnabled()) { logger.info("Recipient Count SQL statement: " + countStatement); } 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); } RecipientForm form = aForm; form.setDeactivatePagination(false); Company company = AgnUtils.getCompany(request); int maxRecipients = company.getMaxRecipients(); if (maxRecipients != 0) { // check the max recipients for company JdbcTemplate aTemplate = new JdbcTemplate(dataSource); int totalRows = aTemplate.queryForInt(countStatement, sqlStatementManagerForCount.getPreparedSqlParameters()); if (totalRows > maxRecipients) { aForm.setPage("1"); aForm.setNumberOfRowsChanged(false); pageStr = "1"; form.setDeactivatePagination(true); } } SqlPreparedStatementManager sqlStatementManagerForSelect = recipientQueryBuilder.getSQLStatement(request, aForm, targetRepresentationFactory, targetNodeFactory, form.isDeactivatePagination(), false); String selectStatement = sqlStatementManagerForSelect.getPreparedSqlString() .replaceAll("cust[.]bind", "bind").replace("lower(cust.email)", "cust.email"); if (logger.isInfoEnabled()) { logger.info("Recipient Select SQL statement: " + selectStatement); } String sort = getSort(request, aForm); String direction = request.getParameter("dir"); int rownums = aForm.getNumberofRows(); if (direction == null) { direction = aForm.getOrder(); } else { aForm.setOrder(direction); } if (aForm.isNumberOfRowsChanged()) { aForm.setPage("1"); aForm.setNumberOfRowsChanged(false); pageStr = "1"; } Future<PaginatedList> future = executorService.submit(new RecipientBeanQueryWorker(recipientDao, recipientDbColumns, countStatement, sqlStatementManagerForCount.getPreparedSqlParameters(), selectStatement, sqlStatementManagerForSelect.getPreparedSqlParameters(), sort, direction, Integer.parseInt(pageStr), rownums, aForm.getAll())); return future; } private boolean updateRecipientFormProperties(HttpServletRequest req, RecipientForm form) { int lastIndex = form.getNumTargetNodes(); int removeIndex = -1; // If "add" was clicked, add new rule if (AgnUtils.parameterNotEmpty(req, "addTargetNode") || (AgnUtils.parameterNotEmpty(req, "Update") && !StringUtils.isEmpty(form.getPrimaryValueNew()))) { form.setColumnAndType(lastIndex, form.getColumnAndTypeNew()); form.setChainOperator(lastIndex, form.getChainOperatorNew()); form.setParenthesisOpened(lastIndex, form.getParenthesisOpenedNew()); form.setPrimaryOperator(lastIndex, form.getPrimaryOperatorNew()); form.setPrimaryValue(lastIndex, form.getPrimaryValueNew()); form.setParenthesisClosed(lastIndex, form.getParenthesisClosedNew()); form.setDateFormat(lastIndex, form.getDateFormatNew()); form.setSecondaryOperator(lastIndex, form.getSecondaryOperatorNew()); form.setSecondaryValue(lastIndex, form.getSecondaryValueNew()); lastIndex++; } int nodeToRemove = -1; String nodeToRemoveStr = req.getParameter("targetNodeToRemove"); if (AgnUtils.parameterNotEmpty(req, "targetNodeToRemove")) { nodeToRemove = Integer.parseInt(nodeToRemoveStr); } // Iterate over all target rules for (int index = 0; index < lastIndex; index++) { if (index != nodeToRemove) { String colAndType = form.getColumnAndType(index); String column = colAndType.substring(0, colAndType.indexOf('#')); String type = colAndType.substring(colAndType.indexOf('#') + 1); form.setColumnName(index, column); if (type.equalsIgnoreCase("VARCHAR") || type.equalsIgnoreCase("VARCHAR2") || type.equalsIgnoreCase("CHAR")) { form.setValidTargetOperators(index, TargetNodeString.getValidOperators()); form.setColumnType(index, TargetForm.COLUMN_TYPE_STRING); } else if (type.equalsIgnoreCase("INTEGER") || type.equalsIgnoreCase("DOUBLE") || type.equalsIgnoreCase("NUMBER")) { form.setValidTargetOperators(index, TargetNodeNumeric.getValidOperators()); form.setColumnType(index, TargetForm.COLUMN_TYPE_NUMERIC); } else if (type.equalsIgnoreCase("DATE")) { form.setValidTargetOperators(index, TargetNodeDate.getValidOperators()); form.setColumnType(index, TargetForm.COLUMN_TYPE_DATE); } } else { if (removeIndex != -1) throw new RuntimeException( "duplicate remove??? (removeIndex = " + removeIndex + ", index = " + index + ")"); removeIndex = index; } } if (removeIndex != -1) { form.removeRule(removeIndex); return true; } else { return false; } } public void setFutureHolder(AbstractMap<String, Future> futureHolder) { this.futureHolder = futureHolder; } public void setMailinglistDao(MailinglistDao mailinglistDao) { this.mailinglistDao = mailinglistDao; } public void setTargetDao(TargetDao targetDao) { this.targetDao = targetDao; } public void setRecipientDao(RecipientDao recipientDao) { this.recipientDao = recipientDao; } public void setTargetRepresentationFactory(TargetRepresentationFactory targetRepresentationFactory) { this.targetRepresentationFactory = targetRepresentationFactory; } public void setTargetNodeFactory(TargetNodeFactory targetNodeFactory) { this.targetNodeFactory = targetNodeFactory; } public void setExecutorService(ExecutorService executorService) { this.executorService = executorService; } public void setRecipientQueryBuilder(RecipientQueryBuilder recipientQueryBuilder) { this.recipientQueryBuilder = recipientQueryBuilder; } public void setColumnInfoService(ColumnInfoService columnInfoService) { this.columnInfoService = columnInfoService; } public void setRecipientFactory(RecipientFactory recipientFactory) { this.recipientFactory = recipientFactory; } public void setBindingEntryFactory(BindingEntryFactory bindingEntryFactory) { this.bindingEntryFactory = bindingEntryFactory; } public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } }