View Javadoc

1   /*
2    * $Id: StdioMessageReceiver.java 10961 2008-02-22 19:01:02Z dfeist $
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.transport.stdio;
12  
13  import org.mule.DefaultMuleMessage;
14  import org.mule.api.MuleMessage;
15  import org.mule.api.endpoint.InboundEndpoint;
16  import org.mule.api.lifecycle.CreateException;
17  import org.mule.api.service.Service;
18  import org.mule.api.transport.Connector;
19  import org.mule.transport.AbstractPollingMessageReceiver;
20  
21  import java.io.InputStream;
22  import java.io.PrintStream;
23  import java.io.PushbackInputStream;
24  
25  import org.apache.commons.lang.BooleanUtils;
26  import org.apache.commons.lang.SystemUtils;
27  
28  /**
29   * <code>StdioMessageReceiver</code> is a listener for events from Mule components
30   * which then simply passes the events on to the target components.
31   */
32  public class StdioMessageReceiver extends AbstractPollingMessageReceiver
33  {
34      public static final int DEFAULT_BUFFER_SIZE = 4096;
35  
36      private int bufferSize = DEFAULT_BUFFER_SIZE;
37      private InputStream inputStream;
38      private StdioConnector connector;
39  
40      private boolean sendStream;
41  
42      public StdioMessageReceiver(Connector connector,
43                                  Service service,
44                                  InboundEndpoint endpoint,
45                                  long checkFrequency) throws CreateException
46      {
47          super(connector, service, endpoint);
48          this.setFrequency(checkFrequency);
49  
50          this.connector = (StdioConnector) connector;
51          String streamName = endpoint.getEndpointURI().getAddress();
52          if (StdioConnector.STREAM_SYSTEM_IN.equalsIgnoreCase(streamName))
53          {
54              inputStream = System.in;
55          }
56          else
57          {
58              inputStream = this.connector.getInputStream();
59          }
60  
61          // apply connector-specific properties
62          if (connector instanceof PromptStdioConnector)
63          {
64              PromptStdioConnector ssc = (PromptStdioConnector) connector;
65  
66              String promptMessage = (String) endpoint.getProperties().get("promptMessage");
67              if (promptMessage != null)
68              {
69                  ssc.setPromptMessage(promptMessage);
70              }
71          }
72          
73          this.sendStream = BooleanUtils.toBoolean((String) endpoint.getProperties().get("sendStream"));
74      }
75  
76      protected void doDispose()
77      {
78          // template method
79      }
80  
81      public void doConnect() throws Exception
82      {
83          if (connector instanceof PromptStdioConnector)
84          {
85              PromptStdioConnector ssc = (PromptStdioConnector) connector;
86              DelayedMessageWriter writer = new DelayedMessageWriter(ssc);
87              writer.start();
88          }
89      }
90  
91      public void doDisconnect() throws Exception
92      {
93          // noop
94      }
95  
96      /*
97       * (non-Javadoc)
98       * 
99       * @see org.mule.util.timer.TimeEventListener#timeExpired(org.mule.util.timer.TimeEvent)
100      */
101     public void poll()
102     {
103         try
104         {
105             if (sendStream)
106             {
107                 PushbackInputStream in = new PushbackInputStream(inputStream);
108 
109                 //Block until we have some data
110                 int i = in.read();
111                 //Roll back our read
112                 in.unread(i);
113                 MuleMessage umoMessage = new DefaultMuleMessage(connector.getMessageAdapter(in));
114                 routeMessage(umoMessage, endpoint.isSynchronous());
115             }
116             else
117             {
118                 byte[] inputBuffer = new byte[bufferSize];
119                 int len = inputStream.read(inputBuffer);
120 
121                 if (len == -1)
122                 {
123                     return;
124                 }
125 
126                 StringBuffer fullBuffer = new StringBuffer(bufferSize);
127                 while (len > 0)
128                 {
129                     fullBuffer.append(new String(inputBuffer, 0, len));
130                     len = 0; // mark as read
131                     if (inputStream.available() > 0)
132                     {
133                         len = inputStream.read(inputBuffer);
134                     }
135                 }
136 
137                 // remove any trailing CR/LF
138                 String finalMessageString;
139                 int noCRLFLength = fullBuffer.length() - SystemUtils.LINE_SEPARATOR.length();
140                 if (fullBuffer.indexOf(SystemUtils.LINE_SEPARATOR, noCRLFLength) != -1)
141                 {
142                     finalMessageString = fullBuffer.substring(0, noCRLFLength);
143                 }
144                 else
145                 {
146                     finalMessageString = fullBuffer.toString();
147                 }
148 
149                 MuleMessage umoMessage = new DefaultMuleMessage(connector.getMessageAdapter(finalMessageString));
150                 routeMessage(umoMessage, endpoint.isSynchronous());
151             }
152 
153             doConnect();
154         }
155         catch (Exception e)
156         {
157             handleException(e);
158         }
159     }
160 
161     public InputStream getInputStream()
162     {
163         return inputStream;
164     }
165 
166     public void setInputStream(InputStream inputStream)
167     {
168         this.inputStream = inputStream;
169     }
170 
171     public int getBufferSize()
172     {
173         return bufferSize;
174     }
175 
176     public void setBufferSize(int bufferSize)
177     {
178         this.bufferSize = bufferSize;
179     }
180 
181     private class DelayedMessageWriter extends Thread
182     {
183         private long delay = 0;
184         private PromptStdioConnector ssc;
185 
186         public DelayedMessageWriter(PromptStdioConnector ssc)
187         {
188             this.delay = ssc.getMessageDelayTime();
189             this.ssc = ssc;
190         }
191 
192         public void run()
193         {
194             if (delay > 0)
195             {
196                 try
197                 {
198                     // Allow all other console message to be printed out first
199                     sleep(delay);
200                 }
201                 catch (InterruptedException e1)
202                 {
203                     // ignore
204                 }
205             }
206             ((PrintStream) ssc.getOutputStream()).println();
207             ((PrintStream) ssc.getOutputStream()).print(ssc.getPromptMessage());
208         }
209     }
210 }