View Javadoc

1   /**
2    * This file Copyright (c) 2003-2010 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
32   *
33   */
34  package info.magnolia.cms.taglibs.util;
35  
36  import info.magnolia.cms.core.Content;
37  import info.magnolia.cms.util.ExclusiveWrite;
38  import info.magnolia.cms.taglibs.Resource;
39  import info.magnolia.context.MgnlContext;
40  import info.magnolia.module.mail.MailConstants;
41  import info.magnolia.module.mail.MailModule;
42  import info.magnolia.module.mail.templates.MgnlEmail;
43  
44  import org.apache.commons.lang.StringUtils;
45  import org.apache.commons.lang.exception.NestableRuntimeException;
46  import org.slf4j.Logger;
47  import org.slf4j.LoggerFactory;
48  
49  import javax.jcr.RepositoryException;
50  import javax.servlet.http.HttpServletRequest;
51  import javax.servlet.http.HttpServletResponse;
52  import javax.servlet.jsp.JspException;
53  import javax.servlet.jsp.JspWriter;
54  import javax.servlet.jsp.tagext.Tag;
55  import javax.servlet.jsp.tagext.TagSupport;
56  import java.io.File;
57  import java.io.FileOutputStream;
58  import java.io.IOException;
59  import java.text.DateFormat;
60  import java.util.Calendar;
61  import java.util.Date;
62  import java.util.GregorianCalendar;
63  import java.util.HashMap;
64  import java.util.Iterator;
65  import java.util.Map;
66  
67  
68  /**
69   * Sends a simple mail generated with all the fields found in nodeCollectionName.
70   *
71   * @jsp.tag name="simpleMail" body-content="empty"
72   *
73   * @author Fabrizio Giustina
74   * @version $Revision: 32667 $ ($Author: gjoseph $)
75   * @deprecated since 4.0
76   */
77  public class SimpleMailTag extends TagSupport {
78  
79      /**
80       * Stable serialVersionUID.
81       */
82      private static final long serialVersionUID = 222L;
83  
84      private String nodeCollectionName = "mainColumnParagraphs";
85  
86      private String from;
87  
88      private String to;
89  
90      private String cc;
91  
92      private String bcc;
93  
94      private String replyTo;
95  
96      private String subject;
97  
98      private String redirect;
99  
100     private String type;
101 
102     /**
103      * Alternatively to the type you can use a template to render the email dynamically.
104      */
105     private String template;
106 
107     /**
108      * log the mails
109      */
110     private boolean logging;
111 
112     /**
113      * encoding of the log file
114      */
115     private String loggingEncoding = "UTF8";
116 
117     /**
118      * directory to place the log files
119      */
120     private String loggingDirectory = "/mailtracking";
121 
122     /**
123      * The extension for the log files
124      */
125     private String loggingExtension = "log";
126 
127     /**
128      * Name of the file. Prefix only.
129      */
130     private String loggingFilename;
131 
132     /**
133      * Logger.
134      */
135     private static Logger log = LoggerFactory.getLogger(SimpleMailTag.class);
136 
137     /**
138      * Mail "bcc" field.
139      * @jsp.attribute required="false" rtexprvalue="true"
140      */
141     public void setBcc(String bcc) {
142         this.bcc = bcc;
143     }
144 
145     /**
146      * Mail "replyTo" field.
147      * @jsp.attribute required="false" rtexprvalue="true"
148      */
149     public void setReplyTo(String replyTo) {
150         this.replyTo = replyTo;
151     }
152 
153     /**
154      * Mail "cc" field.
155      * @jsp.attribute required="false" rtexprvalue="true"
156      */
157     public void setCc(String cc) {
158         this.cc = cc;
159     }
160 
161     /**
162      * Mail "from" field.
163      * @jsp.attribute required="true" rtexprvalue="true"
164      */
165     public void setFrom(String from) {
166         this.from = from;
167     }
168 
169     /**
170      * Collection (paragraphs) that holds the configured form fields. If not set the current collection is used.
171      * @jsp.attribute required="false" rtexprvalue="true"
172      */
173     public void setNodeCollectionName(String nodeCollectionName) {
174         this.nodeCollectionName = nodeCollectionName;
175     }
176 
177     /**
178      * Mail "to" field.
179      * @jsp.attribute required="true" rtexprvalue="true"
180      */
181     public void setTo(String to) {
182         this.to = to;
183     }
184 
185     /**
186      * Mail "subject" field.
187      * @jsp.attribute required="true" rtexprvalue="true"
188      */
189     public void setSubject(String subject) {
190         this.subject = subject;
191     }
192 
193     /**
194      * Page to redirect to after a successfull submission.
195      * @jsp.attribute required="false" rtexprvalue="true"
196      */
197     public void setRedirect(String redirect) {
198         this.redirect = redirect;
199     }
200 
201     /**
202      * Mail type. Used to get the mail from the factory.
203      * @jsp.attribute required="false" rtexprvalue="true"
204      */
205     public void setType(String type) {
206         this.type = type;
207     }
208 
209     /**
210      * Log all the information sent by the mail.
211      * @jsp.attribute required="false" rtexprvalue="true" type="boolean"
212      */
213     public void setLogging(boolean trackMail) {
214         this.logging = trackMail;
215     }
216 
217     /**
218      * Instead of the mail type you can define a template to use.
219      * This template must be registered in the mail module.
220      * @jsp.attribute required="false" rtexprvalue="true"
221      */
222     public void setTemplate(String template) {
223         this.template = template;
224     }
225 
226     /**
227      * @see javax.servlet.jsp.tagext.TagSupport#doEndTag()
228      */
229     public int doEndTag() throws JspException {
230 
231         HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
232 
233         StringBuffer body = new StringBuffer(); // build and send email
234 
235         // tracking mail: Excel friendly csv format
236         StringBuffer mailTitles = new StringBuffer();
237         StringBuffer mailValues = new StringBuffer();
238         // timestamp
239         mailValues.append(DateFormat.getDateTimeInstance().format(new Date(System.currentTimeMillis()))).append(';');
240 
241         if (nodeCollectionName == null) {
242             this.nodeCollectionName = Resource.getLocalContentNodeCollectionName();
243         }
244 
245         Content activePage = MgnlContext.getAggregationState().getMainContent();
246         Content fieldsNode = null;
247         Iterator it;
248         try {
249             Content localContentNode = Resource.getLocalContentNode();
250             if (localContentNode != null && localContentNode.hasContent(nodeCollectionName)) {
251                 fieldsNode = localContentNode.getContent(nodeCollectionName);
252             }
253             else {
254                 fieldsNode = activePage.getContent(nodeCollectionName);
255             }
256             it = fieldsNode.getChildren().iterator();
257         }
258         catch (RepositoryException e) {
259             throw new NestableRuntimeException(e);
260         }
261 
262         while (it.hasNext()) {
263             Content node = (Content) it.next();
264             String[] values = request.getParameterValues("field_" + node.getName());
265             if (values == null) {
266                 values = request.getParameterValues(node.getName());
267             }
268             if (values != null) {
269                 body.append(node.getNodeData("title").getString()).append('\n');
270                 mailTitles.append(excelCSVFormat(node.getNodeData("title").getString())).append(';');
271                 StringBuffer csvValue = new StringBuffer();
272                 for (int i = 0; i < values.length; i++) {
273                     body.append(values[i]).append('\n');
274                     csvValue.append(values[i]);
275                     if (i < values.length - 1) {
276                         csvValue.append('\n');
277                     }
278                 }
279                 mailValues.append(excelCSVFormat(csvValue.toString())).append(';');
280                 body.append("\n");
281             }
282         }
283 
284         if (logging) {
285             trackMail(request, activePage.getHandle(), mailTitles, mailValues);
286         }
287 
288         String mailType = type;
289         if (StringUtils.isEmpty(mailType)) {
290             mailType = MailConstants.MAIL_TEMPLATE_SIMPLE;
291         }
292 
293         MgnlEmail email;
294         try {
295             Map parameters = new HashMap(request.getParameterMap());
296             // TODO: avoid those kinds of redundacies in the mail system
297             if (StringUtils.isEmpty(template)) {
298                 parameters.put("contentType", "text");
299                 email = MailModule.getInstance().getFactory().getEmailFromType(parameters, mailType);
300                 email.setBody(body.toString());
301             }
302             else {
303                 parameters.put("all", body.toString());
304                 email = MailModule.getInstance().getFactory().getEmailFromTemplate(template, parameters);
305                 email.setBodyFromResourceFile();
306             }
307             email.setToList(to);
308             email.setCcList(cc);
309             email.setBccList(bcc);
310             email.setReplyToList(replyTo);
311             email.setFrom(from);
312             email.setSubject(subject);
313             MailModule.getInstance().getFactory().getEmailHandler().sendMail(email);
314         }
315         catch (Exception e) {
316             // you may want to warn the user redirecting him to a different page...
317             log.error(e.getMessage(), e);
318         }
319 
320         if (StringUtils.isNotEmpty(redirect)) {
321             HttpServletResponse response = (HttpServletResponse) pageContext.getResponse();
322 
323             if (!response.isCommitted()) {
324                 try {
325                     response.reset();
326                     response.sendRedirect(request.getContextPath() + redirect);
327                 }
328                 catch (IOException e) {
329                     // should never happen
330                     log.error(e.getMessage(), e);
331                 }
332             }
333             else {
334                 // response committed, cannot do a server side redirect
335                 JspWriter out = pageContext.getOut();
336 
337                 try {
338                     out.write("<script type='text/javascript'>//<!--\n");
339                     out.write("window.location = \"");
340                     out.write(request.getContextPath());
341                     out.write(redirect);
342                     out.write("\"\n//-->\n");
343                     out.write("</script>");
344                 }
345                 catch (IOException e) {
346                     // should never happen
347                     log.error(e.getMessage(), e);
348                 }
349 
350             }
351 
352             return Tag.SKIP_PAGE;
353         }
354         // release(); release must never be called directly, only managed by the container!
355         return super.doEndTag();
356     }
357 
358     protected String excelCSVFormat(String str) {
359         if (!StringUtils.containsNone(str, "\n;")) {
360             return "\"" + StringUtils.replace(str, "\"", "\"\"") + "\"";
361         }
362         return str;
363     }
364 
365     protected void trackMail(HttpServletRequest request, String activePagePath, StringBuffer titles, StringBuffer values) {
366         String fileName = this.getLoggingFilename();
367         if (StringUtils.isEmpty(fileName)) {
368             activePagePath = StringUtils.removeStart(activePagePath, "/");
369             fileName = StringUtils.replace(activePagePath, "/", "_");
370         }
371 
372         fileName = fileName + "_" + new GregorianCalendar().get(Calendar.WEEK_OF_YEAR) + "." + getLoggingExtension();
373         String folder = pageContext.getServletContext().getRealPath(this.getLoggingDirectory());
374 
375         synchronized (ExclusiveWrite.getInstance()) {
376             new File(folder).mkdirs();
377 
378             File file = new File(folder + File.separator + fileName);
379             boolean exists = file.exists();
380 
381             try {
382                 FileOutputStream out = new FileOutputStream(file, true);
383                 if (!exists) {
384                     out.write("Timestamp;".toString().getBytes(this.getLoggingEncoding()));
385                     titles.replace(titles.length() - 1, titles.length(), "\n");
386                     out.write(titles.toString().getBytes(this.getLoggingEncoding()));
387                 }
388                 values.replace(values.length() - 1, values.length(), "\n");
389                 out.write(values.toString().getBytes(this.getLoggingEncoding()));
390                 out.flush();
391                 out.close();
392 
393             }
394             catch (Exception e) {
395                 log.error("Exception while tracking mail", e);
396             }
397         }
398     }
399 
400     /**
401      * @see javax.servlet.jsp.tagext.TagSupport#release()
402      */
403     public void release() {
404         this.nodeCollectionName = null;
405         this.to = null;
406         this.from = null;
407         this.cc = null;
408         this.bcc = null;
409         this.subject = null;
410         this.type = null;
411         this.template = null;
412         super.release();
413     }
414 
415     public String getLoggingDirectory() {
416         return loggingDirectory;
417     }
418 
419     /**
420      * Where to log to. For each page the log is created separately on a weekly basis.
421      * @jsp.attribute required="false" rtexprvalue="true"
422      */
423     public void setLoggingDirectory(String loggingDirectory) {
424         this.loggingDirectory = loggingDirectory;
425     }
426 
427     public String getLoggingEncoding() {
428         return loggingEncoding;
429     }
430 
431     /**
432      * Encoding of the log file. Default is UTF8. For windows excel use ISO-8859-1.
433      * @jsp.attribute required="false" rtexprvalue="true"
434      */
435     public void setLoggingEncoding(String loggingEncoding) {
436         this.loggingEncoding = loggingEncoding;
437     }
438 
439     public boolean isLogging() {
440         return logging;
441     }
442 
443     /**
444      * The file extension to use for new files. Default is log. Use csv for easy opening with Excel.
445      * @jsp.attribute required="false" rtexprvalue="true"
446      */
447     public void setLoggingExtension(String loggingExtension) {
448         this.loggingExtension = loggingExtension;
449     }
450 
451     public String getLoggingExtension() {
452         return loggingExtension;
453     }
454 
455     /**
456      * Name for the file (without extension). If not set, the pages path is used to create a file.
457      * @jsp.attribute required="false" rtexprvalue="true"
458      */
459     public void setLoggingFilename(String loggingFilename) {
460         this.loggingFilename = loggingFilename;
461     }
462 
463     public String getLoggingFilename() {
464         return loggingFilename;
465     }
466 
467 }