001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.lib.collab.util;
043:
044: import java.io.IOException;
045: import java.io.OutputStream;
046: import java.io.InputStream;
047:
048: import java.net.Socket;
049: import java.net.SocketException;
050: import java.net.SocketAddress;
051: import java.net.InetAddress;
052: import java.net.SocketTimeoutException;
053: import javax.net.ssl.SSLSocket;
054: import javax.net.ssl.SSLSession;
055:
056: import java.nio.ByteBuffer;
057: import java.nio.channels.ByteChannel;
058: import java.nio.channels.SocketChannel;
059:
060: /**
061: *
062: *
063: * @author Vijayakumar Palaniappan
064: *
065: */
066: public class StreamChannelSocketAdaptor extends Socket {
067:
068: private Socket _channelSocket = null;
069: private Socket _wrapperSocket = null;
070: private boolean _sslSock = false;
071: private OutStream _outStream = new OutStream();
072: private InStream _inStream = new InStream();
073: private ByteChannel _byteChannel;
074:
075: /** Creates a new instance of StreamChannelSocketAdaptor */
076: public StreamChannelSocketAdaptor(Socket channelSocket) {
077: this (channelSocket, null);
078: }
079:
080: public StreamChannelSocketAdaptor(Socket channelSocket,
081: ByteChannel byteChannel) {
082: _channelSocket = channelSocket;
083: _byteChannel = byteChannel;
084: if (_byteChannel == null) {
085: _byteChannel = channelSocket.getChannel();
086: }
087: }
088:
089: //Init this only once.
090: public void initWrapperSocket(Socket sock) {
091: _wrapperSocket = sock;
092: //To avoid instanceof check each time.
093: _sslSock = _wrapperSocket instanceof SSLSocket;
094: }
095:
096: public OutputStream getOutputStream() throws IOException {
097: //System.out.println("Get the output stream");
098: return _outStream;
099: //return _channelSocket.getOutputStream();
100: }
101:
102: public InputStream getInputStream() throws IOException {
103: return _inStream;
104: //return _channelSocket.getInputStream();
105: }
106:
107: public void bind(SocketAddress socketaddress_1) throws IOException {
108: _channelSocket.bind(socketaddress_1);
109: }
110:
111: public synchronized void close() throws IOException {
112: _channelSocket.close();
113: }
114:
115: public void connect(SocketAddress socketaddress_1)
116: throws IOException {
117: _channelSocket.connect(socketaddress_1);
118: }
119:
120: public void connect(SocketAddress socketaddress_1, int int_1)
121: throws IOException {
122: _channelSocket.connect(socketaddress_1, int_1);
123: }
124:
125: public SocketChannel getChannel() {
126: return _channelSocket.getChannel();
127: }
128:
129: public InetAddress getInetAddress() {
130: return _channelSocket.getInetAddress();
131: }
132:
133: public boolean getKeepAlive() throws SocketException {
134: return _channelSocket.getKeepAlive();
135: }
136:
137: public InetAddress getLocalAddress() {
138: return _channelSocket.getLocalAddress();
139: }
140:
141: public int getLocalPort() {
142: return _channelSocket.getLocalPort();
143: }
144:
145: public SocketAddress getLocalSocketAddress() {
146: return _channelSocket.getLocalSocketAddress();
147: }
148:
149: public boolean getOOBInline() throws SocketException {
150: return _channelSocket.getOOBInline();
151: }
152:
153: public int getPort() {
154: return _channelSocket.getPort();
155: }
156:
157: public synchronized int getReceiveBufferSize()
158: throws SocketException {
159: return _channelSocket.getReceiveBufferSize();
160: }
161:
162: public SocketAddress getRemoteSocketAddress() {
163: return _channelSocket.getRemoteSocketAddress();
164: }
165:
166: public boolean getReuseAddress() throws SocketException {
167: return _channelSocket.getReuseAddress();
168: }
169:
170: public synchronized int getSendBufferSize() throws SocketException {
171: return _channelSocket.getSendBufferSize();
172: }
173:
174: public int getSoLinger() throws SocketException {
175: return _channelSocket.getSoLinger();
176: }
177:
178: public synchronized int getSoTimeout() throws SocketException {
179: return _channelSocket.getSoTimeout();
180: }
181:
182: public boolean getTcpNoDelay() throws SocketException {
183: return _channelSocket.getTcpNoDelay();
184: }
185:
186: public int getTrafficClass() throws SocketException {
187: return _channelSocket.getTrafficClass();
188: }
189:
190: public boolean isBound() {
191: return _channelSocket.isBound();
192: }
193:
194: public boolean isClosed() {
195: return _channelSocket.isClosed();
196: }
197:
198: public boolean isConnected() {
199: return _channelSocket.isConnected();
200: }
201:
202: public boolean isInputShutdown() {
203: return _channelSocket.isInputShutdown();
204: }
205:
206: public boolean isOutputShutdown() {
207: return _channelSocket.isOutputShutdown();
208: }
209:
210: public void sendUrgentData(int int_1) throws IOException {
211: _channelSocket.sendUrgentData(int_1);
212: }
213:
214: public void setKeepAlive(boolean boolean_1) throws SocketException {
215: _channelSocket.setKeepAlive(boolean_1);
216: }
217:
218: public void setOOBInline(boolean boolean_1) throws SocketException {
219: _channelSocket.setOOBInline(boolean_1);
220: }
221:
222: public synchronized void setReceiveBufferSize(int int_1)
223: throws SocketException {
224: _channelSocket.setReceiveBufferSize(int_1);
225: }
226:
227: public void setReuseAddress(boolean boolean_1)
228: throws SocketException {
229: _channelSocket.setReuseAddress(boolean_1);
230: }
231:
232: public synchronized void setSendBufferSize(int int_1)
233: throws SocketException {
234: _channelSocket.setSendBufferSize(int_1);
235: }
236:
237: public void setSoLinger(boolean boolean_1, int int_1)
238: throws SocketException {
239: _channelSocket.setSoLinger(boolean_1, int_1);
240: }
241:
242: public synchronized void setSoTimeout(int int_1)
243: throws SocketException {
244: //System.out.println("Setting timeout " + int_1);
245: _channelSocket.setSoTimeout(int_1);
246: }
247:
248: public void setTcpNoDelay(boolean boolean_1) throws SocketException {
249: _channelSocket.setTcpNoDelay(boolean_1);
250: }
251:
252: public void setTrafficClass(int int_1) throws SocketException {
253: _channelSocket.setTrafficClass(int_1);
254: }
255:
256: public void shutdownInput() throws IOException {
257: _channelSocket.shutdownInput();
258: }
259:
260: public void shutdownOutput() throws IOException {
261: _channelSocket.shutdownOutput();
262: }
263:
264: private class OutStream extends OutputStream {
265: public void write(int b) throws IOException {
266: write(new byte[] { (byte) b }, 0, 1);
267: }
268:
269: public void write(byte[] b, int off, int len)
270: throws IOException {
271: //System.out.println("Wrirting... " + len);
272: int written = 0;
273: if (len != 0) {
274: ByteBuffer byteBuffer = ByteBuffer.wrap(b, off, len);
275: int waitTime = 10;
276: int lastCount = 0;
277: boolean done = false;
278: while (!done) {
279: int size = _byteChannel.write(byteBuffer);
280:
281: if (size < 0) {
282: throw new IOException(
283: "error writing to socket : " + size);
284: }
285:
286: written += size;
287:
288: if (written >= len) {
289: break;
290: }
291: //non blocking channels
292: //try after sometime
293: if (lastCount != written) {
294: waitTime = 10;
295: }
296:
297: lastCount = written;
298:
299: try {
300: Thread.sleep(waitTime);
301: // keep increasing wait time in order to release some cpu
302: waitTime += waitTime;
303: } catch (Exception e) {
304: }
305: }
306: }
307: }
308:
309: public void close() throws IOException {
310: //_channelSocket.getChannel().close();
311: _byteChannel.close();
312: }
313: }
314:
315: private class InStream extends InputStream {
316: public int read() throws IOException {
317: return read(new byte[1], 0, 1);
318: }
319:
320: public void close() throws IOException {
321: //_channelSocket.getChannel().close();
322: _byteChannel.close();
323: }
324:
325: public int read(byte[] data, int offset, int len)
326: throws IOException {
327: //System.out.println("read(byte,i1,i2) " + offset + " " + len);
328: int read = _byteChannel.read(ByteBuffer.wrap(data, offset,
329: len));
330: boolean handle_bug_4836493 = false;
331: if (_sslSock) {
332: //This is to avoid a problem in jsse Bug - 4836493
333: //If SSL Layer is trying to read, then block
334: SSLSession session = ((SSLSocket) _wrapperSocket)
335: .getSession();
336: handle_bug_4836493 = session
337: .getValue("BUG_4836493_READ") != Boolean.TRUE;
338: session.removeValue("BUG_4836493_READ");
339: }
340: if (read == 0) {
341: if (handle_bug_4836493) {
342: while (read == 0) {
343: try {
344: Thread.sleep(_channelSocket.getSoTimeout());
345: } catch (InterruptedException e) {
346: }
347: read = _channelSocket.getChannel().read(
348: ByteBuffer.wrap(data, offset, len));
349: }
350: } else {
351: if (_channelSocket.getSoTimeout() != 0) {
352: throw new SocketTimeoutException();
353: }
354: }
355: }
356: return read;
357: }
358: }
359: }
|