KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > net > axis > transport > mailto > server > MailTransportService


1 /*
2  * JBoss, the OpenSource J2EE webOS
3  *
4  * Distributable under LGPL license.
5  * See terms of license at gnu.org.
6  */

7 package org.jboss.net.axis.transport.mailto.server;
8
9 import javax.mail.Flags JavaDoc;
10 import javax.mail.Message JavaDoc;
11 import javax.mail.MessagingException JavaDoc;
12
13 import org.apache.axis.AxisEngine;
14 import org.apache.axis.AxisFault;
15 import org.apache.axis.MessageContext;
16 import org.apache.axis.server.AxisServer;
17 import org.jboss.net.axis.server.JMXEngineConfigurationFactory;
18 import org.jboss.net.axis.transport.mailto.server.MailTransportServiceMBean;
19 import org.jboss.net.axis.transport.mailto.AbstractMailTransportService;
20 import org.jboss.net.axis.transport.mailto.MailConstants;
21
22 /**
23  * <dl>
24  * <dt><b>Title: </b><dd>Mail Transport MBean</dd>
25  * <p>
26  * <dt><b>Description: </b>
27  * <dd>
28  * <p>This MBean is the service that polls the mail box (pop/imap) and processes any soap messages it finds there.
29  *
30  * <p> To define a mail transport and the transport level handlers, the jboss-net.sar/server-config.wsdd file must be
31  * modified to include:
32  * <pre>
33  * &lt;transport name="mail"&gt;
34  * &lt;requestFlow&gt;
35  * &lt;handler type="java:org.jboss.net.axis.transport.mail.server.handler.TargetServiceHandler"/&gt;
36  * &lt;/requestFlow&gt;
37  * &lt;responseFlow&gt;
38  * &lt;!-- response flow specific handlers can go here --&gt;
39  * &lt;/responseFlow&gt;
40  * &lt;/transport&gt;
41  * </pre>
42  *
43  * <p>To enable this service edit the jboss-net.sar/META-INF/jboss-service.xml file to include :
44  * <pre>
45  * &lt;mbean code="org.jboss.net.axis.transport.mailto.server.MailTransportService"
46  * name="jboss.net:service=MailTransport"&gt;
47  * &lt;depends&gt;jboss.net:service=Axis&lt;/depends&gt;
48  * &lt;attribute name="SessionName"&gt;java:/Mail&lt;/attribute&gt;
49  * &lt;attribute name="FolderName"&gt;INBOX&lt;/attribute&gt;
50  * &lt;attribute name="TransportName"&gt;mail&lt;/attribute&gt;
51  * &lt;attribute name="EngineName"&gt;jboss.net:service=Axis&lt;/attribute&gt;
52  * &lt;attribute name="DeleteMail"&gt;true&lt;/attribute&gt;
53  * &lt;/mbean&gt;
54  * </pre>
55  *
56  * <p> If you don't want to hammer on the pollMail button from the mbean interface (jmx|web-console) then it would be
57  * best to set up a schedule to do it for you (again in the jboss-service.xml file:
58  * <pre>
59  * &lt;mbean code="org.jboss.varia.scheduler.Scheduler"
60  * name="jboss.net:service=Scheduler,name=MailTransport"&gt;
61  * &lt;attribute name="StartAtStartup"&gt;true&lt;/attribute&gt;
62  * &lt;attribute name="SchedulableMBean"&gt;jboss.net:service=MailTransport&lt;/attribute&gt;
63  * &lt;attribute name="SchedulableMBeanMethod"&gt;pollMail()&lt;/attribute&gt;
64  * &lt;attribute name="InitialStartDate"&gt;NOW&lt;/attribute&gt;
65  * &lt;attribute name="SchedulePeriod"&gt;30000&lt;/attribute&gt;
66  * &lt;attribute name="InitialRepetitions"&gt;-1&lt;/attribute&gt;
67  * &lt;/mbean&gt;
68  * </pre>
69  *
70  * <p> This transport assumes the use of <a HREF="http://ws.apache.org/ws-fx/addressing/">ws-addressing</a>
71  * handlers and as such has no provision for sending a response. The addressing handler will create a new call
72  * with the response if there is a wsa:Reply-To header. Otherwise the response will disappear into the ether
73  * with nary a log entry.
74  *
75  * </dd>
76  * </dl>
77  * @author <a HREF="mailto:jasone@greenrivercomputing.com">Jason Essington</a>
78  * @version $Revision: 1.2 $
79  *
80  * @jboss.service
81  * servicefile="jboss"
82  *
83  * @jmx.mbean
84  * name="jboss.net:service=MailTransport"
85  * description="email transport for soap messages"
86  * extends="org.jboss.net.axis.transport.mailto.AbstractMailTransportServiceMBean"
87  *
88  */

89 public class MailTransportService extends AbstractMailTransportService implements MailTransportServiceMBean,
90    MailConstants
91 {
92
93    // members
94

95    private AxisServer server = null;
96
97    private String JavaDoc transportName = "mailto";
98
99    /**
100     * @return The name this transport has been given.
101     *
102     * @jmx.managed-attribute
103     * description="the name of the transport for email messages"
104     * value="mailto"
105     */

106    public String JavaDoc getTransportName()
107    {
108       return this.transportName;
109    }
110
111    /**
112     * @param name The name this transport will be known as (smtp for instance).
113     *
114     * @jmx.managed-attribute
115     */

116    public void setTransportName(String JavaDoc name)
117    {
118       this.transportName = name;
119    }
120
121    /** override AxisServlet.getEngine() in order to redirect to
122     * the corresponding AxisEngine.
123     *
124     * This is taken pretty much verbatem from the AxisServiceServlet
125     */

126    public AxisServer getEngine() throws AxisFault
127    {
128       if (server == null)
129       {
130          try
131          {
132             server = JMXEngineConfigurationFactory.newJMXFactory(getEngineName()).getAxisServer();
133          }
134          catch (NullPointerException JavaDoc e)
135          {
136             throw new AxisFault("Could not access JMX configuration factory.", e);
137          }
138       }
139
140       return server;
141    }
142
143    /* (non-Javadoc)
144     * @see org.jboss.net.axis.transport.mail.AbstractMailTransportService#processMessages(javax.mail.Message[])
145     */

146    protected void processMessages(Message JavaDoc[] msgs)
147    {
148       // iterate over all the messages processing them in turn.
149
for (int i = 0; i < msgs.length; i++)
150       {
151          processMessage(msgs[i]);
152
153          /*
154           * we will need to delete the request messages in all cases
155           * otherwise the inbox will just pile up with the messages that could not
156           * be processed.
157           *
158           * if deleteMail is set to false then the server will respond to any valid messages repeatedly!
159           * perhaps we should have a persistent way to remember which messages we have processed?
160           */

161          if (getDeleteMail())
162          {
163             try
164             {
165                msgs[i].setFlag(Flags.Flag.DELETED, true);
166             }
167             catch (MessagingException JavaDoc e1)
168             {
169                log.warn("Unable to flag the message for deletion.", e1);
170             }
171          }
172       }
173    }
174
175    /**
176     * Creates a message context that will be used while processing this request.
177     *
178     * @param engine Server engine
179     * @param msg Email message
180     * @return
181     * @throws AxisFault
182     */

183    protected MessageContext createMessageContext(AxisEngine engine, Message JavaDoc msg)
184       throws AxisFault
185    {
186       MessageContext msgCtx = new MessageContext(engine);
187
188       // set the transport
189
msgCtx.setTransportName(transportName);
190
191       // NOTE the axis servlet adds lot's more stuff than this to the message context, maybe we should too?
192
return msgCtx;
193    }
194
195    /**
196     * Serialize the email message body into a SOAPMessage.
197     * @param mc MessageContext that will be used while processing this message
198     * @param msg Email Message
199     * @throws AxisFault if we need to abort this message (drop the context and delete the email message
200     * with out sending a response message.)
201     */

202    protected void processMessageBody(MessageContext mc, Message JavaDoc msg) throws AxisFault
203    {
204       String JavaDoc msgNS = null;
205       try
206       {
207          org.apache.axis.Message soapMsg = new org.apache.axis.Message(msg.getInputStream(), false, msg
208             .getContentType(), null);
209
210          mc.setRequestMessage(soapMsg);
211       }
212       catch (Exception JavaDoc e)
213       {
214          log.warn("This message doesn't appear to be a SOAP Message,", e);
215       }
216    }
217
218    /**
219     * @param ctx MessageContext that is being used for processing this request
220     * @param msg Email message that is theoretically holding a SOAP request.
221     * @return The value of the first Message-ID header found.
222     */

223    protected String JavaDoc processHeaders(MessageContext ctx, Message JavaDoc msg) throws AxisFault
224    {
225       // over ride this method if you need to do something funky with
226
// the headers of the email message.
227
String JavaDoc msgID = null;
228       try
229       {
230          String JavaDoc[] msgIDs = msg.getHeader(HEADER_MESSAGE_ID);
231          if (msgIDs != null && msgIDs.length > 0)
232          {
233             msgID = msgIDs[0];
234          }
235       }
236       catch (MessagingException JavaDoc e)
237       {
238          throw new AxisFault("Unable to process mail headers.", e);
239       }
240       return msgID;
241    }
242    
243    /**
244     * Does the actual work of making the incoming request suitable to send off to the axis engine.
245     *
246     * @param msg incoming email message.
247     */

248    private void processMessage(Message JavaDoc msg)
249    //private Message processMessage(Message msg)//, Session mail, Folder folder)
250
{
251
252       org.apache.axis.MessageContext sMsgCtx = null;
253       org.apache.axis.Message sResMsg = null;
254
255       try
256       {
257          // create a new soap message context
258
sMsgCtx = createMessageContext(getEngine(), msg);
259
260          // wsa can worry about the headers
261
String JavaDoc msgID = processHeaders(sMsgCtx, msg);
262          
263          // decide if the body of our email is a soap envelope
264
processMessageBody(sMsgCtx, msg);
265          
266          archiveMessage(msgID, sMsgCtx);
267
268          // send it all off to the Axis Server
269
if (log.isDebugEnabled())
270             log.debug("Invoking Axis Server.");
271
272          getEngine().invoke(sMsgCtx);
273
274          if (log.isDebugEnabled())
275             log.debug("Return from Axis Server.");
276
277       }
278       catch (AxisFault e)
279       {
280          // There is not much we can do here since we don't have the ability to send email
281
// any faults that happened after engine.invoke should be handled by the addressingHandler's onFault() method.
282
// any faults that happend prior to that will just be logged.
283
log.fatal("The email message number "+msg.getMessageNumber()+" caused an AxisFault:",e);
284       }
285    }
286
287    /**
288     * Override this method if you need to store incoming messages.<br>
289     * Note: If web service security handlers are in the handler chain,
290     * the message will not have been verified/decrypted yet.
291     * @param msgID
292     * @param msgCtx
293     */

294    protected void archiveMessage(String JavaDoc msgID, MessageContext msgCtx)
295    {
296    }
297
298 }
299
Popular Tags