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