001: /*
002: * $Id: DefaultMuleEventContext.java 11343 2008-03-13 10:58:26Z tcarlson $
003: * --------------------------------------------------------------------------------------
004: * Copyright (c) MuleSource, Inc. All rights reserved. http://www.mulesource.com
005: *
006: * The software in this package is published under the terms of the CPAL v1.0
007: * license, a copy of which has been included with this distribution in the
008: * LICENSE.txt file.
009: */
010:
011: package org.mule;
012:
013: import org.mule.api.FutureMessageResult;
014: import org.mule.api.MuleContext;
015: import org.mule.api.MuleEvent;
016: import org.mule.api.MuleEventContext;
017: import org.mule.api.MuleException;
018: import org.mule.api.MuleMessage;
019: import org.mule.api.MuleSession;
020: import org.mule.api.config.MuleProperties;
021: import org.mule.api.endpoint.EndpointURI;
022: import org.mule.api.endpoint.InboundEndpoint;
023: import org.mule.api.endpoint.OutboundEndpoint;
024: import org.mule.api.service.Service;
025: import org.mule.api.transaction.Transaction;
026: import org.mule.api.transaction.TransactionException;
027: import org.mule.api.transformer.TransformerException;
028: import org.mule.config.i18n.CoreMessages;
029: import org.mule.transaction.TransactionCoordination;
030:
031: import java.io.OutputStream;
032:
033: import edu.emory.mathcs.backport.java.util.concurrent.Callable;
034:
035: import org.apache.commons.logging.Log;
036: import org.apache.commons.logging.LogFactory;
037:
038: /**
039: * <code>DefaultMuleEventContext</code> is the context object for the current request.
040: * Using the context, developers can send/dispatch/receive events programmatically as
041: * well as manage transactions.
042: */
043: public class DefaultMuleEventContext implements MuleEventContext {
044: /**
045: * logger used by this class
046: */
047: protected static final Log logger = LogFactory
048: .getLog(DefaultMuleEventContext.class);
049:
050: private final MuleEvent event;
051: private final MuleSession session;
052: private MuleContext muleContext;
053:
054: public DefaultMuleEventContext(MuleEvent event) {
055: this .event = event;
056: this .session = event.getSession();
057: this .muleContext = event.getMuleContext();
058: }
059:
060: /**
061: * Returns the message payload for this event
062: *
063: * @return the message payload for this event
064: */
065: public MuleMessage getMessage() {
066: return event.getMessage();
067: }
068:
069: /**
070: * Reterns the conents of the message as a byte array.
071: *
072: * @return the conents of the message as a byte array
073: * @throws org.mule.api.MuleException if the message cannot be converted into an
074: * array of bytes
075: */
076: public byte[] getMessageAsBytes() throws MuleException {
077: return event.getMessageAsBytes();
078: }
079:
080: /**
081: * Returns the message transformed into it's recognised or expected format. The
082: * transformer used is the one configured on the endpoint through which this
083: * event was received.
084: *
085: * @return the message transformed into it's recognised or expected format.
086: * @throws org.mule.api.transformer.TransformerException if a failure occurs in
087: * the transformer
088: * @see org.mule.api.transformer.Transformer
089: */
090: public Object transformMessage() throws TransformerException {
091: return event.transformMessage();
092: }
093:
094: /**
095: * Returns the message transformed into its recognised or expected format. The
096: * transformer used is the one configured on the endpoint through which this
097: * event was received.
098: *
099: * @param expectedType The class type required for the return object. This param
100: * just provides a convienient way to manage type casting of
101: * transformed objects
102: * @return the message transformed into it's recognised or expected format.
103: * @throws org.mule.api.transformer.TransformerException if a failure occurs or
104: * if the return type is not the same as the expected type in the
105: * transformer
106: * @see org.mule.api.transformer.Transformer
107: */
108: public Object transformMessage(Class expectedType)
109: throws TransformerException {
110: return event.transformMessage(expectedType);
111: }
112:
113: /**
114: * Returns the message transformed into it's recognised or expected format and
115: * then into an array of bytes. The transformer used is the one configured on the
116: * endpoint through which this event was received.
117: *
118: * @return the message transformed into it's recognised or expected format as an
119: * array of bytes.
120: * @throws org.mule.api.transformer.TransformerException if a failure occurs in
121: * the transformer
122: * @see org.mule.api.transformer.Transformer
123: */
124: public byte[] transformMessageToBytes() throws TransformerException {
125: return event.transformMessageToBytes();
126: }
127:
128: /**
129: * Returns the message contents as a string
130: *
131: * @return the message contents as a string
132: * @throws org.mule.api.MuleException if the message cannot be converted into a
133: * string
134: */
135: public String getMessageAsString(String encoding)
136: throws MuleException {
137: return event.getMessageAsString(encoding);
138: }
139:
140: /**
141: * Returns the message transformed into it's recognised or expected format and
142: * then into a String. The transformer used is the one configured on the endpoint
143: * through which this event was received. This method will use the default
144: * encoding on the event
145: *
146: * @return the message transformed into it's recognised or expected format as a
147: * Strings.
148: * @throws org.mule.api.transformer.TransformerException if a failure occurs in
149: * the transformer
150: * @see org.mule.api.transformer.Transformer
151: */
152: public String transformMessageToString()
153: throws TransformerException {
154: return event.transformMessageToString();
155: }
156:
157: /**
158: * Returns the message contents as a string This method will use the default
159: * encoding on the event
160: *
161: * @return the message contents as a string
162: * @throws org.mule.api.MuleException if the message cannot be converted into a
163: * string
164: */
165: public String getMessageAsString() throws MuleException {
166: return event.getMessageAsString();
167: }
168:
169: /**
170: * Returns the current transaction (if any) for the session
171: *
172: * @return the current transaction for the session or null if there is no
173: * transaction in progress
174: */
175: public Transaction getCurrentTransaction() {
176: return TransactionCoordination.getInstance().getTransaction();
177: }
178:
179: public void markTransactionForRollback()
180: throws TransactionException {
181: if (getCurrentTransaction() != null) {
182: getCurrentTransaction().setRollbackOnly();
183: }
184: }
185:
186: /**
187: * This will send an event via the configured outbound router on the service
188: *
189: * @param message the message to send
190: * @return the result of the send if any
191: * @throws org.mule.api.MuleException if there is no outbound endpoint configured
192: * on the service or the events fails during dispatch
193: */
194: public MuleMessage sendEvent(Object message) throws MuleException {
195: return sendEvent(new DefaultMuleMessage(message, event
196: .getMessage()));
197: }
198:
199: /**
200: * Depending on the session state this methods either Passes an event
201: * synchronously to the next available Mule UMO in the pool or via the endpoint
202: * configured for the event
203: *
204: * @param message the event message payload to send
205: * @param endpoint The endpoint to disptch the event through.
206: * @return the return Message from the call or null if there was no result
207: * @throws org.mule.api.MuleException if the event fails to be processed by the
208: * service or the transport for the endpoint
209: */
210: public MuleMessage sendEvent(MuleMessage message,
211: OutboundEndpoint endpoint) throws MuleException {
212: // If synchronous receive has not been explicitly set, default it to true
213: setRemoteSync(message, endpoint);
214: return session.sendEvent(message, endpoint);
215: }
216:
217: /**
218: * Depending on the session state this methods either Passes an event
219: * synchronously to the next available Mule UMO in the pool or via the endpoint
220: * configured for the event
221: *
222: * @param message the message payload to send
223: * @return the return Message from the call or null if there was no result
224: * @throws org.mule.api.MuleException if the event fails to be processed by the
225: * service or the transport for the endpoint
226: */
227: public MuleMessage sendEvent(MuleMessage message)
228: throws MuleException {
229: // If synchronous receive has not been explicitly set, default it to
230: // true
231: setRemoteSync(message, (OutboundEndpoint) event.getEndpoint());
232: return session.sendEvent(message);
233: }
234:
235: /**
236: * Depending on the session state this methods either Passes an event
237: * synchronously to the next available Mule UMO in the pool or via the
238: * endpointUri configured for the event
239: *
240: * @param message the event message payload to send
241: * @param endpointUri The endpointUri to disptch the event through
242: * @return the return Message from the call or null if there was no result
243: * @throws org.mule.api.MuleException if the event fails to be processed by the
244: * service or the transport for the endpointUri
245: */
246: public MuleMessage sendEvent(MuleMessage message,
247: EndpointURI endpointUri) throws MuleException {
248: OutboundEndpoint endpoint = getMuleContext().getRegistry()
249: .lookupEndpointFactory().getOutboundEndpoint(
250: endpointUri);
251:
252: // If synchronous receive has not been explicitly set, default it to
253: // true
254: setRemoteSync(message, endpoint);
255: return session.sendEvent(message, endpoint);
256: }
257:
258: /**
259: * sends an event request via the configured outbound router for this service.
260: * This method return immediately, but the result of the event invocation
261: * available from the returned a Future result that can be accessed later by the
262: * the returned FutureMessageResult. the Future messageResult can be queried at
263: * any time to check that the invocation has completed. A timeout is associated
264: * with the invocation, which is the maximum time in milli-seconds that the
265: * invocation should take to complete
266: *
267: * @param message the object that is the payload of the event
268: * @param timeout how long to block in milliseconds waiting for a result
269: * @return the result message if any of the invocation
270: * @throws org.mule.api.MuleException if the dispatch fails or the components or
271: * transfromers cannot be found
272: * @see org.mule.api.FutureMessageResult
273: */
274: public FutureMessageResult sendEventAsync(final Object message,
275: final int timeout) throws MuleException {
276: Callable callable = new Callable() {
277: public Object call() throws Exception {
278: MuleMessage umoMessage = new DefaultMuleMessage(
279: message, event.getMessage());
280: umoMessage.setBooleanProperty(
281: MuleProperties.MULE_REMOTE_SYNC_PROPERTY, true);
282: umoMessage.setIntProperty(
283: MuleProperties.MULE_EVENT_TIMEOUT_PROPERTY,
284: timeout);
285: return sendEvent(umoMessage);
286: }
287: };
288:
289: FutureMessageResult result = new FutureMessageResult(callable);
290: // TODO MULE-732: use injected ExecutorService
291: result.execute();
292: return result;
293: }
294:
295: /**
296: * sends an event request via the configured outbound router for this service.
297: * This method return immediately, but the result of the event invocation
298: * available from the returned a Future result that can be accessed later by the
299: * the returned FutureMessageResult. the Future messageResult can be queried at
300: * any time to check that the invocation has completed. A timeout is associated
301: * with the invocation, which is the maximum time in milli-seconds that the
302: * invocation should take to complete
303: *
304: * @param message the MuleMessage of the event
305: * @param timeout how long to block in milliseconds waiting for a result
306: * @return the result message if any of the invocation
307: * @throws org.mule.api.MuleException if the dispatch fails or the components or
308: * transfromers cannot be found
309: * @see org.mule.api.FutureMessageResult
310: */
311: public FutureMessageResult sendEventAsync(
312: final MuleMessage message, final int timeout)
313: throws MuleException {
314: Callable callable = new Callable() {
315: public Object call() throws Exception {
316: message.setBooleanProperty(
317: MuleProperties.MULE_REMOTE_SYNC_PROPERTY, true);
318: message.setIntProperty(
319: MuleProperties.MULE_EVENT_TIMEOUT_PROPERTY,
320: timeout);
321: return sendEvent(message);
322: }
323: };
324:
325: FutureMessageResult result = new FutureMessageResult(callable);
326: // TODO MULE-732: use injected ExecutorService
327: result.execute();
328: return result;
329: }
330:
331: /**
332: * sends an event request via the configured outbound router for this service.
333: * This method return immediately, but the result of the event invocation
334: * available from the returned a Future result that can be accessed later by the
335: * the returned FutureMessageResult. the Future messageResult can be queried at
336: * any time to check that the invocation has completed. A timeout is associated
337: * with the invocation, which is the maximum time in milli-seconds that the
338: * invocation should take to complete
339: *
340: * @param message the MuleMessage of the event
341: * @param endpointUri the endpointUri to dispatch to
342: * @param timeout how long to block in milliseconds waiting for a result
343: * @return the result message if any of the invocation
344: * @throws org.mule.api.MuleException if the dispatch fails or the components or
345: * transfromers cannot be found
346: * @see org.mule.api.FutureMessageResult
347: */
348: public FutureMessageResult sendEventAsync(
349: final MuleMessage message, final EndpointURI endpointUri,
350: final int timeout) throws MuleException {
351: Callable callable = new Callable() {
352: public Object call() throws Exception {
353: message.setBooleanProperty(
354: MuleProperties.MULE_REMOTE_SYNC_PROPERTY, true);
355: message.setIntProperty(
356: MuleProperties.MULE_EVENT_TIMEOUT_PROPERTY,
357: timeout);
358: return sendEvent(message, endpointUri);
359: }
360: };
361:
362: FutureMessageResult result = new FutureMessageResult(callable);
363: // TODO MULE-732: use injected ExecutorService
364: result.execute();
365: return result;
366: }
367:
368: /**
369: * sends an event request via the configured outbound router for this service.
370: * This method return immediately, but the result of the event invocation
371: * available from the returned a Future result that can be accessed later by the
372: * the returned FutureMessageResult. the Future messageResult can be queried at
373: * any time to check that the invocation has completed. A timeout is associated
374: * with the invocation, which is the maximum time in milli-seconds that the
375: * invocation should take to complete
376: *
377: * @param message the MuleMessage of the event
378: * @param endpointName The endpoint name to disptch the event through. This will
379: * be looked up first on the service configuration and then on the
380: * mule manager configuration
381: * @param timeout how long to block in milliseconds waiting for a result
382: * @return the result message if any of the invocation
383: * @throws org.mule.api.MuleException if the dispatch fails or the components or
384: * transfromers cannot be found
385: * @see org.mule.api.FutureMessageResult
386: */
387: public FutureMessageResult sendEventAsync(
388: final MuleMessage message, final String endpointName,
389: final int timeout) throws MuleException {
390: Callable callable = new Callable() {
391: public Object call() throws Exception {
392: message.setBooleanProperty(
393: MuleProperties.MULE_REMOTE_SYNC_PROPERTY, true);
394: message.setIntProperty(
395: MuleProperties.MULE_EVENT_TIMEOUT_PROPERTY,
396: timeout);
397: return sendEvent(message, endpointName);
398: }
399: };
400:
401: FutureMessageResult result = new FutureMessageResult(callable);
402: // TODO MULE-732: use injected ExecutorService
403: result.execute();
404: return result;
405: }
406:
407: /**
408: * Depending on the session state this methods either Passes an event
409: * synchronously to the next available Mule UMO in the pool or via the endpoint
410: * configured for the event
411: *
412: * @param message the event message payload to send
413: * @param endpointName The endpoint name to disptch the event through. This will
414: * be looked up first on the service configuration and then on the
415: * mule manager configuration
416: * @return the return Message from the call or null if there was no result
417: * @throws org.mule.api.MuleException if the event fails to be processed by the
418: * service or the transport for the endpoint
419: */
420: public MuleMessage sendEvent(MuleMessage message,
421: String endpointName) throws MuleException {
422: OutboundEndpoint endpoint = RegistryContext.getRegistry()
423: .lookupEndpointFactory().getOutboundEndpoint(
424: endpointName);
425: setRemoteSync(message, endpoint);
426: return session.sendEvent(message, endpoint);
427: }
428:
429: /**
430: * This will dispatch an event asynchronously via the configured outbound
431: * endpoint on the service for this session
432: *
433: * @param message payload to dispatch
434: * @throws org.mule.api.MuleException if there is no outbound endpoint configured
435: * on the service or the events fails during dispatch
436: */
437: public void dispatchEvent(Object message) throws MuleException {
438: session.dispatchEvent(new DefaultMuleMessage(message, event
439: .getMessage()));
440: }
441:
442: /**
443: * This will dispatch an event asynchronously via the configured outbound
444: * endpoint on the service for this session
445: *
446: * @param message the message to send
447: * @throws org.mule.api.MuleException if there is no outbound endpoint configured
448: * on the service or the events fails during dispatch
449: */
450: public void dispatchEvent(MuleMessage message) throws MuleException {
451: session.dispatchEvent(message);
452: }
453:
454: /**
455: * Depending on the session state this methods either Passes an event
456: * asynchronously to the next available Mule UMO in the pool or via the
457: * endpointUri configured for the event
458: *
459: * @param message the event message payload to send
460: * @param endpointUri the endpointUri to dispatc the event to first on the
461: * service configuration and then on the mule manager configuration
462: * @throws org.mule.api.MuleException if the event fails to be processed by the
463: * service or the transport for the endpointUri
464: */
465: public void dispatchEvent(MuleMessage message,
466: EndpointURI endpointUri) throws MuleException {
467: OutboundEndpoint endpoint = getMuleContext().getRegistry()
468: .lookupEndpointFactory().getOutboundEndpoint(
469: endpointUri);
470: session.dispatchEvent(message, endpoint);
471: }
472:
473: /**
474: * Depending on the session state this methods either Passes an event
475: * asynchronously to the next available Mule UMO in the pool or via the endpoint
476: * configured for the event
477: *
478: * @param message the event message payload to send
479: * @param endpointName The endpoint name to disptch the event through. This will
480: * be looked up first on the service configuration and then on the
481: * mule manager configuration
482: * @throws org.mule.api.MuleException if the event fails to be processed by the
483: * service or the transport for the endpoint
484: */
485: public void dispatchEvent(MuleMessage message, String endpointName)
486: throws MuleException {
487: session.dispatchEvent(message, endpointName);
488: }
489:
490: /**
491: * Depending on the session state this methods either Passes an event
492: * asynchronously to the next available Mule UMO in the pool or via the endpoint
493: * configured for the event
494: *
495: * @param message the event message payload to send
496: * @param endpoint The endpoint name to disptch the event through.
497: * @throws org.mule.api.MuleException if the event fails to be processed by the
498: * service or the transport for the endpoint
499: */
500: public void dispatchEvent(MuleMessage message,
501: OutboundEndpoint endpoint) throws MuleException {
502: session.dispatchEvent(message, endpoint);
503: }
504:
505: /**
506: * Requests a synchronous receive of an event on the service
507: *
508: * @param endpoint the endpoint identifing the endpointUri on ewhich the event
509: * will be received
510: * @param timeout time in milliseconds before the request timesout
511: * @return The requested event or null if the request times out
512: * @throws org.mule.api.MuleException if the request operation fails
513: */
514: public MuleMessage requestEvent(InboundEndpoint endpoint,
515: long timeout) throws MuleException {
516: return session.requestEvent(endpoint, timeout);
517: }
518:
519: /**
520: * Requests a synchronous receive of an event on the service
521: *
522: * @param endpointName the endpoint identifing the endpointUri on ewhich the
523: * event will be received
524: * @param timeout time in milliseconds before the request timesout
525: * @return The requested event or null if the request times out
526: * @throws org.mule.api.MuleException if the request operation fails
527: */
528: public MuleMessage requestEvent(String endpointName, long timeout)
529: throws MuleException {
530: return session.requestEvent(endpointName, timeout);
531: }
532:
533: /**
534: * Requests a synchronous receive of an event on the service
535: *
536: * @param endpointUri the endpointUri on which the event will be received
537: * @param timeout time in milliseconds before the request timesout
538: * @return The requested event or null if the request times out
539: * @throws org.mule.api.MuleException if the request operation fails
540: */
541: public MuleMessage requestEvent(EndpointURI endpointUri,
542: long timeout) throws MuleException {
543: InboundEndpoint endpoint = getMuleContext().getRegistry()
544: .lookupEndpointFactory()
545: .getInboundEndpoint(endpointUri);
546: return session.requestEvent(endpoint, timeout);
547: }
548:
549: /**
550: * @return the service descriptor of the service that received this event
551: */
552: public Service getService() {
553: return event.getService();
554: }
555:
556: /**
557: * Determines whether the default processing for this event will be executed. By
558: * default, the Mule server will route events according to a components
559: * configuration. The user can override this behaviour by obtaining a reference
560: * to the MuleEvent context, either by implementing
561: * <code>org.mule.api.lifecycle.Callable</code> or calling
562: * <code>RequestContext.getEventContext</code> to obtain the MuleEventContext for
563: * the current thread. The user can programmatically control how events are
564: * dispatched.
565: *
566: * @return Returns true is the user has set stopFurtherProcessing.
567: * @see org.mule.api.MuleEventContext
568: * @see org.mule.api.lifecycle.Callable
569: */
570: public boolean isStopFurtherProcessing() {
571: return RequestContext.getEvent().isStopFurtherProcessing();
572: }
573:
574: /**
575: * Determines whether the default processing for this event will be executed. By
576: * default, the Mule server will route events according to a components
577: * configuration. The user can override this behaviour by obtaining a reference
578: * to the MuleEvent context, either by implementing
579: * <code>org.mule.api.lifecycle.Callable</code> or calling
580: * <code>UMOManager.getEventContext</code> to obtain the MuleEventContext for
581: * the current thread. The user can programmatically control how events are
582: * dispached.
583: *
584: * @param stopFurtherProcessing the value to set.
585: */
586: public void setStopFurtherProcessing(boolean stopFurtherProcessing) {
587: event.setStopFurtherProcessing(stopFurtherProcessing);
588: }
589:
590: /**
591: * An outputstream the can optionally be used write response data to an incoming
592: * message.
593: *
594: * @return an output stream if one has been made available by the message receiver
595: * that received the message
596: */
597: public OutputStream getOutputStream() {
598: return event.getOutputStream();
599: }
600:
601: /**
602: * Determines whether the was sent synchrounously or not
603: *
604: * @return true if the event is synchronous
605: */
606: public boolean isSynchronous() {
607: return event.isSynchronous();
608: }
609:
610: public EndpointURI getEndpointURI() {
611: return event.getEndpoint().getEndpointURI();
612: }
613:
614: /**
615: * Returns the transaction for the current event or null if there is no
616: * transaction in progresss
617: *
618: * @return the transaction for the current event or null if there is no
619: * transaction in progresss
620: */
621: public Transaction getTransaction() {
622: return TransactionCoordination.getInstance().getTransaction();
623: }
624:
625: /**
626: * Get the timeout value associated with the event
627: *
628: * @return the timeout for the event
629: */
630: public int getTimeout() {
631: return event.getTimeout();
632: }
633:
634: private void setRemoteSync(MuleMessage message,
635: OutboundEndpoint endpoint) {
636: if (endpoint.isRemoteSync()) {
637: if (getTransaction() == null) {
638: message.setBooleanProperty(
639: MuleProperties.MULE_REMOTE_SYNC_PROPERTY, true);
640: } else {
641: throw new IllegalStateException(CoreMessages
642: .cannotUseTxAndRemoteSync().getMessage());
643: }
644: }
645: }
646:
647: /**
648: * Gets the encoding for the current message. For potocols that send encoding
649: * Information with the message, this method should be overriden to expose the
650: * transport encoding, otherwise the default encoding in the Mule configuration
651: * will be used
652: *
653: * @return the encoding for this message. This method must never return null
654: */
655: public String getEncoding() {
656: return event.getEncoding();
657: }
658:
659: public MuleSession getSession() {
660: return event.getSession();
661: }
662:
663: public String toString() {
664: return event.toString();
665: }
666:
667: public MuleContext getMuleContext() {
668: return event.getMuleContext();
669: }
670:
671: }
|