Difference between revisions of "Documentation/DevGuide/OfficeDev/Closing Documents"

From Apache OpenOffice Wiki
Jump to: navigation, search
 
(One intermediate revision by one other user not shown)
Line 10: Line 10:
 
<!--<idltopic>com.sun.star.lang.XComponent;com.sun.star.util.XCloseable;com.sun.star.util.XCloseListener</idltopic>-->
 
<!--<idltopic>com.sun.star.lang.XComponent;com.sun.star.util.XCloseable;com.sun.star.util.XCloseListener</idltopic>-->
 
The <idlm>com.sun.star.frame.XComponentLoader:loadComponentFromURL()</idlm> has previously been discussed. The return value is a reference to a <idl>com.sun.star.lang.XComponent</idl> interface, the corresponding object is a disposable component, and the caller must take care of its lifetime. An <code>XComponent</code> supports the following methods:
 
The <idlm>com.sun.star.frame.XComponentLoader:loadComponentFromURL()</idlm> has previously been discussed. The return value is a reference to a <idl>com.sun.star.lang.XComponent</idl> interface, the corresponding object is a disposable component, and the caller must take care of its lifetime. An <code>XComponent</code> supports the following methods:
<source lang="idl">
+
<syntaxhighlight lang="idl">
 
   void dispose ()
 
   void dispose ()
 
   void addEventListener ( [in] com::sun::star::lang::XEventListener xListener)
 
   void addEventListener ( [in] com::sun::star::lang::XEventListener xListener)
 
   void removeEventListener ( [in] com::sun::star::lang::XEventListener xListener)
 
   void removeEventListener ( [in] com::sun::star::lang::XEventListener xListener)
</source>
+
</syntaxhighlight>
 
In principle, there is a simple rule. The documentation of a <idl>com.sun.star.lang.XComponent</idl> specifies the objects that can own a component. Normally, a client using an <code>XComponent</code> is the owner of the <code>XComponent</code> and has the responsibility to dispose of it or it is not the owner. If it is not the owner, it may add itself as a <idl>com.sun.star.lang.XEventListener</idl> at the <code>XComponent</code> and not call <code>dispose()</code> on it. This type of <code>XEventListener</code> supports one method in which a component reacts upon the fact that another component is about to be disposed of:
 
In principle, there is a simple rule. The documentation of a <idl>com.sun.star.lang.XComponent</idl> specifies the objects that can own a component. Normally, a client using an <code>XComponent</code> is the owner of the <code>XComponent</code> and has the responsibility to dispose of it or it is not the owner. If it is not the owner, it may add itself as a <idl>com.sun.star.lang.XEventListener</idl> at the <code>XComponent</code> and not call <code>dispose()</code> on it. This type of <code>XEventListener</code> supports one method in which a component reacts upon the fact that another component is about to be disposed of:
<source lang="idl">
+
<syntaxhighlight lang="idl">
 
   void disposing ( [in] com::sun::star::lang::EventObject Source )
 
   void disposing ( [in] com::sun::star::lang::EventObject Source )
</source>
+
</syntaxhighlight>
 
However, the frame, controller and model are interwoven tightly, and situations do occur in which there are several owners, for example, if there is more than one view for one model, or one of these components is in use and cannot be disposed of, for example, while a print job is running or a modal dialog is open. Therefore, developers must cope with these situations and remember a few things concerning the deletion of components.  
 
However, the frame, controller and model are interwoven tightly, and situations do occur in which there are several owners, for example, if there is more than one view for one model, or one of these components is in use and cannot be disposed of, for example, while a print job is running or a modal dialog is open. Therefore, developers must cope with these situations and remember a few things concerning the deletion of components.  
  
Line 25: Line 25:
 
=== Reacting Upon Closing ===
 
=== Reacting Upon Closing ===
  
The first aspect is that someone else wants to close a component for which you hold a reference. In the current version of {{PRODUCTNAME}}, there are three possibilities.  
+
The first aspect is that someone else wants to close a component for which you hold a reference. In the current version of {{AOo}}, there are three possibilities.  
  
 
* If the component is used briefly as a stack variable, you do not care about the component after loading, or you are sure there will be no interference, it is justifiable to load the component without taking further measures. If the user is going to close the component, let the reference go out of scope, or release the reference when no longer required.
 
* If the component is used briefly as a stack variable, you do not care about the component after loading, or you are sure there will be no interference, it is justifiable to load the component without taking further measures. If the user is going to close the component, let the reference go out of scope, or release the reference when no longer required.
Line 31: Line 31:
 
* If a hard reference is held or you want to know that the component has been closed and the new situation has to be accommodated, add a <idl>com.sun.star.lang.XEventListener</idl> at the <idl>com.sun.star.lang.XComponent</idl> interface. In this case, release the reference on a <code>disposing()</code> notification.
 
* If a hard reference is held or you want to know that the component has been closed and the new situation has to be accommodated, add a <idl>com.sun.star.lang.XEventListener</idl> at the <idl>com.sun.star.lang.XComponent</idl> interface. In this case, release the reference on a <code>disposing()</code> notification.
  
Sometimes it is necessary to exercise more control over the closing process. For this an optional interface <idl>com.sun.star.util.XCloseable</idl> has been introduced. If the object you are referencing is a <idls>com.sun.star.util.XCloseable</idls>, register it as a <idl>com.sun.star.util.XCloseListener</idl> and throw a <idl>com.sun.star.util.CloseVetoException</idl> when prompted to close. Since <code>XCloseable</code> is specified as an optional interface for frames and models, do not assume that this interface is supported. It is possible that the code runs with a {{PRODUCTNAME}} version where frames and models do not implement <code>XCloseable</code>. Therefore, be prepared for the case when you receive null when you try to query <code>XCloseable</code>. The <code>XCloseable</code> interface is described in more detail below.
+
Sometimes it is necessary to exercise more control over the closing process. For this an optional interface <idl>com.sun.star.util.XCloseable</idl> has been introduced. If the object you are referencing is a <idls>com.sun.star.util.XCloseable</idls>, register it as a <idl>com.sun.star.util.XCloseListener</idl> and throw a <idl>com.sun.star.util.CloseVetoException</idl> when prompted to close. Since <code>XCloseable</code> is specified as an optional interface for frames and models, do not assume that this interface is supported. It is possible that the code runs with a {{AOo}} version where frames and models do not implement <code>XCloseable</code>. Therefore, be prepared for the case when you receive null when you try to query <code>XCloseable</code>. The <code>XCloseable</code> interface is described in more detail below.
  
 
=== How to Trigger Closing ===
 
=== How to Trigger Closing ===
Line 37: Line 37:
 
The second aspect - to close a view of a component or the entire viewable component ''yourself'' - is more complex. The necessary steps depend on how you want to treat modified documents.
 
The second aspect - to close a view of a component or the entire viewable component ''yourself'' - is more complex. The necessary steps depend on how you want to treat modified documents.
  
{{Documentation/Caution|If a component supports <code>XCloseable</code>, you must not use any closing procedure other than calling <idlm>com.sun.star.util.XCloseable:close</idlm>.}}
+
{{Warn|If a component supports <code>XCloseable</code>, you must not use any closing procedure other than calling <idlm>com.sun.star.util.XCloseable:close</idlm>.}}
  
The following three diagrams show the decisions to be made when closing a frame or a document model. The important points are: if you expect modifications, you must either handle them using <idl>com.sun.star.util.XModifiable</idl> and <idl>com.sun.star.frame.XStorable</idl>, or let the user do the necessary interaction by calling <code>suspend()</code> on the controller. In any case, check if the frame or model is an <code>XCloseable</code> and prefer <idlml>com.sun.star.util.XCloseable:close</idlml>() over a call to <code>dispose()</code>. The first two diagrams illustrate the separate closing process for frames and models, the third diagram covers the actual termination of frames and models.
+
The following three diagrams show the decisions to be made when closing a frame or a document model. The important points are: if you expect modifications, you must either handle them using <idl>com.sun.star.util.XModifiable</idl> and <idl>com.sun.star.frame.XStorable</idl>, or let the user do the necessary interaction by calling <code>suspend()</code> on the controller. In any case, check if the frame or model is an <code>XCloseable</code> and prefer <idlm>com.sun.star.util.XCloseable:close</idlm>() over a call to <code>dispose()</code>. The first two diagrams illustrate the separate closing process for frames and models, the third diagram covers the actual termination of frames and models.
  
 
[[Image:ClosingFrame.png|none|thumb|500px|Closing a Frame]]
 
[[Image:ClosingFrame.png|none|thumb|500px|Closing a Frame]]
Line 53: Line 53:
 
A closing mechanism is required that enables all involved objects to negotiate if deletion is possible and to veto, if necessary. By offering the interface <idl>com.sun.star.util.XCloseable</idl>, a component tells it must be destroyed by calling <code>close()</code>. Calling <code>dispose()</code> on an <code>XCloseable</code> might lead to deadlocks or crash the entire application.
 
A closing mechanism is required that enables all involved objects to negotiate if deletion is possible and to veto, if necessary. By offering the interface <idl>com.sun.star.util.XCloseable</idl>, a component tells it must be destroyed by calling <code>close()</code>. Calling <code>dispose()</code> on an <code>XCloseable</code> might lead to deadlocks or crash the entire application.
  
In {{PRODUCTNAME}}, model or frame objects are possible candidates for implementing the interface <code>XCloseable</code>, therefore query for that interface before destroying the object. Call <code>dispose()</code> directly if the model or frame does not support the interface, thus declaring that it handles all the problems.
+
In {{AOo}}, model or frame objects are possible candidates for implementing the interface <code>XCloseable</code>, therefore query for that interface before destroying the object. Call <code>dispose()</code> directly if the model or frame does not support the interface, thus declaring that it handles all the problems.
  
 
An object implementing <code>XCloseable</code> registers close listeners. When a close request is received, all listeners are asked for permission. If a listener wants to deprecate, it throws an exception derived from <idl>com.sun.star.util.CloseVetoException</idl> containing the reason why the component can not be closed. This exception is passed to the close requester. The <code>XCloseable</code> itself can veto the destruction by throwing an exception. If there is no veto, the <code>XCloseable</code> calls <code>dispose()</code> on itself and returns.
 
An object implementing <code>XCloseable</code> registers close listeners. When a close request is received, all listeners are asked for permission. If a listener wants to deprecate, it throws an exception derived from <idl>com.sun.star.util.CloseVetoException</idl> containing the reason why the component can not be closed. This exception is passed to the close requester. The <code>XCloseable</code> itself can veto the destruction by throwing an exception. If there is no veto, the <code>XCloseable</code> calls <code>dispose()</code> on itself and returns.
Line 61: Line 61:
 
A close listener that is asked for permission can object for any reason if the close call does not force it to assume ownership of the closeable object.The close requester is aware of a possible failure. If the close call forces the ownership, the close listener must be careful. An objection is only allowed if the reason is temporary. As soon as the reason no longer exists, the owner automatically calls close on the object that should be closed, now being in the same situation as the initial close requester.
 
A close listener that is asked for permission can object for any reason if the close call does not force it to assume ownership of the closeable object.The close requester is aware of a possible failure. If the close call forces the ownership, the close listener must be careful. An objection is only allowed if the reason is temporary. As soon as the reason no longer exists, the owner automatically calls close on the object that should be closed, now being in the same situation as the initial close requester.
  
A permanent reason for objection is not allowed. For example,. the document being modified is not a valid reason to object, because it is unlikely that the document becomes unmodified by itself. Consequently, it could never be closed. Therefore, if an API programmer wants to avoid data loss, he must use the <idl>com.sun.star.util.XModifiable</idl> and <idl>com.sun.star.frame.XStorable</idl> interfaces of the document. The fact that a model refuses to be closed if it is modified is not dependable.  
+
A permanent reason for objection is not allowed. For example, the document being modified is not a valid reason to object, because it is unlikely that the document becomes unmodified by itself. Consequently, it could never be closed. Therefore, if an API programmer wants to avoid data loss, he must use the <idl>com.sun.star.util.XModifiable</idl> and <idl>com.sun.star.frame.XStorable</idl> interfaces of the document. The fact that a model refuses to be closed if it is modified is not dependable.  
  
 
The interface <idl>com.sun.star.util.XCloseable</idl> inherits from <idl>com.sun.star.util.XCloseBroadcaster</idl> and has the following methods:
 
The interface <idl>com.sun.star.util.XCloseable</idl> inherits from <idl>com.sun.star.util.XCloseBroadcaster</idl> and has the following methods:
<source lang="idl">
+
<syntaxhighlight lang="idl">
 
   [oneway] void addCloseListener ( [in] com::sun::star::util::XCloseListener Listener );  
 
   [oneway] void addCloseListener ( [in] com::sun::star::util::XCloseListener Listener );  
 
   [oneway] void removeCloseListener ( [in] com::sun::star::util::XCloseListener Listener );  
 
   [oneway] void removeCloseListener ( [in] com::sun::star::util::XCloseListener Listener );  
 
   void close ( [in] boolean DeliverOwnership )  
 
   void close ( [in] boolean DeliverOwnership )  
</source>
+
</syntaxhighlight>
 
The <idl>com.sun.star.util.XCloseListener</idl> is notified twice when <code>close()</code> is called on an <code>XClosable</code> :
 
The <idl>com.sun.star.util.XCloseListener</idl> is notified twice when <code>close()</code> is called on an <code>XClosable</code> :
<source lang="idl">
+
<syntaxhighlight lang="idl">
 
   void queryClosing ( [in] com::sun::star::lang::EventObject Source,  
 
   void queryClosing ( [in] com::sun::star::lang::EventObject Source,  
 
                       [in] boolean GetsOwnership )  
 
                       [in] boolean GetsOwnership )  
 
   void notifyClosing ( [in] com::sun::star::lang::EventObject Source )
 
   void notifyClosing ( [in] com::sun::star::lang::EventObject Source )
</source>
+
</syntaxhighlight>
<idlml>com.sun.star.util.XCloseable:close</idlml>() and <idlml>com.sun.star.util.XCloseListener:queryClosing</idlml>() throw a <idl>com.sun.star.util.CloseVetoException</idl>.
+
<idlm>com.sun.star.util.XCloseable:close</idlm>() and <idlm>com.sun.star.util.XCloseListener:queryClosing</idlm>() throw a <idl>com.sun.star.util.CloseVetoException</idl>.
  
 
In the closing negotiations, an <code>XClosable</code> is asked to close itself. In the call to close(), the caller passes a boolean parameter <code>DeliverOwnership</code> to tell the <code>XClosable</code> that it will give up ownership in favor of an <code>XCloseListener</code>, or the <code>XCloseable</code> that might have to finish a job first, but will close the <code>XClosable</code> immediately when the job is completed.
 
In the closing negotiations, an <code>XClosable</code> is asked to close itself. In the call to close(), the caller passes a boolean parameter <code>DeliverOwnership</code> to tell the <code>XClosable</code> that it will give up ownership in favor of an <code>XCloseListener</code>, or the <code>XCloseable</code> that might have to finish a job first, but will close the <code>XClosable</code> immediately when the job is completed.
Line 89: Line 89:
 
The example below closes a loaded document component. It does not save modified documents or prompts the user to save.  
 
The example below closes a loaded document component. It does not save modified documents or prompts the user to save.  
 
<!--[SOURCE:OfficeDev/DesktopEnvironment/FunctionHelper.java]-->
 
<!--[SOURCE:OfficeDev/DesktopEnvironment/FunctionHelper.java]-->
<source lang="java">
+
<syntaxhighlight lang="java">
 
   // Conditions: xDocument = m_xLoadedDocument  
 
   // Conditions: xDocument = m_xLoadedDocument  
 
   // Check supported functionality of the document (model or controller).  
 
   // Check supported functionality of the document (model or controller).  
Line 136: Line 136:
 
   }
 
   }
  
</source>
+
</syntaxhighlight>
 
{{PDL1}}
 
{{PDL1}}
  
 
[[Category:Documentation/Developer's Guide/Office Development]]
 
[[Category:Documentation/Developer's Guide/Office Development]]

Latest revision as of 17:59, 2 January 2021



The loadComponentFromURL() has previously been discussed. The return value is a reference to a com.sun.star.lang.XComponent interface, the corresponding object is a disposable component, and the caller must take care of its lifetime. An XComponent supports the following methods:

  void dispose ()
  void addEventListener ( [in] com::sun::star::lang::XEventListener xListener)
  void removeEventListener ( [in] com::sun::star::lang::XEventListener xListener)

In principle, there is a simple rule. The documentation of a com.sun.star.lang.XComponent specifies the objects that can own a component. Normally, a client using an XComponent is the owner of the XComponent and has the responsibility to dispose of it or it is not the owner. If it is not the owner, it may add itself as a com.sun.star.lang.XEventListener at the XComponent and not call dispose() on it. This type of XEventListener supports one method in which a component reacts upon the fact that another component is about to be disposed of:

  void disposing ( [in] com::sun::star::lang::EventObject Source )

However, the frame, controller and model are interwoven tightly, and situations do occur in which there are several owners, for example, if there is more than one view for one model, or one of these components is in use and cannot be disposed of, for example, while a print job is running or a modal dialog is open. Therefore, developers must cope with these situations and remember a few things concerning the deletion of components.

Closing a document has two aspects. It is possible that someone else wants to close a document being currently worked on And you may want to close a component someone else is using at the same time. Both aspects are discussed in the following sections. A code example that closes a document is provided at the end of this section.

Reacting Upon Closing

The first aspect is that someone else wants to close a component for which you hold a reference. In the current version of Apache OpenOffice, there are three possibilities.

  • If the component is used briefly as a stack variable, you do not care about the component after loading, or you are sure there will be no interference, it is justifiable to load the component without taking further measures. If the user is going to close the component, let the reference go out of scope, or release the reference when no longer required.
  • If a reference is used, but it is not necessary to react when it becomes invalid and the object supports com.sun.star.uno.XWeak, you can hold a weak reference instead of a hard reference. Weak references are automatically converted to null if the object they reference is going to be disposed. Because the generic frame implementation, and also the controllers and models of all standard document types implement XWeak, it is recommended to use it when possible.
  • If a hard reference is held or you want to know that the component has been closed and the new situation has to be accommodated, add a com.sun.star.lang.XEventListener at the com.sun.star.lang.XComponent interface. In this case, release the reference on a disposing() notification.

Sometimes it is necessary to exercise more control over the closing process. For this an optional interface com.sun.star.util.XCloseable has been introduced. If the object you are referencing is a XCloseable, register it as a com.sun.star.util.XCloseListener and throw a com.sun.star.util.CloseVetoException when prompted to close. Since XCloseable is specified as an optional interface for frames and models, do not assume that this interface is supported. It is possible that the code runs with a Apache OpenOffice version where frames and models do not implement XCloseable. Therefore, be prepared for the case when you receive null when you try to query XCloseable. The XCloseable interface is described in more detail below.

How to Trigger Closing

The second aspect - to close a view of a component or the entire viewable component yourself - is more complex. The necessary steps depend on how you want to treat modified documents.

Documentation caution.png If a component supports XCloseable, you must not use any closing procedure other than calling close.

The following three diagrams show the decisions to be made when closing a frame or a document model. The important points are: if you expect modifications, you must either handle them using com.sun.star.util.XModifiable and com.sun.star.frame.XStorable, or let the user do the necessary interaction by calling suspend() on the controller. In any case, check if the frame or model is an XCloseable and prefer close() over a call to dispose(). The first two diagrams illustrate the separate closing process for frames and models, the third diagram covers the actual termination of frames and models.

Closing a Frame
Closing a Model
Terminate Frame/Model

XCloseable

The dispose mechanism has shortcomings in complex situations, such as the frame-controller-model interaction. The dispose call cannot be rejected, but as shown above, sometimes it is necessary to prevent destruction of objects due to shared ownership or a state of the documents that forbids destruction.

A closing mechanism is required that enables all involved objects to negotiate if deletion is possible and to veto, if necessary. By offering the interface com.sun.star.util.XCloseable, a component tells it must be destroyed by calling close(). Calling dispose() on an XCloseable might lead to deadlocks or crash the entire application.

In Apache OpenOffice, model or frame objects are possible candidates for implementing the interface XCloseable, therefore query for that interface before destroying the object. Call dispose() directly if the model or frame does not support the interface, thus declaring that it handles all the problems.

An object implementing XCloseable registers close listeners. When a close request is received, all listeners are asked for permission. If a listener wants to deprecate, it throws an exception derived from com.sun.star.util.CloseVetoException containing the reason why the component can not be closed. This exception is passed to the close requester. The XCloseable itself can veto the destruction by throwing an exception. If there is no veto, the XCloseable calls dispose() on itself and returns.

The XCloseable handles problems that occur if a component rejects destruction. A script programmer usually can not cope with a component not used anymore that refuses to be destroyed. Ensure that the component is destroyed to avoid a memory leak. The close() method offers a method to pass the responsibility to close the object to any possible close listener that vetoes closing or to the XCloseable if the initial caller is not able to stay in memory to try again later. This responsibility is referred to as delivered ownership. The mechanism sets some constraints on the possible reasons for an objection against a close request.

A close listener that is asked for permission can object for any reason if the close call does not force it to assume ownership of the closeable object.The close requester is aware of a possible failure. If the close call forces the ownership, the close listener must be careful. An objection is only allowed if the reason is temporary. As soon as the reason no longer exists, the owner automatically calls close on the object that should be closed, now being in the same situation as the initial close requester.

A permanent reason for objection is not allowed. For example, the document being modified is not a valid reason to object, because it is unlikely that the document becomes unmodified by itself. Consequently, it could never be closed. Therefore, if an API programmer wants to avoid data loss, he must use the com.sun.star.util.XModifiable and com.sun.star.frame.XStorable interfaces of the document. The fact that a model refuses to be closed if it is modified is not dependable.

The interface com.sun.star.util.XCloseable inherits from com.sun.star.util.XCloseBroadcaster and has the following methods:

  [oneway] void addCloseListener ( [in] com::sun::star::util::XCloseListener Listener ); 
  [oneway] void removeCloseListener ( [in] com::sun::star::util::XCloseListener Listener ); 
  void close ( [in] boolean DeliverOwnership )

The com.sun.star.util.XCloseListener is notified twice when close() is called on an XClosable :

  void queryClosing ( [in] com::sun::star::lang::EventObject Source, 
                      [in] boolean GetsOwnership ) 
  void notifyClosing ( [in] com::sun::star::lang::EventObject Source )

close() and queryClosing() throw a com.sun.star.util.CloseVetoException.

In the closing negotiations, an XClosable is asked to close itself. In the call to close(), the caller passes a boolean parameter DeliverOwnership to tell the XClosable that it will give up ownership in favor of an XCloseListener, or the XCloseable that might have to finish a job first, but will close the XClosable immediately when the job is completed.

After a call to close(), the XClosable notifies its listeners twice. First, it checks if it can be closed. If not, it throws a CloseVetoException, otherwise it uses queryClosing() to see if a listener has any objections against closing. The value of DeliverOwnership is conveyed in the GetsOwnership parameter of queryClosing(). If no listener disapproves of closing, the XClosable exercises notifyClosing() on the listeners and disposes itself. The result of a call to close() on a model is that all frames, controllers and the model itself are destroyed. The result of a call to close() on a frame is that this frame is closed, but the model stays alive if there are other controllers.

If an XCloseListener does not agree on closing, it throws a CloseVetoException, and the XClosable lets the exception pass in close(), so that the caller receives the exception. The CloseVetoException tells the caller that closing failed. If the caller delegated its ownership in the call to close() by setting the DeliverOwnership parameter to true, an XCloseListener knows that it automatically assumes ownership by throwing a CloseVetoException. The caller knows that someone else is now the owner if it receives a CloseVetoException. The new owner is compelled to close the XClosable as soon as possible. If the XCloseable was the object that threw an exception, it is compelled also to close itself as soon as possible.

Documentation note.png No API exists for trivial components. As a consequence, components are not allowed to do anything that prevents them from being destroyed. For example, since the office crashes when a container window or component window has an open modal dialog, every component that wants to open a modal dialog must implement the com.sun.star.frame.XController interface.

If a model object supports XCloseable, calling dispose() on it is forbidden, try to close() the XCloseable and catch a possible CloseVetoException. Components that cannot cope with a destroyed model add a close listener at the model. This enables them to object when the model receives a close() request. They also add as a close listener if they are not already added as an (dispose) event listener. This can be done by every controller object that uses that model. It is also possible to let the model iterate through its controllers and call their suspend() methods explicitly as a part of its implementation of the close method. It is only necessary to know that a method close() must be called to close the model with its controllers. The method the model chooses is an implementation detail.

The example below closes a loaded document component. It does not save modified documents or prompts the user to save.

  // Conditions: xDocument = m_xLoadedDocument 
  // Check supported functionality of the document (model or controller). 
  com.sun.star.frame.XModel xModel = 
    (com.sun.star.frame.XModel)UnoRuntime.queryInterface( 
      com.sun.star.frame.XModel.class,xDocument);  
 
  if(xModel!=null) 
  { 
    // It is a full featured office document. 
    // Try to use close mechanism instead of a hard dispose().
    // But maybe such service is not available on this model. 
    com.sun.star.util.XCloseable xCloseable = 
      (com.sun.star.util.XCloseable)UnoRuntime.queryInterface( 
        com.sun.star.util.XCloseable.class,xModel); 
 
  if(xCloseable!=null) 
  { 
    try 
      { 
        // use close(boolean DeliverOwnership)
        // The boolean parameter DeliverOwnership tells objects vetoing the close process that they may
        // assume ownership if they object the closure by throwing a CloseVetoException
        // Here we give up ownership. To be on the safe side, catch possible veto exception anyway.  
        xCloseable.close(true); 
      } 
      catch(com.sun.star.util.CloseVetoException exCloseVeto) 
      {
      } 
  } 
  // If close is not supported by this model - try to dispose it. 
  // But if the model disagree with a reset request for the modify state 
  // we shouldn't do so. Otherwhise some strange things can happen. 
  else 
  { 
      com.sun.star.lang.XComponent xDisposeable = 
        (com.sun.star.lang.XComponent)UnoRuntime.queryInterface( 
         com.sun.star.lang.XComponent.class,xModel);  
         xDisposeable.dispose(); 
       } 
       catch(com.sun.star.beans.PropertyVetoException exModifyVeto) 
       {
       } 
      } 
    } 
  }
Content on this page is licensed under the Public Documentation License (PDL).
Personal tools
In other languages