View Javadoc
1   /**
2    * The contents of this file are subject to the Mozilla Public License Version 1.1
3    * (the "License"); you may not use this file except in compliance with the License.
4    * You may obtain a copy of the License at http://www.mozilla.org/MPL/
5    * Software distributed under the License is distributed on an "AS IS" basis,
6    * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
7    * specific language governing rights and limitations under the License.
8    *
9    * The Original Code is ""  Description:
10   * ""
11   *
12   * The Initial Developer of the Original Code is University Health Network. Copyright (C)
13   * 2001.  All Rights Reserved.
14   *
15   * Contributor(s): ______________________________________.
16   *
17   * Alternatively, the contents of this file may be used under the terms of the
18   * GNU General Public License (the  "GPL"), in which case the provisions of the GPL are
19   * applicable instead of those above.  If you wish to allow use of your version of this
20   * file only under the terms of the GPL and not to allow others to use your version
21   * of this file under the MPL, indicate your decision by deleting  the provisions above
22   * and replace  them with the notice and other provisions required by the GPL License.
23   * If you do not delete the provisions above, a recipient may use your version of
24   * this file under either the MPL or the GPL.
25   */
26  package ca.uhn.hl7v2.testpanel.util.llp;
27  
28  import java.io.ByteArrayOutputStream;
29  import java.io.IOException;
30  import java.io.InputStream;
31  import java.io.OutputStream;
32  
33  import org.slf4j.Logger;
34  import org.slf4j.LoggerFactory;
35  
36  import ca.uhn.hl7v2.llp.HL7Reader;
37  import ca.uhn.hl7v2.llp.HL7Writer;
38  import ca.uhn.hl7v2.llp.LLPException;
39  import ca.uhn.hl7v2.llp.LowerLayerProtocol;
40  
41  public class ByteCapturingMinLowerLayerProtocolWrapper extends LowerLayerProtocol {
42  
43  	private static final Logger ourLog = LoggerFactory.getLogger(ByteCapturingMinLowerLayerProtocolWrapper.class);
44  	
45  	private final LowerLayerProtocol myProtocolToWrap;
46  	private final ByteArrayOutputStream myReaderCapture;
47  	private final ByteArrayOutputStream myWriterCapture;
48  
49  	public ByteCapturingMinLowerLayerProtocolWrapper(LowerLayerProtocol theProtocolToWrap) {
50  		myProtocolToWrap = theProtocolToWrap;
51  		myReaderCapture = new ByteArrayOutputStream();
52  		myWriterCapture = new ByteArrayOutputStream();
53  	}
54  
55  	public ByteCapturingMinLowerLayerProtocolWrapper(LowerLayerProtocol theProtocolToWrap, ByteArrayOutputStream theReaderCapture, ByteArrayOutputStream theWriterCapture) {
56  		myProtocolToWrap = theProtocolToWrap;
57  		myReaderCapture = theReaderCapture;
58  		myWriterCapture = theWriterCapture;
59  	}
60  
61  	@Override
62  	public HL7Reader getReader(InputStream theIn) throws LLPException {
63  		theIn = new InputStreamWrapper(theIn);
64  		return myProtocolToWrap.getReader(theIn);
65  	}
66  
67  	@Override
68  	public HL7Writer getWriter(OutputStream theOut) throws LLPException {
69  		theOut = new OutputStreamWrapper(theOut);
70  		return myProtocolToWrap.getWriter(theOut);
71  	}
72  
73  	/**
74  	 * @return the readerCapture
75  	 */
76  	public byte[] getReadBytes() {
77  		synchronized (myReaderCapture) {
78  			byte[] retVal = myReaderCapture.toByteArray();
79  			myReaderCapture.reset();
80  			return retVal;
81  		}
82  	}
83  
84  	/**
85  	 * @return the readerCapture
86  	 */
87  	public byte[] getWriteBytes() {
88  		synchronized (myWriterCapture) {
89  			byte[] retVal = myWriterCapture.toByteArray();
90  			myWriterCapture.reset();
91  			return retVal;
92  		}
93  	}
94  
95  	private class InputStreamWrapper extends InputStream {
96  		private InputStream myWrap;
97  
98  		public InputStreamWrapper(InputStream theWrap) {
99  			myWrap = theWrap;
100 		}
101 
102 		@Override
103 		public int available() throws IOException {
104 			int available = myWrap.available();
105 			ourLog.trace("Available bytes: {}", available);
106 			return available;
107 		}
108 
109 		@Override
110 		public void close() throws IOException {
111 			ourLog.trace("Close");
112 			myWrap.close();
113 		}
114 
115 		@Override
116 		public int read() throws IOException {
117 			ourLog.trace("read()");
118 			
119 			int retVal = myWrap.read();
120 			if (retVal == 65533) {
121 				retVal = -1;
122 			}
123 			
124 			if (retVal >= 0) {
125 				synchronized (myReaderCapture) {
126 					myReaderCapture.write(retVal);
127 				}
128 			}
129 			
130 			ourLog.trace("read() returned {}", retVal);
131 			
132 			return retVal;
133 		}
134 
135 		@Override
136 		public long skip(long theN) throws IOException {
137 			ourLog.trace("skip {}", theN);
138 			return super.skip(theN);
139 		}
140 
141 		@Override
142 		public synchronized void mark(int theReadlimit) {
143 			ourLog.trace("mark {}", theReadlimit);
144 			myWrap.mark(theReadlimit);
145 		}
146 
147 		@Override
148 		public boolean markSupported() {
149 			ourLog.trace("markSupported");
150 			return myWrap.markSupported();
151 		}
152 
153 		@Override
154 		public int read(byte[] theB) throws IOException {
155 			return read(theB, 0, theB.length);
156 		}
157 
158 		@Override
159 		public int read(byte[] theB, int theOff, int theLen) throws IOException {
160 			ourLog.trace("ReadBAOL for offset {} and length {}", theOff, theLen);
161 		
162 			int read = 0;
163 			for (; read < Math.min(theLen, available()) || read == 0; read++) {
164 				theB[read + theOff] = (byte) read();
165 			}
166 			
167 			if (read == 1 && theB[theOff] == -1) {
168 				return -1;
169 			}
170 			
171 			ourLog.trace("ReadBAOL read {} bytes", read);
172 			return read;
173 		}
174 
175 		@Override
176 		public synchronized void reset() throws IOException {
177 			ourLog.trace("Reset");
178 			myWrap.reset();
179 		}
180 
181 	}
182 
183 	private class OutputStreamWrapper extends OutputStream {
184 		private OutputStream myWrap;
185 
186 		public OutputStreamWrapper(OutputStream theWrap) {
187 			myWrap = theWrap;
188 		}
189 
190 		@Override
191 		public void write(int theB) throws IOException {
192 			ourLog.trace("write() {}", theB);
193 			
194 			synchronized (myWriterCapture) {
195 				myWriterCapture.write(theB);
196 			}
197 			myWrap.write(theB);
198 		}
199 
200 		@Override
201 		public void flush() throws IOException {
202 			myWrap.flush();
203 		}
204 
205 		@Override
206 		public void close() throws IOException {
207 			myWrap.close();
208 		}
209 
210 	}
211 
212 }