| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| package com.sun.star.lib.connections.socket; |
| |
| |
| import java.io.BufferedInputStream; |
| import java.io.BufferedOutputStream; |
| import java.io.InputStream; |
| import java.io.IOException; |
| import java.io.OutputStream; |
| |
| import java.net.Socket; |
| |
| import java.util.Enumeration; |
| import java.util.Vector; |
| |
| |
| import com.sun.star.io.XStreamListener; |
| |
| import com.sun.star.connection.XConnection; |
| import com.sun.star.connection.XConnectionBroadcaster; |
| |
| /** |
| * The SocketConnection implements the <code>XConnection</code> interface |
| * and is uses by the <code>SocketConnector</code> and the <code>SocketAcceptor</code>. |
| * This class is not part of the provided <code>api</code>. |
| * <p> |
| * @version $Revision: 1.6 $ $ $Date: 2008-04-11 11:14:31 $ |
| * @author Kay Ramme |
| * @see com.sun.star.comp.connections.SocketAcceptor |
| * @see com.sun.star.comp.connections.SocketConnector |
| * @see com.sun.star.connections.XConnection |
| * @since UDK1.0 |
| */ |
| public class SocketConnection implements XConnection, XConnectionBroadcaster { |
| /** |
| * When set to true, enables various debugging output. |
| */ |
| static public final boolean DEBUG = false; |
| |
| protected String _description; |
| protected Socket _socket; |
| protected InputStream _inputStream; |
| protected OutputStream _outputStream; |
| protected Vector _listeners; |
| protected boolean _firstRead; |
| |
| /** |
| * Constructs a new <code>SocketConnection</code>. |
| * <p> |
| * @param description the description of the connection |
| * @param socket the socket of the connection |
| */ |
| public SocketConnection(String description, Socket socket) throws IOException { |
| if (DEBUG) System.err.println("##### " + getClass().getName() + " - instantiated " + description + " " + socket); |
| |
| _description = description |
| + ",localHost=" + socket.getLocalAddress().getHostName() |
| + ",localPort=" + socket.getLocalPort() |
| + ",peerHost=" + socket.getInetAddress().getHostName() |
| + ",peerPort=" + socket.getPort(); |
| |
| _socket = socket; |
| _inputStream = new BufferedInputStream(socket.getInputStream()); |
| _outputStream = new BufferedOutputStream(socket.getOutputStream()); |
| |
| _listeners = new Vector(); |
| _firstRead = true; |
| } |
| |
| |
| |
| |
| public void addStreamListener(XStreamListener aListener ) throws com.sun.star.uno.RuntimeException { |
| _listeners.addElement(aListener); |
| } |
| |
| public void removeStreamListener(XStreamListener aListener ) throws com.sun.star.uno.RuntimeException { |
| _listeners.removeElement(aListener); |
| } |
| |
| private void notifyListeners_open() { |
| Enumeration elements = _listeners.elements(); |
| while(elements.hasMoreElements()) { |
| XStreamListener xStreamListener = (XStreamListener)elements.nextElement(); |
| xStreamListener.started(); |
| } |
| } |
| |
| private void notifyListeners_close() { |
| Enumeration elements = _listeners.elements(); |
| while(elements.hasMoreElements()) { |
| XStreamListener xStreamListener = (XStreamListener)elements.nextElement(); |
| xStreamListener.closed(); |
| } |
| } |
| |
| private void notifyListeners_error(com.sun.star.uno.Exception exception) { |
| Enumeration elements = _listeners.elements(); |
| while(elements.hasMoreElements()) { |
| XStreamListener xStreamListener = (XStreamListener)elements.nextElement(); |
| xStreamListener.error(exception); |
| } |
| } |
| |
| |
| /** |
| * Read the required number of bytes. |
| * <p> |
| * @return the number of bytes read |
| * @param aReadBytes the outparameter, where the bytes have to be placed |
| * @param nBytesToRead the number of bytes to read |
| * @see com.sun.star.connections.XConnection#read |
| */ |
| public int read(/*OUT*/byte[][] bytes, int nBytesToRead) throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException { |
| if(_firstRead) { |
| _firstRead = false; |
| |
| notifyListeners_open(); |
| } |
| |
| String errMessage = null; |
| |
| int read_bytes = 0; |
| bytes[0] = new byte[nBytesToRead]; |
| |
| try { |
| int count ; |
| |
| do { |
| count = _inputStream.read(bytes[0], read_bytes, nBytesToRead - read_bytes); |
| if(count == -1) |
| errMessage = "EOF reached - " + getDescription(); |
| |
| read_bytes += count; |
| } |
| while(read_bytes >= 0 && read_bytes < nBytesToRead && count >= 0); |
| } |
| catch(IOException ioException) { |
| if(DEBUG) { |
| System.err.println("##### " + getClass().getName() + ".read - exception occurred:" + ioException); |
| ioException.printStackTrace(); |
| } |
| |
| errMessage = ioException.toString(); |
| } |
| |
| if(errMessage != null) { |
| com.sun.star.io.IOException unoIOException = new com.sun.star.io.IOException(errMessage); |
| notifyListeners_error(unoIOException); |
| |
| throw unoIOException; |
| } |
| |
| if (DEBUG) System.err.println("##### " + getClass().getName() + " - read byte:" + read_bytes + " " + bytes[0]); |
| |
| return read_bytes; |
| } |
| |
| /** |
| * Write bytes. |
| * <p> |
| * @param aData the bytes to write |
| * @see com.sun.star.connections.XConnection#write |
| */ |
| public void write(byte aData[]) throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException { |
| try { |
| _outputStream.write(aData); |
| } |
| catch(IOException ioException) { |
| com.sun.star.io.IOException unoIOException = new com.sun.star.io.IOException(ioException.toString()); |
| notifyListeners_error(unoIOException); |
| |
| throw unoIOException; |
| } |
| |
| if (DEBUG) System.err.println("##### " + getClass().getName() + " - written bytes:" + aData + " " + aData.length); |
| } |
| |
| /** |
| * Flushes the buffer. |
| * <p> |
| * @see com.sun.star.connections.XConnection#flush |
| */ |
| public void flush() throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException { |
| try { |
| _outputStream.flush(); |
| } |
| catch(IOException ioException) { |
| com.sun.star.io.IOException unoIOException = new com.sun.star.io.IOException(ioException.toString()); |
| notifyListeners_error(unoIOException); |
| |
| throw unoIOException; |
| } |
| } |
| |
| /** |
| * Closes the connection. |
| * <p> |
| * @see com.sun.star.connections.XConnection#close |
| */ |
| public void close() throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException { |
| try { |
| _socket.close(); |
| } |
| catch(IOException ioException) { |
| com.sun.star.io.IOException unoIOException = new com.sun.star.io.IOException(ioException.toString()); |
| notifyListeners_error(unoIOException); |
| |
| throw unoIOException; |
| } |
| if (DEBUG) System.err.println("##### " + getClass().getName() + " - socket closed"); |
| |
| notifyListeners_close(); |
| } |
| |
| /** |
| * Gives a description of the connection. |
| * <p> |
| * @return the description |
| * @see com.sun.star.connections.XConnection#getDescription |
| */ |
| public String getDescription() throws com.sun.star.uno.RuntimeException { |
| return _description; |
| } |
| |
| } |
| |