xref: /AOO41X/main/bean/com/sun/star/comp/beans/OOoBean.java (revision d4cc1e8c350bb591a80bbabe126ff6af34c125a2)
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