| 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 | } |