View Javadoc

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