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