xref: /AOO41X/main/bean/com/sun/star/comp/beans/LocalOfficeConnection.java (revision d4cc1e8c350bb591a80bbabe126ff6af34c125a2)
1*d4cc1e8cSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*d4cc1e8cSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*d4cc1e8cSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*d4cc1e8cSAndrew Rist  * distributed with this work for additional information
6*d4cc1e8cSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*d4cc1e8cSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*d4cc1e8cSAndrew Rist  * "License"); you may not use this file except in compliance
9*d4cc1e8cSAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*d4cc1e8cSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*d4cc1e8cSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*d4cc1e8cSAndrew Rist  * software distributed under the License is distributed on an
15*d4cc1e8cSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*d4cc1e8cSAndrew Rist  * KIND, either express or implied.  See the License for the
17*d4cc1e8cSAndrew Rist  * specific language governing permissions and limitations
18*d4cc1e8cSAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*d4cc1e8cSAndrew Rist  *************************************************************/
21*d4cc1e8cSAndrew Rist 
22*d4cc1e8cSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir package com.sun.star.comp.beans;
25cdf0e10cSrcweir 
26cdf0e10cSrcweir import java.awt.Container;
27cdf0e10cSrcweir import java.io.File;
28cdf0e10cSrcweir import java.util.Iterator;
29cdf0e10cSrcweir import java.util.List;
30cdf0e10cSrcweir import java.util.Vector;
31cdf0e10cSrcweir 
32cdf0e10cSrcweir import com.sun.star.lang.XMultiComponentFactory;
33cdf0e10cSrcweir import com.sun.star.lang.XComponent;
34cdf0e10cSrcweir import com.sun.star.lang.XEventListener;
35cdf0e10cSrcweir import com.sun.star.connection.XConnection;
36cdf0e10cSrcweir import com.sun.star.connection.XConnector;
37cdf0e10cSrcweir import com.sun.star.bridge.XBridge;
38cdf0e10cSrcweir import com.sun.star.bridge.XBridgeFactory;
39cdf0e10cSrcweir import com.sun.star.beans.XPropertySet;
40cdf0e10cSrcweir import com.sun.star.uno.XComponentContext;
41cdf0e10cSrcweir import com.sun.star.uno.UnoRuntime;
42cdf0e10cSrcweir import com.sun.star.uno.Exception;
43cdf0e10cSrcweir import com.sun.star.lib.uno.helper.UnoUrl;
44cdf0e10cSrcweir import com.sun.star.lib.util.NativeLibraryLoader;
45cdf0e10cSrcweir 
46cdf0e10cSrcweir /**
47cdf0e10cSrcweir  * This class reprecents a connection to the local office application.
48cdf0e10cSrcweir  *
49cdf0e10cSrcweir  * @since OOo 2.0.0
50cdf0e10cSrcweir  */
51cdf0e10cSrcweir public class LocalOfficeConnection
52cdf0e10cSrcweir     implements OfficeConnection
53cdf0e10cSrcweir {
54cdf0e10cSrcweir     public static final String      OFFICE_APP_NAME     = "soffice";
55cdf0e10cSrcweir     public static final String      OFFICE_LIB_NAME     = "officebean";
56cdf0e10cSrcweir     public static final String      OFFICE_ID_SUFFIX    = "_Office";
57cdf0e10cSrcweir 
58cdf0e10cSrcweir     private static String           mProgramPath;
59cdf0e10cSrcweir 
60cdf0e10cSrcweir     private Process             mProcess;
61cdf0e10cSrcweir     private ContainerFactory        mContainerFactory;
62cdf0e10cSrcweir     private XComponentContext       mContext;
63cdf0e10cSrcweir     private XBridge mBridge;
64cdf0e10cSrcweir 
65cdf0e10cSrcweir     private String              mURL;
66cdf0e10cSrcweir     private String              mConnType;
67cdf0e10cSrcweir     private String              mPipe;
68cdf0e10cSrcweir     private String              mPort;
69cdf0e10cSrcweir     private String              mProtocol;
70cdf0e10cSrcweir     private String              mInitialObject;
71cdf0e10cSrcweir 
72cdf0e10cSrcweir     private List                mComponents     = new Vector();
73cdf0e10cSrcweir 
74cdf0e10cSrcweir     private static long m_nBridgeCounter = 0;
75cdf0e10cSrcweir     //-------------------------------------------------------------------------
76cdf0e10cSrcweir     static
77cdf0e10cSrcweir     {
78cdf0e10cSrcweir         // preload shared libraries whichs import lips are linked to officebean
79cdf0e10cSrcweir         if ( System.getProperty( "os.name" ).startsWith( "Windows" ) )
80cdf0e10cSrcweir         {
81cdf0e10cSrcweir             try
82cdf0e10cSrcweir             {
LocalOfficeConnection.class.getClassLoader()83cdf0e10cSrcweir                 NativeLibraryLoader.loadLibrary(LocalOfficeConnection.class.getClassLoader(), "msvcr70");
84cdf0e10cSrcweir             }
85cdf0e10cSrcweir             catch (Throwable e)
86cdf0e10cSrcweir             {
87cdf0e10cSrcweir                 // loading twice would fail
88cdf0e10cSrcweir                 System.err.println( "cannot find msvcr70" );
89cdf0e10cSrcweir             }
90cdf0e10cSrcweir 
91cdf0e10cSrcweir             try
92cdf0e10cSrcweir             {
LocalOfficeConnection.class.getClassLoader()93cdf0e10cSrcweir                 NativeLibraryLoader.loadLibrary(LocalOfficeConnection.class.getClassLoader(), "msvcr71");
94cdf0e10cSrcweir             }
95cdf0e10cSrcweir             catch (Throwable e)
96cdf0e10cSrcweir             {
97cdf0e10cSrcweir                 // loading twice would fail
98cdf0e10cSrcweir                 System.err.println( "cannot find msvcr71" );
99cdf0e10cSrcweir             }
100cdf0e10cSrcweir 
101cdf0e10cSrcweir             try
102cdf0e10cSrcweir             {
LocalOfficeConnection.class.getClassLoader()103cdf0e10cSrcweir                 NativeLibraryLoader.loadLibrary(LocalOfficeConnection.class.getClassLoader(), "uwinapi");
104cdf0e10cSrcweir             }
105cdf0e10cSrcweir             catch (Throwable e)
106cdf0e10cSrcweir             {
107cdf0e10cSrcweir                 // loading twice would fail
108cdf0e10cSrcweir                 System.err.println( "cannot find uwinapi" );
109cdf0e10cSrcweir             }
110cdf0e10cSrcweir 
111cdf0e10cSrcweir             try
112cdf0e10cSrcweir             {
LocalOfficeConnection.class.getClassLoader()113cdf0e10cSrcweir                 NativeLibraryLoader.loadLibrary(LocalOfficeConnection.class.getClassLoader(), "jawt");
114cdf0e10cSrcweir             }
115cdf0e10cSrcweir             catch (Throwable e)
116cdf0e10cSrcweir             {
117cdf0e10cSrcweir                 // loading twice would fail
118cdf0e10cSrcweir                 System.err.println( "cannot find jawt" );
119cdf0e10cSrcweir             }
120cdf0e10cSrcweir         }
121cdf0e10cSrcweir 
122cdf0e10cSrcweir         // load shared library for JNI code
LocalOfficeConnection.class.getClassLoader()123cdf0e10cSrcweir         NativeLibraryLoader.loadLibrary( LocalOfficeConnection.class.getClassLoader(), "officebean" );
124cdf0e10cSrcweir     }
125cdf0e10cSrcweir 
126cdf0e10cSrcweir     //-------------------------------------------------------------------------
127cdf0e10cSrcweir     // debugging method
dbgPrint( String aMessage )128cdf0e10cSrcweir     private void dbgPrint( String aMessage )
129cdf0e10cSrcweir     {
130cdf0e10cSrcweir         System.err.println( aMessage );
131cdf0e10cSrcweir     }
132cdf0e10cSrcweir 
133cdf0e10cSrcweir     /**
134cdf0e10cSrcweir      * Constructor.
135cdf0e10cSrcweir      * Sets up paths to the office application and native libraries if
136cdf0e10cSrcweir      * values are available in <code>OFFICE_PROP_FILE</code> in the user
137cdf0e10cSrcweir      * home directory.<br />
138cdf0e10cSrcweir      * "com.sun.star.beans.path" - the office application directory;<br/>
139cdf0e10cSrcweir      * "com.sun.star.beans.libpath" - native libraries directory.
140cdf0e10cSrcweir      */
LocalOfficeConnection()141cdf0e10cSrcweir     public LocalOfficeConnection()
142cdf0e10cSrcweir     {
143cdf0e10cSrcweir         // init member vars
144cdf0e10cSrcweir         try
145cdf0e10cSrcweir         {
146cdf0e10cSrcweir             setUnoUrl( "uno:pipe,name=" + getPipeName() + ";urp;StarOffice.ServiceManager" );
147cdf0e10cSrcweir         }
148cdf0e10cSrcweir         catch ( java.net.MalformedURLException e )
149cdf0e10cSrcweir         {}
150cdf0e10cSrcweir     }
151cdf0e10cSrcweir 
152cdf0e10cSrcweir         /**
153cdf0e10cSrcweir          * protected Constructor
154cdf0e10cSrcweir          * Initialise a LocalOfficeConnection with an already running office.
155cdf0e10cSrcweir          * This C'Tor is only used in complex tests at the moment.
156cdf0e10cSrcweir          * @param xContext
157cdf0e10cSrcweir          */
LocalOfficeConnection(com.sun.star.uno.XComponentContext xContext)158cdf0e10cSrcweir         protected LocalOfficeConnection(com.sun.star.uno.XComponentContext xContext)
159cdf0e10cSrcweir         {
160cdf0e10cSrcweir             this.mContext = xContext;
161cdf0e10cSrcweir         }
162cdf0e10cSrcweir 
163cdf0e10cSrcweir         /**
164cdf0e10cSrcweir      * Sets a connection URL.
165cdf0e10cSrcweir      * This implementation accepts a UNO URL with following format:<br />
166cdf0e10cSrcweir      * <pre>
167cdf0e10cSrcweir      * url    := uno:localoffice[,&lt;params&gt;];urp;StarOffice.ServiceManager
168cdf0e10cSrcweir      * params := &lt;path&gt;[,&lt;pipe&gt;]
169cdf0e10cSrcweir      * path   := path=&lt;pathv&gt;
170cdf0e10cSrcweir      * pipe   := pipe=&lt;pipev&gt;
171cdf0e10cSrcweir      * pathv  := platform_specific_path_to_the_local_office_distribution
172cdf0e10cSrcweir      * pipev  := local_office_connection_pipe_name
173cdf0e10cSrcweir      * </pre>
174cdf0e10cSrcweir      *
175cdf0e10cSrcweir      * @param url This is UNO URL which discribes the type of a connection.
176cdf0e10cSrcweir      */
setUnoUrl(String url)177cdf0e10cSrcweir     public void setUnoUrl(String url)
178cdf0e10cSrcweir         throws java.net.MalformedURLException
179cdf0e10cSrcweir     {
180cdf0e10cSrcweir         mURL    = null;
181cdf0e10cSrcweir 
182cdf0e10cSrcweir         String prefix = "uno:localoffice";
183cdf0e10cSrcweir         if ( url.startsWith(prefix) )
184cdf0e10cSrcweir             parseUnoUrlWithOfficePath( url, prefix );
185cdf0e10cSrcweir         else
186cdf0e10cSrcweir         {
187cdf0e10cSrcweir             try
188cdf0e10cSrcweir             {
189cdf0e10cSrcweir                 UnoUrl aURL = UnoUrl.parseUnoUrl( url );
190cdf0e10cSrcweir                 mProgramPath = null;
191cdf0e10cSrcweir                 mConnType = aURL.getConnection();
192cdf0e10cSrcweir                 mPipe = (String) aURL.getConnectionParameters().get( "pipe" );
193cdf0e10cSrcweir                 mPort = (String) aURL.getConnectionParameters().get( "port" );
194cdf0e10cSrcweir                 mProtocol = aURL.getProtocol();
195cdf0e10cSrcweir                 mInitialObject = aURL.getRootOid();
196cdf0e10cSrcweir             }
197cdf0e10cSrcweir             catch ( com.sun.star.lang.IllegalArgumentException eIll )
198cdf0e10cSrcweir             {
199cdf0e10cSrcweir                 throw new java.net.MalformedURLException(
200cdf0e10cSrcweir                     "Invalid UNO connection URL.");
201cdf0e10cSrcweir             }
202cdf0e10cSrcweir         }
203cdf0e10cSrcweir         mURL    = url;
204cdf0e10cSrcweir     }
205cdf0e10cSrcweir 
206cdf0e10cSrcweir     /**
207cdf0e10cSrcweir      * Sets an AWT container catory.
208cdf0e10cSrcweir      *
209cdf0e10cSrcweir      * @param containerFactory This is a application provided AWT container
210cdf0e10cSrcweir      *  factory.
211cdf0e10cSrcweir      */
setContainerFactory(ContainerFactory containerFactory)212cdf0e10cSrcweir     public void setContainerFactory(ContainerFactory containerFactory)
213cdf0e10cSrcweir     {
214cdf0e10cSrcweir         mContainerFactory   = containerFactory;
215cdf0e10cSrcweir     }
216cdf0e10cSrcweir 
217cdf0e10cSrcweir     /**
218cdf0e10cSrcweir      * Retrives the UNO component context.
219cdf0e10cSrcweir      * Establishes a connection if necessary and initialises the
220cdf0e10cSrcweir      * UNO service manager if it has not already been initialised.
221cdf0e10cSrcweir      * This method can return <code>null</code> if it fails to connect
222cdf0e10cSrcweir      * to the office application.
223cdf0e10cSrcweir      *
224cdf0e10cSrcweir      * @return The office UNO component context.
225cdf0e10cSrcweir      */
getComponentContext()226cdf0e10cSrcweir     synchronized public XComponentContext getComponentContext()
227cdf0e10cSrcweir     {
228cdf0e10cSrcweir         if ( mContext == null )
229cdf0e10cSrcweir             mContext = connect();
230cdf0e10cSrcweir         return mContext;
231cdf0e10cSrcweir     }
232cdf0e10cSrcweir 
233cdf0e10cSrcweir     /**
234cdf0e10cSrcweir      * Creates an office window.
235cdf0e10cSrcweir      * The window is either a sub-class of java.awt.Canvas (local) or
236cdf0e10cSrcweir      * java.awt.Container (RVP).
237cdf0e10cSrcweir      *
238cdf0e10cSrcweir      * @param container This is an AWT container.
239cdf0e10cSrcweir      * @return The office window instance.
240cdf0e10cSrcweir      */
createOfficeWindow(Container container)241cdf0e10cSrcweir     public OfficeWindow createOfficeWindow(Container container)
242cdf0e10cSrcweir     {
243cdf0e10cSrcweir         return new LocalOfficeWindow(this);
244cdf0e10cSrcweir     }
245cdf0e10cSrcweir 
246cdf0e10cSrcweir     /**
247cdf0e10cSrcweir      * Closes the connection.
248cdf0e10cSrcweir      */
dispose()249cdf0e10cSrcweir     public void dispose()
250cdf0e10cSrcweir     {
251cdf0e10cSrcweir         Iterator itr = mComponents.iterator();
252cdf0e10cSrcweir         while (itr.hasNext() == true) {
253cdf0e10cSrcweir             // ignore runtime exceptions in dispose
254cdf0e10cSrcweir             try { ((XEventListener)itr.next()).disposing(null); }
255cdf0e10cSrcweir             catch ( RuntimeException aExc ) {}
256cdf0e10cSrcweir         }
257cdf0e10cSrcweir         mComponents.clear();
258cdf0e10cSrcweir 
259cdf0e10cSrcweir         //Terminate the bridge. It turned out that this is necessary for the bean
260cdf0e10cSrcweir         //to work properly when displayed in an applet within Internet Explorer.
261cdf0e10cSrcweir         //When navigating off the page which is showing  the applet and then going
262cdf0e10cSrcweir         //back to it, then the Java remote bridge is damaged. That is the Java threads
263cdf0e10cSrcweir         //do not work properly anymore. Therefore when Applet.stop is called the connection
264cdf0e10cSrcweir         //to the office including the bridge needs to be terminated.
265cdf0e10cSrcweir         if (mBridge != null)
266cdf0e10cSrcweir         {
267cdf0e10cSrcweir             XComponent comp = (XComponent)UnoRuntime.queryInterface(
268cdf0e10cSrcweir                     XComponent.class, mBridge);
269cdf0e10cSrcweir             if (comp != null)
270cdf0e10cSrcweir                comp.dispose();
271cdf0e10cSrcweir             else
272cdf0e10cSrcweir                 System.err.println("LocalOfficeConnection: could not dispose bridge!");
273cdf0e10cSrcweir 
274cdf0e10cSrcweir             mBridge = null;
275cdf0e10cSrcweir         }
276cdf0e10cSrcweir 
277cdf0e10cSrcweir         mContainerFactory = null;
278cdf0e10cSrcweir         mContext = null;
279cdf0e10cSrcweir     }
280cdf0e10cSrcweir 
281cdf0e10cSrcweir     /**
282cdf0e10cSrcweir      * Adds an event listener to the object.
283cdf0e10cSrcweir      *
284cdf0e10cSrcweir      * @param listener is a listener object.
285cdf0e10cSrcweir      */
addEventListener(XEventListener listener)286cdf0e10cSrcweir     public void addEventListener(XEventListener listener)
287cdf0e10cSrcweir     {
288cdf0e10cSrcweir         mComponents.add(listener);
289cdf0e10cSrcweir     }
290cdf0e10cSrcweir 
291cdf0e10cSrcweir     /**
292cdf0e10cSrcweir      * Removes an event listener from the listener list.
293cdf0e10cSrcweir      *
294cdf0e10cSrcweir      * @param listener is a listener object.
295cdf0e10cSrcweir      */
removeEventListener(XEventListener listener)296cdf0e10cSrcweir     public void removeEventListener(XEventListener listener)
297cdf0e10cSrcweir     {
298cdf0e10cSrcweir         mComponents.remove(listener);
299cdf0e10cSrcweir     }
300cdf0e10cSrcweir 
301cdf0e10cSrcweir     /**
302cdf0e10cSrcweir      * Establishes the connection to the office.
303cdf0e10cSrcweir      */
connect()304cdf0e10cSrcweir     private XComponentContext connect()
305cdf0e10cSrcweir     {
306cdf0e10cSrcweir         try
307cdf0e10cSrcweir         {
308cdf0e10cSrcweir             // create default local component context
309cdf0e10cSrcweir             XComponentContext xLocalContext =
310cdf0e10cSrcweir                 com.sun.star.comp.helper.Bootstrap.createInitialComponentContext(null);
311cdf0e10cSrcweir 
312cdf0e10cSrcweir             // initial serviceManager
313cdf0e10cSrcweir             XMultiComponentFactory xLocalServiceManager = xLocalContext.getServiceManager();
314cdf0e10cSrcweir 
315cdf0e10cSrcweir             // try to connect to soffice
316cdf0e10cSrcweir             Object aInitialObject = null;
317cdf0e10cSrcweir             try
318cdf0e10cSrcweir             {
319cdf0e10cSrcweir                 aInitialObject = resolve(xLocalContext, mURL);
320cdf0e10cSrcweir             }
321cdf0e10cSrcweir             catch( com.sun.star.connection.NoConnectException e )
322cdf0e10cSrcweir             {
323cdf0e10cSrcweir                 // launch soffice
324cdf0e10cSrcweir                 OfficeService aSOffice = new OfficeService();
325cdf0e10cSrcweir                 aSOffice.startupService();
326cdf0e10cSrcweir 
327cdf0e10cSrcweir                 // wait until soffice is started
328cdf0e10cSrcweir                 long nMaxMillis = System.currentTimeMillis() + 1000*aSOffice.getStartupTime();
329cdf0e10cSrcweir                 while ( aInitialObject == null )
330cdf0e10cSrcweir                 {
331cdf0e10cSrcweir                     try
332cdf0e10cSrcweir                     {
333cdf0e10cSrcweir                         // try to connect to soffice
334cdf0e10cSrcweir                         Thread.currentThread().sleep( 500 );
335cdf0e10cSrcweir                         aInitialObject = resolve(xLocalContext, mURL);
336cdf0e10cSrcweir                     }
337cdf0e10cSrcweir                     catch( com.sun.star.connection.NoConnectException aEx )
338cdf0e10cSrcweir                     {
339cdf0e10cSrcweir                         // soffice did not start in time
340cdf0e10cSrcweir                         if ( System.currentTimeMillis() > nMaxMillis )
341cdf0e10cSrcweir                             throw aEx;
342cdf0e10cSrcweir 
343cdf0e10cSrcweir                     }
344cdf0e10cSrcweir                 }
345cdf0e10cSrcweir             }
346cdf0e10cSrcweir             finally
347cdf0e10cSrcweir             {
348cdf0e10cSrcweir             }
349cdf0e10cSrcweir 
350cdf0e10cSrcweir             // XComponentContext
351cdf0e10cSrcweir             if( null != aInitialObject )
352cdf0e10cSrcweir             {
353cdf0e10cSrcweir                 XPropertySet xPropertySet = (XPropertySet)
354cdf0e10cSrcweir                     UnoRuntime.queryInterface( XPropertySet.class, aInitialObject);
355cdf0e10cSrcweir                         Object xContext = xPropertySet.getPropertyValue("DefaultContext");
356cdf0e10cSrcweir                         XComponentContext xComponentContext = (XComponentContext) UnoRuntime.queryInterface(
357cdf0e10cSrcweir                     XComponentContext.class, xContext);
358cdf0e10cSrcweir                 return xComponentContext;
359cdf0e10cSrcweir             }
360cdf0e10cSrcweir         }
361cdf0e10cSrcweir         catch( com.sun.star.connection.NoConnectException e )
362cdf0e10cSrcweir         {
363cdf0e10cSrcweir             System.out.println( "Couldn't connect to remote server" );
364cdf0e10cSrcweir             System.out.println( e.getMessage() );
365cdf0e10cSrcweir         }
366cdf0e10cSrcweir         catch( com.sun.star.connection.ConnectionSetupException e )
367cdf0e10cSrcweir         {
368cdf0e10cSrcweir             System.out.println( "Couldn't access necessary local resource to establish the interprocess connection" );
369cdf0e10cSrcweir             System.out.println( e.getMessage() );
370cdf0e10cSrcweir         }
371cdf0e10cSrcweir         catch( com.sun.star.lang.IllegalArgumentException e )
372cdf0e10cSrcweir         {
373cdf0e10cSrcweir             System.out.println( "uno-url is syntactical illegal ( " + mURL + " )" );
374cdf0e10cSrcweir             System.out.println( e.getMessage() );
375cdf0e10cSrcweir         }
376cdf0e10cSrcweir         catch( com.sun.star.uno.RuntimeException e )
377cdf0e10cSrcweir         {
378cdf0e10cSrcweir             System.out.println( "--- RuntimeException:" );
379cdf0e10cSrcweir             System.out.println( e.getMessage() );
380cdf0e10cSrcweir             e.printStackTrace();
381cdf0e10cSrcweir             System.out.println( "--- end." );
382cdf0e10cSrcweir             throw e;
383cdf0e10cSrcweir         }
384cdf0e10cSrcweir         catch( java.lang.Exception e )
385cdf0e10cSrcweir         {
386cdf0e10cSrcweir             System.out.println( "java.lang.Exception: " );
387cdf0e10cSrcweir             System.out.println( e );
388cdf0e10cSrcweir             e.printStackTrace();
389cdf0e10cSrcweir             System.out.println( "--- end." );
390cdf0e10cSrcweir             throw new com.sun.star.uno.RuntimeException( e.toString() );
391cdf0e10cSrcweir         }
392cdf0e10cSrcweir 
393cdf0e10cSrcweir         return null;
394cdf0e10cSrcweir     }
395cdf0e10cSrcweir 
396cdf0e10cSrcweir 
397cdf0e10cSrcweir     //The function is copied and adapted from the UrlResolver.resolve.
398cdf0e10cSrcweir     //We cannot use the URLResolver because we need access to the bridge which has
399cdf0e10cSrcweir     //to be disposed when Applet.stop is called.
resolve(XComponentContext xLocalContext, String dcp)400cdf0e10cSrcweir     private Object resolve(XComponentContext xLocalContext, String dcp)
401cdf0e10cSrcweir         throws com.sun.star.connection.NoConnectException,
402cdf0e10cSrcweir             com.sun.star.connection.ConnectionSetupException,
403cdf0e10cSrcweir             com.sun.star.lang.IllegalArgumentException
404cdf0e10cSrcweir     {
405cdf0e10cSrcweir         String conDcp = null;
406cdf0e10cSrcweir         String protDcp = null;
407cdf0e10cSrcweir         String rootOid = null;
408cdf0e10cSrcweir 
409cdf0e10cSrcweir         if(dcp.indexOf(';') == -1) {// use old style
410cdf0e10cSrcweir             conDcp = dcp;
411cdf0e10cSrcweir             protDcp = "iiop";
412cdf0e10cSrcweir             rootOid = "classic_uno";
413cdf0e10cSrcweir         }
414cdf0e10cSrcweir         else { // new style
415cdf0e10cSrcweir             int index = dcp.indexOf(':');
416cdf0e10cSrcweir             String url = dcp.substring(0, index).trim();
417cdf0e10cSrcweir             dcp = dcp.substring(index + 1).trim();
418cdf0e10cSrcweir 
419cdf0e10cSrcweir             index = dcp.indexOf(';');
420cdf0e10cSrcweir             conDcp = dcp.substring(0, index).trim();
421cdf0e10cSrcweir             dcp = dcp.substring(index + 1).trim();
422cdf0e10cSrcweir 
423cdf0e10cSrcweir             index = dcp.indexOf(';');
424cdf0e10cSrcweir             protDcp = dcp.substring(0, index).trim();
425cdf0e10cSrcweir             dcp = dcp.substring(index + 1).trim();
426cdf0e10cSrcweir 
427cdf0e10cSrcweir             rootOid = dcp.trim().trim();
428cdf0e10cSrcweir         }
429cdf0e10cSrcweir 
430cdf0e10cSrcweir         Object rootObject = null;
431cdf0e10cSrcweir         XBridgeFactory xBridgeFactory= null;
432cdf0e10cSrcweir 
433cdf0e10cSrcweir         XMultiComponentFactory xLocalServiceManager = xLocalContext.getServiceManager();
434cdf0e10cSrcweir         try {
435cdf0e10cSrcweir             xBridgeFactory = (XBridgeFactory)UnoRuntime.queryInterface(
436cdf0e10cSrcweir                     XBridgeFactory.class,
437cdf0e10cSrcweir                     xLocalServiceManager.createInstanceWithContext(
438cdf0e10cSrcweir                         "com.sun.star.bridge.BridgeFactory", xLocalContext));
439cdf0e10cSrcweir         } catch (com.sun.star.uno.Exception e) {
440cdf0e10cSrcweir             throw new com.sun.star.uno.RuntimeException(e.getMessage());
441cdf0e10cSrcweir         }
442cdf0e10cSrcweir         synchronized(this) {
443cdf0e10cSrcweir             if(mBridge == null) {
444cdf0e10cSrcweir                 Object connector= null;
445cdf0e10cSrcweir                 try {
446cdf0e10cSrcweir                     connector = xLocalServiceManager.createInstanceWithContext(
447cdf0e10cSrcweir                             "com.sun.star.connection.Connector", xLocalContext);
448cdf0e10cSrcweir                 } catch (com.sun.star.uno.Exception e) {
449cdf0e10cSrcweir                     throw new com.sun.star.uno.RuntimeException(e.getMessage());
450cdf0e10cSrcweir                 }
451cdf0e10cSrcweir                 XConnector connector_xConnector = (XConnector)UnoRuntime.queryInterface(XConnector.class, connector);
452cdf0e10cSrcweir                 // connect to the server
453cdf0e10cSrcweir                 XConnection xConnection = connector_xConnector.connect(conDcp);
454cdf0e10cSrcweir                 // create the bridge name. This should not be necessary if we pass an
455cdf0e10cSrcweir                 //empty string as bridge name into createBridge. Then we should always get
456cdf0e10cSrcweir                 //a new bridge. This does not work because of (i51323). Therefore we
457cdf0e10cSrcweir                 //create unique bridge names for the current process.
458cdf0e10cSrcweir                 String sBridgeName = "OOoBean_private_bridge_" + String.valueOf(m_nBridgeCounter++);
459cdf0e10cSrcweir                 try {
460cdf0e10cSrcweir                     mBridge = xBridgeFactory.createBridge(sBridgeName, protDcp, xConnection, null);
461cdf0e10cSrcweir                 } catch (com.sun.star.bridge.BridgeExistsException e) {
462cdf0e10cSrcweir                     throw new com.sun.star.uno.RuntimeException(e.getMessage());
463cdf0e10cSrcweir                 }
464cdf0e10cSrcweir             }
465cdf0e10cSrcweir             rootObject = mBridge.getInstance(rootOid);
466cdf0e10cSrcweir             return rootObject;
467cdf0e10cSrcweir         }
468cdf0e10cSrcweir     }
469cdf0e10cSrcweir 
470cdf0e10cSrcweir 
471cdf0e10cSrcweir     /**
472cdf0e10cSrcweir      * Retrives a path to the office program folder.
473cdf0e10cSrcweir      *
474cdf0e10cSrcweir      * @return The path to the office program folder.
475cdf0e10cSrcweir      */
getProgramPath()476cdf0e10cSrcweir     static private String getProgramPath()
477cdf0e10cSrcweir     {
478cdf0e10cSrcweir         if (mProgramPath == null)
479cdf0e10cSrcweir         {
480cdf0e10cSrcweir             // determine name of executable soffice
481cdf0e10cSrcweir             String aExec = OFFICE_APP_NAME; // default for UNIX
482cdf0e10cSrcweir             String aOS = System.getProperty("os.name");
483cdf0e10cSrcweir 
484cdf0e10cSrcweir             // running on Windows?
485cdf0e10cSrcweir             if (aOS.startsWith("Windows"))
486cdf0e10cSrcweir                 aExec = OFFICE_APP_NAME + ".exe";
487cdf0e10cSrcweir 
488cdf0e10cSrcweir             // add other non-UNIX operating systems here
489cdf0e10cSrcweir             // ...
490cdf0e10cSrcweir 
491cdf0e10cSrcweir             // find soffice executable relative to this class's class loader:
492cdf0e10cSrcweir             File path = NativeLibraryLoader.getResource(
493cdf0e10cSrcweir                 LocalOfficeConnection.class.getClassLoader(), aExec);
494cdf0e10cSrcweir             if (path != null)
495cdf0e10cSrcweir                 mProgramPath = path.getParent();
496cdf0e10cSrcweir 
497cdf0e10cSrcweir             // default is ""
498cdf0e10cSrcweir             if ( mProgramPath == null )
499cdf0e10cSrcweir                 mProgramPath = "";
500cdf0e10cSrcweir         }
501cdf0e10cSrcweir         return mProgramPath;
502cdf0e10cSrcweir     }
503cdf0e10cSrcweir 
504cdf0e10cSrcweir     /**
505cdf0e10cSrcweir      * Parses a connection URL.
506cdf0e10cSrcweir      * This method accepts a UNO URL with following format:<br />
507cdf0e10cSrcweir      * <pre>
508cdf0e10cSrcweir      * url    := uno:localoffice[,&lt;params&gt;];urp;StarOffice.NamingService
509cdf0e10cSrcweir      * params := &lt;path&gt;[,&lt;pipe&gt;]
510cdf0e10cSrcweir      * path   := path=&lt;pathv&gt;
511cdf0e10cSrcweir      * pipe   := pipe=&lt;pipev&gt;
512cdf0e10cSrcweir      * pathv  := platform_specific_path_to_the_local_office_distribution
513cdf0e10cSrcweir      * pipev  := local_office_connection_pipe_name
514cdf0e10cSrcweir      * </pre>
515cdf0e10cSrcweir      *
516cdf0e10cSrcweir      * <h4>Examples</h4>
517cdf0e10cSrcweir      * <ul>
518cdf0e10cSrcweir      *  <li>"uno:localoffice,pipe=xyz_Office,path=/opt/openoffice11/program;urp;StarOffice.ServiceManager";
519cdf0e10cSrcweir      *  <li>"uno:socket,host=localhost,port=8100;urp;StarOffice.ServiceManager";
520cdf0e10cSrcweir      * </ul>
521cdf0e10cSrcweir      *
522cdf0e10cSrcweir      * @param url This is UNO URL which describes the type of a connection.
523cdf0e10cSrcweir      * @exception java.net.MalformedURLException when inappropreate URL was
524cdf0e10cSrcweir      *  provided.
525cdf0e10cSrcweir      */
parseUnoUrlWithOfficePath(String url, String prefix)526cdf0e10cSrcweir     private void parseUnoUrlWithOfficePath(String url, String prefix)
527cdf0e10cSrcweir         throws java.net.MalformedURLException
528cdf0e10cSrcweir     {
529cdf0e10cSrcweir         // Extruct parameters.
530cdf0e10cSrcweir         int idx = url.indexOf(";urp;StarOffice.NamingService");
531cdf0e10cSrcweir         if (idx < 0)
532cdf0e10cSrcweir             throw new java.net.MalformedURLException(
533cdf0e10cSrcweir                 "Invalid UNO connection URL.");
534cdf0e10cSrcweir         String  params  = url.substring(prefix.length(), idx + 1);
535cdf0e10cSrcweir 
536cdf0e10cSrcweir         // Parse parameters.
537cdf0e10cSrcweir         String  name    = null;
538cdf0e10cSrcweir         String  path    = null;
539cdf0e10cSrcweir         String  pipe    = null;
540cdf0e10cSrcweir         char    ch;
541cdf0e10cSrcweir         int     state   = 0;
542cdf0e10cSrcweir         StringBuffer    buffer  = new StringBuffer();
543cdf0e10cSrcweir         for(idx = 0; idx < params.length(); idx += 1) {
544cdf0e10cSrcweir             ch  = params.charAt(idx);
545cdf0e10cSrcweir             switch (state) {
546cdf0e10cSrcweir             case 0: // initial state
547cdf0e10cSrcweir                 switch(ch) {
548cdf0e10cSrcweir                 case ',':
549cdf0e10cSrcweir                     buffer.delete(0, buffer.length());
550cdf0e10cSrcweir                     state   = 1;
551cdf0e10cSrcweir                     break;
552cdf0e10cSrcweir 
553cdf0e10cSrcweir                 case ';':
554cdf0e10cSrcweir                     state   = 7;
555cdf0e10cSrcweir                     break;
556cdf0e10cSrcweir 
557cdf0e10cSrcweir                 default:
558cdf0e10cSrcweir                     buffer.delete(0, buffer.length());
559cdf0e10cSrcweir                     buffer.append(ch);
560cdf0e10cSrcweir                     state   = 1;
561cdf0e10cSrcweir                     break;
562cdf0e10cSrcweir                 }
563cdf0e10cSrcweir                 break;
564cdf0e10cSrcweir 
565cdf0e10cSrcweir             case 1: // parameter name
566cdf0e10cSrcweir                 switch(ch) {
567cdf0e10cSrcweir                 case ' ':
568cdf0e10cSrcweir                 case '=':
569cdf0e10cSrcweir                     name    = buffer.toString();
570cdf0e10cSrcweir                     state   = (ch == ' ')? 2: 3;
571cdf0e10cSrcweir                     break;
572cdf0e10cSrcweir 
573cdf0e10cSrcweir                 case ',':
574cdf0e10cSrcweir                 case ';':
575cdf0e10cSrcweir                     state   = -6;           // error: invalid name
576cdf0e10cSrcweir                     break;
577cdf0e10cSrcweir 
578cdf0e10cSrcweir                 default:
579cdf0e10cSrcweir                     buffer.append(ch);
580cdf0e10cSrcweir                     break;
581cdf0e10cSrcweir                 }
582cdf0e10cSrcweir                 break;
583cdf0e10cSrcweir 
584cdf0e10cSrcweir             case 2: // equal between the name and the value
585cdf0e10cSrcweir                 switch(ch) {
586cdf0e10cSrcweir                 case '=':
587cdf0e10cSrcweir                     state   = 3;
588cdf0e10cSrcweir                     break;
589cdf0e10cSrcweir 
590cdf0e10cSrcweir                 case ' ':
591cdf0e10cSrcweir                     break;
592cdf0e10cSrcweir 
593cdf0e10cSrcweir                 default:
594cdf0e10cSrcweir                     state   = -1;           // error: missing '='
595cdf0e10cSrcweir                     break;
596cdf0e10cSrcweir                 }
597cdf0e10cSrcweir                 break;
598cdf0e10cSrcweir 
599cdf0e10cSrcweir             case 3: // value leading spaces
600cdf0e10cSrcweir                 switch(ch) {
601cdf0e10cSrcweir                 case ' ':
602cdf0e10cSrcweir                     break;
603cdf0e10cSrcweir 
604cdf0e10cSrcweir                 default:
605cdf0e10cSrcweir                     buffer.delete(0, buffer.length());
606cdf0e10cSrcweir                     buffer.append(ch);
607cdf0e10cSrcweir                     state   = 4;
608cdf0e10cSrcweir                     break;
609cdf0e10cSrcweir                 }
610cdf0e10cSrcweir                 break;
611cdf0e10cSrcweir 
612cdf0e10cSrcweir             case 4: // value
613cdf0e10cSrcweir                 switch(ch) {
614cdf0e10cSrcweir                 case ' ':
615cdf0e10cSrcweir                 case ',':
616cdf0e10cSrcweir                 case ';':
617cdf0e10cSrcweir                     idx     -= 1;           // put back the last read character
618cdf0e10cSrcweir                     state   = 5;
619cdf0e10cSrcweir                     if (name.equals("path")) {
620cdf0e10cSrcweir                         if (path == null)
621cdf0e10cSrcweir                             path    = buffer.toString();
622cdf0e10cSrcweir                         else
623cdf0e10cSrcweir                             state   = -3;   // error: more then one 'path'
624cdf0e10cSrcweir                     } else if (name.equals("pipe")) {
625cdf0e10cSrcweir                         if (pipe == null)
626cdf0e10cSrcweir                             pipe    = buffer.toString();
627cdf0e10cSrcweir                         else
628cdf0e10cSrcweir                             state   = -4;   // error: more then one 'pipe'
629cdf0e10cSrcweir                     } else
630cdf0e10cSrcweir                         state   = -2;       // error: unknown parameter
631cdf0e10cSrcweir                     buffer.delete(0, buffer.length());
632cdf0e10cSrcweir                     break;
633cdf0e10cSrcweir 
634cdf0e10cSrcweir                 default:
635cdf0e10cSrcweir                     buffer.append(ch);
636cdf0e10cSrcweir                     break;
637cdf0e10cSrcweir                 }
638cdf0e10cSrcweir                 break;
639cdf0e10cSrcweir 
640cdf0e10cSrcweir             case 5: // a delimeter after the value
641cdf0e10cSrcweir                 switch(ch) {
642cdf0e10cSrcweir                 case ' ':
643cdf0e10cSrcweir                     break;
644cdf0e10cSrcweir 
645cdf0e10cSrcweir                 case ',':
646cdf0e10cSrcweir                     state   = 6;
647cdf0e10cSrcweir                     break;
648cdf0e10cSrcweir 
649cdf0e10cSrcweir                 case ';':
650cdf0e10cSrcweir                     state   = 7;
651cdf0e10cSrcweir                     break;
652cdf0e10cSrcweir 
653cdf0e10cSrcweir                 default:
654cdf0e10cSrcweir                     state   = -5;           // error: ' ' inside the value
655cdf0e10cSrcweir                     break;
656cdf0e10cSrcweir                 }
657cdf0e10cSrcweir                 break;
658cdf0e10cSrcweir 
659cdf0e10cSrcweir             case 6: // leading spaces before next parameter name
660cdf0e10cSrcweir                 switch(ch) {
661cdf0e10cSrcweir                 case ' ':
662cdf0e10cSrcweir                     break;
663cdf0e10cSrcweir 
664cdf0e10cSrcweir                 default:
665cdf0e10cSrcweir                     buffer.delete(0, buffer.length());
666cdf0e10cSrcweir                     buffer.append(ch);
667cdf0e10cSrcweir                     state   = 1;
668cdf0e10cSrcweir                     break;
669cdf0e10cSrcweir                 }
670cdf0e10cSrcweir                 break;
671cdf0e10cSrcweir 
672cdf0e10cSrcweir             default:
673cdf0e10cSrcweir                 throw new java.net.MalformedURLException(
674cdf0e10cSrcweir                     "Invalid UNO connection URL.");
675cdf0e10cSrcweir             }
676cdf0e10cSrcweir         }
677cdf0e10cSrcweir         if (state != 7)
678cdf0e10cSrcweir             throw new java.net.MalformedURLException(
679cdf0e10cSrcweir                 "Invalid UNO connection URL.");
680cdf0e10cSrcweir 
681cdf0e10cSrcweir         // Set up the connection parameters.
682cdf0e10cSrcweir         if (path != null)
683cdf0e10cSrcweir             mProgramPath = path;
684cdf0e10cSrcweir         if (pipe != null)
685cdf0e10cSrcweir             mPipe = pipe;
686cdf0e10cSrcweir     }
687cdf0e10cSrcweir 
688cdf0e10cSrcweir     /* replaces each substring aSearch in aString by aReplace.
689cdf0e10cSrcweir 
690cdf0e10cSrcweir         StringBuffer.replaceAll() is not avaialable in Java 1.3.x.
691cdf0e10cSrcweir      */
replaceAll(String aString, String aSearch, String aReplace )692cdf0e10cSrcweir     private static String replaceAll(String aString, String aSearch, String aReplace )
693cdf0e10cSrcweir     {
694cdf0e10cSrcweir         StringBuffer aBuffer = new StringBuffer(aString);
695cdf0e10cSrcweir 
696cdf0e10cSrcweir         int nPos = aString.length();
697cdf0e10cSrcweir         int nOfs = aSearch.length();
698cdf0e10cSrcweir 
699cdf0e10cSrcweir         while ( ( nPos = aString.lastIndexOf( aSearch, nPos - 1 ) ) > -1 )
700cdf0e10cSrcweir             aBuffer.replace( nPos, nPos+nOfs, aReplace );
701cdf0e10cSrcweir 
702cdf0e10cSrcweir         return aBuffer.toString();
703cdf0e10cSrcweir     }
704cdf0e10cSrcweir 
705cdf0e10cSrcweir 
706cdf0e10cSrcweir     /** creates a unique pipe name.
707cdf0e10cSrcweir     */
getPipeName()708cdf0e10cSrcweir     static String getPipeName()
709cdf0e10cSrcweir     {
710cdf0e10cSrcweir         // turn user name into a URL and file system safe name (% chars will not work)
711cdf0e10cSrcweir         String aPipeName = System.getProperty("user.name") + OFFICE_ID_SUFFIX;
712cdf0e10cSrcweir         aPipeName = replaceAll( aPipeName, "_", "%B7" );
713cdf0e10cSrcweir         return replaceAll( replaceAll( java.net.URLEncoder.encode(aPipeName), "+", "%20" ), "%", "_" );
714cdf0e10cSrcweir     }
715cdf0e10cSrcweir 
716cdf0e10cSrcweir     /**
717cdf0e10cSrcweir      * @para This is an implementation of the native office service.
718cdf0e10cSrcweir      */
719cdf0e10cSrcweir     private class OfficeService
720cdf0e10cSrcweir         implements NativeService
721cdf0e10cSrcweir     {
722cdf0e10cSrcweir         /**
723cdf0e10cSrcweir          * Retrive the office service identifier.
724cdf0e10cSrcweir          *
725cdf0e10cSrcweir          * @return The identifier of the office service.
726cdf0e10cSrcweir          */
getIdentifier()727cdf0e10cSrcweir         public String getIdentifier()
728cdf0e10cSrcweir         {
729cdf0e10cSrcweir             if ( mPipe == null)
730cdf0e10cSrcweir                 return getPipeName();
731cdf0e10cSrcweir             else
732cdf0e10cSrcweir                 return mPipe;
733cdf0e10cSrcweir         }
734cdf0e10cSrcweir 
735cdf0e10cSrcweir         /**
736cdf0e10cSrcweir          * Starts the office process.
737cdf0e10cSrcweir          */
startupService()738cdf0e10cSrcweir         public void startupService()
739cdf0e10cSrcweir             throws java.io.IOException
740cdf0e10cSrcweir         {
741cdf0e10cSrcweir             int nSizeCmdArray = 4;
742cdf0e10cSrcweir             String sOption = null;
743cdf0e10cSrcweir             //examine if user specified command-line options in system properties.
744cdf0e10cSrcweir             //We may offer later a more sophisticated way of providing options if
745cdf0e10cSrcweir             //the need arises. Currently this is intended to ease the pain during
746cdf0e10cSrcweir             //development  with pre-release builds of OOo where one wants to start
747cdf0e10cSrcweir             //OOo with the -norestore options. The value of the property is simple
748cdf0e10cSrcweir             //passed on to the Runtime.exec call.
749cdf0e10cSrcweir             try {
750cdf0e10cSrcweir                 sOption = System.getProperty("com.sun.star.officebean.Options");
751cdf0e10cSrcweir                 if (sOption != null)
752cdf0e10cSrcweir                     nSizeCmdArray ++;
753cdf0e10cSrcweir             } catch (java.lang.SecurityException e)
754cdf0e10cSrcweir             {
755cdf0e10cSrcweir                 e.printStackTrace();
756cdf0e10cSrcweir             }
757cdf0e10cSrcweir            // create call with arguments
758cdf0e10cSrcweir             String[] cmdArray = new String[nSizeCmdArray];
759cdf0e10cSrcweir 
760cdf0e10cSrcweir             // read UNO_PATH environment variable to get path to soffice binary
761cdf0e10cSrcweir             String unoPath = System.getenv("UNO_PATH");
762cdf0e10cSrcweir             if (unoPath == null)
763cdf0e10cSrcweir                 throw new java.io.IOException( "UNO_PATH environment variable is not set (required system path to the office program directory)" );
764cdf0e10cSrcweir 
765cdf0e10cSrcweir //          cmdArray[0] = (new File(getProgramPath(), OFFICE_APP_NAME)).getPath();
766cdf0e10cSrcweir             cmdArray[0] = (new File(unoPath, OFFICE_APP_NAME)).getPath();
767cdf0e10cSrcweir             cmdArray[1] = "-nologo";
768cdf0e10cSrcweir             cmdArray[2] = "-nodefault";
769cdf0e10cSrcweir             if ( mConnType.equals( "pipe" ) )
770cdf0e10cSrcweir                 cmdArray[3] = "-accept=pipe,name=" + getIdentifier() + ";" +
771cdf0e10cSrcweir                           mProtocol + ";" + mInitialObject;
772cdf0e10cSrcweir             else if ( mConnType.equals( "socket" ) )
773cdf0e10cSrcweir                 cmdArray[3] = "-accept=socket,port=" + mPort + ";urp";
774cdf0e10cSrcweir             else
775cdf0e10cSrcweir                 throw new java.io.IOException( "not connection specified" );
776cdf0e10cSrcweir 
777cdf0e10cSrcweir             if (sOption != null)
778cdf0e10cSrcweir                 cmdArray[4] = sOption;
779cdf0e10cSrcweir 
780cdf0e10cSrcweir             // start process
781cdf0e10cSrcweir             mProcess = Runtime.getRuntime().exec(cmdArray);
782cdf0e10cSrcweir             if ( mProcess == null )
783cdf0e10cSrcweir                 throw new RuntimeException( "cannot start soffice: " + cmdArray );
784cdf0e10cSrcweir             new StreamProcessor(mProcess.getInputStream(), System.out);
785cdf0e10cSrcweir             new StreamProcessor(mProcess.getErrorStream(), System.err);
786cdf0e10cSrcweir         }
787cdf0e10cSrcweir 
788cdf0e10cSrcweir         /**
789cdf0e10cSrcweir          * Retrives the ammount of time to wait for the startup.
790cdf0e10cSrcweir          *
791cdf0e10cSrcweir          * @return The ammount of time to wait in seconds(?).
792cdf0e10cSrcweir          */
getStartupTime()793cdf0e10cSrcweir         public int getStartupTime()
794cdf0e10cSrcweir         {
795cdf0e10cSrcweir             return 60;
796cdf0e10cSrcweir         }
797cdf0e10cSrcweir     }
798cdf0e10cSrcweir 
799cdf0e10cSrcweir 
800cdf0e10cSrcweir 
801cdf0e10cSrcweir     class StreamProcessor extends Thread
802cdf0e10cSrcweir     {
803cdf0e10cSrcweir         java.io.InputStream m_in;
804cdf0e10cSrcweir         java.io.PrintStream m_print;
805cdf0e10cSrcweir 
StreamProcessor(final java.io.InputStream in, final java.io.PrintStream out)806cdf0e10cSrcweir         public StreamProcessor(final java.io.InputStream in, final java.io.PrintStream out)
807cdf0e10cSrcweir         {
808cdf0e10cSrcweir             m_in = in;
809cdf0e10cSrcweir             m_print = out;
810cdf0e10cSrcweir             start();
811cdf0e10cSrcweir         }
812cdf0e10cSrcweir 
run()813cdf0e10cSrcweir         public void run() {
814cdf0e10cSrcweir             java.io.BufferedReader r = new java.io.BufferedReader(
815cdf0e10cSrcweir                 new java.io.InputStreamReader(m_in) );
816cdf0e10cSrcweir             try {
817cdf0e10cSrcweir                 for ( ; ; ) {
818cdf0e10cSrcweir                     String s = r.readLine();
819cdf0e10cSrcweir                     if ( s == null ) {
820cdf0e10cSrcweir                         break;
821cdf0e10cSrcweir                     }
822cdf0e10cSrcweir                     m_print.println(s);
823cdf0e10cSrcweir                 }
824cdf0e10cSrcweir             } catch ( java.io.IOException e ) {
825cdf0e10cSrcweir                 e.printStackTrace( System.err );
826cdf0e10cSrcweir             }
827cdf0e10cSrcweir         }
828cdf0e10cSrcweir     }
829cdf0e10cSrcweir 
830cdf0e10cSrcweir }
831