package org.agnitas.service; import javax.servlet.http.HttpServletRequest; import org.agnitas.dao.TargetDao; import org.agnitas.target.TargetNode; import org.agnitas.target.TargetNodeFactory; import org.agnitas.target.TargetRepresentation; 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.SqlPreparedStatementManager; import org.agnitas.web.RecipientForm; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; /** * Helper-class for building the sql-query in /recipient/list.jsp * * @author ms */ public class RecipientQueryBuilder { private static final transient Logger logger = Logger.getLogger(RecipientQueryBuilder.class); private static final String PREFIX_BIND = "bind"; private static final String PREFIX_CUST = "cust"; private TargetDao targetDao; public void setTargetDao(TargetDao targetDao) { this.targetDao = targetDao; } private TargetRepresentation createTargetRepresentationFromForm(RecipientForm form, TargetRepresentationFactory targetRepresentationFactory, TargetNodeFactory targetNodeFactory) { TargetRepresentation target = targetRepresentationFactory.newTargetRepresentation(); int lastIndex = form.getNumTargetNodes(); for (int index = 0; index < lastIndex; index++) { String colAndType = form.getColumnAndType(index); String column = colAndType.substring(0, colAndType.indexOf('#')); String type = colAndType.substring(colAndType.indexOf('#') + 1); TargetNode node = null; if (type.equalsIgnoreCase("VARCHAR") || type.equalsIgnoreCase("VARCHAR2") || type.equalsIgnoreCase("CHAR")) { node = createStringNode(form, column, type, index, targetNodeFactory); } else if (type.equalsIgnoreCase("INTEGER") || type.equalsIgnoreCase("DOUBLE") || type.equalsIgnoreCase("NUMBER")) { node = createNumericNode(form, column, type, index, targetNodeFactory); } else if (type.equalsIgnoreCase("DATE")) { node = createDateNode(form, column, type, index, targetNodeFactory); } target.addNode(node); } return target; } /** * construct a sql query from all the provided parameters * * @param request * * @return * @throws Exception */ public SqlPreparedStatementManager getSQLStatement(HttpServletRequest request, RecipientForm aForm, TargetRepresentationFactory targetRepresentationFactory, TargetNodeFactory targetNodeFactory, boolean optimized, boolean queryForCount) throws Exception { if (logger.isInfoEnabled()) { logger.info("Creating SQL statement for recipients"); } if (logger.isDebugEnabled()) { logger.debug("Oracle DB: " + AgnUtils.isOracleDB()); logger.debug("optimized: " + optimized); logger.debug("result type: " + (queryForCount ? "count" : "list")); } String sort = request.getParameter("sort"); if (sort == null) { sort = aForm.getSort(); if (logger.isDebugEnabled()) { logger.debug("request parameter sort = null"); logger.debug("using form parameter sort = " + sort); } } String direction = request.getParameter("dir"); if (direction == null) { direction = aForm.getOrder(); if (logger.isDebugEnabled()) { logger.debug("request parameter dir = null"); logger.debug("using form parameter order = " + direction); } } if (request.getParameter("listID") != null) { if (logger.isDebugEnabled()) { logger.debug("parameter listID = " + request.getParameter("listID")); } aForm.setListID(Integer.parseInt(request.getParameter("listID"))); } int mailingListID = aForm.getListID(); if (request.getParameter("targetID") != null) { if (logger.isDebugEnabled()) { logger.debug("parameter targetID = " + request.getParameter("targetID")); } aForm.setTargetID(Integer.parseInt(request.getParameter("targetID"))); } int targetID = aForm.getTargetID(); if (request.getParameter("user_type") != null) { if (logger.isDebugEnabled()) { logger.debug("parameter user_type = " + request.getParameter("user_type")); } aForm.setUser_type(request.getParameter("user_type")); } String user_type = aForm.getUser_type(); if (request.getParameter("searchFirstName") != null) { if (logger.isDebugEnabled()) { logger.debug("parameter searchFirstName = " + request.getParameter("searchFirstName")); } aForm.setSearchFirstName(request.getParameter("searchFirstName")); } String firstName = aForm.getSearchFirstName(); if (request.getParameter("searchLastName") != null) { if (logger.isDebugEnabled()) { logger.debug("parameter searchLastName = " + request.getParameter("searchLastName")); } aForm.setSearchLastName(request.getParameter("searchLastName")); } String lastName = aForm.getSearchLastName(); if (request.getParameter("searchEmail") != null) { aForm.setSearchEmail(request.getParameter("searchEmail")); } String email = aForm.getSearchEmail(); if (request.getParameter("user_status") != null) { aForm.setUser_status(Integer.parseInt(request.getParameter("user_status"))); } int user_status = aForm.getUser_status(); SqlPreparedStatementManager mainStatement; if (queryForCount) { mainStatement = new SqlPreparedStatementManager("SELECT COUNT(*) FROM customer_" + AgnUtils.getCompanyID(request) + "_tbl " + PREFIX_CUST); } else { mainStatement = new SqlPreparedStatementManager("SELECT * FROM customer_" + AgnUtils.getCompanyID(request) + "_tbl " + PREFIX_CUST); } if (targetID != 0) { mainStatement.addWhereClause(targetDao.getTarget(targetID, AgnUtils.getCompanyID(request)).getTargetSQL()); } if (StringUtils.isNotEmpty(firstName)) { mainStatement.addWhereClause("lower(" + PREFIX_CUST + ".firstname) = ?", firstName.toLowerCase().trim()); } if (StringUtils.isNotEmpty(lastName)) { mainStatement.addWhereClause("lower(" + PREFIX_CUST + ".lastname) = ?", lastName.toLowerCase().trim()); } if (StringUtils.isNotEmpty(email)) { mainStatement.addWhereClause(PREFIX_CUST + ".email like ('%' || ? || '%')", email.toLowerCase().trim()); } if (AgnUtils.isOracleDB() && optimized) { int maxRownum = 20; if (!StringUtils.isEmpty(aForm.getPage()) && StringUtils.isNumeric(aForm.getPage())) { maxRownum = ((Integer.parseInt(aForm.getPage()) - 1) * aForm.getNumberofRows()) + aForm.getNumberofRows() + 1; } mainStatement.addWhereClause("rownum < ?", maxRownum); } SqlPreparedStatementManager customerIdSubSelectStatement = new SqlPreparedStatementManager("SELECT customer_id FROM customer_" + AgnUtils.getCompanyID(request) + "_binding_tbl " + PREFIX_BIND); if (user_type != null && !"E".equalsIgnoreCase(user_type)) { customerIdSubSelectStatement.addWhereClause(PREFIX_BIND + ".user_type = ?", user_type); } if (user_status != 0) { customerIdSubSelectStatement.addWhereClause(PREFIX_BIND + ".user_status = ?", user_status); } if (mailingListID != 0) { customerIdSubSelectStatement.addWhereClause(PREFIX_BIND + ".mailinglist_id = ?", mailingListID); } TargetRepresentation targetRep = createTargetRepresentationFromForm(aForm, targetRepresentationFactory, targetNodeFactory); if (targetRep.generateSQL().length() > 0 && targetRep.checkBracketBalance()) { if (targetRep.generateSQL().contains("bind.")) { customerIdSubSelectStatement.addWhereClause(targetRep.generateSQL()); } else { mainStatement.addWhereClause(targetRep.generateSQL()); } } if (customerIdSubSelectStatement.hasAppendedWhereClauses()) { mainStatement.addWhereClause(PREFIX_CUST + ".customer_id in (" + customerIdSubSelectStatement.getPreparedSqlString() + ")", customerIdSubSelectStatement.getPreparedSqlParameters()); } // we need the sorting of inner query only for Oracle if (AgnUtils.isOracleDB()) { if (StringUtils.isNotBlank(sort)) { mainStatement.finalizeStatement("ORDER BY " + sort.trim() + " " + direction); } } return mainStatement; } private TargetNodeString createStringNode(RecipientForm form, String column, String type, int index, TargetNodeFactory factory) { return factory.newStringNode(form.getChainOperator(index), form.getParenthesisOpened(index), column, type, form.getPrimaryOperator(index), form.getPrimaryValue(index), form.getParenthesisClosed(index)); } private TargetNodeNumeric createNumericNode(RecipientForm form, String column, String type, int index, TargetNodeFactory factory) { int primaryOperator = form.getPrimaryOperator(index); int secondaryOperator = form.getSecondaryOperator(index); int secondaryValue = 0; if (primaryOperator == TargetNode.OPERATOR_MOD.getOperatorCode()) { try { secondaryOperator = Integer.parseInt(form.getSecondaryValue(index)); } catch (Exception e) { secondaryOperator = TargetNode.OPERATOR_EQ.getOperatorCode(); } try { secondaryValue = Integer.parseInt(form.getSecondaryValue(index)); } catch (Exception e) { secondaryValue = 0; } } return factory.newNumericNode(form.getChainOperator(index), form.getParenthesisOpened(index), column, type, primaryOperator, form.getPrimaryValue(index), secondaryOperator, secondaryValue, form.getParenthesisClosed(index)); } private TargetNodeDate createDateNode(RecipientForm form, String column, String type, int index, TargetNodeFactory factory) { return factory.newDateNode(form.getChainOperator(index), form.getParenthesisOpened(index), column, type, form.getPrimaryOperator(index), form.getDateFormat(index), form.getPrimaryValue(index), form.getParenthesisClosed(index)); } }