org.agnitas.web.OnePixelCount.java Source code

Java tutorial

Introduction

Here is the source code for org.agnitas.web.OnePixelCount.java

Source

/*********************************************************************************
 * 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.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.agnitas.actions.EmmAction;
import org.agnitas.beans.Company;
import static org.agnitas.beans.Company.STATUS_ACTIVE;
import org.agnitas.dao.CompanyDao;
import org.agnitas.dao.EmmActionDao;
import org.agnitas.dao.MailingDao;
import org.agnitas.dao.OnepixelDao;
import org.agnitas.emm.core.commons.uid.ExtensibleUID;
import org.agnitas.emm.core.commons.uid.ExtensibleUIDConstants;
import org.agnitas.emm.core.commons.uid.ExtensibleUIDService;
import org.agnitas.emm.core.commons.uid.parser.exception.UIDParseException;
import org.agnitas.util.AgnUtils;
import org.apache.commons.collections.map.CaseInsensitiveMap;
import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

/**
 * The servlet is used for registration of opening emails have been sent to customers and loading one pixel gif image
 * that is automatically adding into content of each OpenEMM mailing.
 * Each time the customer opens the email, the request is sent to the server, the data about the mailing and customer
 * are logged in database and the server returns http response that contains one pixel gif image.
 */
public class OnePixelCount extends HttpServlet {
    private static final transient Logger logger = Logger.getLogger(OnePixelCount.class);

    private static final long serialVersionUID = -3837933074485365451L;
    protected byte[] onePixelGif = { 71, 73, 70, 56, 57, 97, 1, 0, 1, 0, -128, -1, 0, -64, -64, -64, 0, 0, 0, 33,
            -7, 4, 1, 0, 0, 0, 0, 44, 0, 0, 0, 0, 1, 0, 1, 0, 0, 2, 2, 68, 1, 0, 59 };
    private static Company cachedCompany = null;

    /**
     * Gets company data from database and stores it in cachedCompany variable.
     * @param companyID
     * @return
     */
    protected Company getCompany(int companyID) {
        if (cachedCompany == null) {
            ApplicationContext con = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
            CompanyDao cDao = (CompanyDao) con.getBean("CompanyDao");

            cachedCompany = cDao.getCompany(companyID);
        }
        return cachedCompany;
    }

    /**
     * Servlet service-method, is invoked on calling the servlet.
     * Parses data from uid parameter (company id, mailing id and customer id),
     * stores the data from the request in database,
     * writes one pixel gif image into response.
     * Also executes mailing open action, if the mailing has one.
     * Returns nothing if the company is not in status "active" or if some execution error occurs.
     * @param req HTTP request; should contain "uid" parameter with values of company id, mailing id and customer id
     * @param res HTTP response, contains one pixel gif image
     * @throws IOException if an input/output error occurs
     * @throws ServletException if a servlet exception occurs
     */
    @Override
    public void service(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
        ApplicationContext con = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
        String param = null;
        OnepixelDao pixelDao = (OnepixelDao) con.getBean("OnepixelDao");

        ExtensibleUIDService uidService = (ExtensibleUIDService) con
                .getBean(ExtensibleUIDConstants.SERVICE_BEAN_NAME);

        // send gif to Browser.
        res.setContentType("image/gif");
        OutputStream out = res.getOutputStream();
        out.write(onePixelGif);
        out.close();

        param = req.getParameter("uid");
        if (param == null) {
            logger.error("service: no uid set");
            return;
        }

        try {
            // validate uid
            ExtensibleUID uid = null;
            Company company = null;

            try {
                uid = uidService.parse(param);
            } catch (UIDParseException e) {
                logger.warn("Error parsing UID: " + param + " (" + e.getMessage() + ")");
                logger.debug(e);
            }

            if (uid == null || uid.getCompanyID() == 0) {
                return;
            }

            company = getCompany((int) uid.getCompanyID());

            if (company == null) {
                logger.error("Company with ID: " + uid.getCompanyID() + " not found ");
                return;
            }

            /*
            // TODO: Create a separate Helper class to validate the old UIDs
            if(uid.validateUID(company.getSecret())==false) {
               logger.warn("uid invalid: " + param);
               return;
            }
            */

            if (!STATUS_ACTIVE.equals(company.getStatus())) {
                return;
            }

            persistLog(req, pixelDao, uid);
            executeMailingOpenAction(uid, con, req);

        } catch (Exception e) {
            logger.error(e);
            return;
        }
    }

    /**
     * Calls writePixelLogToDB method and logs to console in case of its successful execution.
     * @param req  HTTP request
     * @param pixelDao  OnePixelDao object
     * @param uid  ExtensibleUID object, contains parsed data from the "uid" request parameter
     */
    protected void persistLog(HttpServletRequest req, OnepixelDao pixelDao, ExtensibleUID uid) {
        if (writePixelLogToDB(req, pixelDao, uid)) {
            logger.info("Onepixel: cust: " + uid.getCustomerID() + " mi: " + uid.getMailingID() + " ci: "
                    + uid.getCompanyID());
        }
    }

    /**
     * Stores opened email data (company id, mailing id, customer id, client IP address) in database.
     * @param req HTTP request, is used fot getting the IP address of the client that sent the request
     * @param pixelDao OnePixelDao object
     * @param uid ExtensibleUID object, contains parsed data from the "uid" request parameter
     * @return  true==success
     *          false==error
     */
    protected boolean writePixelLogToDB(HttpServletRequest req, OnepixelDao pixelDao, ExtensibleUID uid) {
        return pixelDao.writePixel(uid.getCompanyID(), uid.getCustomerID(), uid.getMailingID(),
                req.getRemoteAddr());
    }

    /**
     * Gets the id of action to be exequted on opening the mailing; if the action id > 0, executes the action with
     * parameters from the request.
     * @param uid ExtensibleUID object, contains parsed data from the "uid" request parameter
     * @param context application context
     * @param req  HTTP request
     */
    protected void executeMailingOpenAction(ExtensibleUID uid, ApplicationContext context, HttpServletRequest req) {
        MailingDao mailingDao = (MailingDao) context.getBean("MailingDao");
        EmmActionDao actionDao = (EmmActionDao) context.getBean("EmmActionDao");
        int companyID = uid.getCompanyID();
        int mailingID = uid.getMailingID();
        int customerID = uid.getCustomerID();
        int openActionID = mailingDao.getMailingOpenAction(mailingID, companyID);
        if (openActionID != 0) {
            EmmAction emmAction = actionDao.getEmmAction(openActionID, companyID);
            if (emmAction != null) {
                // execute configured actions
                CaseInsensitiveMap params = new CaseInsensitiveMap();
                params.put("requestParameters", AgnUtils.getReqParameters(req));
                params.put("_request", req);
                params.put("customerID", customerID);
                params.put("mailingID", mailingID);
                emmAction.executeActions(context, params);
            }
        }
    }
}