org.ambraproject.action.article.EmailArticleAction.java Source code

Java tutorial

Introduction

Here is the source code for org.ambraproject.action.article.EmailArticleAction.java

Source

/*
 * $HeadURL$
 * $Id$
 * Copyright (c) 2006-2012 by Public Library of Science http://plos.org http://ambraproject.org
 * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.ambraproject.action.article;

import org.ambraproject.ApplicationException;
import org.ambraproject.action.user.UserActionSupport;
import org.ambraproject.models.Article;
import org.ambraproject.models.UserProfile;
import org.ambraproject.service.article.ArticleService;
import org.ambraproject.service.article.NoSuchArticleIdException;
import org.ambraproject.service.captcha.CaptchaService;
import org.ambraproject.service.mailer.AmbraMailer;
import org.ambraproject.service.xml.XMLService;
import org.ambraproject.util.TextUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.validator.routines.EmailValidator;
import org.apache.struts2.ServletActionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Required;
import org.ambraproject.email.impl.FreemarkerTemplateMailer;
import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;

/**
 * Email the article to another user.
 */
public class EmailArticleAction extends UserActionSupport {
    private String articleURI;
    private String emailTo;
    private String emailFrom;
    private String senderName;
    private String note;
    private String title;
    private String description;
    private String journalName;
    private String captchaHTML;
    private String captchaChallenge;
    private String captchaResponse;

    private AmbraMailer ambraMailer;
    private XMLService secondaryObjectService;
    private ArticleService articleService;
    private CaptchaService captchaService;
    private static final Logger log = LoggerFactory.getLogger(EmailArticleAction.class);
    private static final int MAX_TO_EMAIL = 5;

    /**
     * Render the page with the values passed in
     * @return webwork status
     * @throws Exception Exception
     */
    public String executeRender() throws Exception {
        if (!validatesArticleURI())
            return INPUT;

        final UserProfile ambraUser = getCurrentUser();
        if (null != ambraUser) {
            senderName = ambraUser.getDisplayName();
            emailFrom = ambraUser.getEmail();
        }

        setArticleTitleAndDesc(articleURI);
        setNewReCaptcha();

        return SUCCESS;
    }

    /**
     * Send the email
     * @return webwork status
     * @throws Exception Exception
     */
    public String executeSend() throws Exception {

        if (!validates())
            return INPUT;

        setArticleTitleAndDesc(articleURI);

        final Map<String, String> mapFields = new HashMap<String, String>();
        mapFields.put("articleURI", articleURI);
        mapFields.put("senderName", senderName);
        mapFields.put(FreemarkerTemplateMailer.USER_NAME_KEY, senderName);
        mapFields.put("note", note);
        mapFields.put("title", title);
        mapFields.put("description", description);
        mapFields.put("journalName", journalName);
        mapFields.put("subject", "An Article from PLoS: " + TextUtils.simpleStripAllTags(title));

        ambraMailer.sendEmailThisArticleEmail(emailTo, emailFrom, mapFields);

        return SUCCESS;
    }

    private void setArticleTitleAndDesc(final String articleURI)
            throws NoSuchArticleIdException, ApplicationException {
        final Article article = articleService.getArticle(articleURI, getAuthId());
        title = article.getTitle();

        description = article.getDescription();

        if (description != null && description.trim().length() > 0) {
            description = secondaryObjectService.getTransformedDescription(description);
        } else {
            description = "";
        }
    }

    private boolean validates() {
        boolean isValid = true;

        isValid = validatesArticleURI();

        if (StringUtils.isBlank(emailFrom)) {
            addFieldError("emailFrom", "This field is required.");
            isValid = false;
        } else {

            if (!EmailValidator.getInstance().isValid(emailFrom)) {
                addFieldError("emailFrom", "Invalid e-mail address");
                isValid = false;
            }
        }

        isValid = checkEmails(emailTo) && isValid;

        if (StringUtils.isBlank(senderName)) {
            addFieldError("senderName", "This field is required.");
            isValid = false;
        }

        HttpServletRequest request = ServletActionContext.getRequest();

        if (!captchaService.validateCaptcha(request.getRemoteAddr(), captchaChallenge, captchaResponse)) {
            addFieldError("captcha", "Verification is incorrect. Please try again.");
            isValid = false;
        }

        if (!isValid) {
            setNewReCaptcha();
        }

        return isValid;
    }

    private void setNewReCaptcha() {
        captchaHTML = captchaService.getCaptchaHTML();
    }

    /**
     * Validate article uri
     * @return false if article uri is not valid
     */
    private boolean validatesArticleURI() {
        boolean isValid = true;
        if (StringUtils.isBlank(articleURI)) {
            addFieldError("articleURI", "Article URI cannot be empty");
            isValid = false;
        } else {
            try {
                articleURI = URLDecoder.decode(articleURI, "UTF-8");
                new URI(articleURI);
            } catch (UnsupportedEncodingException ex) {
                addFieldError("articleURI", "Must be a valid URI, character encoding is bad.");
                isValid = false;
            } catch (URISyntaxException ex) {
                addFieldError("articleURI", "Must be a valid URI");
                isValid = false;
            }
        }

        return isValid;
    }

    private boolean checkEmails(String emailList) {
        if (StringUtils.isBlank(emailList)) {
            addFieldError("emailTo", "This field is required.");
            return false;
        } else {
            final StringTokenizer emailTokens = new StringTokenizer(emailList, " \t\n\r\f,");
            if (emailTokens.countTokens() > MAX_TO_EMAIL) {
                addFieldError("emailTo", "Maximum of " + MAX_TO_EMAIL + " email addresses");
                return false;
            }
            EmailValidator validator = EmailValidator.getInstance();
            ArrayList<String> invalidEmails = new ArrayList<String>();

            while (emailTokens.hasMoreTokens()) {
                String email = emailTokens.nextToken();
                if (!validator.isValid(email)) {
                    invalidEmails.add(email);
                }
            }
            final int numInvalid = invalidEmails.size();
            if (numInvalid != 0) {
                StringBuilder errorMsg = new StringBuilder("Invalid e-mail address");
                if (numInvalid > 1) {
                    errorMsg.append("es: ");
                } else {
                    errorMsg.append(": ");
                }
                Iterator<String> iter = invalidEmails.iterator();
                while (iter.hasNext()) {
                    errorMsg.append(iter.next());
                    if (iter.hasNext()) {
                        errorMsg.append(", ");
                    }
                }
                addFieldError("emailTo", errorMsg.toString());
            }
            return (numInvalid == 0);
        }
    }

    /**
     * Getter for articleURI.
     * @return Value of articleURI.
     */
    public String getArticleURI() {
        return articleURI;
    }

    /**
     * Setter for articleURI.
     * @param articleURI Value to set for articleURI.
     */
    public void setArticleURI(final String articleURI) {
        this.articleURI = articleURI;
    }

    /**
     * Getter for emailFrom.
     * @return Value of emailFrom.
     */
    public String getEmailFrom() {
        return emailFrom;
    }

    /**
     * Setter for emailFrom.
     * @param emailFrom Value to set for emailFrom.
     */
    public void setEmailFrom(final String emailFrom) {
        this.emailFrom = emailFrom;
    }

    /**
     * Getter for emailTo.
     * @return Value of emailTo.
     */
    public String getEmailTo() {
        return emailTo;
    }

    /**
     * Setter for emailTo.
     * @param emailTo Value to set for emailTo.
     */
    public void setEmailTo(final String emailTo) {
        this.emailTo = emailTo;
    }

    /**
     * Getter for note.
     * @return Value of note.
     */
    public String getNote() {
        return note;
    }

    /**
     * Setter for note.
     * @param note Value to set for note.
     */
    public void setNote(final String note) {
        this.note = note;
    }

    /**
     * Getter for senderName.
     * @return Value of senderName.
     */
    public String getSenderName() {
        return senderName;
    }

    /**
     * Setter for senderName.
     * @param senderName Value to set for senderName.
     */
    public void setSenderName(final String senderName) {
        this.senderName = senderName;
    }

    /**
     * Setter for ambraMailer.
     * @param ambraMailer Value to set for ambraMailer.
     */
    @Required
    public void setAmbraMailer(final AmbraMailer ambraMailer) {
        this.ambraMailer = ambraMailer;
    }

    /**
     * Setter for fetchArticleService.
     * @param articleService Value to set for ArticleService.
     */
    @Required
    public void setArticleService(ArticleService articleService) {
        this.articleService = articleService;
    }

    /**
     * @param secondaryObjectService The XMLService to set.
     */
    @Required
    public void setSecondaryObjectService(XMLService secondaryObjectService) {
        this.secondaryObjectService = secondaryObjectService;
    }

    /**
     * @param captchaService The captchaService to set.
     */
    @Required
    public void setCaptchaService(CaptchaService captchaService) {
        this.captchaService = captchaService;
    }

    /**
     * Getter for description.
     * @return Value of description.
     */
    public String getDescription() {
        return description;
    }

    /**
     * Getter for title.
     * @return Value of title.
     */
    public String getTitle() {
        return title;
    }

    /**
     * @param title The title to set.
     */
    public void setTitle(String title) {
        this.title = title;
    }

    /**
     * @return Returns the journalName.
     */
    public String getJournalName() {
        return journalName;
    }

    /**
     * @param journalName The journalName to set.
     */
    public void setJournalName(String journalName) {
        this.journalName = journalName;
    }

    /**
     * @return Returns the mAX_TO_EMAIL.
     */
    public int getMaxEmails() {
        return MAX_TO_EMAIL;
    }

    /**
     * @return Returns the RecaptchaHTML block
     */
    public String getCaptchaHTML() {
        return captchaHTML;
    }

    /**
     * This field is defined in the form that the google recaptcha sends us and
     * as best as I can tell, can't be changed.
     *
     * @param recaptcha_challenge_field
     */
    public void setRecaptcha_challenge_field(String recaptcha_challenge_field) {
        captchaChallenge = recaptcha_challenge_field;
    }

    /**
     * This field is defined in the form that the google recaptcha sends us and
     * as best as I can tell, can't be changed.
     *
     * @param recaptcha_challenge_field
     */
    public void setRecaptcha_response_field(String recaptcha_response_field) {
        captchaResponse = recaptcha_response_field;
    }
}