1 | /**************************************************************** |
2 | ??*??Licensed??to??the??Apache??Software??Foundation??(ASF)??under??one??????* |
3 | ??*??or??more??contributor??license??agreements.????See??the??NOTICE??file??* |
4 | ??*??distributed??with??this??work??for??additional??information????????????????* |
5 | ??*??regarding??copyright??ownership.????The??ASF??licenses??this??file??????* |
6 | ??*??to??you??under??the??Apache??License,??Version??2.0??(the????????????????????????* |
7 | ??*??"License");??you??may??not??use??this??file??except??in??compliance??????* |
8 | ??*??with??the??License.????You??may??obtain??a??copy??of??the??License??at??????* |
9 | ??*????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????* |
10 | ??*??????http://www.apache.org/licenses/LICENSE-2.0??????????????????????????????????* |
11 | ??*????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????* |
12 | ??*??Unless??required??by??applicable??law??or??agreed??to??in??writing,??????* |
13 | ??*??software??distributed??under??the??License??is??distributed??on??an????* |
14 | ??*??"AS??IS"??BASIS,??WITHOUT??WARRANTIES??OR??CONDITIONS??OF??ANY??????????????* |
15 | ??*??KIND,??either??express??or??implied.????See??the??License??for??the????????* |
16 | ??*??specific??language??governing??permissions??and??limitations????????????* |
17 | ??*??under??the??License.??????????????????????????????????????????????????????????????????????????????????????* |
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 | ????????/**??Number??of??milliseconds??to??sleep??after??empty??read??*/ |
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 | ????????????????????????//??fake??shabang |
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 | //????????????May??have??partial??read |
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 | //????????????????????????????Reached??end??of??the??line |
94 | ????????????????????????????????result??=??false; |
95 | ????????????????????????}??else??if??(next??==??'\r')??{ |
96 | //????????????????????????????CRLF??line??endings??so??drop |
97 | ????????????????????????????????monitor.debug("[CR]"); |
98 | ????????????????????????????????result??=??true; |
99 | ????????????????????????}??else??{ |
100 | //????????????????????????????Load??buffer |
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 | //????????????????????????????No??response??yet |
110 | //????????????????????????????Wait??a??little??while |
111 | ????????????????????????????????Thread.sleep(SHORT_WAIT_FOR_INPUT); |
112 | ????????????????????????} |
113 | //????????????????????Reset??for??transfer??into??string??buffer |
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 | ??????????*??Constructs??a??<code>String</code>??with??all??attributes |
149 | ??????????*??in??name??=??value??format. |
150 | ??????????* |
151 | ??????????*??@return??a??<code>String</code>??representation?? |
152 | ??????????*??of??this??object. |
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 | } |