1 *a4c7eb23SAndrew Rist /**************************************************************
2 *a4c7eb23SAndrew Rist  *
3 *a4c7eb23SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4 *a4c7eb23SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5 *a4c7eb23SAndrew Rist  * distributed with this work for additional information
6 *a4c7eb23SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7 *a4c7eb23SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8 *a4c7eb23SAndrew Rist  * "License"); you may not use this file except in compliance
9 *a4c7eb23SAndrew Rist  * with the License.  You may obtain a copy of the License at
10 *a4c7eb23SAndrew Rist  *
11 *a4c7eb23SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12 *a4c7eb23SAndrew Rist  *
13 *a4c7eb23SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14 *a4c7eb23SAndrew Rist  * software distributed under the License is distributed on an
15 *a4c7eb23SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 *a4c7eb23SAndrew Rist  * KIND, either express or implied.  See the License for the
17 *a4c7eb23SAndrew Rist  * specific language governing permissions and limitations
18 *a4c7eb23SAndrew Rist  * under the License.
19 *a4c7eb23SAndrew Rist  *
20 *a4c7eb23SAndrew Rist  *************************************************************/
21 *a4c7eb23SAndrew Rist 
22 cdf0e10cSrcweir /*
23 cdf0e10cSrcweir  * To change this template, choose Tools | Templates
24 cdf0e10cSrcweir  * and open the template in the editor.
25 cdf0e10cSrcweir  */
26 cdf0e10cSrcweir 
27 cdf0e10cSrcweir package complex.sfx2;
28 cdf0e10cSrcweir 
29 cdf0e10cSrcweir import com.sun.star.document.DocumentEvent;
30 cdf0e10cSrcweir import com.sun.star.document.XDocumentEventBroadcaster;
31 cdf0e10cSrcweir import com.sun.star.document.XDocumentEventListener;
32 cdf0e10cSrcweir import com.sun.star.lang.EventObject;
33 cdf0e10cSrcweir import com.sun.star.lang.XEventListener;
34 cdf0e10cSrcweir import com.sun.star.uno.Exception;
35 cdf0e10cSrcweir import com.sun.star.uno.UnoRuntime;
36 cdf0e10cSrcweir import com.sun.star.util.CloseVetoException;
37 cdf0e10cSrcweir import com.sun.star.util.XCloseListener;
38 cdf0e10cSrcweir import com.sun.star.util.XCloseable;
39 cdf0e10cSrcweir import java.util.Vector;
40 cdf0e10cSrcweir import java.util.logging.Level;
41 cdf0e10cSrcweir import java.util.logging.Logger;
42 cdf0e10cSrcweir import org.junit.After;
43 cdf0e10cSrcweir import org.junit.Before;
44 cdf0e10cSrcweir import org.junit.Test;
45 cdf0e10cSrcweir import static org.junit.Assert.*;
46 cdf0e10cSrcweir import org.openoffice.test.tools.OfficeDocument;
47 cdf0e10cSrcweir 
48 cdf0e10cSrcweir /**
49 cdf0e10cSrcweir  *
50 cdf0e10cSrcweir  * @author frank.shoenheit@oracle.com
51 cdf0e10cSrcweir  */
52 cdf0e10cSrcweir public class DocumentEvents extends JUnitBasedTest
53 cdf0e10cSrcweir {
54 cdf0e10cSrcweir     @Before
beforeTest()55 cdf0e10cSrcweir     public void beforeTest() throws Exception
56 cdf0e10cSrcweir     {
57 cdf0e10cSrcweir         m_document = OfficeDocument.blankTextDocument( this.getORB() );
58 cdf0e10cSrcweir     }
59 cdf0e10cSrcweir 
60 cdf0e10cSrcweir     @After
afterTest()61 cdf0e10cSrcweir     public void afterTest()
62 cdf0e10cSrcweir     {
63 cdf0e10cSrcweir         if ( m_document != null )
64 cdf0e10cSrcweir         {
65 cdf0e10cSrcweir             assertTrue( "closing the test document failed", m_document.close() );
66 cdf0e10cSrcweir             m_document = null;
67 cdf0e10cSrcweir         }
68 cdf0e10cSrcweir     }
69 cdf0e10cSrcweir 
70 cdf0e10cSrcweir     /**
71 cdf0e10cSrcweir      * sets up the environment for a test which checks the behavior upon closing a doc
72 cdf0e10cSrcweir      */
impl_setupDocCloseTest()73 cdf0e10cSrcweir     private void impl_setupDocCloseTest()
74 cdf0e10cSrcweir     {
75 cdf0e10cSrcweir         m_observedCloseEvents.clear();
76 cdf0e10cSrcweir 
77 cdf0e10cSrcweir         final XDocumentEventBroadcaster docEventBroadcaster = UnoRuntime.queryInterface(
78 cdf0e10cSrcweir             XDocumentEventBroadcaster.class, m_document.getDocument() );
79 cdf0e10cSrcweir         docEventBroadcaster.addDocumentEventListener( new DocumentEventListener() );
80 cdf0e10cSrcweir 
81 cdf0e10cSrcweir         final XCloseable docCloseable = UnoRuntime.queryInterface( XCloseable.class,
82 cdf0e10cSrcweir                 m_document.getDocument() );
83 cdf0e10cSrcweir         docCloseable.addCloseListener( new CloseListener() );
84 cdf0e10cSrcweir 
85 cdf0e10cSrcweir         m_document.getDocument().addEventListener( new DocDisposeListener() );
86 cdf0e10cSrcweir     }
87 cdf0e10cSrcweir 
88 cdf0e10cSrcweir     /**
89 cdf0e10cSrcweir      * sets up the environment for a test which checks the behavior upon closing a doc
90 cdf0e10cSrcweir      */
impl_tearDownDocCloseTest( final String i_docCloseMethod )91 cdf0e10cSrcweir     private void impl_tearDownDocCloseTest( final String i_docCloseMethod )
92 cdf0e10cSrcweir     {
93 cdf0e10cSrcweir         synchronized( m_document )
94 cdf0e10cSrcweir         {
95 cdf0e10cSrcweir             try
96 cdf0e10cSrcweir             {
97 cdf0e10cSrcweir                 m_document.wait(10000);
98 cdf0e10cSrcweir             }
99 cdf0e10cSrcweir             catch (InterruptedException ex)
100 cdf0e10cSrcweir             {
101 cdf0e10cSrcweir                 // don't continue the test if somebody interrupted us ...
102 cdf0e10cSrcweir                 return;
103 cdf0e10cSrcweir             }
104 cdf0e10cSrcweir         }
105 cdf0e10cSrcweir 
106 cdf0e10cSrcweir         m_document = null;
107 cdf0e10cSrcweir         synchronized( m_observedCloseEvents )
108 cdf0e10cSrcweir         {
109 cdf0e10cSrcweir             assertArrayEquals(
110 cdf0e10cSrcweir                 "wrong order of events when closing a doc " + i_docCloseMethod,
111 cdf0e10cSrcweir                 new CloseEventType[] { CloseEventType.OnUnload, CloseEventType.NotifyClosing, CloseEventType.Disposing },
112 cdf0e10cSrcweir                 m_observedCloseEvents.toArray( new CloseEventType[0] )
113 cdf0e10cSrcweir             );
114 cdf0e10cSrcweir         }
115 cdf0e10cSrcweir     }
116 cdf0e10cSrcweir 
117 cdf0e10cSrcweir     @Test
testCloseWinEvents()118 cdf0e10cSrcweir     public void testCloseWinEvents() throws Exception
119 cdf0e10cSrcweir     {
120 cdf0e10cSrcweir         impl_setupDocCloseTest();
121 cdf0e10cSrcweir         m_document.getCurrentView().dispatch( ".uno:CloseWin" );
122 cdf0e10cSrcweir         impl_tearDownDocCloseTest( "via .uno:CloseWin" );
123 cdf0e10cSrcweir     }
124 cdf0e10cSrcweir 
125 cdf0e10cSrcweir     //@Test
testCloseDocEvents()126 cdf0e10cSrcweir     public void testCloseDocEvents() throws Exception
127 cdf0e10cSrcweir     {
128 cdf0e10cSrcweir         impl_setupDocCloseTest();
129 cdf0e10cSrcweir         m_document.getCurrentView().dispatch( ".uno:CloseDoc" );
130 cdf0e10cSrcweir         impl_tearDownDocCloseTest( "via .uno:CloseDoc" );
131 cdf0e10cSrcweir     }
132 cdf0e10cSrcweir 
133 cdf0e10cSrcweir     //@Test
testCloseByAPI()134 cdf0e10cSrcweir     public void testCloseByAPI() throws Exception
135 cdf0e10cSrcweir     {
136 cdf0e10cSrcweir         impl_setupDocCloseTest();
137 cdf0e10cSrcweir         // closing the doc by API is synchronous, so do this in a separate thread, else we will get a deadlock
138 cdf0e10cSrcweir         // when the document tries to call back our listener (well, I admit I didn't understand *why* we get this
139 cdf0e10cSrcweir         // deadlock ... :-\ )
140 cdf0e10cSrcweir         (new DocCloser()).start();
141 cdf0e10cSrcweir         impl_tearDownDocCloseTest( "by API" );
142 cdf0e10cSrcweir     }
143 cdf0e10cSrcweir 
144 cdf0e10cSrcweir     private class DocumentEventListener implements XDocumentEventListener
145 cdf0e10cSrcweir     {
146 cdf0e10cSrcweir 
documentEventOccured( DocumentEvent i_documentEvent )147 cdf0e10cSrcweir         public void documentEventOccured( DocumentEvent i_documentEvent )
148 cdf0e10cSrcweir         {
149 cdf0e10cSrcweir             if ( i_documentEvent.EventName.equals( "OnUnload" ) )
150 cdf0e10cSrcweir             {
151 cdf0e10cSrcweir                 synchronized( m_observedCloseEvents )
152 cdf0e10cSrcweir                 {
153 cdf0e10cSrcweir                     m_observedCloseEvents.add( CloseEventType.OnUnload );
154 cdf0e10cSrcweir                 }
155 cdf0e10cSrcweir             }
156 cdf0e10cSrcweir         }
157 cdf0e10cSrcweir 
disposing(EventObject eo)158 cdf0e10cSrcweir         public void disposing(EventObject eo)
159 cdf0e10cSrcweir         {
160 cdf0e10cSrcweir             // not interested in
161 cdf0e10cSrcweir         }
162 cdf0e10cSrcweir     };
163 cdf0e10cSrcweir 
164 cdf0e10cSrcweir     private class CloseListener implements XCloseListener
165 cdf0e10cSrcweir     {
166 cdf0e10cSrcweir 
queryClosing(EventObject eo, boolean bln)167 cdf0e10cSrcweir         public void queryClosing(EventObject eo, boolean bln) throws CloseVetoException
168 cdf0e10cSrcweir         {
169 cdf0e10cSrcweir             // not interested in
170 cdf0e10cSrcweir         }
171 cdf0e10cSrcweir 
notifyClosing(EventObject eo)172 cdf0e10cSrcweir         public void notifyClosing(EventObject eo)
173 cdf0e10cSrcweir         {
174 cdf0e10cSrcweir             synchronized( m_observedCloseEvents )
175 cdf0e10cSrcweir             {
176 cdf0e10cSrcweir                 m_observedCloseEvents.add( CloseEventType.NotifyClosing );
177 cdf0e10cSrcweir             }
178 cdf0e10cSrcweir         }
179 cdf0e10cSrcweir 
disposing(EventObject eo)180 cdf0e10cSrcweir         public void disposing(EventObject eo)
181 cdf0e10cSrcweir         {
182 cdf0e10cSrcweir             // not interested in
183 cdf0e10cSrcweir         }
184 cdf0e10cSrcweir     };
185 cdf0e10cSrcweir 
186 cdf0e10cSrcweir     private class DocDisposeListener implements XEventListener
187 cdf0e10cSrcweir     {
disposing(EventObject eo)188 cdf0e10cSrcweir         public void disposing(EventObject eo)
189 cdf0e10cSrcweir         {
190 cdf0e10cSrcweir             synchronized( m_observedCloseEvents )
191 cdf0e10cSrcweir             {
192 cdf0e10cSrcweir                 m_observedCloseEvents.add( CloseEventType.Disposing );
193 cdf0e10cSrcweir             }
194 cdf0e10cSrcweir             synchronized ( m_document )
195 cdf0e10cSrcweir             {
196 cdf0e10cSrcweir                 m_document.notifyAll();
197 cdf0e10cSrcweir             }
198 cdf0e10cSrcweir         }
199 cdf0e10cSrcweir     };
200 cdf0e10cSrcweir 
201 cdf0e10cSrcweir     private class DocCloser extends Thread
202 cdf0e10cSrcweir     {
203 cdf0e10cSrcweir         @Override
run()204 cdf0e10cSrcweir         public void run()
205 cdf0e10cSrcweir         {
206 cdf0e10cSrcweir             try
207 cdf0e10cSrcweir             {
208 cdf0e10cSrcweir                 final XCloseable docCloseable = UnoRuntime.queryInterface(XCloseable.class, m_document.getDocument());
209 cdf0e10cSrcweir                 docCloseable.close(true);
210 cdf0e10cSrcweir             }
211 cdf0e10cSrcweir             catch (CloseVetoException ex)
212 cdf0e10cSrcweir             {
213 cdf0e10cSrcweir                 Logger.getLogger(DocumentEvents.class.getName()).log(Level.SEVERE, null, ex);
214 cdf0e10cSrcweir             }
215 cdf0e10cSrcweir         }
216 cdf0e10cSrcweir     };
217 cdf0e10cSrcweir 
218 cdf0e10cSrcweir     private enum CloseEventType
219 cdf0e10cSrcweir     {
220 cdf0e10cSrcweir         OnUnload,
221 cdf0e10cSrcweir         NotifyClosing,
222 cdf0e10cSrcweir         Disposing
223 cdf0e10cSrcweir     };
224 cdf0e10cSrcweir 
225 cdf0e10cSrcweir     private OfficeDocument m_document = null;
226 cdf0e10cSrcweir     final private Vector< CloseEventType > m_observedCloseEvents = new Vector<DocumentEvents.CloseEventType>();
227 cdf0e10cSrcweir }
228