View Javadoc

1   /*
2    * $Id: DeferredOutputStream.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  package org.mule.impl.model.streaming;
11  
12  import org.mule.config.i18n.CoreMessages;
13  import org.mule.providers.streaming.StreamMessageAdapter;
14  import org.mule.umo.MessagingException;
15  import org.mule.umo.UMODescriptor;
16  import org.mule.umo.UMOEventContext;
17  import org.mule.umo.UMOException;
18  import org.mule.umo.endpoint.UMOEndpoint;
19  import org.mule.umo.endpoint.UMOEndpointURI;
20  import org.mule.umo.routing.UMOOutboundRouter;
21  import org.mule.umo.routing.UMOOutboundRouterCollection;
22  
23  import java.io.BufferedOutputStream;
24  import java.io.IOException;
25  import java.io.OutputStream;
26  import java.util.Iterator;
27  
28  import org.apache.commons.logging.Log;
29  import org.apache.commons.logging.LogFactory;
30  
31  /**
32   * This outputStream allows a stream to be choosen after this has been created.  It is used by
33   * Mule when using streaming to pass to the Streaming component. The actual output stream is
34   * choosen at the point where the first byte is written. At this point an outbound router can be
35   * choosen and vales set on the event context can affect which stream is choosen.
36   */
37  public class DeferredOutputStream extends OutputStream
38  {
39      
40      protected final Log logger = LogFactory.getLog(DeferredOutputStream.class);
41      private UMOEventContext event;
42      private OutputStream out = null;
43      private int buffer = 0;
44  
45  
46      public DeferredOutputStream(UMOEventContext event)
47      {
48          this.event = event;
49      }
50  
51  
52      public DeferredOutputStream(UMOEventContext event, int buffer)
53      {
54          this.event = event;
55          this.buffer = buffer;
56      }
57  
58      public void write(int b) throws IOException
59      {
60          if (out == null)
61          {
62              out = getOutputStream();
63          }
64          out.write(b);
65      }
66  
67  
68      public void flush() throws IOException
69      {
70          //out could be null if the stream hasn't been written to yet
71          if (out != null)
72          {
73              logger.debug("flushing deferred output stream");
74              out.flush();
75          }
76          else
77          {
78              logger.debug("deferred output stream unflushed");
79          }
80      }
81  
82      public void close() throws IOException
83      {
84          //out could be null if the stream hasn't been written to yet
85          if (out != null)
86          {
87              out.close();
88          }
89      }
90  
91      protected OutputStream getOutputStream() throws IOException
92      {
93          StreamMessageAdapter adapter = (StreamMessageAdapter) event.getMessage().getAdapter();
94          OutputStream temp = getOutputStreamFromRouter();
95          if (temp == null)
96          {
97              temp = adapter.getOutputStream();
98          }
99          if (temp == null)
100         {
101             throw new IOException("No output stream was found for the current event: " + event);
102         }
103         else if (getBuffer() > 0)
104         {
105             return new BufferedOutputStream(temp, getBuffer());
106         }
107         else
108         {
109             return temp;
110         }
111     }
112 
113 
114     public int getBuffer()
115     {
116         return buffer;
117     }
118 
119     public void setBuffer(int buffer)
120     {
121         if (out != null)
122         {
123             throw new IllegalStateException("The stream buffer cannot be set after the stream has been written to");
124         }
125         this.buffer = buffer;
126     }
127 
128     protected OutputStream getOutputStreamFromRouter() throws IOException
129     {
130         UMODescriptor descriptor = event.getComponentDescriptor();
131         UMOEndpointURI endpoint = event.getEndpointURI();
132 
133         UMOOutboundRouterCollection messageRouter = descriptor.getOutboundRouter();
134         if (messageRouter.hasEndpoints())
135         {
136             for (Iterator iterator = messageRouter.getRouters().iterator(); iterator.hasNext();)
137             {
138                 UMOOutboundRouter router = (UMOOutboundRouter) iterator.next();
139                 boolean match = false;
140                 try
141                 {
142                     match = router.isMatch(event.getMessage());
143                 }
144                 catch (MessagingException e)
145                 {
146                     throw (IOException) new IOException(e.toString()).initCause(e);
147                 }
148                 if (match)
149                 {
150                     if (router.getEndpoints().size() != 1)
151                     {
152                         throw new IOException(
153                             CoreMessages.streamingComponentMustHaveOneEndpoint(descriptor.getName()).toString());
154                     }
155                     else
156                     {
157                         UMOEndpoint ep = (UMOEndpoint) router.getEndpoints().get(0);
158                         try
159                         {
160                             return ep.getConnector().getOutputStream(ep, event.getMessage());
161                         }
162                         catch (UMOException e)
163                         {
164                             throw (IOException) new IOException(
165                                 CoreMessages.streamingFailedForEndpoint(endpoint.toString()).toString()).initCause(e);
166                         }
167                     }
168                 }
169             }
170             //If we got to here there are no matching outbound Routers
171             throw new IOException(
172                 CoreMessages.streamingComponentMustHaveOneEndpoint(descriptor.getName()).toString());
173         }
174         if (logger.isDebugEnabled())
175         {
176             logger.debug("there are no outbound endpoints configured on this component, the otput stream provided from the message adapter will be used");
177         }
178 
179         //Use the response output stream on the StreamingMessage adapter
180         return null;
181     }
182 }