Source Code Cross Referenced for NotificationServices.java in  » ERP-CRM-Financial » SourceTap-CRM » org » ofbiz » content » email » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » ERP CRM Financial » SourceTap CRM » org.ofbiz.content.email 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * $Id: NotificationServices.java,v 1.5 2003/12/23 12:34:17 jonesde Exp $
003:         *
004:         * Copyright (c) 2003 The Open For Business Project - www.ofbiz.org
005:         *
006:         * Permission is hereby granted, free of charge, to any person obtaining a
007:         * copy of this software and associated documentation files (the "Software"),
008:         * to deal in the Software without restriction, including without limitation
009:         * the rights to use, copy, modify, merge, publish, distribute, sublicense,
010:         * and/or sell copies of the Software, and to permit persons to whom the
011:         * Software is furnished to do so, subject to the following conditions:
012:         *
013:         * The above copyright notice and this permission notice shall be included
014:         * in all copies or substantial portions of the Software.
015:         *
016:         * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
017:         * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
018:         * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
019:         * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
020:         * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
021:         * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
022:         * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
023:         *
024:         */
025:        package org.ofbiz.content.email;
026:
027:        import java.io.IOException;
028:        import java.io.InputStreamReader;
029:        import java.io.StringWriter;
030:        import java.io.Writer;
031:        import java.net.InetAddress;
032:        import java.net.URL;
033:        import java.net.UnknownHostException;
034:        import java.util.HashMap;
035:        import java.util.Map;
036:
037:        import org.ofbiz.base.util.Debug;
038:        import org.ofbiz.base.util.UtilMisc;
039:        import org.ofbiz.base.util.UtilProperties;
040:        import org.ofbiz.base.util.UtilURL;
041:        import org.ofbiz.entity.GenericDelegator;
042:        import org.ofbiz.entity.GenericEntityException;
043:        import org.ofbiz.entity.GenericValue;
044:        import org.ofbiz.service.DispatchContext;
045:        import org.ofbiz.service.GenericServiceException;
046:        import org.ofbiz.service.LocalDispatcher;
047:        import org.ofbiz.service.ModelService;
048:        import org.ofbiz.service.ServiceUtil;
049:        import org.ofbiz.content.webapp.ftl.FreeMarkerWorker;
050:        import org.ofbiz.content.webapp.ftl.OfbizCurrencyTransform;
051:
052:        import freemarker.ext.beans.BeansWrapper;
053:        import freemarker.template.Configuration;
054:        import freemarker.template.Template;
055:        import freemarker.template.TemplateException;
056:        import freemarker.template.TemplateHashModel;
057:
058:        /**
059:         * Provides generic services related to preparing and
060:         * delivering notifications via email.
061:         * <p>
062:         * To use the NotificationService, a message specific service should be 
063:         * defined for a particular <a href="http://freemarker.sourceforge.net/docs/dgui_quickstart_template.html">
064:         * Freemarker Template</a> mapping the required fields of the 
065:         * template to the required attributes of the service.
066:         * <p>
067:         * This service definition should extend the <code>sendNotificationInterface<code>
068:         * or the <code>prepareNotificationInterface</code> service interface
069:         * and simply invoke the associated method defined in this class.
070:         * <p>
071:         * <blockquote>
072:         * <pre>
073:         *     &lt;service name="sendPoPickupNotification" engine="java"
074:         *             location="org.ofbiz.content.email.NotificationServices" invoke="sendNotification"&gt;
075:         *         &lt;description&gt;Sends notification based on a message template&lt;/description&gt;
076:         *         &lt;implements service="sendNotificationInterface"/&gt;
077:         *         &lt;attribute name="orderId" type="String" mode="IN" optional="false"/&gt;
078:         *     &lt;/service&gt;
079:         * </pre>
080:         * </blockquote>
081:         * <p>
082:         * An optional parameter available to all message templates is <code>baseUrl</code>
083:         * which can either be specified when the service is invoked or let the 
084:         * <code>NotificationService</code> attempt to resolve it as best it can, 
085:         * see {@link #setBaseUrl(GenericDelegator, String, Map) setBaseUrl(Map)} for details on how this is achieved.
086:         * <p>
087:         * The following example shows what a simple notification message template, 
088:         * associated with the above service, might contain: 
089:         * <blockquote>
090:         * <pre>
091:         *     Please use the following link to schedule a delivery date:
092:         *     &lt;p&gt;
093:         *     ${baseUrl}/ordermgr/control/schedulepo?order_id=${orderId}"
094:         * </pre>
095:         * </blockquote> 
096:         * <p>
097:         * The template file must be found on the classpath at runtime and
098:         * match the "templateName" field passed to the service when it
099:         * is invoked.
100:         * <p>
101:         * For complex messages with a large number of dynamic fields, it may be wise
102:         * to implement a custom service that takes one or two parameters that can
103:         * be used to resolve the rest of the required fields and then pass them to
104:         * the {@link #prepareNotification(DispatchContext, Map) prepareNotification(DispatchContext, Map)}
105:         * or {@link #sendNotification(DispatchContext, Map) sendNotification(DispatchContext, Map)} 
106:         * methods directly to generate or generate and send the notification respectively.
107:         * 
108:         *
109:         * @author     <a href="mailto:tristana@twibble.org">Tristan Austin</a>
110:         * @author     <a href="mailto:jaz@ofbiz.org">Andy Zeneski</a>
111:         * @version    $Revision: 1.5 $
112:         * @since      2.2
113:         */
114:        public class NotificationServices {
115:
116:            public static final String module = NotificationServices.class
117:                    .getName();
118:
119:            /** 
120:             * This will use the {@link #prepareNotification(DispatchContext, Map) prepareNotification(DispatchContext, Map)}
121:             * method to generate the body of the notification message to send
122:             * and then deliver it via the "sendMail" service.
123:             * <p>
124:             * If the "body" parameter is already specified, the message body generation
125:             * phase will be skipped and the notification will be sent with the
126:             * specified body instead. This can be used to combine both service
127:             * calls in a decoupled manner if other steps are required between
128:             * generating the message body and sending the notification.
129:             * 
130:             * @param ctx   The dispatching context of the service
131:             * @param context The map containing all the fields associated with
132:             * the sevice
133:             * @return A Map with the service response messages in it
134:             */
135:            public static Map sendNotification(DispatchContext ctx, Map context) {
136:                LocalDispatcher dispatcher = ctx.getDispatcher();
137:                Map result = null;
138:
139:                try {
140:                    // see whether the optional 'body' attribute was specified or needs to be processed
141:                    // nulls are handled the same as not specified
142:                    String body = (String) context.get("body");
143:
144:                    if (body == null) {
145:                        // prepare the body of the notification email                         
146:                        Map bodyResult = prepareNotification(ctx, context);
147:
148:                        // ensure the body was generated successfully                
149:                        if (bodyResult.get(ModelService.RESPONSE_MESSAGE)
150:                                .equals(ModelService.RESPOND_SUCCESS)) {
151:                            body = (String) bodyResult.get("body");
152:                        } else {
153:                            // otherwise just report the error
154:                            Debug.logError("prepareNotification failed: "
155:                                    + bodyResult
156:                                            .get(ModelService.ERROR_MESSAGE),
157:                                    module);
158:                            body = null;
159:                        }
160:                    }
161:
162:                    // make sure we have a valid body before sending
163:                    if (body != null) {
164:                        // retain only the required attributes for the sendMail service
165:                        Map emailContext = new HashMap();
166:                        emailContext.put("sendTo", context.get("sendTo"));
167:                        emailContext.put("body", body);
168:                        emailContext.put("sendCc", context.get("sendCc"));
169:                        emailContext.put("sendBcc", context.get("sendBcc"));
170:                        emailContext.put("sendFrom", context.get("sendFrom"));
171:                        emailContext.put("subject", context.get("subject"));
172:                        emailContext.put("sendVia", context.get("sendVia"));
173:                        emailContext.put("sendType", context.get("sendType"));
174:                        emailContext.put("contentType", context
175:                                .get("contentType"));
176:
177:                        // pass on to the sendMail service                 
178:                        result = dispatcher.runSync("sendMail", emailContext);
179:                    } else {
180:                        Debug.logError(
181:                                "Invalid email body; null is not allowed",
182:                                module);
183:                        result = ServiceUtil
184:                                .returnError("Invalid email body; null is not allowed");
185:                    }
186:                } catch (GenericServiceException serviceException) {
187:                    Debug.logError(serviceException, "Error sending email",
188:                            module);
189:                    result = ServiceUtil
190:                            .returnError("Email delivery error, see error log");
191:                }
192:
193:                return result;
194:            }
195:
196:            /**
197:             * This will process the associated notification template definition
198:             * with all the fields contained in the given context and generate
199:             * the message body of the notification.
200:             * <p>
201:             * The result returned will contain the appropriate response
202:             * messages indicating succes or failure and the OUT parameter,
203:             * "body" containing the generated message.
204:             * 
205:             * @param ctx   The dispatching context of the service
206:             * @param context The map containing all the fields associated with
207:             * the sevice
208:             * @return A new Map indicating success or error containing the
209:             * body generated from the template and the input parameters. 
210:             */
211:            public static Map prepareNotification(DispatchContext ctx,
212:                    Map context) {
213:                GenericDelegator delegator = ctx.getDelegator();
214:                String templateName = (String) context.get("templateName");
215:                Map templateData = (Map) context.get("templateData");
216:                String webSiteId = (String) context.get("webSiteId");
217:
218:                Map result = null;
219:                if (templateData == null) {
220:                    templateData = new HashMap();
221:                }
222:
223:                try {
224:                    // ensure the baseURl is defined
225:                    setBaseUrl(delegator, webSiteId, templateData);
226:
227:                    // initialize the template reader and processor
228:                    URL templateUrl = UtilURL.fromResource(templateName);
229:
230:                    if (templateUrl == null) {
231:                        Debug.logError("Problem getting the template URL: "
232:                                + templateName + " not found", module);
233:                        return ServiceUtil
234:                                .returnError("Problem finding template; see logs");
235:                    }
236:
237:                    InputStreamReader templateReader = new InputStreamReader(
238:                            templateUrl.openStream());
239:
240:                    // process the template with the given data and write
241:                    // the email body to the String buffer
242:                    Writer writer = new StringWriter();
243:                    FreeMarkerWorker.renderTemplate(templateName,
244:                            templateReader, templateData, writer);
245:
246:                    // extract the newly created body for the notification email
247:                    String notificationBody = writer.toString();
248:
249:                    // generate the successfull reponse
250:                    result = ServiceUtil
251:                            .returnSuccess("Message body generated successfully");
252:                    result.put("body", notificationBody);
253:                } catch (IOException ie) {
254:                    Debug.logError(ie, "Problems reading template", module);
255:                    result = ServiceUtil
256:                            .returnError("Template reading problem, see error logs");
257:                } catch (TemplateException te) {
258:                    Debug.logError(te, "Problems processing template", module);
259:                    result = ServiceUtil
260:                            .returnError("Template processing problem, see error log");
261:                }
262:
263:                return result;
264:            }
265:
266:            /**
267:             * The expectation is that a lot of notification messages will include
268:             * a link back to one or more pages in the system, which will require knowledge
269:             * of the base URL to extrapolate. This method will ensure that the
270:             * <code>baseUrl</code> field is set in the given context.
271:             * <p>
272:             * If it has been specified a default <code>baseUrl</code> will be
273:             * set using a best effort approach. If it is specified in the 
274:             * url.properties configuration files of the system, that will be
275:             * used, otherwise it will attempt resolve the fully qualified 
276:             * local host name.
277:             * <p>
278:             * <i>Note:</i> I thought it might be useful to have some dynamic way
279:             * of extending the default properties provided by the NotificationService,
280:             * such as the <code>baseUrl</code>, perhaps using the standard 
281:             * <code>ResourceBundle</code> java approach so that both classes
282:             * and static files may be invoked.
283:             *  
284:             * @param context   The context to check and, if necessary, set the
285:             * <code>baseUrl</code>.
286:             */
287:            public static void setBaseUrl(GenericDelegator delegator,
288:                    String webSiteId, Map context) {
289:                StringBuffer httpBase = null;
290:                StringBuffer httpsBase = null;
291:
292:                String localServer = null;
293:
294:                String httpsPort = null;
295:                String httpsServer = null;
296:                String httpPort = null;
297:                String httpServer = null;
298:                Boolean enableHttps = null;
299:
300:                // If the baseUrl was not specified we can do a best effort instead
301:                if (!context.containsKey("baseUrl")) {
302:                    try {
303:                        // using just the IP address of localhost if we don't have a defined server
304:                        InetAddress localHost = InetAddress.getLocalHost();
305:                        localServer = localHost.getHostAddress();
306:                    } catch (UnknownHostException hostException) {
307:                        Debug
308:                                .logWarning(
309:                                        hostException,
310:                                        "Could not determine localhost, using '127.0.0.1'",
311:                                        module);
312:                        localServer = "127.0.0.1";
313:                    }
314:
315:                    // load the properties from the website entity        
316:                    GenericValue webSite = null;
317:                    if (webSiteId != null) {
318:                        try {
319:                            webSite = delegator.findByPrimaryKeyCache(
320:                                    "WebSite", UtilMisc.toMap("webSiteId",
321:                                            webSiteId));
322:                            if (webSite != null) {
323:                                httpsPort = webSite.getString("httpsPort");
324:                                httpsServer = webSite.getString("httpsHost");
325:                                httpPort = webSite.getString("httpPort");
326:                                httpServer = webSite.getString("httpHost");
327:                                enableHttps = webSite.getBoolean("enableHttps");
328:                            }
329:                        } catch (GenericEntityException e) {
330:                            Debug
331:                                    .logWarning(
332:                                            e,
333:                                            "Problems with WebSite entity; using global defaults",
334:                                            module);
335:                        }
336:                    }
337:
338:                    // fill in any missing properties with fields from the global file
339:                    if (httpsPort == null) {
340:                        httpsPort = UtilProperties.getPropertyValue(
341:                                "url.properties", "port.https", "443");
342:                    }
343:                    if (httpServer == null) {
344:                        httpsServer = UtilProperties.getPropertyValue(
345:                                "url.properties", "force.https.host",
346:                                localServer);
347:                    }
348:                    if (httpPort == null) {
349:                        httpPort = UtilProperties.getPropertyValue(
350:                                "url.properties", "port.http", "80");
351:                    }
352:                    if (httpServer == null) {
353:                        httpServer = UtilProperties.getPropertyValue(
354:                                "url.properties", "force.http.host",
355:                                localServer);
356:                    }
357:                    if (enableHttps == null) {
358:                        enableHttps = new Boolean(UtilProperties
359:                                .propertyValueEqualsIgnoreCase(
360:                                        "url.properties", "port.https.enabled",
361:                                        "Y"));
362:                    }
363:
364:                    // prepare the (non-secure) URL
365:                    httpBase = new StringBuffer("http://");
366:                    httpBase.append(httpServer);
367:                    if (!"80".equals(httpPort)) {
368:                        httpBase.append(":");
369:                        httpBase.append(httpPort);
370:                    }
371:
372:                    // set the base (non-secure) URL for any messages requiring it
373:                    context.put("baseUrl", httpBase.toString());
374:
375:                    if (enableHttps.booleanValue()) {
376:                        // prepare the (secure) URL
377:                        httpsBase = new StringBuffer("https://");
378:                        httpsBase.append(httpsServer);
379:                        if (!"443".equals(httpsPort)) {
380:                            httpsBase.append(":");
381:                            httpsBase.append(httpsPort);
382:                        }
383:
384:                        // set the base (secure) URL for any messages requiring it
385:                        context.put("baseSecureUrl", httpsBase.toString());
386:                    } else {
387:                        context.put("baseSecureUrl", httpBase.toString());
388:                    }
389:                }
390:            }
391:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.