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