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