xref: /aoo41x/main/bean/com/sun/star/comp/beans/OOoBean.java (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 package com.sun.star.comp.beans;
29 
30 import com.sun.star.uno.UnoRuntime;
31 
32 // @requirement FUNC.PERF.LRN/0.6
33 // @requirement FUNC.PERF.LOC/0.6
34 // @requirement FUNC.PERF.FIX/0.6
35 /** This is the basic JavaBean for all OOo application modules.
36 
37     @requirement FUNC.RES.OTH/0.2
38     	No other resources are needed yet.
39 
40     @since OOo 2.0.0
41  */
42 public class OOoBean
43 
44 	// @requirement FUNC.BEAN.VIEW/0.4
45 	extends java.awt.Container
46 
47 	implements
48 		// @requirement FUNC.PER/0.2
49 		java.io.Externalizable
50 {
51 	// timeout values (milli secs)
52 	int nOOoStartTimeOut = 60000;
53 	int nOOoCallTimeOut =   3000;
54 	int nOOoCheckCycle =    1000;
55 
56 	// This member contains the connection to an OOo instance if established.
57 	private transient OfficeConnection		iConnection;
58 	private transient EventListener			xConnectionListener;
59 
60 	// @requirement FUNC.BEAN.VIEW/0.4
61 	// @requirement FUNC.BEAN.EDIT/0.4
62 	// This member contains the OOo window
63 	// if a connection is established.
64 	// It is a child of the OOoBean canvas.
65 	private OfficeWindow xFrameWindow;
66 
67 	// application environment
68 	private transient com.sun.star.lang.XMultiServiceFactory xServiceFactory;
69 	private transient com.sun.star.frame.XDesktop xDesktop;
70 
71 	// document and frame
72 	private transient Frame aFrame;
73 	private transient Controller aController;
74 	private transient OfficeDocument aDocument;
75 
76 	// slot command execution environment
77 	private transient com.sun.star.frame.XDispatchProvider xDispatcher;
78 	private transient com.sun.star.util.XURLTransformer xURLTransformer;
79 
80 	// properties
81 	private boolean bIgnoreVisibility = false; // to show even if already visible
82     private boolean bMenuBarVisible = true;
83     private boolean bStandardBarVisible = true;
84     private boolean bToolBarVisible = true;
85     private boolean bStatusBarVisible = true;
86 
87 
88 	// debugging method
89 	private void dbgPrint( String aMessage )
90 	{
91 		// System.err.println( "OOoBean: " + aMessage );
92 	}
93 
94 	// @requirement FUNC.PER/0.2
95 	/** @internal
96      *  @deprecated
97 	 */
98 	public void writeExternal( java.io.ObjectOutput aObjOut )
99 	{
100 		// TBD
101 	}
102 
103 	// @requirement FUNC.PER/0.2
104 	/** @internal
105      *  @deprecated
106 	 */
107 	public void readExternal( java.io.ObjectInput aObjIn )
108 	{
109 		// TBD
110 	}
111 
112 	/** Generic constructor of the OOoBean.
113 
114 	    Neither a connection is established nor any document loaded.
115 	 */
116 	public OOoBean()
117 	{}
118 
119    	// @requirement FUNC.CON.MULT/0.3
120 	/** Constructor for an OOoBean which uses a specific office connection.
121 
122 	    The connection must be established but no document is loaded.
123 
124 	    @throws NoConnectionException
125 	    	if the connection is not established.
126 
127         @deprecated Clients could use the getOOoConnection to obtain an OfficeConnection
128         and use it as argument in a constructor for another OOoBean instance. Calling
129         the dispose method of the OfficeConnection or the OOoBean's stopOOoConnection
130         method would make all instances of OOoBean stop working.
131 	 */
132 	public OOoBean( OfficeConnection iConnection )
133 		throws NoConnectionException
134 	{
135 		try { setOOoConnection( iConnection ); }
136 		catch ( HasConnectionException aExc )
137 		{ /* impossible here */ }
138 	}
139 
140 	/** Sets the timeout for methods which launch OOo in milli seconds.
141 
142 		This method does not need a connection to an OOo instance.
143 	 */
144 	public void setOOoStartTimeOut( int nMilliSecs )
145 	{
146 		nOOoStartTimeOut = nMilliSecs;
147 	}
148 
149 	/** Sets the timeout for normal OOO methods calls in milli seconds.
150 
151 		This method does not need a connection to an OOo instance.
152 	 */
153 	public void setOOoCallTimeOut( int nMilliSecs )
154 	{
155 		nOOoCallTimeOut = nMilliSecs;
156 	}
157 
158 	/** Sets the period length in milli seconds to check the OOo connection.
159 
160 		This method does not need a connection to an OOo instance.
161 	 */
162 	public void setOOoCheckCycle( int nMilliSecs )
163 	{
164 		nOOoCheckCycle = nMilliSecs;
165 	}
166 
167 	/** Sets the a connection to an OOo instance.
168 
169 	    @internal
170 	 */
171 	private synchronized void setOOoConnection( OfficeConnection iNewConnection )
172 		throws	HasConnectionException, NoConnectionException
173 	{
174 		// the connection cannot be exchanged
175 		if ( iConnection != null )
176 			throw new HasConnectionException();
177 
178 		// is there a real connection, not just the proxy?
179 		com.sun.star.uno.XComponentContext xComponentContext = null;
180 		try { xComponentContext = iNewConnection.getComponentContext(); }
181 		catch ( java.lang.Throwable aExc )
182 		{ throw new NoConnectionException(); }
183 		if ( xComponentContext == null )
184 			throw new NoConnectionException();
185 
186 		// set the connection
187 		iConnection = iNewConnection;
188 
189 		// get notified when connection dies
190 		if ( xConnectionListener != null )
191 			xConnectionListener.end();
192 		xConnectionListener = this.new EventListener("setOOoConnection");
193 	}
194 
195 	// @requirement FUNC.CON.STRT/0.4
196 	/** Starts a connection to an OOo instance which is lauched if not running.
197 
198 		@throws HasConnectionException
199 			if a connection was already established.
200 
201 		@throws NoConnectionException
202 			if the specified connection cannot be established
203 	 */
204 	public void startOOoConnection( String aConnectionURL )
205 		throws	java.net.MalformedURLException,
206 			HasConnectionException,
207 			NoConnectionException
208 	{
209 		// create a new connection from the given connection URL
210 		LocalOfficeConnection aConnection = new LocalOfficeConnection();
211 		aConnection.setUnoUrl( aConnectionURL );
212 		setOOoConnection( aConnection );
213 	}
214 
215 	// @requirement FUNC.CON.CHK/0.7
216 	/** Returns true if this OOoBean is connected to an OOo instance,
217 	    false otherwise.
218 
219         @deprecated This method is not useful in a multithreaded environment. Then
220         all threads accessing the instance would have to be synchronized in order to
221         make is method work. It is better
222         to call OOoBean's methods and be prepared to catch a NoConnectionException.
223 	 */
224 	public boolean isOOoConnected()
225 	{
226 		return iConnection != null;
227 	}
228 
229 	// @requirement FUNC.CON.STOP/0.4
230 	/** Disconnects from the connected OOo instance.
231 
232 		If there was no connection yet or anymore, this method can be called
233 		anyway.
234 
235         When the OOoBean is displayed in an applet by a web browser, then this
236         method must be called from within java.applet.Applet.stop.
237 	 */
238 	public synchronized void stopOOoConnection()
239 	{
240 		// clear OOo document, frame etc.
241 		clear();
242 
243 		// cut the connection
244 		OfficeConnection iExConnection = iConnection;
245 		if ( iConnection != null )
246 		{
247 			if ( xConnectionListener != null )
248 			{
249 				xConnectionListener.end();
250 			}
251 			iConnection = null;
252 			iExConnection.dispose();
253 		}
254 
255 	}
256 
257 	// @requirement FUNC.CON.STOP/0.4 (via XComponent.dispose())
258    	// @requirement FUNC.CON.NTFY/0.4 (via XComponent.addEventListener())
259 	/** Returns the a connection to an OOo instance.
260 
261 	    If no connection exists, a default connection will be created. An OfficeConnection
262         can be used to register listeners of type com.sun.star.lang.EventListener,
263         which are notified when the connection to the
264         office dies. One should not call the dispose method, because this may result
265         in receiving com.sun.star.lang.DisposedExceptions when calling
266         {@link #stopOOoConnection stopOOoConnection} or other API methods. If other instances share the
267         same connection then they will stop function properly, because they loose their
268         connection as well. The recommended way to end the connection is
269         calling {@link #stopOOoConnection stopOOoConnection}.
270 
271 		@throws NoConnectionException
272 			if no connection can be established
273 
274 	 */
275 	public synchronized OfficeConnection getOOoConnection()
276 		throws NoConnectionException
277 	{
278 		if ( iConnection == null )
279 		{
280 			try { setOOoConnection( new LocalOfficeConnection() ); }
281 			catch ( HasConnectionException aExc )
282 			{ /* impossible here */ }
283 		}
284 		if ( iConnection.getComponentContext() == null )
285 			throw new NoConnectionException();
286 		return iConnection;
287 	}
288 
289 	/**	Returns the service factory used by this OOoBean instance.
290 
291 		@throws NoConnectionException
292 			if no connection is established and no default connection can be established.
293 	 */
294 	public synchronized com.sun.star.lang.XMultiServiceFactory getMultiServiceFactory()
295 		throws NoConnectionException
296 	{
297 		if ( xServiceFactory == null )
298 		{
299 			// avoid concurrent access from multiple threads
300 			final OfficeConnection iConn = getOOoConnection();
301 
302 			Thread aConnectorThread = new Thread() {
303 				public void run()
304 				{
305 					com.sun.star.lang.XMultiComponentFactory aFactory =
306 						iConn.getComponentContext().getServiceManager();
307 					xServiceFactory	= (com.sun.star.lang.XMultiServiceFactory)
308 						UnoRuntime.queryInterface(
309 							com.sun.star.lang.XMultiServiceFactory.class, aFactory );
310 				}
311 			};
312 			aConnectorThread.start();
313 			try { aConnectorThread.join(nOOoStartTimeOut); }
314 			catch ( java.lang.InterruptedException aExc )
315 			{ throw new NoConnectionException(); }
316 			if ( xServiceFactory == null )
317 				throw new NoConnectionException();
318 		}
319 
320 		return xServiceFactory;
321 	}
322 
323 	/** Returns the XDesktop interface of the OOo instance used by this OOoBean.
324 
325 		@throws NoConnectionException
326 			if no connection is established and no default connection can be established.
327 	 */
328 	public synchronized com.sun.star.frame.XDesktop getOOoDesktop()
329 		throws NoConnectionException
330 	{
331 		if ( xDesktop == null )
332 		{
333 			try
334 			{
335 				Object aObject = getMultiServiceFactory().createInstance( "com.sun.star.frame.Desktop");
336 				xDesktop = (com.sun.star.frame.XDesktop) UnoRuntime.queryInterface(
337 						com.sun.star.frame.XDesktop.class, aObject );
338 			}
339 			catch ( com.sun.star.uno.Exception aExc )
340 			{} // TBD: what if no connection exists?
341 		}
342 
343 		return xDesktop;
344 	}
345 
346 	/** Resets this bean to an empty document.
347 
348 	   If a document is loaded and the content modified,
349 	   the changes are dismissed.  Otherwise nothing happens.
350 
351 	   This method is intended to be overridden in derived classes.
352        This implementation simply calls clear.
353 
354 	   @param bClearStateToo
355 	   	Not only the document content but also the state of the bean,
356 		like visibility of child components is cleared.
357 
358         @deprecated There is currently no way to dismiss changes, except for loading
359         of the unchanged initial document. Furthermore it is unclear how derived classes
360         handle this and what exactly their state is (e.g. what members make up their state).
361         Calling this method on a derived class requires knowledge about their implementation.
362         Therefore a deriving class should declare their own clearDocument if needed. Clients
363         should call the clearDocument of the deriving class or {@link #clear} which discards
364         the currently displayed document.
365 	 */
366 	public synchronized void clearDocument( boolean bClearStateToo )
367 		throws
368 			com.sun.star.util.CloseVetoException,
369 			NoConnectionException
370 	{
371 		// TBD
372         clear();
373 	}
374 
375 	/** Resets the OOoBean to an empty status.
376 
377 	    Any loaded document is unloaded, no matter whether it is modified or not.
378 	    After calling this method, the OOoBean has no office document and no frame
379 	    anymore.  The connection will stay, though.
380 
381 		This method works with or without an established connection.
382 	 */
383 	public synchronized void clear()
384 	{
385 		dbgPrint( "clear()" );
386 
387 		try
388 		{
389 			CallWatchThread aCallWatchThread =
390 				new CallWatchThread( nOOoCallTimeOut, "clear" );
391             //By closing the frame we avoid that dialogs are displayed, for example when
392             //the document is modified.
393         	com.sun.star.util.XCloseable xCloseable = (com.sun.star.util.XCloseable)
394     			UnoRuntime.queryInterface( com.sun.star.util.XCloseable.class, aFrame );
395         	if ( xCloseable != null )
396             {
397                 try
398                 {
399                     xCloseable.close(true);
400                 }
401                 catch (com.sun.star.util.CloseVetoException exc)
402                 { // a print job may be running
403                 }
404             }
405 
406 			aDocument = null;
407 			xDispatcher = null;
408 			aFrame = null;
409 
410 			// clear xFrameWindow
411 			if ( xFrameWindow != null )
412 			{
413 				try { releaseSystemWindow(); }
414 				catch ( NoConnectionException aExc )
415 				{} // ignore
416 				catch ( SystemWindowException aExc )
417 				{} // ignore
418 				remove( xFrameWindow.getAWTComponent() );
419 				xFrameWindow = null;
420 			}
421 
422 			// clear xURTTransformer
423 			if ( xURLTransformer != null )
424 			{
425 				try
426 				{
427 					com.sun.star.lang.XComponent xComp = (com.sun.star.lang.XComponent)
428 						UnoRuntime.queryInterface(
429 							com.sun.star.lang.XComponent.class, xURLTransformer );
430 					if ( xComp != null )
431 						xComp.dispose();
432 				}
433 				catch ( java.lang.Throwable aExc )
434 				{} // ignore
435 				xURLTransformer = null;
436 			}
437 
438 			xDesktop = null;
439 			xServiceFactory = null;
440 
441 			aCallWatchThread.cancel();
442 		}
443 		catch ( java.lang.InterruptedException aExc )
444 		{ /* can be ignored */ }
445 	}
446 
447 	// @requirement FUNC.PAR.LWP/0.4
448 	/** This method causes the office window to be displayed.
449 
450 	    If no document is loaded and the instance is added to a Java container that
451         is showing, then this method needs not to be called. If later one of the methods
452         {@link #loadFromURL loadFromURL}, {@link #loadFromStream loadFromStream1},
453         or {@link #loadFromByteArray loadFromByteArray}
454         is called, then the document is automatically displayed.
455 
456         Should one of the load methods have been called before the Java container
457         was showing, then this method needs to be called after the container window
458         was made visible (java.lang.Component.setVisible(true)).
459         <p>
460         Another scenario is that a OOoBean contains a document and is removed
461         from a Java container and later added again. Then aquireSystemWindow needs
462         to be called after the container window is displayed.
463 
464 	    @throws SystemWindowException
465 	    	if no system window can be aquired.
466 
467 	    @throws NoConnectionException
468 	    	if the connection is not established.
469 	 */
470 	public synchronized void aquireSystemWindow()
471 		throws
472 			SystemWindowException,
473 
474 			// @requirement FUNC.CON.LOST/0.2
475 			NoConnectionException
476 	{
477 		if ( iConnection == null )
478 			throw new NoConnectionException();
479 		if ( !isShowing() )
480 			throw new SystemWindowException();
481 
482 		if ( xFrameWindow != null )
483 			xFrameWindow.getAWTComponent().setVisible(true);
484 		doLayout();
485 	}
486 
487 	// @requirement FUNC.PAR.RWL/0.4
488 	// @estimation 16h
489 	/** This method must be called when the OOoBean before the
490 	    sytem window may be released by it's parent AWT/Swing component.
491 
492 	    This is the case when java.awt.Component.isDisplayable() returns
493 	    true.  This is definitely the case when the OOoBean is removed
494 	    from it's parent container.
495 
496 	    @throws SystemWindowException
497 	    	if system window is not aquired.
498 
499 	    @throws NoConnectionException
500 	    	if the connection is not established.
501 
502         @deprecated When Component.removeNotify of the parent window of the actual
503         office window is called, then the actions are performed for which this method
504         needed to be called previously.
505 	 */
506 	public synchronized void releaseSystemWindow()
507 		throws
508 			SystemWindowException,
509 
510 			// @requirement FUNC.CON.LOST/0.2
511 			NoConnectionException
512 	{
513 		if ( iConnection == null )
514 			throw new NoConnectionException();
515 
516 		try { xFrameWindow.getAWTComponent().setVisible(false); }
517 		catch ( com.sun.star.lang.DisposedException aExc )
518 		{ throw new NoConnectionException(); }
519 	}
520 
521    	// @requirement FUNC.BEAN.LOAD/0.4
522    	// @requirement FUNC.CON.AUTO/0.3
523 	/** Loads the bean from the given URL.
524 
525 	    If a document is already loaded and the content modified,
526 	    the changes are dismissed.
527 
528 	    If no connection exists, a default connection is established.
529 
530 	    @throws IllegalArgumentException
531 	    	if either of the arguments is out of the specified range.
532 
533 	    @throws java.io.IOException
534 	    	if an IO error occurs reading the ressource specified by the URL.
535 
536 	    @throws com.sun.star.lang.NoConnectionException
537 	    	if no connection can be established.
538 
539         @throws com.sun.star.util.CloseVetoException
540             if the currently displayed document cannot be closed because it is
541             still be used, for example it is printed.
542 	 */
543 	public void loadFromURL(
544 			final String aURL,
545 			final com.sun.star.beans.PropertyValue aArguments[] )
546 		throws
547 			// @requirement FUNC.CON.LOST/0.2
548 			NoConnectionException,
549 			java.io.IOException,
550 			com.sun.star.lang.IllegalArgumentException,
551             com.sun.star.util.CloseVetoException
552 	{
553 		dbgPrint( "loadFromURL()" );
554  		// try loading
555 		try
556 		{
557 			boolean bLoaded = false;
558 			while ( !bLoaded )
559 			{
560 				// watch loading in a thread with a timeout (if OOo hangs)
561 				CallWatchThread aCallWatchThread =
562 					new CallWatchThread( nOOoStartTimeOut, "loadFromURL" );
563 
564 				try
565 				{
566 					// get window from OOo on demand
567 					if ( xFrameWindow == null )
568 					{
569 						// Establish the connection by request of the ServiceFactory.
570 						getMultiServiceFactory();
571 
572 						// remove existing child windows
573 						removeAll();
574 
575 						// Create the OfficeWindow.
576 						xFrameWindow = getOOoConnection().createOfficeWindow(OOoBean.this);
577 						add( xFrameWindow.getAWTComponent() );
578 					}
579 
580 					// create the document frame from UNO window.
581 					if ( aFrame == null )
582 					{
583 						// create the frame
584 						com.sun.star.awt.XWindow xWindow =
585 							(com.sun.star.awt.XWindow) UnoRuntime.queryInterface(
586 							com.sun.star.awt.XWindow.class, xFrameWindow.getUNOWindowPeer());
587 						Object xFrame = xServiceFactory.createInstance( "com.sun.star.frame.Frame");
588 						aFrame = new Frame( (com.sun.star.frame.XFrame)UnoRuntime.queryInterface(
589 								com.sun.star.frame.XFrame.class, xFrame ) );
590 						aFrame.initialize( xWindow );
591 						aFrame.setName( aFrame.toString() );
592 
593 						// register the frame at the desktop
594 						com.sun.star.frame.XFrames xFrames =
595 								( (com.sun.star.frame.XFramesSupplier)UnoRuntime.queryInterface(
596 								com.sun.star.frame.XFramesSupplier.class, getOOoDesktop() ) ).getFrames();
597 						xFrames.append( aFrame );
598 					}
599 
600 					// Initializes the slot command execution environment.
601 					xURLTransformer	= (com.sun.star.util.XURLTransformer) UnoRuntime.queryInterface(
602 						com.sun.star.util.XURLTransformer.class,
603 						xServiceFactory.createInstance( "com.sun.star.util.URLTransformer") );
604 
605                                         try
606                                         {
607                                             xDispatcher = UnoRuntime.queryInterface(com.sun.star.frame.XDispatchProvider.class, aFrame);
608                                         }
609                                         catch (Exception e)
610                                         {
611                                             /*ignore!*/
612                                         }
613 
614 					// get XComponentLoader from frame
615 					com.sun.star.frame.XComponentLoader xLoader = (com.sun.star.frame.XComponentLoader)
616 						UnoRuntime.queryInterface( com.sun.star.frame.XComponentLoader.class, aFrame );
617 					if ( xLoader == null )
618 					{
619 						throw new java.lang.RuntimeException(
620 							"com.sun.star.frame.Frame(" + aFrame +
621 								") without com.sun.star.frame.XComponentLoader" );
622 					}
623 
624 					// Avoid Dialog 'Document changed' while reloading
625 					if ( aDocument != null )
626 					{
627                         try {
628                             aDocument.setModified(false);
629                         } catch (com.sun.star.beans.PropertyVetoException ep) {
630                             //it dosn't make sense to throw the exception here. The interface does not
631                             //offer a way to add/remove respective listeners.
632                         } catch (com.sun.star.lang.DisposedException ed) {
633                             // can be disposed if user closed document via UI
634                         }
635 
636                         com.sun.star.frame.XController xOldController = null;
637 						if ( aFrame != null )
638 							xOldController = aFrame.getController();
639 
640 						try
641 						{
642 
643 							if ( aFrame != null && xOldController != null )
644 								if (xOldController.suspend(true) == false)
645                                     throw new com.sun.star.util.CloseVetoException(
646                                             "Dokument is still being used and cannot be closed.", this);
647 
648 						}
649 						catch (java.lang.IllegalStateException exp)
650 						{}
651 					}
652 
653 					// load the document.
654 					com.sun.star.beans.PropertyValue aArgs[] =
655 						addArgument( aArguments, new com.sun.star.beans.PropertyValue(
656 							"MacroExecutionMode", -1,
657 							new Short( com.sun.star.document.MacroExecMode.USE_CONFIG ),
658 							com.sun.star.beans.PropertyState.DIRECT_VALUE ) );
659 									//String fn = aFRame.getName();
660 
661 					com.sun.star.lang.XComponent xComponent = xLoader.loadComponentFromURL(
662 						aURL, /*aFrame.getName()*/"_self", 0, aArgs );
663 
664 					// nothing loaded?
665 					if ( xComponent == null && aDocument != null )
666 					{
667 						// reactivate old document
668 						if ( aFrame != null && aFrame.getController() != null )
669 							aFrame.getController().suspend(false);
670 						aDocument.setModified(true);
671 
672 						// throw exception
673 						throw new java.io.IOException(
674 							"Can not load a document: \"" + aURL + "\"");
675 					}
676 					// mDocumentURL = aURL; TBD: still needed?
677 
678 					// Get document's XModifiable interface if any.
679 					aDocument = new OfficeDocument(
680 						(com.sun.star.frame.XModel) UnoRuntime.queryInterface(
681 						com.sun.star.frame.XModel.class, xComponent ) );
682 					bLoaded = true;
683 				}
684 				catch ( NoConnectionException aExc )
685 				{
686 					// stop, clear and retry
687 					stopOOoConnection();
688 				}
689 				catch ( com.sun.star.lang.DisposedException aExc )
690 				{
691 					// stop, clear and retry
692 					stopOOoConnection();
693 				}
694 				catch ( com.sun.star.uno.Exception aExc )
695 				{
696 					// TDB: handling failure in createInstance
697 					aExc.printStackTrace();
698 					throw new java.io.IOException();
699 				}
700 
701 				aCallWatchThread.cancel();
702 				if ( xServiceFactory == null )
703 					throw new NoConnectionException();
704 			}
705 			if ( iConnection == null )
706 			{
707 				throw new NoConnectionException();
708 			}
709 
710 			applyToolVisibilities();
711 		}
712 		catch ( java.lang.InterruptedException aExc )
713 		{
714 			throw new NoConnectionException();
715 		}
716 	}
717 
718 	/** Loads a document from a Java stream.
719 
720 	   	See loadFromURL() for further information.
721 	 */
722 	public void loadFromStream(
723 			final java.io.InputStream iInStream,
724 			final com.sun.star.beans.PropertyValue aArguments[] )
725 		throws
726 			// @requirement FUNC.CON.LOST/0.2
727 			NoConnectionException,
728 			java.io.IOException,
729 			com.sun.star.lang.IllegalArgumentException,
730             com.sun.star.util.CloseVetoException
731 	{
732 		// wrap Java stream into UNO stream
733                 /*
734 		com.sun.star.io.XInputStream xStream =
735 				new com.sun.star.lib.uno.adapter.InputStreamToXInputStreamAdapter(
736 					iInStream );
737                  */
738                  // copy stream....
739 
740                  int s = 4096;
741                  int r=0 ,n = 0;
742                  byte[] buffer = new byte[s];
743                  byte[] newBuffer = null;
744                  while ((r = iInStream.read(buffer, n, buffer.length-n))>0) {
745                      n += r;
746                      if (iInStream.available() > buffer.length - n) {
747                          newBuffer = new byte[buffer.length*2];
748                          System.arraycopy(buffer, 0, newBuffer, 0, n);
749                          buffer = newBuffer;
750                      }
751                 }
752                 if (buffer.length != n) {
753                     newBuffer = new byte[n];
754                     System.arraycopy(buffer, 0, newBuffer, 0, n);
755                     buffer = newBuffer;
756                 }
757                 com.sun.star.io.XInputStream xStream =
758                     new com.sun.star.lib.uno.adapter.ByteArrayToXInputStreamAdapter(buffer);
759 
760 		// add stream to arguments
761 		com.sun.star.beans.PropertyValue[] aExtendedArguments =
762 			addArgument( aArguments, new com.sun.star.beans.PropertyValue(
763 				"InputStream", -1, xStream, com.sun.star.beans.PropertyState.DIRECT_VALUE ) );
764 
765 		// call normal load method
766 		loadFromURL( "private:stream", aExtendedArguments );
767 	}
768 
769 	/** Loads a document from a byte array.
770 
771 	   	See loadFromURL() for further information.
772 	 */
773 	public void loadFromByteArray(
774 			final byte aInBuffer[],
775 			final com.sun.star.beans.PropertyValue aArguments[] )
776 		throws
777 			// @requirement FUNC.CON.LOST/0.2
778 			NoConnectionException,
779 			java.io.IOException,
780 			com.sun.star.lang.IllegalArgumentException,
781             com.sun.star.util.CloseVetoException
782 	{
783 		// wrap byte arrray into UNO stream
784 		com.sun.star.io.XInputStream xStream =
785 				new com.sun.star.lib.uno.adapter.ByteArrayToXInputStreamAdapter(
786 					aInBuffer );
787 
788 		// add stream to arguments
789 		com.sun.star.beans.PropertyValue[] aExtendedArguments =
790 			addArgument( aArguments, new com.sun.star.beans.PropertyValue(
791 				"InputStream", -1, xStream, com.sun.star.beans.PropertyState.DIRECT_VALUE ) );
792 
793 		// call normal load method
794 		loadFromURL( "private:stream", aExtendedArguments );
795 	}
796 
797 	/** Stores a document to the given URL.
798         <p>
799         Due due a bug (50651) calling this method may cause the office to crash,
800         when at the same time the office writes a backup of the document. This bug
801         also affects {@link #storeToByteArray storeToByteArray} and
802         {@link #storeToStream storeToStream}. The workaround
803         is to start the office with the option -norestore, which disables the automatic
804         backup and recovery mechanism. OOoBean offers currently no supported way of providing
805         startup options for OOo. But it is possible to set a Java property when starting
806         Java, which is examined by OOoBean:
807         <pre>
808             java -Dcom.sun.star.officebean.Options=-norestore  ...
809         </pre>
810         It is planned to offer a way of specifying startup options in a future version.
811         The property can be used until then. When using this property only one option
812         can be provided.
813 
814 	    @throws IllegalArgumentException
815 	    	if either of the arguments is out of the specified range.
816 
817 	    @throws java.io.IOException
818 	    	if an IO error occurs reading the ressource specified by the URL.
819 
820 	    @throws com.sun.star.lang.NoConnectionException
821 	    	if no connection is established.
822 
823 		@throws NoDocumentException
824 			if no document is loaded
825 	 */
826 	public void storeToURL(
827 			final String aURL,
828 			final com.sun.star.beans.PropertyValue aArguments[] )
829 		throws
830 			// @requirement FUNC.CON.LOST/0.2
831 			NoConnectionException,
832 			java.io.IOException,
833 			com.sun.star.lang.IllegalArgumentException,
834 			NoDocumentException
835 	{
836 		// no document available?
837 		if ( aDocument == null )
838 			throw new NoDocumentException();
839 
840 		try
841 		{
842 			// start runtime timeout
843 			CallWatchThread aCallWatchThread =
844 				new CallWatchThread( nOOoCallTimeOut, "storeToURL" );
845 
846 			// store the document
847 			try { aDocument.storeToURL( aURL, aArguments ); }
848 			catch ( com.sun.star.io.IOException aExc )
849 			{ throw new java.io.IOException(); }
850 
851 			// end runtime timeout
852 			aCallWatchThread.cancel();
853 		}
854 		catch ( java.lang.InterruptedException aExc )
855 		{ throw new NoConnectionException(); }
856 	}
857 
858 	/** Stores a document to a stream.
859 
860 	   	See {@link #storeToURL storeToURL} for further information.
861         @see #storeToURL storeToURL
862 	 */
863 	public java.io.OutputStream storeToStream(
864 			java.io.OutputStream aOutStream,
865 			final com.sun.star.beans.PropertyValue aArguments[] )
866 		throws
867 			// @requirement FUNC.CON.LOST/0.2
868 			NoConnectionException,
869 			NoDocumentException,
870 			java.io.IOException,
871 			com.sun.star.lang.IllegalArgumentException
872 
873 	{
874 		// wrap Java stream into UNO stream
875 		com.sun.star.lib.uno.adapter.OutputStreamToXOutputStreamAdapter aStream =
876 				new com.sun.star.lib.uno.adapter.OutputStreamToXOutputStreamAdapter(
877 					aOutStream );
878 
879 		// add stream to arguments
880 		com.sun.star.beans.PropertyValue[] aExtendedArguments =
881 			addArgument( aArguments, new com.sun.star.beans.PropertyValue(
882 				"OutputStream", -1, aStream, com.sun.star.beans.PropertyState.DIRECT_VALUE ) );
883 
884 		// call normal store method
885 		storeToURL( "private:stream", aExtendedArguments );
886 
887 		// get byte array from document stream
888 		try { aStream.closeOutput(); }
889 		catch ( com.sun.star.io.NotConnectedException aExc )
890 		{ /* TDB */ }
891 		catch ( com.sun.star.io.BufferSizeExceededException aExc )
892 		{ /* TDB */ }
893 		catch ( com.sun.star.io.IOException aExc )
894 		{ throw new java.io.IOException(); }
895 		return aOutStream;
896 	}
897 
898 	/** Stores a document to a byte array.
899 
900 	   	See {@link #storeToURL storeToURL} for further information.
901         @see #storeToURL storeToURL
902 	 */
903 	public byte[] storeToByteArray(
904 			byte aOutBuffer[],
905 			final com.sun.star.beans.PropertyValue aArguments[] )
906 		throws
907 			// @requirement FUNC.CON.LOST/0.2
908 			NoConnectionException,
909 			NoDocumentException,
910 			java.io.IOException,
911 			com.sun.star.lang.IllegalArgumentException
912 	{
913 		// wrap byte arrray into UNO stream
914 		com.sun.star.lib.uno.adapter.XOutputStreamToByteArrayAdapter aStream =
915 				new com.sun.star.lib.uno.adapter.XOutputStreamToByteArrayAdapter(
916 					aOutBuffer );
917 
918 		// add stream to arguments
919 		com.sun.star.beans.PropertyValue[] aExtendedArguments =
920 			addArgument( aArguments, new com.sun.star.beans.PropertyValue(
921 				"OutputStream", -1, aStream, com.sun.star.beans.PropertyState.DIRECT_VALUE ) );
922 
923 		// call normal store method
924 		storeToURL( "private:stream", aExtendedArguments );
925 
926 		// get byte array from document stream
927 		try { aStream.closeOutput(); }
928 		catch ( com.sun.star.io.NotConnectedException aExc )
929 		{ /* TDB */ }
930 		catch ( com.sun.star.io.BufferSizeExceededException aExc )
931 		{ /* TDB */ }
932 		catch ( com.sun.star.io.IOException aExc )
933 		{ throw new java.io.IOException(); }
934 		return aStream.getBuffer();
935 	}
936 
937 	// @requirement FUNC.BEAN.PROG/0.5
938 	// @requirement API.SIM.SEAP/0.2
939 	/** returns the <type scope="com::sun::star::frame">Frame</a>
940 	    of the bean.
941 
942 	    @returns
943 	    	a Java class which implements all interfaces which the service
944 		<type scope="com::sun::star::frame">Frame</a> implements.
945 		Thus, methods can be called directly without queryInterface.
946 		This feature might be implemented by UNO or explicitely coded.
947 
948 	    @throws NoConnectionException
949 	    	if the connection is not established.
950 
951 	    @throws NotDocumentException
952 	    	if no document is loaded an thus no frame is available.
953 	 */
954 	public Frame getFrame()
955 
956 		throws
957 			NoConnectionException // @requirement FUNC.CON.LOST/0.2
958 	{
959 		if ( iConnection == null )
960 			throw new NoConnectionException();
961 		return aFrame;
962 	}
963 
964    	// @requirement FUNC.BEAN.PROG/0.5
965    	// @requirement API.SIM.SEAP/0.2
966 	/** returns the <type scope="com::sun::star::frame::Controller"> of the bean.
967 
968 	    @returns
969 	    	a Java class which implements all interfaces which the service
970 		<type scope="com::sun::star::frame">Controller</a> implements.
971 		Thus, methods can be called directly without queryInterface.
972 		This feature might be implemented by UNO or explicitely coded.
973 
974 	    @throws NoConnectionException
975 	    	if the connection is not established.
976 	 */
977 	public Controller getController()
978 
979 		// @requirement FUNC.CON.LOST/0.2
980 		throws NoConnectionException
981 	{
982 		if ( iConnection == null )
983 			throw new NoConnectionException();
984 		if ( aController == null )
985 			aController = new Controller( aFrame.getController() );
986 		return aController;
987 	}
988 
989     // @requirement FUNC.BEAN.PROG/0.5
990     // @requirement FUNC.BEAN.STOR/0.4
991     // @requirement FUNC.BEAN.PRNT/0.4
992     // @requirement API.SIM.SEAP/0.2
993    	/** returns the <type scope="com::sun::star::document::OfficeDocument">
994 	    of the bean.
995 
996 	    @returns
997 	    	a Java class which implements all interfaces which the service
998 		<type scope="com::sun::star::document">OfficeDocument</a>
999 		implements.
1000 		Thus, methods can be called directly without queryInterface.
1001 		This feature might be implemented by UNO or explicitely coded.
1002 
1003 	    @throws NoConnectionException
1004 	    	if the connection is not established.
1005 	 */
1006 	public OfficeDocument getDocument()
1007 
1008 		// @requirement FUNC.CON.LOST/0.2
1009 		throws NoConnectionException
1010 	{
1011 		if ( iConnection == null )
1012 			throw new NoConnectionException();
1013 		return aDocument;
1014 	}
1015 
1016     /**	Sets visibility of all tool bars known by this OOoBean version.
1017 
1018 	 	Initially all tool bars are visible.  By hiding all tool bars
1019 		utilizing this method, it is possible to turn just a subset of
1020 		tool bars on afterwards, no matter whether all available tool
1021 		bars are known or not.
1022         <p>
1023 		If an older OOoBean instance is used with a newer OOo instance,
1024 		some tool bars might not be affected by this method.
1025         <p>
1026 		If no connection is established or no document is loaded,
1027 		the setting is memorized until a document is loaded.  Same
1028 		is valid when the connection dies within this function call.
1029 
1030         @deprecated Clients should use the service com.sun.star.frame.LayoutManager,
1031         which can be obtained from a frame, to control toolbars. For example:
1032         <pre>
1033 com.sun.star.beans.XPropertySet xPropSet =
1034   (com.sun.star.beans.XPropertySet) UnoRuntime.queryInterface(
1035     com.sun.star.beans.XPropertySet.class, aFrame );
1036 com.sun.star.frame.XLayoutManager xLayoutManager =
1037   (com.sun.star.frame.XLayoutManager) UnoRuntime.queryInterface(
1038     com.sun.star.frame.XLayoutManager.class,
1039     xPropSet.getPropertyValue( "LayoutManager" ) );
1040 xLayoutManager.showElement("private:resource/menubar/menubar");
1041         </pre>
1042      */
1043 	public void setAllBarsVisible( boolean bVisible )
1044 	{
1045 		bIgnoreVisibility = true;
1046 		setMenuBarVisible( bVisible );
1047 		setStandardBarVisible( bVisible );
1048 		setToolBarVisible( bVisible );
1049 		setStatusBarVisible( bVisible );
1050 		bIgnoreVisibility = false;
1051 	}
1052 
1053 	//--------------------------------------------------------------------------
1054     /**	Applies all tool visiblities to the real thing.
1055 
1056         @deprecated Clients should use the service com.sun.star.frame.LayoutManager,
1057         which can be obtained from a frame, to control toolbars. See also
1058         {@link #setAllBarsVisible setAllBarsVisible}.
1059      */
1060 	protected void applyToolVisibilities()
1061 		throws
1062 			java.lang.InterruptedException
1063 	{
1064 		bIgnoreVisibility = true;
1065 		setMenuBarVisible( bMenuBarVisible );
1066 		setStandardBarVisible( bStandardBarVisible );
1067 		setToolBarVisible( bToolBarVisible );
1068 		setStatusBarVisible( bStatusBarVisible );
1069 		bIgnoreVisibility = false;
1070 	}
1071 
1072     /**	Helper method to set tool bar visibilty.
1073 
1074      	@param bnewValue
1075 			If false, the tool bar is disabled,
1076 			If true, the tool bar is visible.
1077 
1078         @deprecated Clients should use the service com.sun.star.frame.LayoutManager,
1079         which can be obtained from a frame, to control toolbars. See also
1080         {@link #setAllBarsVisible}.
1081      */
1082     protected boolean setToolVisible( String aProperty, String aResourceURL,
1083         boolean bOldValue, boolean bNewValue )
1084 
1085 		throws
1086 			java.lang.InterruptedException
1087     {
1088 		// start runtime timeout
1089 		CallWatchThread aCallWatchThread =
1090 			new CallWatchThread( nOOoCallTimeOut, "setToolVisible" );
1091 
1092 		// Does a frame exist?
1093 		if ( aFrame != null )
1094 		{
1095 			if ( bIgnoreVisibility || bOldValue != bNewValue )
1096 			{
1097 				try
1098 				{
1099 					com.sun.star.beans.XPropertySet xPropSet =
1100 							(com.sun.star.beans.XPropertySet) UnoRuntime.queryInterface(
1101 							com.sun.star.beans.XPropertySet.class, aFrame );
1102 					com.sun.star.frame.XLayoutManager xLayoutManager =
1103 							(com.sun.star.frame.XLayoutManager) UnoRuntime.queryInterface(
1104 							com.sun.star.frame.XLayoutManager.class,
1105 							xPropSet.getPropertyValue( "LayoutManager" ) );
1106 					if ( bNewValue )
1107 						xLayoutManager.showElement( aResourceURL );
1108 					else
1109 						xLayoutManager.hideElement( aResourceURL );
1110 				}
1111 				catch (  com.sun.star.beans.UnknownPropertyException aExc )
1112 				{
1113 					throw new RuntimeException( "not layout manager found" );
1114 				}
1115 				catch (  com.sun.star.lang.WrappedTargetException aExc )
1116 				{
1117 					throw new RuntimeException( "not layout manager found" );
1118 				}
1119 
1120 				// notify change
1121 				firePropertyChange( aProperty, new Boolean(bOldValue), new Boolean(bNewValue) );
1122 		   }
1123 		}
1124 
1125 		// end runtime timeout
1126 		aCallWatchThread.cancel();
1127 
1128 		// the new value will be stored by caller
1129 		return bNewValue;
1130 	}
1131 
1132     /**	Sets the visibility of the menu bar.
1133 
1134 		Initially the menu bar is visible.
1135         <p>
1136 		If not connected or no document loaded, the value is stored
1137 		and automatically applied to the document after it is loaded.
1138 		Same is valid when the connection dies within this function call.
1139 
1140      	@param bVisible
1141 			If false, the menu bar is disabled,
1142 			If true, the menu bar is visible.
1143 
1144         @deprecated Clients should use the service com.sun.star.frame.LayoutManager,
1145         which can be obtained from a frame, to control toolbars. See also
1146         {@link #setAllBarsVisible}.
1147      */
1148     public void setMenuBarVisible(boolean bVisible)
1149     {
1150 		try
1151 		{
1152 			bMenuBarVisible = setToolVisible( "MenuBarVisible",
1153                     "private:resource/menubar/menubar",	bMenuBarVisible, bVisible );
1154 		}
1155 		catch ( java.lang.InterruptedException aExc )
1156 		{
1157             bMenuBarVisible = bVisible;
1158         }
1159 	}
1160 
1161   	/** Returns the visibility of the menu bar.
1162 
1163 	   	This method works independently from a connetion or loaded document.
1164 		If no connection is established or no document is loaded,
1165 		this method just returns a memorized status.
1166 
1167     	@return
1168 			True if the menu bar is visible,
1169 			false if the menu bar is hidden.
1170 
1171         @deprecated Clients should use the service com.sun.star.frame.LayoutManager,
1172         which can be obtained from a frame, to control toolbars. See also
1173         {@link #setAllBarsVisible}.
1174      */
1175 	public boolean isMenuBarVisible()
1176 	{
1177 		return bMenuBarVisible;
1178 	}
1179 
1180     /**	Sets the main function bar visibilty.
1181 
1182 		Initially the standard bar is visible.
1183 
1184 		If not connected or no document loaded, the value is stored
1185 		and automatically applied to the document after it is loaded.
1186 		Same is valid when the connection dies within this function call.
1187 
1188      	@param bVisible
1189 			If false, the main function bar is disabled,
1190 			If true, the main function bar is visible.
1191 
1192         @deprecated Clients should use the service com.sun.star.frame.LayoutManager,
1193         which can be obtained from a frame, to control toolbars. See also
1194         {@link #setAllBarsVisible}.
1195      */
1196     public void setStandardBarVisible(boolean bVisible)
1197     {
1198 		try
1199 		{
1200 			bStandardBarVisible = setToolVisible( "StandardBarVisible",
1201                     "private:resource/toolbar/standardbar", bStandardBarVisible, bVisible );
1202 		}
1203 		catch ( java.lang.InterruptedException aExc )
1204 		{
1205             bMenuBarVisible = bVisible;
1206         }
1207 	}
1208 
1209   	/** Returns the visibility of the main function bar.
1210 
1211 	   	This method works independently from a connetion or loaded document.
1212 		If no connection is established or no document is loaded,
1213 		this method just returns a memorized status.
1214 
1215     	@return
1216 			True if the main function bar is visible,
1217 			false if the main function bar is hidden.
1218 
1219         @deprecated Clients should use the service com.sun.star.frame.LayoutManager,
1220         which can be obtained from a frame, to control toolbars. See also
1221         {@link #setAllBarsVisible}.
1222     */
1223 	public boolean isStandardBarVisible()
1224 	{
1225 		return bStandardBarVisible;
1226 	}
1227 
1228     /**	Sets the tool function bar visibilty.
1229 
1230 		Initially the tool bar is visible.
1231 
1232 		If not connected or no document loaded, the value is stored
1233 		and automatically applied to the document after it is loaded.
1234 		Same is valid when the connection dies within this function call.
1235 
1236      	@param bVisible
1237 			If false, the tool function bar is disabled,
1238 			If true, the tool function bar is visible.
1239 
1240         @deprecated Clients should use the service com.sun.star.frame.LayoutManager,
1241         which can be obtained from a frame, to control toolbars. See also
1242         {@link #setAllBarsVisible}.
1243      */
1244     public void setToolBarVisible(boolean bVisible)
1245     {
1246 		try
1247 		{
1248 			bToolBarVisible = setToolVisible( "ToolBarVisible",
1249                     "private:resource/toolbar/toolbar", bToolBarVisible, bVisible );
1250 		}
1251 		catch ( java.lang.InterruptedException aExc )
1252 		{
1253             bMenuBarVisible = bVisible;
1254         }
1255 	}
1256 
1257   	/** Returns the visibility of the tool function bar.
1258 
1259 	   	This method works independently from a connetion or loaded document.
1260 		If no connection is established or no document is loaded,
1261 		this method just returns a memorized status.
1262 
1263     	@return
1264 			True if the tool function bar is visible,
1265 			false if the tool function bar is hidden.
1266 
1267         @deprecated Clients should use the service com.sun.star.frame.LayoutManager,
1268         which can be obtained from a frame, to control toolbars. See also
1269         {@link #setAllBarsVisible}.
1270      */
1271 	public boolean isToolBarVisible()
1272 	{
1273 		return bToolBarVisible;
1274 	}
1275 
1276     /**	Sets the status function bar visibilty.
1277 
1278 		Initially the status bar is visible.
1279 
1280 		If not connected or no document loaded, the value is stored
1281 		and automatically applied to the document after it is loaded.
1282 		Same is valid when the connection dies within this function call.
1283 
1284      	@param bVisible
1285 			If false, the status function bar is disabled,
1286 			If true, the status function bar is visible.
1287 
1288         @deprecated Clients should use the service com.sun.star.frame.LayoutManager,
1289         which can be obtained from a frame, to control toolbars. See also
1290         {@link #setAllBarsVisible}.
1291      */
1292     public void setStatusBarVisible(boolean bVisible)
1293     {
1294 		try
1295 		{
1296 			bStatusBarVisible = setToolVisible( "StatusBarVisible",
1297                     "private:resource/statusbar/statusbar", bStatusBarVisible, bVisible );
1298 		}
1299 		catch ( java.lang.InterruptedException aExc )
1300 		{
1301             bMenuBarVisible = bVisible;
1302         }
1303 	}
1304 
1305   	/**	Returns the visibility of the status function bar.
1306 
1307 	   	This method works independently from a connetion or loaded document.
1308 		If no connection is established or no document is loaded,
1309 		this method just returns a memorized status.
1310 
1311     	@return
1312 			True if the status function bar is visible,
1313 			false if the status function bar is hidden.
1314 
1315         @deprecated Clients should use the service com.sun.star.frame.LayoutManager,
1316         which can be obtained from a frame, to control toolbars. See also
1317         {@link #setAllBarsVisible}.
1318      */
1319 	public boolean isStatusBarVisible()
1320 	{
1321 		return bStatusBarVisible;
1322 	}
1323 
1324 	//===========================================================================
1325 	// Helper Methods / Internal Methods
1326 	//---------------------------------------------------------------------------
1327 
1328 	// general instance intializer
1329 	{
1330 		setLayout(new java.awt.BorderLayout());
1331 	}
1332 
1333     /**
1334         @deprecated
1335      */
1336 	public void paint( java.awt.Graphics aGraphics )
1337 	{
1338 	}
1339 
1340 	/** Adds a single argument to an array of arguments.
1341 
1342 		If the argument by its name is already in aArguments
1343 		it is exchanged and aArguments is returned.
1344         <p>
1345 		If the argument by its name is not yet in aArguments,
1346 		a new array is created, aArgument added and the new
1347 		array returned.
1348 	*/
1349 	protected com.sun.star.beans.PropertyValue[] addArgument(
1350 				com.sun.star.beans.PropertyValue aArguments[],
1351 				final com.sun.star.beans.PropertyValue aArgument )
1352 	{
1353 		// get number of current arguments
1354 		int nNumArgs = 0;
1355 		if ( aArguments != null )
1356 			nNumArgs = aArguments.length;
1357 
1358 		// is new argument already set?
1359 		for ( int n = 0; n < nNumArgs; ++n )
1360 		{
1361 			if ( aArguments[n].Name == aArgument.Name )
1362 			{
1363 				// substitute this argument
1364 				aArguments[n] = aArgument;
1365 
1366 				// return current array
1367 				return aArguments;
1368 			}
1369 		}
1370 
1371 		// create extended arguments
1372 		com.sun.star.beans.PropertyValue[] aExtendedArguments =
1373 			new com.sun.star.beans.PropertyValue[ nNumArgs + 1 ];
1374 
1375 		// copy current arguments
1376 		for ( int n = 0; n < nNumArgs; ++n )
1377 			aExtendedArguments[n] = aArguments[n];
1378 
1379 		// add new argument
1380 		aExtendedArguments[ nNumArgs ] = aArgument;
1381 
1382 		// return new arguments
1383 		return aExtendedArguments;
1384 	}
1385 
1386 	//===========================================================================
1387 	// Helper Classes
1388 	//---------------------------------------------------------------------------
1389 
1390 	/** Helper class to listen on the connection to learn when it dies.
1391 
1392 	    @internal
1393 	 */
1394 	private class EventListener
1395 		extends Thread
1396 		implements
1397 			com.sun.star.lang.XEventListener,
1398 			com.sun.star.frame.XTerminateListener
1399 	{
1400 		String aTag;
1401 
1402 		EventListener( String aTag )
1403 			throws NoConnectionException
1404 		{
1405 			// init members
1406 			this.aTag = aTag;
1407 
1408 			// listen on a dying connection
1409 			iConnection.addEventListener( this );
1410 
1411 			// listen on a terminating OOo
1412 			getOOoDesktop().addTerminateListener( this );
1413 
1414 			// start this thread as a daemon
1415 			setDaemon( true );
1416 			start();
1417 		}
1418 
1419 		public void end()
1420 		{
1421 			// do not listen on a dying connection anymore
1422 			try {
1423 				iConnection.removeEventListener( this );
1424 			}
1425 			catch ( Throwable aExc ) {};
1426 
1427 			// do not listen on a terminating OOo anymore
1428 			try {
1429 				getOOoDesktop().removeTerminateListener( this );
1430 			}
1431 			catch ( Throwable aExc ) {};
1432 
1433 			// stop thread
1434             this.interrupt();
1435 		}
1436 
1437 		/// gets called when the connection dies
1438 		public void disposing( /*IN*/ com.sun.star.lang.EventObject Source )
1439 		{
1440 			// empty the OOoBean and cut the connection
1441 			stopOOoConnection();
1442 		}
1443 
1444 		/// gets called when the user wants to terminate OOo
1445 	   	public void queryTermination( /*IN*/ com.sun.star.lang.EventObject Event )
1446 			throws com.sun.star.frame.TerminationVetoException
1447 		{
1448 			// disallow termination of OOo while a OOoBean exists
1449 			throw new com.sun.star.frame.TerminationVetoException();
1450 		}
1451 
1452 		/// gets called when OOo terminates
1453 		public void notifyTermination( /*IN*/ com.sun.star.lang.EventObject Event )
1454 		{
1455 			// empty the OOoBean and cut the connection
1456 			stopOOoConnection();
1457 		}
1458 
1459 		/// watching the connection
1460 		public void run()
1461 		{
1462 			dbgPrint( "EventListener(" + aTag + ").run()" );
1463 
1464 			// remote call might hang => watch try
1465 			CallWatchThread aCallWatchThread =
1466 				new CallWatchThread( nOOoCallTimeOut, "EventListener(" + aTag + ")" );
1467 
1468 			// continue to trying to connect the OOo instance
1469 			long n = 0;
1470 			while ( isInterrupted() == false
1471                     && iConnection != null
1472                     && iConnection.getComponentContext() != null )
1473 			{
1474 				dbgPrint( "EventListener(" + aTag + ").running() #" + ++n );
1475 
1476 				// still alive?
1477 				com.sun.star.lang.XMultiComponentFactory xServiceManager = null;
1478 				try
1479 				{
1480 					// an arbitrary (but cheap) call into OOo
1481 					xServiceManager = iConnection.getComponentContext().getServiceManager();
1482 
1483 					// call successfully performed, restart watch for next loop
1484 					try
1485 					{
1486 						aCallWatchThread.restart();
1487 					}
1488 					catch ( java.lang.InterruptedException aExc )
1489 					{
1490 						// ignore late interrupt
1491 					}
1492 				}
1493 				catch ( java.lang.RuntimeException aExc )
1494 				{
1495 					// hung
1496 					OfficeConnection iDeadConn = iConnection;
1497 					iConnection = null;
1498 					iDeadConn.dispose();
1499 				}
1500 
1501 				// sleep
1502 				try {
1503 						sleep(nOOoCheckCycle);
1504 				}
1505 				catch ( java.lang.InterruptedException aExc )
1506 				{
1507                     dbgPrint("EventListener(" + aTag + ") interupted.");
1508                     //thread can be ended by EvendListener.end();
1509                     break;
1510 				}
1511 			}
1512 		}
1513 	}
1514 
1515 }
1516 
1517 
1518 
1519