xref: /AOO41X/main/bean/com/sun/star/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.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.XEventListener;
34cdf0e10cSrcweir import com.sun.star.bridge.XUnoUrlResolver;
35cdf0e10cSrcweir import com.sun.star.uno.XComponentContext;
36cdf0e10cSrcweir import com.sun.star.uno.UnoRuntime;
37cdf0e10cSrcweir import com.sun.star.lib.uno.helper.UnoUrl;
38cdf0e10cSrcweir import com.sun.star.lib.util.NativeLibraryLoader;
39cdf0e10cSrcweir 
40cdf0e10cSrcweir /**
41cdf0e10cSrcweir  * This class reprecents a connection to the local office application.
42cdf0e10cSrcweir  * @deprecated
43cdf0e10cSrcweir  */
44cdf0e10cSrcweir public class LocalOfficeConnection
45cdf0e10cSrcweir 	implements OfficeConnection
46cdf0e10cSrcweir {
47cdf0e10cSrcweir 	public static final String		OFFICE_APP_NAME		= "soffice";
48cdf0e10cSrcweir 	public static final String		OFFICE_LIB_NAME		= "officebean";
49cdf0e10cSrcweir 	public static final String		OFFICE_ID_SUFFIX	= "_Office";
50cdf0e10cSrcweir 
51cdf0e10cSrcweir 	private Process				mProcess;
52cdf0e10cSrcweir 	private ContainerFactory		mContainerFactory;
53cdf0e10cSrcweir 	private XComponentContext		mContext;
54cdf0e10cSrcweir 
55cdf0e10cSrcweir 	private String				mURL;
56cdf0e10cSrcweir 	private String				mProgramPath;
57cdf0e10cSrcweir 	private String				mConnType;
58cdf0e10cSrcweir 	private String				mPipe;
59cdf0e10cSrcweir 	private String				mPort;
60cdf0e10cSrcweir 	private String				mProtocol;
61cdf0e10cSrcweir 	private String				mInitialObject;
62cdf0e10cSrcweir 
63cdf0e10cSrcweir 	private List				mComponents		= new Vector();
64cdf0e10cSrcweir 
65cdf0e10cSrcweir 	/**
66cdf0e10cSrcweir 	 * Constructor.
67cdf0e10cSrcweir 	 * Sets up paths to the office application and native libraries if
68cdf0e10cSrcweir 	 * values are available in <code>OFFICE_PROP_FILE</code> in the user
69cdf0e10cSrcweir 	 * home directory.<br />
70cdf0e10cSrcweir 	 * "com.sun.star.beans.path" - the office application directory;<br/>
71cdf0e10cSrcweir 	 * "com.sun.star.beans.libpath" - native libraries directory.
72cdf0e10cSrcweir 	 */
LocalOfficeConnection()73cdf0e10cSrcweir 	public LocalOfficeConnection()
74cdf0e10cSrcweir 	{
75cdf0e10cSrcweir 		// init member vars
76cdf0e10cSrcweir 		try
77cdf0e10cSrcweir 		{
78cdf0e10cSrcweir 			setUnoUrl( "uno:pipe,name=" + getPipeName() + ";urp;StarOffice.ServiceManager" );
79cdf0e10cSrcweir 		}
80cdf0e10cSrcweir 		catch ( java.net.MalformedURLException e )
81cdf0e10cSrcweir 		{}
82cdf0e10cSrcweir 
83cdf0e10cSrcweir 		// load libofficebean.so/officebean.dll
84cdf0e10cSrcweir 		String aSharedLibName = getProgramPath() + java.io.File.separator +
85cdf0e10cSrcweir 			System.mapLibraryName(OFFICE_LIB_NAME);
86cdf0e10cSrcweir 		System.load( aSharedLibName );
87cdf0e10cSrcweir 	}
88cdf0e10cSrcweir 
89cdf0e10cSrcweir 	/**
90cdf0e10cSrcweir 	 * Sets a connection URL.
91cdf0e10cSrcweir 	 * This implementation accepts a UNO URL with following format:<br />
92cdf0e10cSrcweir 	 * <pre>
93cdf0e10cSrcweir 	 * url    := uno:localoffice[,&lt;params&gt;];urp;StarOffice.ServiceManager
94cdf0e10cSrcweir 	 * params := &lt;path&gt;[,&lt;pipe&gt;]
95cdf0e10cSrcweir 	 * path   := path=&lt;pathv&gt;
96cdf0e10cSrcweir 	 * pipe   := pipe=&lt;pipev&gt;
97cdf0e10cSrcweir 	 * pathv  := platform_specific_path_to_the_local_office_distribution
98cdf0e10cSrcweir 	 * pipev  := local_office_connection_pipe_name
99cdf0e10cSrcweir 	 * </pre>
100cdf0e10cSrcweir 	 *
101cdf0e10cSrcweir 	 * @param url This is UNO URL which discribes the type of a connection.
102cdf0e10cSrcweir 	 */
setUnoUrl(String url)103cdf0e10cSrcweir 	public void setUnoUrl(String url)
104cdf0e10cSrcweir 		throws java.net.MalformedURLException
105cdf0e10cSrcweir 	{
106cdf0e10cSrcweir 		mURL	= null;
107cdf0e10cSrcweir 
108cdf0e10cSrcweir 		String prefix = "uno:localoffice";
109cdf0e10cSrcweir 		if ( url.startsWith(prefix) )
110cdf0e10cSrcweir 			parseUnoUrlWithOfficePath( url, prefix );
111cdf0e10cSrcweir 		else
112cdf0e10cSrcweir 		{
113cdf0e10cSrcweir 			try
114cdf0e10cSrcweir 			{
115cdf0e10cSrcweir 				UnoUrl aURL = UnoUrl.parseUnoUrl( url );
116cdf0e10cSrcweir 				mProgramPath = null;
117cdf0e10cSrcweir 				mConnType = aURL.getConnection();
118cdf0e10cSrcweir 				mPipe = (String) aURL.getConnectionParameters().get( "pipe" );
119cdf0e10cSrcweir 				mPort = (String) aURL.getConnectionParameters().get( "port" );
120cdf0e10cSrcweir 				mProtocol = aURL.getProtocol();
121cdf0e10cSrcweir 				mInitialObject = aURL.getRootOid();
122cdf0e10cSrcweir 			}
123cdf0e10cSrcweir 			catch ( com.sun.star.lang.IllegalArgumentException eIll )
124cdf0e10cSrcweir 			{
125cdf0e10cSrcweir 				throw new java.net.MalformedURLException(
126cdf0e10cSrcweir 					"Invalid UNO connection URL.");
127cdf0e10cSrcweir 			}
128cdf0e10cSrcweir 		}
129cdf0e10cSrcweir 		mURL	= url;
130cdf0e10cSrcweir 	}
131cdf0e10cSrcweir 
132cdf0e10cSrcweir 	/**
133cdf0e10cSrcweir 	 * Sets an AWT container catory.
134cdf0e10cSrcweir 	 *
135cdf0e10cSrcweir 	 * @param containerFactory This is a application provided AWT container
136cdf0e10cSrcweir 	 *	factory.
137cdf0e10cSrcweir 	 */
setContainerFactory(ContainerFactory containerFactory)138cdf0e10cSrcweir 	public void setContainerFactory(ContainerFactory containerFactory)
139cdf0e10cSrcweir 	{
140cdf0e10cSrcweir 		mContainerFactory	= containerFactory;
141cdf0e10cSrcweir 	}
142cdf0e10cSrcweir 
143cdf0e10cSrcweir 	/**
144cdf0e10cSrcweir 	 * Retrives the UNO component context.
145cdf0e10cSrcweir 	 * Establishes a connection if necessary and initialises the
146cdf0e10cSrcweir 	 * UNO service manager if it has not already been initialised.
147cdf0e10cSrcweir 	 * This method can return <code>null</code> if it fails to connect
148cdf0e10cSrcweir 	 * to the office application.
149cdf0e10cSrcweir 	 *
150cdf0e10cSrcweir 	 * @return The office UNO component context.
151cdf0e10cSrcweir 	 */
getComponentContext()152cdf0e10cSrcweir 	public XComponentContext getComponentContext()
153cdf0e10cSrcweir 	{
154cdf0e10cSrcweir 		if ( mContext == null )
155cdf0e10cSrcweir 			mContext = connect();
156cdf0e10cSrcweir 		return mContext;
157cdf0e10cSrcweir 	}
158cdf0e10cSrcweir 
159cdf0e10cSrcweir 	/**
160cdf0e10cSrcweir 	 * Creates an office window.
161cdf0e10cSrcweir 	 * The window is either a sub-class of java.awt.Canvas (local) or
162cdf0e10cSrcweir 	 * java.awt.Container (RVP).
163cdf0e10cSrcweir 	 *
164cdf0e10cSrcweir 	 * @param container This is an AWT container.
165cdf0e10cSrcweir 	 * @return The office window instance.
166cdf0e10cSrcweir 	 */
createOfficeWindow(Container container)167cdf0e10cSrcweir 	public OfficeWindow createOfficeWindow(Container container)
168cdf0e10cSrcweir 	{
169cdf0e10cSrcweir 		return new LocalOfficeWindow(this);
170cdf0e10cSrcweir 	}
171cdf0e10cSrcweir 
172cdf0e10cSrcweir 	/**
173cdf0e10cSrcweir 	 * Closes the connection.
174cdf0e10cSrcweir 	 */
dispose()175cdf0e10cSrcweir 	public void dispose()
176cdf0e10cSrcweir 	{
177cdf0e10cSrcweir 		Iterator itr = mComponents.iterator();
178cdf0e10cSrcweir 		while (itr.hasNext() == true) {
179cdf0e10cSrcweir 			// ignore runtime exceptions in dispose
180cdf0e10cSrcweir 			try { ((XEventListener)itr.next()).disposing(null); }
181cdf0e10cSrcweir 			catch ( RuntimeException aExc ) {}
182cdf0e10cSrcweir 		}
183cdf0e10cSrcweir 		mComponents.clear();
184cdf0e10cSrcweir 
185cdf0e10cSrcweir 		mContainerFactory = null;
186cdf0e10cSrcweir 		mContext = null;
187cdf0e10cSrcweir 	}
188cdf0e10cSrcweir 
189cdf0e10cSrcweir 	/**
190cdf0e10cSrcweir 	 * Adds an event listener to the object.
191cdf0e10cSrcweir 	 *
192cdf0e10cSrcweir 	 * @param listener is a listener object.
193cdf0e10cSrcweir 	 */
addEventListener(XEventListener listener)194cdf0e10cSrcweir 	public void addEventListener(XEventListener listener)
195cdf0e10cSrcweir 	{
196cdf0e10cSrcweir 		mComponents.add(listener);
197cdf0e10cSrcweir 	}
198cdf0e10cSrcweir 
199cdf0e10cSrcweir 	/**
200cdf0e10cSrcweir 	 * Removes an event listener from the listener list.
201cdf0e10cSrcweir 	 *
202cdf0e10cSrcweir 	 * @param listener is a listener object.
203cdf0e10cSrcweir 	 */
removeEventListener(XEventListener listener)204cdf0e10cSrcweir 	public void removeEventListener(XEventListener listener)
205cdf0e10cSrcweir 	{
206cdf0e10cSrcweir 		mComponents.remove(listener);
207cdf0e10cSrcweir 	}
208cdf0e10cSrcweir 
209cdf0e10cSrcweir 	/**
210cdf0e10cSrcweir 	 * Establishes the connection to the office.
211cdf0e10cSrcweir 	 */
connect()212cdf0e10cSrcweir 	private XComponentContext connect()
213cdf0e10cSrcweir 	{
214cdf0e10cSrcweir 		try
215cdf0e10cSrcweir 		{
216cdf0e10cSrcweir 			// create default local component context
217cdf0e10cSrcweir 			XComponentContext xLocalContext =
218cdf0e10cSrcweir 			    com.sun.star.comp.helper.Bootstrap.createInitialComponentContext(null);
219cdf0e10cSrcweir 
220cdf0e10cSrcweir 			// initial serviceManager
221cdf0e10cSrcweir 			XMultiComponentFactory xLocalServiceManager = xLocalContext.getServiceManager();
222cdf0e10cSrcweir 
223cdf0e10cSrcweir 			// create a urlresolver
224cdf0e10cSrcweir 			Object urlResolver  = xLocalServiceManager.createInstanceWithContext(
225cdf0e10cSrcweir 			    "com.sun.star.bridge.UnoUrlResolver", xLocalContext );
226cdf0e10cSrcweir 
227cdf0e10cSrcweir 			// query for the XUnoUrlResolver interface
228cdf0e10cSrcweir 			XUnoUrlResolver xUrlResolver =
229cdf0e10cSrcweir 			    (XUnoUrlResolver) UnoRuntime.queryInterface( XUnoUrlResolver.class, urlResolver );
230cdf0e10cSrcweir 
231cdf0e10cSrcweir 			// try to connect to soffice
232cdf0e10cSrcweir 			Object aInitialObject = null;
233cdf0e10cSrcweir 			try
234cdf0e10cSrcweir 			{
235cdf0e10cSrcweir 				aInitialObject = xUrlResolver.resolve( mURL );
236cdf0e10cSrcweir 			}
237cdf0e10cSrcweir 			catch( com.sun.star.connection.NoConnectException e )
238cdf0e10cSrcweir 			{
239cdf0e10cSrcweir 				// launch soffice
240cdf0e10cSrcweir 				OfficeService aSOffice = new OfficeService();
241cdf0e10cSrcweir 				aSOffice.startupService();
242cdf0e10cSrcweir 
243cdf0e10cSrcweir 				// wait until soffice is started
244cdf0e10cSrcweir 				long nMaxMillis = System.currentTimeMillis() + 1000*aSOffice.getStartupTime();
245cdf0e10cSrcweir 				while ( aInitialObject == null )
246cdf0e10cSrcweir 				{
247cdf0e10cSrcweir 					try
248cdf0e10cSrcweir 					{
249cdf0e10cSrcweir 						// try to connect to soffice
250cdf0e10cSrcweir 						Thread.currentThread().sleep( 500 );
251cdf0e10cSrcweir 						aInitialObject = xUrlResolver.resolve( mURL );
252cdf0e10cSrcweir 					}
253cdf0e10cSrcweir 					catch( com.sun.star.connection.NoConnectException aEx )
254cdf0e10cSrcweir 					{
255cdf0e10cSrcweir 						// soffice did not start in time
256cdf0e10cSrcweir 						if ( System.currentTimeMillis() > nMaxMillis )
257cdf0e10cSrcweir 							throw aEx;
258cdf0e10cSrcweir 
259cdf0e10cSrcweir 					}
260cdf0e10cSrcweir 				}
261cdf0e10cSrcweir 			}
262cdf0e10cSrcweir 			finally
263cdf0e10cSrcweir 			{
264cdf0e10cSrcweir 			}
265cdf0e10cSrcweir 
266cdf0e10cSrcweir 			// XComponentContext
267cdf0e10cSrcweir 			if( null != aInitialObject )
268cdf0e10cSrcweir 			{
269cdf0e10cSrcweir 				XPropertySet xPropertySet = (XPropertySet)
270cdf0e10cSrcweir 					UnoRuntime.queryInterface( XPropertySet.class, aInitialObject);
271cdf0e10cSrcweir             			Object xContext = xPropertySet.getPropertyValue("DefaultContext");
272cdf0e10cSrcweir             			XComponentContext xComponentContext = (XComponentContext) UnoRuntime.queryInterface(
273cdf0e10cSrcweir 					XComponentContext.class, xContext);
274cdf0e10cSrcweir 				return xComponentContext;
275cdf0e10cSrcweir 			}
276cdf0e10cSrcweir 		}
277cdf0e10cSrcweir 		catch( com.sun.star.connection.NoConnectException e )
278cdf0e10cSrcweir 		{
279cdf0e10cSrcweir 			System.out.println( "Couldn't connect to remote server" );
280cdf0e10cSrcweir 			System.out.println( e.getMessage() );
281cdf0e10cSrcweir 		}
282cdf0e10cSrcweir 		catch( com.sun.star.connection.ConnectionSetupException e )
283cdf0e10cSrcweir 		{
284cdf0e10cSrcweir 			System.out.println( "Couldn't access necessary local resource to establish the interprocess connection" );
285cdf0e10cSrcweir 			System.out.println( e.getMessage() );
286cdf0e10cSrcweir 		}
287cdf0e10cSrcweir 		catch( com.sun.star.lang.IllegalArgumentException e )
288cdf0e10cSrcweir 		{
289cdf0e10cSrcweir 			System.out.println( "uno-url is syntactical illegal ( " + mURL + " )" );
290cdf0e10cSrcweir 			System.out.println( e.getMessage() );
291cdf0e10cSrcweir 		}
292cdf0e10cSrcweir 		catch( com.sun.star.uno.RuntimeException e )
293cdf0e10cSrcweir 		{
294cdf0e10cSrcweir 			System.out.println( "--- RuntimeException:" );
295cdf0e10cSrcweir 			System.out.println( e.getMessage() );
296cdf0e10cSrcweir 			e.printStackTrace();
297cdf0e10cSrcweir 			System.out.println( "--- end." );
298cdf0e10cSrcweir 			throw e;
299cdf0e10cSrcweir 		}
300cdf0e10cSrcweir 		catch( java.lang.Exception e )
301cdf0e10cSrcweir 		{
302cdf0e10cSrcweir 			System.out.println( "java.lang.Exception: " );
303cdf0e10cSrcweir 			System.out.println( e );
304cdf0e10cSrcweir 			e.printStackTrace();
305cdf0e10cSrcweir 			System.out.println( "--- end." );
306cdf0e10cSrcweir 			throw new com.sun.star.uno.RuntimeException( e.toString() );
307cdf0e10cSrcweir 		}
308cdf0e10cSrcweir 
309cdf0e10cSrcweir 		return null;
310cdf0e10cSrcweir 	}
311cdf0e10cSrcweir 
312cdf0e10cSrcweir 	/**
313cdf0e10cSrcweir 	 * Retrives a path to the office program folder.
314cdf0e10cSrcweir 	 *
315cdf0e10cSrcweir 	 * @return The path to the office program folder.
316cdf0e10cSrcweir 	 */
getProgramPath()317cdf0e10cSrcweir 	private String getProgramPath()
318cdf0e10cSrcweir 	{
319cdf0e10cSrcweir 		if (mProgramPath == null)
320cdf0e10cSrcweir 		{
321cdf0e10cSrcweir 			// determine name of executable soffice
322cdf0e10cSrcweir 			String aExec = OFFICE_APP_NAME; // default for UNIX
323cdf0e10cSrcweir 			String aOS = System.getProperty("os.name");
324cdf0e10cSrcweir 
325cdf0e10cSrcweir 			// running on Windows?
326cdf0e10cSrcweir 			if (aOS.startsWith("Windows"))
327cdf0e10cSrcweir 				aExec = OFFICE_APP_NAME + ".exe";
328cdf0e10cSrcweir 
329cdf0e10cSrcweir 			// add other non-UNIX operating systems here
330cdf0e10cSrcweir 			// ...
331cdf0e10cSrcweir 
332cdf0e10cSrcweir 			// find soffice executable relative to this class's class loader:
333cdf0e10cSrcweir 			File path = NativeLibraryLoader.getResource(
334cdf0e10cSrcweir 				this.getClass().getClassLoader(), aExec);
335cdf0e10cSrcweir 			if (path != null) {
336cdf0e10cSrcweir 				mProgramPath = path.getParent();
337cdf0e10cSrcweir 		}
338cdf0e10cSrcweir 
339cdf0e10cSrcweir 			// default is ""
340cdf0e10cSrcweir 			if ( mProgramPath == null )
341cdf0e10cSrcweir 				mProgramPath = "";
342cdf0e10cSrcweir 		}
343cdf0e10cSrcweir 		return mProgramPath;
344cdf0e10cSrcweir 	}
345cdf0e10cSrcweir 
346cdf0e10cSrcweir 	/**
347cdf0e10cSrcweir 	 * Parses a connection URL.
348cdf0e10cSrcweir 	 * This method accepts a UNO URL with following format:<br />
349cdf0e10cSrcweir 	 * <pre>
350cdf0e10cSrcweir 	 * url    := uno:localoffice[,&lt;params&gt;];urp;StarOffice.NamingService
351cdf0e10cSrcweir 	 * params := &lt;path&gt;[,&lt;pipe&gt;]
352cdf0e10cSrcweir 	 * path   := path=&lt;pathv&gt;
353cdf0e10cSrcweir 	 * pipe   := pipe=&lt;pipev&gt;
354cdf0e10cSrcweir 	 * pathv  := platform_specific_path_to_the_local_office_distribution
355cdf0e10cSrcweir 	 * pipev  := local_office_connection_pipe_name
356cdf0e10cSrcweir 	 * </pre>
357cdf0e10cSrcweir 	 *
358cdf0e10cSrcweir 	 * <h4>Examples</h4>
359cdf0e10cSrcweir 	 * <ul>
360cdf0e10cSrcweir 	 * 	<li>"uno:localoffice,pipe=xyz_Office,path=/opt/openoffice11/program;urp;StarOffice.ServiceManager";
361cdf0e10cSrcweir 	 * 	<li>"uno:socket,host=localhost,port=8100;urp;StarOffice.ServiceManager";
362cdf0e10cSrcweir 	 * </ul>
363cdf0e10cSrcweir 	 *
364cdf0e10cSrcweir 	 * @param url This is UNO URL which describes the type of a connection.
365cdf0e10cSrcweir 	 * @exception java.net.MalformedURLException when inappropreate URL was
366cdf0e10cSrcweir 	 *	provided.
367cdf0e10cSrcweir 	 */
parseUnoUrlWithOfficePath(String url, String prefix)368cdf0e10cSrcweir 	private void parseUnoUrlWithOfficePath(String url, String prefix)
369cdf0e10cSrcweir 		throws java.net.MalformedURLException
370cdf0e10cSrcweir 	{
371cdf0e10cSrcweir 		// Extruct parameters.
372cdf0e10cSrcweir 		int	idx	= url.indexOf(";urp;StarOffice.NamingService");
373cdf0e10cSrcweir 		if (idx < 0)
374cdf0e10cSrcweir 			throw new java.net.MalformedURLException(
375cdf0e10cSrcweir 				"Invalid UNO connection URL.");
376cdf0e10cSrcweir 		String	params	= url.substring(prefix.length(), idx + 1);
377cdf0e10cSrcweir 
378cdf0e10cSrcweir 		// Parse parameters.
379cdf0e10cSrcweir 		String	name	= null;
380cdf0e10cSrcweir 		String	path	= null;
381cdf0e10cSrcweir 		String	pipe	= null;
382cdf0e10cSrcweir 		char	ch;
383cdf0e10cSrcweir 		int		state	= 0;
384cdf0e10cSrcweir 		StringBuffer	buffer	= new StringBuffer();
385cdf0e10cSrcweir 		for(idx = 0; idx < params.length(); idx += 1) {
386cdf0e10cSrcweir 			ch	= params.charAt(idx);
387cdf0e10cSrcweir 			switch (state) {
388cdf0e10cSrcweir 			case 0:	// initial state
389cdf0e10cSrcweir 				switch(ch) {
390cdf0e10cSrcweir 				case ',':
391cdf0e10cSrcweir 					buffer.delete(0, buffer.length());
392cdf0e10cSrcweir 					state	= 1;
393cdf0e10cSrcweir 					break;
394cdf0e10cSrcweir 
395cdf0e10cSrcweir 				case ';':
396cdf0e10cSrcweir 					state	= 7;
397cdf0e10cSrcweir 					break;
398cdf0e10cSrcweir 
399cdf0e10cSrcweir 				default:
400cdf0e10cSrcweir 					buffer.delete(0, buffer.length());
401cdf0e10cSrcweir 					buffer.append(ch);
402cdf0e10cSrcweir 					state	= 1;
403cdf0e10cSrcweir 					break;
404cdf0e10cSrcweir 				}
405cdf0e10cSrcweir 				break;
406cdf0e10cSrcweir 
407cdf0e10cSrcweir 			case 1:	// parameter name
408cdf0e10cSrcweir 				switch(ch) {
409cdf0e10cSrcweir 				case ' ':
410cdf0e10cSrcweir 				case '=':
411cdf0e10cSrcweir 					name	= buffer.toString();
412cdf0e10cSrcweir 					state	= (ch == ' ')? 2: 3;
413cdf0e10cSrcweir 					break;
414cdf0e10cSrcweir 
415cdf0e10cSrcweir 				case ',':
416cdf0e10cSrcweir 				case ';':
417cdf0e10cSrcweir 					state	= -6;			// error: invalid name
418cdf0e10cSrcweir 					break;
419cdf0e10cSrcweir 
420cdf0e10cSrcweir 				default:
421cdf0e10cSrcweir 					buffer.append(ch);
422cdf0e10cSrcweir 					break;
423cdf0e10cSrcweir 				}
424cdf0e10cSrcweir 				break;
425cdf0e10cSrcweir 
426cdf0e10cSrcweir 			case 2:	// equal between the name and the value
427cdf0e10cSrcweir 				switch(ch) {
428cdf0e10cSrcweir 				case '=':
429cdf0e10cSrcweir 					state	= 3;
430cdf0e10cSrcweir 					break;
431cdf0e10cSrcweir 
432cdf0e10cSrcweir 				case ' ':
433cdf0e10cSrcweir 					break;
434cdf0e10cSrcweir 
435cdf0e10cSrcweir 				default:
436cdf0e10cSrcweir 					state	= -1;			// error: missing '='
437cdf0e10cSrcweir 					break;
438cdf0e10cSrcweir 				}
439cdf0e10cSrcweir 				break;
440cdf0e10cSrcweir 
441cdf0e10cSrcweir 			case 3:	// value leading spaces
442cdf0e10cSrcweir 				switch(ch) {
443cdf0e10cSrcweir 				case ' ':
444cdf0e10cSrcweir 					break;
445cdf0e10cSrcweir 
446cdf0e10cSrcweir 				default:
447cdf0e10cSrcweir 					buffer.delete(0, buffer.length());
448cdf0e10cSrcweir 					buffer.append(ch);
449cdf0e10cSrcweir 					state	= 4;
450cdf0e10cSrcweir 					break;
451cdf0e10cSrcweir 				}
452cdf0e10cSrcweir 				break;
453cdf0e10cSrcweir 
454cdf0e10cSrcweir 			case 4:	// value
455cdf0e10cSrcweir 				switch(ch) {
456cdf0e10cSrcweir 				case ' ':
457cdf0e10cSrcweir 				case ',':
458cdf0e10cSrcweir 				case ';':
459cdf0e10cSrcweir 					idx 	-= 1;			// put back the last read character
460cdf0e10cSrcweir 					state	= 5;
461cdf0e10cSrcweir 					if (name.equals("path")) {
462cdf0e10cSrcweir 						if (path == null)
463cdf0e10cSrcweir 							path	= buffer.toString();
464cdf0e10cSrcweir 						else
465cdf0e10cSrcweir 							state	= -3;	// error: more then one 'path'
466cdf0e10cSrcweir 					} else if (name.equals("pipe")) {
467cdf0e10cSrcweir 						if (pipe == null)
468cdf0e10cSrcweir 							pipe	= buffer.toString();
469cdf0e10cSrcweir 						else
470cdf0e10cSrcweir 							state	= -4;	// error: more then one 'pipe'
471cdf0e10cSrcweir 					} else
472cdf0e10cSrcweir 						state	= -2;		// error: unknown parameter
473cdf0e10cSrcweir 					buffer.delete(0, buffer.length());
474cdf0e10cSrcweir 					break;
475cdf0e10cSrcweir 
476cdf0e10cSrcweir 				default:
477cdf0e10cSrcweir 					buffer.append(ch);
478cdf0e10cSrcweir 					break;
479cdf0e10cSrcweir 				}
480cdf0e10cSrcweir 				break;
481cdf0e10cSrcweir 
482cdf0e10cSrcweir 			case 5:	// a delimeter after the value
483cdf0e10cSrcweir 				switch(ch) {
484cdf0e10cSrcweir 				case ' ':
485cdf0e10cSrcweir 					break;
486cdf0e10cSrcweir 
487cdf0e10cSrcweir 				case ',':
488cdf0e10cSrcweir 					state	= 6;
489cdf0e10cSrcweir 					break;
490cdf0e10cSrcweir 
491cdf0e10cSrcweir 				case ';':
492cdf0e10cSrcweir 					state	= 7;
493cdf0e10cSrcweir 					break;
494cdf0e10cSrcweir 
495cdf0e10cSrcweir 				default:
496cdf0e10cSrcweir 					state	= -5;			// error: ' ' inside the value
497cdf0e10cSrcweir 					break;
498cdf0e10cSrcweir 				}
499cdf0e10cSrcweir 				break;
500cdf0e10cSrcweir 
501cdf0e10cSrcweir 			case 6:	// leading spaces before next parameter name
502cdf0e10cSrcweir 				switch(ch) {
503cdf0e10cSrcweir 				case ' ':
504cdf0e10cSrcweir 					break;
505cdf0e10cSrcweir 
506cdf0e10cSrcweir 				default:
507cdf0e10cSrcweir 					buffer.delete(0, buffer.length());
508cdf0e10cSrcweir 					buffer.append(ch);
509cdf0e10cSrcweir 					state	= 1;
510cdf0e10cSrcweir 					break;
511cdf0e10cSrcweir 				}
512cdf0e10cSrcweir 				break;
513cdf0e10cSrcweir 
514cdf0e10cSrcweir 			default:
515cdf0e10cSrcweir 				throw new java.net.MalformedURLException(
516cdf0e10cSrcweir 					"Invalid UNO connection URL.");
517cdf0e10cSrcweir 			}
518cdf0e10cSrcweir 		}
519cdf0e10cSrcweir 		if (state != 7)
520cdf0e10cSrcweir 			throw new java.net.MalformedURLException(
521cdf0e10cSrcweir 				"Invalid UNO connection URL.");
522cdf0e10cSrcweir 
523cdf0e10cSrcweir 		// Set up the connection parameters.
524cdf0e10cSrcweir 		if (path != null)
525cdf0e10cSrcweir 			mProgramPath = path;
526cdf0e10cSrcweir 		if (pipe != null)
527cdf0e10cSrcweir 			mPipe = pipe;
528cdf0e10cSrcweir 	}
529cdf0e10cSrcweir 
530cdf0e10cSrcweir 	/* replaces each substring aSearch in aString by aReplace.
531cdf0e10cSrcweir 
532cdf0e10cSrcweir 		StringBuffer.replaceAll() is not avaialable in Java 1.3.x.
533cdf0e10cSrcweir 	 */
replaceAll(String aString, String aSearch, String aReplace )534cdf0e10cSrcweir     private static String replaceAll(String aString, String aSearch, String aReplace )
535cdf0e10cSrcweir     {
536cdf0e10cSrcweir         StringBuffer aBuffer = new StringBuffer(aString);
537cdf0e10cSrcweir 
538cdf0e10cSrcweir         int nPos = aString.length();
539cdf0e10cSrcweir         int nOfs = aSearch.length();
540cdf0e10cSrcweir 
541cdf0e10cSrcweir         while ( ( nPos = aString.lastIndexOf( aSearch, nPos - 1 ) ) > -1 )
542cdf0e10cSrcweir             aBuffer.replace( nPos, nPos+nOfs, aReplace );
543cdf0e10cSrcweir 
544cdf0e10cSrcweir         return aBuffer.toString();
545cdf0e10cSrcweir     }
546cdf0e10cSrcweir 
547cdf0e10cSrcweir 
548cdf0e10cSrcweir 	/** creates a unique pipe name.
549cdf0e10cSrcweir 	*/
getPipeName()550cdf0e10cSrcweir 	static String getPipeName()
551cdf0e10cSrcweir 	{
552cdf0e10cSrcweir 		// turn user name into a URL and file system safe name (% chars will not work)
553cdf0e10cSrcweir 		String aPipeName = System.getProperty("user.name") + OFFICE_ID_SUFFIX;
554cdf0e10cSrcweir 		aPipeName = replaceAll( aPipeName, "_", "%B7" );
555cdf0e10cSrcweir 		return replaceAll( replaceAll( java.net.URLEncoder.encode(aPipeName), "\\+", "%20" ), "%", "_" );
556cdf0e10cSrcweir 	}
557cdf0e10cSrcweir 
558cdf0e10cSrcweir 	/**
559cdf0e10cSrcweir 	 * @para This is an implementation of the native office service.
560cdf0e10cSrcweir      * @deprecated
561cdf0e10cSrcweir 	 */
562cdf0e10cSrcweir 	private class OfficeService
563cdf0e10cSrcweir 		implements NativeService
564cdf0e10cSrcweir 	{
565cdf0e10cSrcweir 		/**
566cdf0e10cSrcweir 		 * Retrive the office service identifier.
567cdf0e10cSrcweir 		 *
568cdf0e10cSrcweir 		 * @return The identifier of the office service.
569cdf0e10cSrcweir 		 */
getIdentifier()570cdf0e10cSrcweir 		public String getIdentifier()
571cdf0e10cSrcweir 		{
572cdf0e10cSrcweir 			if ( mPipe == null)
573cdf0e10cSrcweir 				return getPipeName();
574cdf0e10cSrcweir 			else
575cdf0e10cSrcweir 				return mPipe;
576cdf0e10cSrcweir 		}
577cdf0e10cSrcweir 
578cdf0e10cSrcweir 		/**
579cdf0e10cSrcweir 		 * Starts the office process.
580cdf0e10cSrcweir 		 */
startupService()581cdf0e10cSrcweir 		public void startupService()
582cdf0e10cSrcweir 			throws java.io.IOException
583cdf0e10cSrcweir 		{
584cdf0e10cSrcweir            // create call with arguments
585cdf0e10cSrcweir 			String[] cmdArray = new String[4];
586cdf0e10cSrcweir 			cmdArray[0] = (new File(getProgramPath(), OFFICE_APP_NAME)).getPath();
587cdf0e10cSrcweir 			cmdArray[1] = "-nologo";
588cdf0e10cSrcweir 			cmdArray[2] = "-nodefault";
589cdf0e10cSrcweir 			if ( mConnType.equals( "pipe" ) )
590cdf0e10cSrcweir 				cmdArray[3] = "-accept=pipe,name=" + getIdentifier() + ";" +
591cdf0e10cSrcweir 						  mProtocol + ";" + mInitialObject;
592cdf0e10cSrcweir 			else if ( mConnType.equals( "socket" ) )
593cdf0e10cSrcweir 				cmdArray[3] = "-accept=socket,port=" + mPort + ";urp";
594cdf0e10cSrcweir 			else
595cdf0e10cSrcweir 				throw new java.io.IOException( "not connection specified" );
596cdf0e10cSrcweir 
597cdf0e10cSrcweir 			// start process
598cdf0e10cSrcweir 			mProcess = Runtime.getRuntime().exec(cmdArray);
599cdf0e10cSrcweir 			if ( mProcess == null )
600cdf0e10cSrcweir 				throw new RuntimeException( "cannot start soffice: " + cmdArray );
601cdf0e10cSrcweir 		}
602cdf0e10cSrcweir 
603cdf0e10cSrcweir 		/**
604cdf0e10cSrcweir 		 * Retrives the ammount of time to wait for the startup.
605cdf0e10cSrcweir 		 *
606cdf0e10cSrcweir 		 * @return The ammount of time to wait in seconds(?).
607cdf0e10cSrcweir 		 */
getStartupTime()608cdf0e10cSrcweir 		public int getStartupTime()
609cdf0e10cSrcweir 		{
610cdf0e10cSrcweir 			return 60;
611cdf0e10cSrcweir 		}
612cdf0e10cSrcweir 	}
613cdf0e10cSrcweir }
614