View Javadoc

1   /*
2    * $Id: AbstractMessageRequester.java 20358 2010-11-26 20:15:18Z tcarlson $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.transport;
12  
13  import org.mule.api.MuleException;
14  import org.mule.api.MuleMessage;
15  import org.mule.api.context.WorkManager;
16  import org.mule.api.endpoint.InboundEndpoint;
17  import org.mule.api.lifecycle.InitialisationException;
18  import org.mule.api.transformer.Transformer;
19  import org.mule.api.transport.MessageRequester;
20  import org.mule.api.transport.ReceiveException;
21  import org.mule.context.notification.EndpointMessageNotification;
22  
23  import java.util.List;
24  
25  /**
26   * The Message Requester is used to explicitly request messages from a message channel or
27   * resource rather than subscribing to inbound events or polling for messages.
28   * This is often used programatically but will not be used for inbound endpoints
29   * configured on services.
30   */
31  public abstract class AbstractMessageRequester extends AbstractTransportMessageHandler implements MessageRequester
32  {
33      private List<Transformer> defaultInboundTransformers;
34  
35      public AbstractMessageRequester(InboundEndpoint endpoint)
36      {
37          super(endpoint);
38      }
39  
40      @Override
41      protected ConnectableLifecycleManager createLifecycleManager()
42      {
43          return new ConnectableLifecycleManager<MessageRequester>(getRequesterName(), this);
44      }
45  
46      /**
47       * Method used to perform any initialisation work. If a fatal error occurs during
48       * initialisation an <code>InitialisationException</code> should be thrown,
49       * causing the Mule instance to shutdown. If the error is recoverable, say by
50       * retrying to connect, a <code>RecoverableException</code> should be thrown.
51       * There is no guarantee that by throwing a Recoverable exception that the Mule
52       * instance will not shut down.
53       * 
54       * @throws org.mule.api.lifecycle.InitialisationException if a fatal error occurs
55       *             causing the Mule instance to shutdown
56       * @throws org.mule.api.lifecycle.RecoverableException if an error occurs that
57       *             can be recovered from
58       */
59      @Override
60      public final void initialise() throws InitialisationException
61      {
62          defaultInboundTransformers = connector.getDefaultInboundTransformers(endpoint);               
63          super.initialise();
64      }
65  
66      protected String getRequesterName()
67      {
68          return getConnector().getName() + ".requester." + System.identityHashCode(this);
69      }
70  
71      /**
72       * Make a specific request to the underlying transport
73       *
74       * @param timeout the maximum time the operation should block before returning.
75       *            The call should return immediately if there is data available. If
76       *            no data becomes available before the timeout elapses, null will be
77       *            returned
78       * @return the result of the request wrapped in a MuleMessage object. Null will be
79       *         returned if no data was available
80       * @throws Exception if the call to the underlying protocol causes an exception
81       */
82      public final MuleMessage request(long timeout) throws Exception
83      {
84          try
85          {
86              // Make sure we are connected
87              connect();
88              MuleMessage result = null;
89              result = doRequest(timeout);
90              if (result != null && !endpoint.isDisableTransportTransformer())
91              {
92                  applyInboundTransformers(result);
93              }
94  
95              if (result != null && connector.isEnableMessageEvents())
96              {
97                  connector.fireNotification(new EndpointMessageNotification(result, endpoint, null,
98                      EndpointMessageNotification.MESSAGE_REQUESTED));
99              }
100             return result;
101         }
102         catch (ReceiveException e)
103         {
104             disposeAndLogException();
105             throw e;
106         }
107         catch (Exception e)
108         {
109             disposeAndLogException();
110             throw new ReceiveException(endpoint, timeout, e);
111         }
112     }
113 
114     protected void applyInboundTransformers(MuleMessage message) throws MuleException
115     {
116         message.applyTransformers(null, defaultInboundTransformers);
117     }
118 
119     @Override
120     protected WorkManager getWorkManager() throws MuleException
121     {
122         return connector.getRequesterWorkManager();
123     }
124     
125     public InboundEndpoint getEndpoint()
126     {
127         return (InboundEndpoint) super.getEndpoint();
128     }
129     
130     /**
131      * Make a specific request to the underlying transport
132      *
133      * @param timeout the maximum time the operation should block before returning.
134      *            The call should return immediately if there is data available. If
135      *            no data becomes available before the timeout elapses, null will be
136      *            returned
137      * @return the result of the request wrapped in a MuleMessage object. Null will be
138      *         returned if no data was avaialable
139      * @throws Exception if the call to the underlying protocal cuases an exception
140      */
141     protected abstract MuleMessage doRequest(long timeout) throws Exception;
142 
143 }