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.pipe;
28 
29 import java.io.IOException;
30 
31 import java.util.StringTokenizer;
32 import java.util.Enumeration;
33 import java.util.Vector;
34 
35 import com.sun.star.lib.util.NativeLibraryLoader;
36 
37 import com.sun.star.io.XStreamListener;
38 
39 import com.sun.star.connection.XConnection;
40 import com.sun.star.connection.XConnectionBroadcaster;
41 
42 /**
43  * The PipeConnection implements the <code>XConnection</code> interface
44  * and is uses by the <code>PipeConnector</code> and the <code>PipeAcceptor</code>.
45  * This class is not part of the provided <code>api</code>.
46  * <p>
47  * @version 	$Revision: 1.7 $ $ $Date: 2008-04-11 11:13:00 $
48  * @author 	    Kay Ramme
49  * @see         com.sun.star.comp.connections.PipeAcceptor
50  * @see         com.sun.star.comp.connections.PipeConnector
51  * @see         com.sun.star.connections.XConnection
52  * @since       UDK1.0
53  */
54 public class PipeConnection implements XConnection, XConnectionBroadcaster {
55 	/**
56 	 * When set to true, enables various debugging output.
57 	 */
58 	static public final boolean DEBUG = false;
59 
60     static {
61 		// load shared library for JNI code
62         NativeLibraryLoader.loadLibrary(PipeConnection.class.getClassLoader(), "jpipe");
63     }
64 
65 	protected String	_aDescription;
66 	protected long		_nPipeHandle;
67 	protected Vector	_aListeners;
68 	protected boolean	_bFirstRead;
69 
70 	/**
71 	 * Constructs a new <code>PipeConnection</code>.
72 	 * <p>
73 	 * @param  description   the description of the connection
74 	 * @param  pipe        the pipe of the connection
75 	 */
76 	public PipeConnection(String description)
77 		throws IOException
78 	{
79 		if (DEBUG) System.err.println("##### " + getClass().getName() + " - instantiated " + description );
80 
81 		_aListeners = new Vector();
82 		_bFirstRead = true;
83 
84 		// get pipe name from pipe descriptor
85 		String aPipeName  ;
86 		StringTokenizer aTokenizer = new StringTokenizer( description, "," );
87 		if ( aTokenizer.hasMoreTokens() )
88 		{
89 			String aConnType = aTokenizer.nextToken();
90 			if ( !aConnType.equals( "pipe" ) )
91 				throw new RuntimeException( "invalid pipe descriptor: does not start with 'pipe,'" );
92 
93 			String aPipeNameParam = aTokenizer.nextToken();
94 			if ( !aPipeNameParam.substring( 0, 5 ).equals( "name=" ) )
95 				throw new RuntimeException( "invalid pipe descriptor: no 'name=' parameter found" );
96 			aPipeName = aPipeNameParam.substring( 5 );
97      		}
98 		else
99 			throw new RuntimeException( "invalid or empty pipe descriptor" );
100 
101 		// create the pipe
102 		try
103 		{ createJNI( aPipeName ); }
104 		catch ( java.lang.NullPointerException aNPE )
105 		{ throw new IOException( aNPE.getMessage() ); }
106 		catch ( com.sun.star.io.IOException aIOE )
107 		{ throw new IOException( aIOE.getMessage() ); }
108 		catch ( java.lang.Exception aE )
109 		{ throw new IOException( aE.getMessage() ); }
110 	}
111 
112 	public void addStreamListener(XStreamListener aListener ) throws com.sun.star.uno.RuntimeException {
113 		_aListeners.addElement(aListener);
114 	}
115 
116 	public void removeStreamListener(XStreamListener aListener ) throws com.sun.star.uno.RuntimeException {
117 		_aListeners.removeElement(aListener);
118 	}
119 
120 	private void notifyListeners_open() {
121 		Enumeration elements = _aListeners.elements();
122 		while(elements.hasMoreElements()) {
123 			XStreamListener xStreamListener = (XStreamListener)elements.nextElement();
124 			xStreamListener.started();
125 		}
126 	}
127 
128 	private void notifyListeners_close() {
129 		Enumeration elements = _aListeners.elements();
130 		while(elements.hasMoreElements()) {
131 			XStreamListener xStreamListener = (XStreamListener)elements.nextElement();
132 			xStreamListener.closed();
133 		}
134 	}
135 
136 	private void notifyListeners_error(com.sun.star.uno.Exception exception) {
137 		Enumeration elements = _aListeners.elements();
138 		while(elements.hasMoreElements()) {
139 			XStreamListener xStreamListener = (XStreamListener)elements.nextElement();
140 			xStreamListener.error(exception);
141 		}
142 	}
143 
144 	// JNI implementation to create the pipe
145 	private native int createJNI( String name )
146 		throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException;
147 
148 	// JNI implementation to read from the pipe
149 	private native int readJNI(/*OUT*/byte[][] bytes, int nBytesToRead)
150 		throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException;
151 
152 	// JNI implementation to write to the pipe
153 	private native void writeJNI(byte aData[])
154 		throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException;
155 
156 	// JNI implementation to flush the pipe
157 	private native void flushJNI()
158 		throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException;
159 
160 	// JNI implementation to close the pipe
161 	private native void closeJNI()
162 		throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException;
163 
164 	/**
165 	 * Read the required number of bytes.
166 	 * <p>
167 	 * @return   the number of bytes read
168 	 * @param    aReadBytes   the outparameter, where the bytes have to be placed
169 	 * @param    nBytesToRead the number of bytes to read
170 	 * @see       com.sun.star.connections.XConnection#read
171 	 */
172 	public int read(/*OUT*/byte[][] bytes, int nBytesToRead)
173 		throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException
174 	{
175 		if(_bFirstRead) {
176 			_bFirstRead = false;
177 
178 			notifyListeners_open();
179 		}
180 
181 		return readJNI( bytes, nBytesToRead );
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[])
191 		throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException
192 	{
193 		writeJNI( aData );
194 	}
195 
196 	/**
197 	 * Flushes the buffer.
198 	 * <p>
199 	 * @see       com.sun.star.connections.XConnection#flush
200 	 */
201 	public void flush()
202 		throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException
203 	{
204 		flushJNI();
205 	}
206 
207 	/**
208 	 * Closes the connection.
209 	 * <p>
210 	 * @see       com.sun.star.connections.XConnection#close
211 	 */
212 	public void close()
213 		throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException
214 	{
215 		if (DEBUG) System.out.print( "PipeConnection::close() " );
216 		closeJNI();
217 		notifyListeners_close();
218 		if (DEBUG) System.out.println( "done" );
219 	}
220 
221 	/**
222 	 * Gives a description of the connection.
223 	 * <p>
224 	 * @return  the description
225  	 * @see       com.sun.star.connections.XConnection#getDescription
226 	 */
227 	public String getDescription() throws com.sun.star.uno.RuntimeException {
228 		return _aDescription;
229 	}
230 
231 }
232 
233