View Javadoc

1   /*
2    * $Id: UdpMessageDispatcher.java 7976 2007-08-21 14:26:13Z dirk.olmes $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.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.providers.udp;
12  
13  import org.mule.impl.MuleMessage;
14  import org.mule.providers.AbstractMessageDispatcher;
15  import org.mule.umo.UMOEvent;
16  import org.mule.umo.UMOMessage;
17  import org.mule.umo.endpoint.UMOImmutableEndpoint;
18  
19  import java.io.IOException;
20  import java.net.DatagramPacket;
21  import java.net.DatagramSocket;
22  import java.net.InetAddress;
23  import java.util.Map;
24  
25  /**
26   * <code>UdpMessageDispatcher</code> is responsible for dispatching MuleEvents as
27   * UDP packets on the network
28   */
29  
30  public class UdpMessageDispatcher extends AbstractMessageDispatcher
31  {
32      protected final UdpConnector connector;
33  
34      public UdpMessageDispatcher(UMOImmutableEndpoint endpoint)
35      {
36          super(endpoint);
37          this.connector = (UdpConnector)endpoint.getConnector();
38      }
39  
40      protected void doConnect() throws Exception
41      {
42          // Test the connection
43          DatagramSocket socket = connector.getSocket(endpoint);
44          connector.releaseSocket(socket, endpoint);
45      }
46  
47      protected void doDisconnect() throws Exception
48      {
49          // nothing to do
50      }
51  
52  
53      protected synchronized void doDispatch(UMOEvent event) throws Exception
54      {
55          UMOImmutableEndpoint ep = event.getEndpoint();
56  
57          DatagramSocket socket = connector.getSocket(ep);
58          try
59          {
60              byte[] payload = event.getTransformedMessageAsBytes();
61  
62              int port = ep.getEndpointURI().getPort();
63              InetAddress inetAddress = null;
64              //TODO, check how expensive this operation is
65              if("null".equalsIgnoreCase(ep.getEndpointURI().getHost()))
66              {
67                  inetAddress = InetAddress.getLocalHost();
68              }
69              else
70              {
71                  inetAddress = InetAddress.getByName(ep.getEndpointURI().getHost());
72              }
73  
74              write(socket, payload, port, inetAddress);
75          }
76          finally
77          {
78              connector.releaseSocket(socket, ep);
79          }
80      }
81  
82      protected void write(DatagramSocket socket, byte[] data, int port, InetAddress inetAddress) throws IOException
83      {
84          DatagramPacket packet = new DatagramPacket(data, data.length);
85          if (port >= 0)
86          {
87              packet.setPort(port);
88          }
89          packet.setAddress(inetAddress);
90          socket.send(packet);
91      }
92  
93      protected synchronized UMOMessage doSend(UMOEvent event) throws Exception
94      {
95          doDispatch(event);
96          // If we're doing sync receive try and read return info from socket
97          if (event.getEndpoint().isRemoteSync())
98          {
99              DatagramSocket socket = connector.getSocket(event.getEndpoint());
100             DatagramPacket result = receive(socket, event.getTimeout());
101             if (result == null)
102             {
103                 return null;
104             }
105             return new MuleMessage(connector.getMessageAdapter(result), event.getMessage());
106         }
107         else
108         {
109             return event.getMessage();
110         }
111     }
112 
113     private DatagramPacket receive(DatagramSocket socket, int timeout) throws IOException
114     {
115         int origTimeout = socket.getSoTimeout();
116         try
117         {
118             DatagramPacket packet = new DatagramPacket(new byte[connector.getReceiveBufferSize()],
119                 connector.getReceiveBufferSize());
120 
121             if(timeout > 0 && timeout != socket.getSoTimeout())
122             {
123                 socket.setSoTimeout(timeout);
124             }
125             socket.receive(packet);
126             return packet;
127         }
128         finally
129         {
130             if(socket.getSoTimeout()!= origTimeout)
131             {
132                 socket.setSoTimeout(origTimeout);
133             }
134         }
135     }
136 
137     /**
138      * Make a specific request to the underlying transport
139      * 
140      * @param timeout the maximum time the operation should block before returning.
141      *            The call should return immediately if there is data available. If
142      *            no data becomes available before the timeout elapses, null will be
143      *            returned
144      * @return the result of the request wrapped in a UMOMessage object. Null will be
145      *         returned if no data was avaialable
146      * @throws Exception if the call to the underlying protocal cuases an exception
147      */
148     protected UMOMessage doReceive(long timeout) throws Exception
149     {
150         DatagramSocket socket = connector.getSocket(endpoint);
151         DatagramPacket result = receive(socket, (int)timeout);
152         if (result == null)
153         {
154             return null;
155         }
156         return new MuleMessage(connector.getMessageAdapter(result), (Map)null);
157     }
158 
159     protected void doDispose()
160     {
161         // template method
162     }
163 }