001: /*
002: * ====================================================================
003: * JAFFA - Java Application Framework For All
004: *
005: * Copyright (C) 2002 JAFFA Development Group
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this library; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: *
021: * Redistribution and use of this software and associated documentation ("Software"),
022: * with or without modification, are permitted provided that the following conditions are met:
023: * 1. Redistributions of source code must retain copyright statements and notices.
024: * Redistributions must also contain a copy of this document.
025: * 2. Redistributions in binary form must reproduce the above copyright notice,
026: * this list of conditions and the following disclaimer in the documentation
027: * and/or other materials provided with the distribution.
028: * 3. The name "JAFFA" must not be used to endorse or promote products derived from
029: * this Software without prior written permission. For written permission,
030: * please contact mail to: jaffagroup@yahoo.com.
031: * 4. Products derived from this Software may not be called "JAFFA" nor may "JAFFA"
032: * appear in their names without prior written permission.
033: * 5. Due credit should be given to the JAFFA Project (http://jaffa.sourceforge.net).
034: *
035: * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
036: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
037: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
038: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
039: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
040: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
041: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
042: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
043: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
044: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
045: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
046: * SUCH DAMAGE.
047: * ====================================================================
048: */
049:
050: package org.jaffa.util;
051:
052: import java.util.Properties;
053: import javax.mail.*;
054: import javax.mail.internet.*;
055: import javax.activation.*;
056: import org.jaffa.presentation.portlet.widgets.model.TableModel;
057: import java.util.List;
058: import java.util.Iterator;
059: import java.util.ArrayList;
060: import org.jaffa.datatypes.DateOnly;
061: import org.jaffa.datatypes.DateTime;
062: import org.jaffa.util.StringHelper;
063: import javax.mail.MessagingException;
064: import org.apache.log4j.Logger;
065:
066: /** Routines for sending emails, with Microsoft Excel Attachements
067: *
068: * @version 1.0
069: * @author PaulE
070: * @since 1.3
071: */
072: public class EmailHelper {
073: private static Logger log = Logger.getLogger(EmailHelper.class);
074:
075: /** Sends an email with an Excel spreadsheet as an attachment
076: * @param smtpLocalhost (Optional) Name of host sending message, used in the HELO message for
077: * server authentication
078: * @param smtpUser (Optional) User name to authenticate to mail server. Not needed if server
079: * is an 'open relay'
080: * @param smtpPass (Optional) Password to authenticate to mail server. Not needed if server
081: * is an 'open relay'
082: * @param smtpHost (REQUIRED) name of mail server ie mail.yahoo.com
083: * @param from (REQUIRED) from email ie paul@yahoo.com
084: * @param to (REQUIRED) array of strings to send email to ie bob@yahoo.com
085: * @param subject Text for the email subject (defaults to 'No Subject' if null)
086: * @param bodyText Text for the main mail's body, in addition to the attachment
087: * @param excelData Data to convert to spread sheet. Mkae sure to specify 'String' as a datatype on columns that
088: * excel should not auto format
089: * @throws MessagingException Contains error if message could not be sent
090: */
091: public static void emailExcel(String smtpHost,
092: String smtpLocalhost, String smtpUser, String smtpPass,
093: String from, String[] to, String subject, String bodyText,
094: TableModel excelData) throws MessagingException {
095: if (smtpHost == null)
096: throw new MessagingException("smptHost is required!");
097: if (from == null)
098: throw new MessagingException("from address is required!");
099: if (to == null || to.length == 0)
100: throw new MessagingException("to address(es) is required!");
101:
102: // create some properties and get the default Session
103: Properties props = new Properties();
104: props.put("mail.smtp.host", smtpHost);
105: // Some servers need this for authentication
106: if (smtpLocalhost != null)
107: props.put("mail.smtp.localhost", smtpLocalhost);
108: if (log.isDebugEnabled()) {
109: log.debug("Turned on SMTP Debug Output");
110: props.put("mail.debug", "true");
111: }
112: Session session = null;
113: // if Authentication is required
114: if (smtpUser != null) {
115: props.put("mail.smtp.auth", "true");
116: session = Session.getInstance(props,
117: new EmailHelperAuthenticator(smtpUser, smtpPass));
118: } else {
119: session = Session.getDefaultInstance(props, null);
120: }
121: if (log.isDebugEnabled()) {
122: log.debug("Turned on SMTP Session Debug Output");
123: session.setDebug(true);
124: }
125:
126: // Define message
127: MimeMessage message = new MimeMessage(session);
128: message.setFrom(new InternetAddress(from));
129: for (int i = 0; i < to.length; i++) {
130: message.addRecipient(Message.RecipientType.TO,
131: new InternetAddress(to[i]));
132: }
133: message.setSubject(subject != null ? subject : "No Subject");
134:
135: // Create the multi-part
136: Multipart multipart = new MimeMultipart();
137:
138: BodyPart messageBodyPart;
139:
140: // Create part one, if there is some test
141: if (bodyText != null) {
142: messageBodyPart = new MimeBodyPart();
143: // Fill the message
144: messageBodyPart.setText(bodyText);
145: // Add the first part
146: multipart.addBodyPart(messageBodyPart);
147: }
148: if (excelData != null) {
149: StringBuffer sb = new StringBuffer();
150: convertTableToExcel(excelData, sb);
151: // Part two is attachment
152: messageBodyPart = new MimeBodyPart();
153: //DataSource source = new FileDataSource(filename);
154: //messageBodyPart.setDataHandler(new DataHandler(source));
155: messageBodyPart.setContent(sb.toString(), "text/html");
156: messageBodyPart.setFileName("excel-file.xls");
157: messageBodyPart.setHeader("Content-Type",
158: "application/vnd.ms-excel");
159: // Add the second part
160: multipart.addBodyPart(messageBodyPart);
161: }
162:
163: // Put parts in message
164: message.setContent(multipart);
165: // Send message
166: Transport.send(message);
167: }
168:
169: private static void convertTableToExcel(TableModel excel,
170: StringBuffer out) {
171: out
172: .append("<html xmlns:o=\"urn:schemas-microsoft-com:office:office\"\n");
173: out
174: .append("xmlns:x=\"urn:schemas-microsoft-com:office:excel\"\n");
175: out.append("xmlns=\"http://www.w3.org/TR/REC-html40\">\n");
176: out.append("\n");
177: out.append("<head>\n");
178: out
179: .append("<meta http-equiv=Content-Type content=\"text/html; charset=windows-1252\">\n");
180: out.append("<meta name=ProgId content=Excel.Sheet>\n");
181: out
182: .append("<meta name=Generator content=\"Microsoft Excel 10\">\n");
183: out.append("<style>\n");
184: out.append("<!--table\n");
185: out.append(" {mso-displayed-decimal-separator:\"\\.\";\n");
186: out.append(" mso-displayed-thousand-separator:\"\\,\";}\n");
187: out.append("@page\n");
188: out.append(" {margin:1.0in .75in 1.0in .75in;\n");
189: out.append(" mso-header-margin:.5in;\n");
190: out.append(" mso-footer-margin:.5in;}\n");
191: out.append("tr\n");
192: out.append(" {mso-height-source:auto;}\n");
193: out.append("col\n");
194: out.append(" {mso-width-source:auto;}\n");
195: out.append("br\n");
196: out.append(" {mso-data-placement:same-cell;}\n");
197: out.append(".style0\n");
198: out.append(" {mso-number-format:General;\n");
199: out.append(" text-align:general;\n");
200: out.append(" vertical-align:bottom;\n");
201: out.append(" white-space:nowrap;\n");
202: out.append(" mso-rotate:0;\n");
203: out.append(" mso-background-source:auto;\n");
204: out.append(" mso-pattern:auto;\n");
205: out.append(" color:windowtext;\n");
206: out.append(" font-size:10.0pt;\n");
207: out.append(" font-weight:400;\n");
208: out.append(" font-style:normal;\n");
209: out.append(" text-decoration:none;\n");
210: out.append(" font-family:Arial;\n");
211: out.append(" mso-generic-font-family:auto;\n");
212: out.append(" mso-font-charset:0;\n");
213: out.append(" border:none;\n");
214: out.append(" mso-protection:locked visible;\n");
215: out.append(" mso-style-name:Normal;\n");
216: out.append(" mso-style-id:0;}\n");
217: out.append("td\n");
218: out.append(" {mso-style-parent:style0;\n");
219: out.append(" padding-top:1px;\n");
220: out.append(" padding-right:1px;\n");
221: out.append(" padding-left:1px;\n");
222: out.append(" mso-ignore:padding;\n");
223: out.append(" color:windowtext;\n");
224: out.append(" font-size:10.0pt;\n");
225: out.append(" font-weight:400;\n");
226: out.append(" font-style:normal;\n");
227: out.append(" text-decoration:none;\n");
228: out.append(" font-family:Arial;\n");
229: out.append(" mso-generic-font-family:auto;\n");
230: out.append(" mso-font-charset:0;\n");
231: out.append(" mso-number-format:General;\n");
232: out.append(" text-align:general;\n");
233: out.append(" vertical-align:bottom;\n");
234: out.append(" border:none;\n");
235: out.append(" mso-background-source:auto;\n");
236: out.append(" mso-pattern:auto;\n");
237: out.append(" mso-protection:locked visible;\n");
238: out.append(" white-space:nowrap;\n");
239: out.append(" mso-rotate:0;}\n");
240: out.append("-->\n");
241: out.append("</style>\n");
242: out.append("<!--[if gte mso 9]><xml>\n");
243: out.append(" <x:ExcelWorkbook>\n");
244: out.append(" <x:ExcelWorksheets>\n");
245: out.append(" <x:ExcelWorksheet>\n");
246: out.append(" <x:Name>Sheet 1</x:Name>\n");
247: out.append(" <x:WorksheetOptions>\n");
248: out.append(" <x:Selected/>\n");
249: out
250: .append(" <x:ProtectContents>False</x:ProtectContents>\n");
251: out.append(" <x:ProtectObjects>False</x:ProtectObjects>\n");
252: out
253: .append(" <x:ProtectScenarios>False</x:ProtectScenarios>\n");
254: out.append(" </x:WorksheetOptions>\n");
255: out.append(" </x:ExcelWorksheet>\n");
256: out.append(" </x:ExcelWorksheets>\n");
257: out
258: .append(" <x:ProtectStructure>False</x:ProtectStructure>\n");
259: out.append(" <x:ProtectWindows>False</x:ProtectWindows>\n");
260: out.append(" </x:ExcelWorkbook>\n");
261: out.append("</xml><![endif]-->\n");
262: out.append("</head>\n");
263: out.append("\n");
264: out.append("<body link=blue vlink=purple>\n");
265: out.append("\n");
266: out
267: .append("<table x:str border=0 cellpadding=0 cellspacing=0 style='border-collapse: collapse;table-layout:fixed;'>\n");
268:
269: List colList = excel.getColumnNames();
270: if (colList != null) {
271: // Write out column headers
272: String[] colName = new String[colList.size()];
273: String[] colType = new String[colList.size()];
274: out.append(" <tr>\n");
275: int i = 0;
276: for (Iterator it = colList.iterator(); it.hasNext(); i++) {
277: colName[i] = (String) it.next();
278: colType[i] = excel.getColumnDataType(colName[i]);
279: if (colType[i] == null)
280: colType[i] = "string";
281: else
282: colType[i] = colType[i].toLowerCase();
283: out.append(" <td x:str='");
284: if (colName[i] != null)
285: out.append(StringHelper.convertToHTML(colName[i]));
286: out.append("'>");
287: if (colName[i] != null)
288: out.append(StringHelper.convertToHTML(colName[i]));
289: out.append("</td>\n");
290: }
291: out.append(" </tr>\n");
292:
293: // Loop for each row...
294: List rowList = excel.getRows();
295: if (rowList != null) {
296:
297: for (Iterator it = rowList.iterator(); it.hasNext();) {
298: List row = (List) it.next();
299: out.append(" <tr>\n");
300: i = 0;
301: if (row != null)
302: for (Iterator it2 = row.iterator(); it2
303: .hasNext(); i++) {
304: Object value = it2.next();
305: out.append(" <td");
306: if ("string".equalsIgnoreCase(colType[i])) {
307: out.append(" x:str='");
308: if (value != null)
309: out.append(StringHelper
310: .convertToHTML(value
311: .toString()));
312: out.append("'");
313: }
314: out.append(">");
315: if (value != null)
316: out
317: .append(StringHelper
318: .convertToHTML(value
319: .toString()));
320: out.append("</td>\n");
321: }
322: out.append(" </tr>\n");
323: }
324: } // rowList
325: } // colList
326: out.append("</table>\n");
327: out.append("\n");
328: out.append("</body>\n");
329: out.append("\n");
330: out.append("</html>\n");
331: }
332:
333: }
|