1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.james.mpt;
21
22 import java.nio.ByteBuffer;
23 import java.nio.channels.SocketChannel;
24 import java.nio.charset.Charset;
25
26 final class ExternalSession implements Session {
27
28
29 private static final int SHORT_WAIT_FOR_INPUT = 10;
30
31 private static final byte[] CRLF = { '\r', '\n' };
32
33 private final SocketChannel socket;
34
35 private final Monitor monitor;
36
37 private final ByteBuffer readBuffer;
38
39 private final Charset ascii;
40
41 private final ByteBuffer lineEndBuffer;
42
43 private boolean first = true;
44
45 private final String shabang;
46
47 public ExternalSession(final SocketChannel socket, final Monitor monitor, String shabang) {
48 this(socket, monitor, shabang, false);
49 }
50
51 public ExternalSession(final SocketChannel socket, final Monitor monitor, String shabang, boolean debug) {
52 super();
53 this.socket = socket;
54 this.monitor = monitor;
55 readBuffer = ByteBuffer.allocateDirect(2048);
56 ascii = Charset.forName("US-ASCII");
57 lineEndBuffer = ByteBuffer.wrap(CRLF);
58 this.shabang = shabang;
59 }
60
61 public String readLine() throws Exception {
62 StringBuffer buffer = new StringBuffer();
63 readlineInto(buffer);
64 final String result;
65 if (first && shabang != null) {
66
67 monitor.note("<-" + buffer.toString());
68 result = shabang;
69 first = false;
70 } else {
71 result = buffer.toString();
72 monitor.note("<-" + result);
73 }
74 return result;
75 }
76
77 private void readlineInto(StringBuffer buffer) throws Exception {
78 monitor.debug("[Reading line]");
79 readBuffer.flip();
80 while (oneFromLine(buffer))
81 ;
82
83 readBuffer.compact();
84 monitor.debug("[Done]");
85 }
86
87 private boolean oneFromLine(StringBuffer buffer) throws Exception {
88 final boolean result;
89 if (readBuffer.hasRemaining()) {
90 char next = (char) readBuffer.get();
91 if (next == '\n') {
92 monitor.debug("[LF]");
93
94 result = false;
95 } else if (next == '\r') {
96
97 monitor.debug("[CR]");
98 result = true;
99 } else {
100
101 monitor.debug(next);
102 buffer.append(next);
103 result = true;
104 }
105 } else {
106 monitor.debug("[Reading into buffer]");
107 readBuffer.clear();
108 while (socket.read(readBuffer) == 0) {
109
110
111 Thread.sleep(SHORT_WAIT_FOR_INPUT);
112 }
113
114 readBuffer.flip();
115 monitor.debug("[Done]");
116 result = true;
117 }
118 return result;
119 }
120
121 public void start() throws Exception {
122 while (!socket.finishConnect()) {
123 monitor.note("connecting...");
124 Thread.sleep(10);
125 }
126 }
127
128 public void stop() throws Exception {
129 monitor.note("closing");
130 socket.close();
131 }
132
133 public void writeLine(String line) throws Exception {
134 monitor.note("-> " + line);
135 monitor.debug("[Writing line]");
136 ByteBuffer writeBuffer = ascii.encode(line);
137 while (writeBuffer.hasRemaining()) {
138 socket.write(writeBuffer);
139 }
140 lineEndBuffer.rewind();
141 while (lineEndBuffer.hasRemaining()) {
142 socket.write(lineEndBuffer);
143 }
144 monitor.debug("[Done]");
145 }
146
147
148
149
150
151
152
153
154 public String toString()
155 {
156 final String TAB = " ";
157
158 String result = "External ( "
159 + "socket = " + this.socket + TAB
160 + "monitor = " + this.monitor + TAB
161 + "readBuffer = " + this.readBuffer + TAB
162 + "ascii = " + this.ascii + TAB
163 + "lineEndBuffer = " + this.lineEndBuffer + TAB
164 + "first = " + this.first + TAB
165 + "shabang = " + this.shabang + TAB
166 + " )";
167
168 return result;
169 }
170
171
172 }