1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 package com.sun.star.lib.connections.socket; 28 29 30 import java.io.BufferedInputStream; 31 import java.io.BufferedOutputStream; 32 import java.io.InputStream; 33 import java.io.IOException; 34 import java.io.OutputStream; 35 36 import java.net.Socket; 37 38 import java.util.Enumeration; 39 import java.util.Vector; 40 41 42 import com.sun.star.io.XStreamListener; 43 44 import com.sun.star.connection.XConnection; 45 import com.sun.star.connection.XConnectionBroadcaster; 46 47 /** 48 * The SocketConnection implements the <code>XConnection</code> interface 49 * and is uses by the <code>SocketConnector</code> and the <code>SocketAcceptor</code>. 50 * This class is not part of the provided <code>api</code>. 51 * <p> 52 * @version $Revision: 1.6 $ $ $Date: 2008-04-11 11:14:31 $ 53 * @author Kay Ramme 54 * @see com.sun.star.comp.connections.SocketAcceptor 55 * @see com.sun.star.comp.connections.SocketConnector 56 * @see com.sun.star.connections.XConnection 57 * @since UDK1.0 58 */ 59 public class SocketConnection implements XConnection, XConnectionBroadcaster { 60 /** 61 * When set to true, enables various debugging output. 62 */ 63 static public final boolean DEBUG = false; 64 65 protected String _description; 66 protected Socket _socket; 67 protected InputStream _inputStream; 68 protected OutputStream _outputStream; 69 protected Vector _listeners; 70 protected boolean _firstRead; 71 72 /** 73 * Constructs a new <code>SocketConnection</code>. 74 * <p> 75 * @param description the description of the connection 76 * @param socket the socket of the connection 77 */ 78 public SocketConnection(String description, Socket socket) throws IOException { 79 if (DEBUG) System.err.println("##### " + getClass().getName() + " - instantiated " + description + " " + socket); 80 81 _description = description 82 + ",localHost=" + socket.getLocalAddress().getHostName() 83 + ",localPort=" + socket.getLocalPort() 84 + ",peerHost=" + socket.getInetAddress().getHostName() 85 + ",peerPort=" + socket.getPort(); 86 87 _socket = socket; 88 _inputStream = new BufferedInputStream(socket.getInputStream()); 89 _outputStream = new BufferedOutputStream(socket.getOutputStream()); 90 91 _listeners = new Vector(); 92 _firstRead = true; 93 } 94 95 96 97 98 public void addStreamListener(XStreamListener aListener ) throws com.sun.star.uno.RuntimeException { 99 _listeners.addElement(aListener); 100 } 101 102 public void removeStreamListener(XStreamListener aListener ) throws com.sun.star.uno.RuntimeException { 103 _listeners.removeElement(aListener); 104 } 105 106 private void notifyListeners_open() { 107 Enumeration elements = _listeners.elements(); 108 while(elements.hasMoreElements()) { 109 XStreamListener xStreamListener = (XStreamListener)elements.nextElement(); 110 xStreamListener.started(); 111 } 112 } 113 114 private void notifyListeners_close() { 115 Enumeration elements = _listeners.elements(); 116 while(elements.hasMoreElements()) { 117 XStreamListener xStreamListener = (XStreamListener)elements.nextElement(); 118 xStreamListener.closed(); 119 } 120 } 121 122 private void notifyListeners_error(com.sun.star.uno.Exception exception) { 123 Enumeration elements = _listeners.elements(); 124 while(elements.hasMoreElements()) { 125 XStreamListener xStreamListener = (XStreamListener)elements.nextElement(); 126 xStreamListener.error(exception); 127 } 128 } 129 130 131 /** 132 * Read the required number of bytes. 133 * <p> 134 * @return the number of bytes read 135 * @param aReadBytes the outparameter, where the bytes have to be placed 136 * @param nBytesToRead the number of bytes to read 137 * @see com.sun.star.connections.XConnection#read 138 */ 139 public int read(/*OUT*/byte[][] bytes, int nBytesToRead) throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException { 140 if(_firstRead) { 141 _firstRead = false; 142 143 notifyListeners_open(); 144 } 145 146 String errMessage = null; 147 148 int read_bytes = 0; 149 bytes[0] = new byte[nBytesToRead]; 150 151 try { 152 int count ; 153 154 do { 155 count = _inputStream.read(bytes[0], read_bytes, nBytesToRead - read_bytes); 156 if(count == -1) 157 errMessage = "EOF reached - " + getDescription(); 158 159 read_bytes += count; 160 } 161 while(read_bytes >= 0 && read_bytes < nBytesToRead && count >= 0); 162 } 163 catch(IOException ioException) { 164 if(DEBUG) { 165 System.err.println("##### " + getClass().getName() + ".read - exception occurred:" + ioException); 166 ioException.printStackTrace(); 167 } 168 169 errMessage = ioException.toString(); 170 } 171 172 if(errMessage != null) { 173 com.sun.star.io.IOException unoIOException = new com.sun.star.io.IOException(errMessage); 174 notifyListeners_error(unoIOException); 175 176 throw unoIOException; 177 } 178 179 if (DEBUG) System.err.println("##### " + getClass().getName() + " - read byte:" + read_bytes + " " + bytes[0]); 180 181 return read_bytes; 182 } 183 184 /** 185 * Write bytes. 186 * <p> 187 * @param aData the bytes to write 188 * @see com.sun.star.connections.XConnection#write 189 */ 190 public void write(byte aData[]) throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException { 191 try { 192 _outputStream.write(aData); 193 } 194 catch(IOException ioException) { 195 com.sun.star.io.IOException unoIOException = new com.sun.star.io.IOException(ioException.toString()); 196 notifyListeners_error(unoIOException); 197 198 throw unoIOException; 199 } 200 201 if (DEBUG) System.err.println("##### " + getClass().getName() + " - written bytes:" + aData + " " + aData.length); 202 } 203 204 /** 205 * Flushes the buffer. 206 * <p> 207 * @see com.sun.star.connections.XConnection#flush 208 */ 209 public void flush() throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException { 210 try { 211 _outputStream.flush(); 212 } 213 catch(IOException ioException) { 214 com.sun.star.io.IOException unoIOException = new com.sun.star.io.IOException(ioException.toString()); 215 notifyListeners_error(unoIOException); 216 217 throw unoIOException; 218 } 219 } 220 221 /** 222 * Closes the connection. 223 * <p> 224 * @see com.sun.star.connections.XConnection#close 225 */ 226 public void close() throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException { 227 try { 228 _socket.close(); 229 } 230 catch(IOException ioException) { 231 com.sun.star.io.IOException unoIOException = new com.sun.star.io.IOException(ioException.toString()); 232 notifyListeners_error(unoIOException); 233 234 throw unoIOException; 235 } 236 if (DEBUG) System.err.println("##### " + getClass().getName() + " - socket closed"); 237 238 notifyListeners_close(); 239 } 240 241 /** 242 * Gives a description of the connection. 243 * <p> 244 * @return the description 245 * @see com.sun.star.connections.XConnection#getDescription 246 */ 247 public String getDescription() throws com.sun.star.uno.RuntimeException { 248 return _description; 249 } 250 251 } 252 253