View Javadoc

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