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