View Javadoc

    1   package org.apache.turbine.util.velocity;
    2
    3
    4   /*
    5    * Licensed to the Apache Software Foundation (ASF) under one
    6    * or more contributor license agreements.  See the NOTICE file
    7    * distributed with this work for additional information
    8    * regarding copyright ownership.  The ASF licenses this file
    9    * to you under the Apache License, Version 2.0 (the
    10   * "License"); you may not use this file except in compliance
    11   * with the License.  You may obtain a copy of the License at
    12   *
    13   *   http://www.apache.org/licenses/LICENSE-2.0
    14   *
    15   * Unless required by applicable law or agreed to in writing,
    16   * software distributed under the License is distributed on an
    17   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    18   * KIND, either express or implied.  See the License for the
    19   * specific language governing permissions and limitations
    20   * under the License.
    21   */
    22
    23  import org.apache.commons.lang.StringUtils;
    24  import org.apache.commons.lang.WordUtils;
    25  import org.apache.commons.logging.Log;
    26  import org.apache.commons.logging.LogFactory;
    27  import org.apache.commons.mail.EmailException;
    28  import org.apache.commons.mail.SimpleEmail;
    29  import org.apache.turbine.Turbine;
    30  import org.apache.turbine.TurbineConstants;
    31  import org.apache.turbine.services.TurbineServices;
    32  import org.apache.turbine.services.velocity.VelocityService;
    33  import org.apache.velocity.context.Context;
    34
    35  /**
    36   * This is a simple class for sending email from within Velocity.
    37   * Essentially, the body of the email is processed with a
    38   * Velocity Context object.
    39   * The beauty of this is that you can send email from within your
    40   * Velocity template or from your business logic in your Java code.
    41   * The body of the email is just a Velocity template so you can use
    42   * all the template functionality of Velocity within your emails!
    43   *
    44   * <p>Example Usage (This all needs to be on one line in your
    45   * template):
    46   *
    47   * <p>Setup your context:
    48   *
    49   * <p><code>context.put ("VelocityEmail", new VelocityEmail() );</code>
    50   *
    51   * <p>Then, in your template:
    52   *
    53   * <pre>
    54   * $VelocityEmail.setTo("Jon Stevens", "jon@latchkey.com")
    55   *     .setFrom("Mom", "mom@mom.com").setSubject("Eat dinner")
    56   *     .setTemplate("email/momEmail.vm")
    57   *     .setContext($context)
    58   * </pre>
    59   *
    60   * The email/momEmail.wm template will then be parsed with the
    61   * Context that was defined with setContext().
    62   *
    63   * <p>If you want to use this class from within your Java code all you
    64   * have to do is something like this:
    65   *
    66   * <pre>
    67   * VelocityEmail ve = new VelocityEmail();
    68   * ve.setTo("Jon Stevens", "jon@latchkey.com");
    69   * ve.setFrom("Mom", "mom@mom.com").setSubject("Eat dinner");
    70   * ve.setContext(context);
    71   * ve.setTemplate("email/momEmail.vm")
    72   * ve.send();
    73   * </pre>
    74   *
    75   * <p>(Note that when used within a Velocity template, the send method
    76   * will be called for you when Velocity tries to convert the
    77   * VelocityEmail to a string by calling toString()).</p>
    78   *
    79   * <p>If you need your email to be word-wrapped, you can add the
    80   * following call to those above:
    81   *
    82   * <pre>
    83   * ve.setWordWrap (60);
    84   * </pre>
    85   *
    86   * <p>This class is just a wrapper around the SimpleEmail class from
    87   * commons-mail using the JavaMail API.
    88   * Thus, it depends on having the
    89   * mail.server property set in the TurbineResources.properties file.
    90   * If you want to use this class outside of Turbine for general
    91   * processing that is also possible by making sure to set the path to
    92   * the TurbineResources.properties.  See the
    93   * TurbineConfig class for more information.</p>
    94   *
    95   * <p>You can turn on debugging for the JavaMail API by calling
    96   * setDebug(true).  The debugging messages will be written to System.out.
    97   *
    98   * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
    99   * @author <a href="mailto:gcoladonato@yahoo.com">Greg Coladonato</a>
    100  * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a>
    101  * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
    102  * @version $Id: VelocityEmail.java 1723699 2016-01-08 11:29:21Z tv $
    103  */
    104 public class VelocityEmail extends SimpleEmail
    105 {
    106     /** Logging */
    107     private static Log log = LogFactory.getLog(VelocityEmail.class);
    108
    109     /** The column to word-wrap at.  <code>0</code> indicates no wrap. */
    110     private int wordWrap = 0;
    111
    112     /** Address of outgoing mail server */
    113     private String mailServer;
    114
    115     /** The template to process, relative to Velocity template directory. */
    116     private String template = null;
    117
    118     /** Velocity context */
    119     private Context context = null;
    120
    121     /**
    122      * Constructor
    123      */
    124     public VelocityEmail()
    125     {
    126         super();
    127     }
    128
    129     /**
    130      * Constructor
    131      * @param context the velocity context to use
    132      */
    133     public VelocityEmail(Context context)
    134     {
    135         this();
    136         this.context = context;
    137     }
    138
    139     /**
    140      * To: toName, toEmail
    141      *
    142      * @param toName A String with the TO toName.
    143      * @param toEmail A String with the TO toEmail.
    144      * @deprecated use addTo(email,name) instead
    145      * @throws EmailException email address could not be parsed
    146      * @return A VelocityEmail (self).
    147      */
    148     @Deprecated
    149     public VelocityEmail setTo(String toName, String toEmail)
    150             throws EmailException
    151     {
    152         addTo(toEmail,toName);
    153         return this;
    154     }
    155
    156     /**
    157      * Velocity template to execute. Path is relative to the Velocity
    158      * templates directory.
    159      *
    160      * @param template relative path of the template to parse including the
    161      *                 filename.
    162      * @return A VelocityEmail (self).
    163      */
    164     public VelocityEmail setTemplate(String template)
    165     {
    166         this.template = template;
    167         return this;
    168     }
    169
    170     /**
    171      * Set the column at which long lines of text should be word-
    172      * wrapped. Setting to zero turns off word-wrap (default).
    173      *
    174      * NOTE: don't use tabs in your email template document,
    175      * or your word-wrapping will be off for the lines with tabs
    176      * in them.
    177      *
    178      * @param wordWrap The column at which to wrap long lines.
    179      * @return A VelocityEmail (self).
    180      */
    181     public VelocityEmail setWordWrap(int wordWrap)
    182     {
    183         this.wordWrap = wordWrap;
    184         return this;
    185     }
    186
    187     /**
    188      * Set the context object that will be merged with the
    189      * template.
    190      *
    191      * @param context A Velocity context object.
    192      * @return A VelocityEmail (self).
    193      */
    194     public VelocityEmail setContext(Context context)
    195     {
    196         this.context = context;
    197         return this;
    198     }
    199
    200     /**
    201      * Get the context object that will be merged with the
    202      * template.
    203      *
    204      * @return A Context (self).
    205      */
    206     public Context getContext()
    207     {
    208         return this.context;
    209     }
    210
    211     /**
    212      * Sets the address of the outgoing mail server.  This method
    213      * should be used when you need to override the value stored in
    214      * TR.props.
    215      *
    216      * @param serverAddress host name of your outgoing mail server
    217      */
    218     public void setMailServer(String serverAddress)
    219     {
    220         this.mailServer = serverAddress;
    221     }
    222
    223     /**
    224      * Gets the host name of the outgoing mail server.  If the server
    225      * name has not been set by calling setMailServer(), the value
    226      * from TR.props for mail.server will be returned.  If TR.props
    227      * has no value for mail.server, localhost will be returned.
    228      *
    229      * @return host name of the mail server.
    230      */
    231     public String getMailServer()
    232     {
    233         return StringUtils.isNotEmpty(mailServer) ? mailServer
    234                 : Turbine.getConfiguration().getString(
    235                 TurbineConstants.MAIL_SERVER_KEY,
    236                 TurbineConstants.MAIL_SERVER_DEFAULT);
    237     }
    238
    239     /**
    240      * This method sends the email.
    241      * <p>If the mail server was not set by calling, setMailServer()
    242      * the value of mail.server will be used from TR.props.  If that
    243      * value was not set, localhost is used.
    244      *
    245      * @throws EmailException Failure during merging the velocity
    246      * template or sending the email.
    247      */
    248     @Override
    249     public String send() throws EmailException
    250     {
    251         String body = null;
    252         try
    253         {
    254             // Process the template.
    255             VelocityService velocityService = (VelocityService)TurbineServices.getInstance().getService(VelocityService.SERVICE_NAME);
    256             body = velocityService.handleRequest(context, template);
    257         }
    258         catch (Exception e)
    259         {
    260             throw new EmailException(
    261                     "Could not render velocity template", e);
    262         }
    263
    264         // If the caller desires word-wrapping, do it here
    265         if (wordWrap > 0)
    266         {
    267             body = WordUtils.wrap(body, wordWrap,
    268                     System.getProperty("line.separator"), false);
    269         }
    270
    271         setMsg(body);
    272         setHostName(getMailServer());
    273         return super.send();
    274     }
    275
    276     /**
    277      * The method toString() calls send() for ease of use within a
    278      * Velocity template (see example usage above).
    279      *
    280      * @return An empty string.
    281      */
    282     @Override
    283     public String toString()
    284     {
    285         try
    286         {
    287             send();
    288         }
    289         catch (Exception e)
    290         {
    291             log.error("VelocityEmail error", e);
    292         }
    293         return "";
    294     }
    295 }