1
2
3
4
5
6
7
8
9
10
11 package org.mule.tck.functional;
12
13 import org.mule.api.MuleEventContext;
14 import org.mule.api.lifecycle.Callable;
15 import org.mule.util.ClassUtils;
16 import org.mule.util.StringMessageUtils;
17
18 import java.io.IOException;
19 import java.io.InputStream;
20
21 import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicInteger;
22 import org.apache.commons.logging.Log;
23 import org.apache.commons.logging.LogFactory;
24
25
26
27
28
29
30
31
32
33
34
35
36
37 public class FunctionalStreamingTestComponent implements Callable
38 {
39 protected transient Log logger = LogFactory.getLog(getClass());
40
41 private static AtomicInteger count = new AtomicInteger(0);
42 private int number = count.incrementAndGet();
43
44 public static final int STREAM_SAMPLE_SIZE = 4;
45 public static final int STREAM_BUFFER_SIZE = 4096;
46 private EventCallback eventCallback;
47 private String summary = null;
48 private long targetSize = -1;
49
50 public FunctionalStreamingTestComponent()
51 {
52 logger.debug("creating " + toString());
53 }
54
55 public void setEventCallback(EventCallback eventCallback, long targetSize)
56 {
57 logger.debug("setting callback: " + eventCallback + " in " + toString());
58 this.eventCallback = eventCallback;
59 this.targetSize = targetSize;
60 }
61
62 public String getSummary()
63 {
64 return summary;
65 }
66
67 public int getNumber()
68 {
69 return number;
70 }
71
72 public Object onCall(MuleEventContext context) throws Exception
73 {
74 InputStream in = (InputStream) context.getMessage().getPayload(InputStream.class);
75 try
76 {
77 logger.debug("arrived at " + toString());
78 byte[] startData = new byte[STREAM_SAMPLE_SIZE];
79 long startDataSize = 0;
80 byte[] endData = new byte[STREAM_SAMPLE_SIZE];
81 long endDataSize = 0;
82 long endRingPointer = 0;
83 long streamLength = 0;
84 byte[] buffer = new byte[STREAM_BUFFER_SIZE];
85
86
87 long bytesRead = 0;
88 while (bytesRead >= 0)
89 {
90 bytesRead = read(in, buffer);
91 if (bytesRead > 0)
92 {
93 if (logger.isDebugEnabled())
94 {
95 logger.debug("read " + bytesRead + " bytes");
96 }
97
98 streamLength += bytesRead;
99 long startOfEndBytes = 0;
100 for (long i = 0; startDataSize < STREAM_SAMPLE_SIZE && i < bytesRead; ++i)
101 {
102 startData[(int) startDataSize++] = buffer[(int) i];
103 ++startOfEndBytes;
104 }
105 startOfEndBytes = Math.max(startOfEndBytes, bytesRead - STREAM_SAMPLE_SIZE);
106 for (long i = startOfEndBytes; i < bytesRead; ++i)
107 {
108 ++endDataSize;
109 endData[(int) (endRingPointer++ % STREAM_SAMPLE_SIZE)] = buffer[(int) i];
110 }
111 if (streamLength >= targetSize)
112 {
113 doCallback(startData, startDataSize,
114 endData, endDataSize, endRingPointer,
115 streamLength, context);
116 }
117 }
118 }
119
120 in.close();
121 }
122 catch (Exception e)
123 {
124 in.close();
125
126 e.printStackTrace();
127 if (logger.isDebugEnabled())
128 {
129 logger.debug(e);
130 }
131 throw e;
132 }
133
134 return null;
135 }
136
137 protected int read(InputStream in, byte[] buffer) throws IOException
138 {
139 return in.read(buffer);
140 }
141
142 private void doCallback(byte[] startData, long startDataSize,
143 byte[] endData, long endDataSize, long endRingPointer,
144 long streamLength, MuleEventContext context) throws Exception
145 {
146
147 StringBuffer result = new StringBuffer("Received stream");
148 result.append("; length: ");
149 result.append(streamLength);
150 result.append("; '");
151
152 for (long i = 0; i < startDataSize; ++i)
153 {
154 result.append((char) startData[(int) i]);
155 }
156
157 long endSize = Math.min(endDataSize, STREAM_SAMPLE_SIZE);
158 if (endSize > 0)
159 {
160 result.append("...");
161 for (long i = 0; i < endSize; ++i)
162 {
163 result.append((char) endData[(int) ((endRingPointer + i) % STREAM_SAMPLE_SIZE)]);
164 }
165 }
166 result.append("'");
167
168 summary = result.toString();
169
170 String msg = StringMessageUtils.getBoilerPlate("Message Received in service: "
171 + context.getService().getName() + ". " + summary
172 + "\n callback: " + eventCallback,
173 '*', 80);
174
175 logger.info(msg);
176
177 if (eventCallback != null)
178 {
179 eventCallback.eventReceived(context, this);
180 }
181 }
182
183 public String toString()
184 {
185 return ClassUtils.getSimpleName(getClass()) + "/" + number;
186 }
187
188 }