1*34dd1e25SAndrew Rist /************************************************************** 2*34dd1e25SAndrew Rist * 3*34dd1e25SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*34dd1e25SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*34dd1e25SAndrew Rist * distributed with this work for additional information 6*34dd1e25SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*34dd1e25SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*34dd1e25SAndrew Rist * "License"); you may not use this file except in compliance 9*34dd1e25SAndrew Rist * with the License. You may obtain a copy of the License at 10*34dd1e25SAndrew Rist * 11*34dd1e25SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*34dd1e25SAndrew Rist * 13*34dd1e25SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*34dd1e25SAndrew Rist * software distributed under the License is distributed on an 15*34dd1e25SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*34dd1e25SAndrew Rist * KIND, either express or implied. See the License for the 17*34dd1e25SAndrew Rist * specific language governing permissions and limitations 18*34dd1e25SAndrew Rist * under the License. 19*34dd1e25SAndrew Rist * 20*34dd1e25SAndrew Rist *************************************************************/ 21*34dd1e25SAndrew Rist 22*34dd1e25SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // __________ Imports __________ 25cdf0e10cSrcweir 26cdf0e10cSrcweir import com.sun.star.uno.UnoRuntime; 27cdf0e10cSrcweir 28cdf0e10cSrcweir import java.lang.*; 29cdf0e10cSrcweir import javax.swing.*; 30cdf0e10cSrcweir import java.util.Vector; 31cdf0e10cSrcweir 32cdf0e10cSrcweir // __________ Implementation __________ 33cdf0e10cSrcweir 34cdf0e10cSrcweir /** 35cdf0e10cSrcweir * This class can be used to intercept dispatched URL's 36cdf0e10cSrcweir * on any frame used in this demo application. 37cdf0e10cSrcweir * It intercept all URL's wich try to create a new empty frame. 38cdf0e10cSrcweir * (e.g. "private:factory/swriter") 39cdf0e10cSrcweir * Nobody can guarantee that this interception will be realy used - 40cdf0e10cSrcweir * because another interceptor (registered at a later time then this one!) 41cdf0e10cSrcweir * will be called before this one. 42cdf0e10cSrcweir * Implementation is executed inside a new thread to prevent application 43cdf0e10cSrcweir * against possible deadlocks. This deadlocks can occure if 44cdf0e10cSrcweir * synchronous/asynchronous ... normal ones and oneway calls are mixed. 45cdf0e10cSrcweir * Notifications of listener will be oneway mostly - her reactions can 46cdf0e10cSrcweir * be synchronous then. => deadlocks are possible 47cdf0e10cSrcweir * 48cdf0e10cSrcweir * @author Andreas Schlüns 49cdf0e10cSrcweir * @created 06.03.2002 09:38 50cdf0e10cSrcweir */ 51cdf0e10cSrcweir public class Interceptor implements com.sun.star.frame.XFrameActionListener, 52cdf0e10cSrcweir com.sun.star.frame.XDispatchProviderInterceptor, 53cdf0e10cSrcweir com.sun.star.frame.XDispatchProvider, 54cdf0e10cSrcweir com.sun.star.frame.XDispatch, 55cdf0e10cSrcweir com.sun.star.frame.XInterceptorInfo, 56cdf0e10cSrcweir IShutdownListener, 57cdf0e10cSrcweir IOnewayLink 58cdf0e10cSrcweir { 59cdf0e10cSrcweir // ____________________ 60cdf0e10cSrcweir 61cdf0e10cSrcweir /** 62cdf0e10cSrcweir * const 63cdf0e10cSrcweir * All these URL's are intercepted by this implementation. 64cdf0e10cSrcweir */ 65cdf0e10cSrcweir private static final String[] INTERCEPTED_URLS = { "private:factory/*" , 66cdf0e10cSrcweir ".uno:SaveAs" , 67cdf0e10cSrcweir "slot:5300" , 68cdf0e10cSrcweir ".uno:Quit" }; 69cdf0e10cSrcweir 70cdf0e10cSrcweir // ____________________ 71cdf0e10cSrcweir 72cdf0e10cSrcweir /** 73cdf0e10cSrcweir * @member m_xMaster use this interceptor if he doesn't handle queried dispatch request 74cdf0e10cSrcweir * @member m_xSlave we can forward all unhandled requests to this slave interceptor 75cdf0e10cSrcweir * @member m_xFrame intercepted frame 76cdf0e10cSrcweir * @member m_bDead there exist more then one way to finish an object of this class - we must know it sometimes 77cdf0e10cSrcweir */ 78cdf0e10cSrcweir private com.sun.star.frame.XDispatchProvider m_xMaster ; 79cdf0e10cSrcweir private com.sun.star.frame.XDispatchProvider m_xSlave ; 80cdf0e10cSrcweir private com.sun.star.frame.XFrame m_xFrame ; 81cdf0e10cSrcweir private boolean m_bIsActionListener ; 82cdf0e10cSrcweir private boolean m_bIsRegistered ; 83cdf0e10cSrcweir private boolean m_bDead ; 84cdf0e10cSrcweir 85cdf0e10cSrcweir // ____________________ 86cdf0e10cSrcweir 87cdf0e10cSrcweir /** 88cdf0e10cSrcweir * ctor 89cdf0e10cSrcweir * Initialize the new interceptor. Given frame reference can be used to 90cdf0e10cSrcweir * register this interceptor on it automaticly later. 91cdf0e10cSrcweir * 92cdf0e10cSrcweir * @seealso startListening() 93cdf0e10cSrcweir * 94cdf0e10cSrcweir * @param xFrame 95cdf0e10cSrcweir * this interceptor will register himself at this frame to intercept dispatched URLs 96cdf0e10cSrcweir */ 97cdf0e10cSrcweir Interceptor(/*IN*/ com.sun.star.frame.XFrame xFrame) 98cdf0e10cSrcweir { 99cdf0e10cSrcweir m_xFrame = xFrame ; 100cdf0e10cSrcweir m_xSlave = null ; 101cdf0e10cSrcweir m_xMaster = null ; 102cdf0e10cSrcweir m_bIsRegistered = false ; 103cdf0e10cSrcweir m_bIsActionListener = false ; 104cdf0e10cSrcweir m_bDead = false ; 105cdf0e10cSrcweir } 106cdf0e10cSrcweir 107cdf0e10cSrcweir //_____________________ 108cdf0e10cSrcweir 109cdf0e10cSrcweir /** 110cdf0e10cSrcweir * start working as frame action listener realy. 111cdf0e10cSrcweir * We will be frame action listener here. In case 112cdf0e10cSrcweir * we get a frame action which indicates, that we should 113cdf0e10cSrcweir * update our interception. Because such using of an interecptor 114cdf0e10cSrcweir * isn't guaranteed - in case a newer one was registered ... 115cdf0e10cSrcweir */ 116cdf0e10cSrcweir public void startListening() 117cdf0e10cSrcweir { 118cdf0e10cSrcweir com.sun.star.frame.XFrame xFrame = null; 119cdf0e10cSrcweir synchronized(this) 120cdf0e10cSrcweir { 121cdf0e10cSrcweir if (m_bDead) 122cdf0e10cSrcweir return; 123cdf0e10cSrcweir if (m_xFrame==null) 124cdf0e10cSrcweir return; 125cdf0e10cSrcweir if (m_bIsActionListener==true) 126cdf0e10cSrcweir return; 127cdf0e10cSrcweir xFrame = m_xFrame; 128cdf0e10cSrcweir } 129cdf0e10cSrcweir m_xFrame.addFrameActionListener(this); 130cdf0e10cSrcweir synchronized(this) 131cdf0e10cSrcweir { 132cdf0e10cSrcweir m_bIsActionListener=true; 133cdf0e10cSrcweir } 134cdf0e10cSrcweir } 135cdf0e10cSrcweir 136cdf0e10cSrcweir //_____________________ 137cdf0e10cSrcweir 138cdf0e10cSrcweir /** 139cdf0e10cSrcweir * In case we got an oneway listener callback - we had to use the office 140cdf0e10cSrcweir * asynchronous then. This method is the callback from the started thread 141cdf0e10cSrcweir * (started inside the original oneway method). We found all parameters of 142cdf0e10cSrcweir * the original request packed inside a vector. Here we unpack it and 143cdf0e10cSrcweir * call the right internal helper method, which implements the right 144cdf0e10cSrcweir * funtionality. 145cdf0e10cSrcweir * 146cdf0e10cSrcweir * @seealso frameAction() 147cdf0e10cSrcweir * @seealso dispatch() 148cdf0e10cSrcweir * 149cdf0e10cSrcweir * @param nRequest 150cdf0e10cSrcweir * indicates, which was the original request (identifies the 151cdf0e10cSrcweir * original called method) 152cdf0e10cSrcweir * 153cdf0e10cSrcweir * @param lParams 154cdf0e10cSrcweir * the vector with all packed parameters of the original request 155cdf0e10cSrcweir */ 156cdf0e10cSrcweir public void execOneway(/*IN*/ int nRequest,/*IN*/ Vector lParams ) 157cdf0e10cSrcweir { 158cdf0e10cSrcweir synchronized(this) 159cdf0e10cSrcweir { 160cdf0e10cSrcweir if (m_bDead) 161cdf0e10cSrcweir return; 162cdf0e10cSrcweir } 163cdf0e10cSrcweir 164cdf0e10cSrcweir // was it frameAction()? 165cdf0e10cSrcweir if (nRequest==OnewayExecutor.REQUEST_FRAMEACTION) 166cdf0e10cSrcweir { 167cdf0e10cSrcweir com.sun.star.frame.FrameActionEvent[] lOutAction = new com.sun.star.frame.FrameActionEvent[1]; 168cdf0e10cSrcweir Vector[] lInParams = new Vector[1]; 169cdf0e10cSrcweir lInParams[0] = lParams; 170cdf0e10cSrcweir 171cdf0e10cSrcweir OnewayExecutor.codeFrameAction( OnewayExecutor.DECODE_PARAMS , 172cdf0e10cSrcweir lInParams , 173cdf0e10cSrcweir lOutAction ); 174cdf0e10cSrcweir impl_frameAction(lOutAction[0]); 175cdf0e10cSrcweir } 176cdf0e10cSrcweir else 177cdf0e10cSrcweir // was it dispatch()? 178cdf0e10cSrcweir if (nRequest==OnewayExecutor.REQUEST_DISPATCH) 179cdf0e10cSrcweir { 180cdf0e10cSrcweir com.sun.star.util.URL[] lOutURL = new com.sun.star.util.URL[1]; 181cdf0e10cSrcweir com.sun.star.beans.PropertyValue[][] lOutProps = new com.sun.star.beans.PropertyValue[1][]; 182cdf0e10cSrcweir Vector[] lInParams = new Vector[1]; 183cdf0e10cSrcweir lInParams[0] = lParams; 184cdf0e10cSrcweir 185cdf0e10cSrcweir OnewayExecutor.codeDispatch( OnewayExecutor.DECODE_PARAMS , 186cdf0e10cSrcweir lInParams , 187cdf0e10cSrcweir lOutURL , 188cdf0e10cSrcweir lOutProps ); 189cdf0e10cSrcweir impl_dispatch(lOutURL[0],lOutProps[0]); 190cdf0e10cSrcweir } 191cdf0e10cSrcweir } 192cdf0e10cSrcweir 193cdf0e10cSrcweir // ____________________ 194cdf0e10cSrcweir 195cdf0e10cSrcweir /** 196cdf0e10cSrcweir * call back for frame action events 197cdf0e10cSrcweir * We use it to update our interception. Because if a new component was loaded into 198cdf0e10cSrcweir * the frame or another interceptor was registered, we should refresh our connection 199cdf0e10cSrcweir * to the frame. Otherwhise we can't guarantee full functionality here. 200cdf0e10cSrcweir * 201cdf0e10cSrcweir * Note: Don't react synchronous in an asynchronous listener callback. So use a thread 202cdf0e10cSrcweir * here to update anything. 203cdf0e10cSrcweir * 204cdf0e10cSrcweir * @seealso impl_frameAction() 205cdf0e10cSrcweir * 206cdf0e10cSrcweir * @param aEvent 207cdf0e10cSrcweir * describes the action 208cdf0e10cSrcweir */ 209cdf0e10cSrcweir public /*ONEWAY*/ void frameAction(/*IN*/ com.sun.star.frame.FrameActionEvent aEvent) 210cdf0e10cSrcweir { 211cdf0e10cSrcweir synchronized(this) 212cdf0e10cSrcweir { 213cdf0e10cSrcweir if (m_bDead) 214cdf0e10cSrcweir return; 215cdf0e10cSrcweir } 216cdf0e10cSrcweir 217cdf0e10cSrcweir boolean bHandle = false; 218cdf0e10cSrcweir switch(aEvent.Action.getValue()) 219cdf0e10cSrcweir { 220cdf0e10cSrcweir case com.sun.star.frame.FrameAction.COMPONENT_ATTACHED_value : bHandle=true; break; 221cdf0e10cSrcweir case com.sun.star.frame.FrameAction.COMPONENT_DETACHING_value : bHandle=true; break; 222cdf0e10cSrcweir case com.sun.star.frame.FrameAction.COMPONENT_REATTACHED_value : bHandle=true; break; 223cdf0e10cSrcweir // Don't react for CONTEXT_CHANGED here. Ok it indicates, that may another interceptor 224cdf0e10cSrcweir // was registered at the frame ... but if we register ourself there - we get a context 225cdf0e10cSrcweir // changed too :-( Best way to produce a never ending recursion ... 226cdf0e10cSrcweir // May be that somewhere find a safe mechanism to detect own produced frame action events 227cdf0e10cSrcweir // and ignore it. 228cdf0e10cSrcweir case com.sun.star.frame.FrameAction.CONTEXT_CHANGED_value : 229cdf0e10cSrcweir System.out.println("Time to update interception ... but may it will start a recursion. So I let it :-("); 230cdf0e10cSrcweir bHandle=false; 231cdf0e10cSrcweir break; 232cdf0e10cSrcweir } 233cdf0e10cSrcweir 234cdf0e10cSrcweir // ignore some events 235cdf0e10cSrcweir if (! bHandle) 236cdf0e10cSrcweir return; 237cdf0e10cSrcweir 238cdf0e10cSrcweir // pack the event and start thread - which call us back later 239cdf0e10cSrcweir Vector[] lOutParams = new Vector[1]; 240cdf0e10cSrcweir com.sun.star.frame.FrameActionEvent[] lInAction = new com.sun.star.frame.FrameActionEvent[1]; 241cdf0e10cSrcweir lInAction[0] = aEvent; 242cdf0e10cSrcweir 243cdf0e10cSrcweir OnewayExecutor.codeFrameAction( OnewayExecutor.ENCODE_PARAMS , 244cdf0e10cSrcweir lOutParams , 245cdf0e10cSrcweir lInAction ); 246cdf0e10cSrcweir OnewayExecutor aExecutor = new OnewayExecutor( (IOnewayLink)this , 247cdf0e10cSrcweir OnewayExecutor.REQUEST_FRAMEACTION , 248cdf0e10cSrcweir lOutParams[0] ); 249cdf0e10cSrcweir aExecutor.start(); 250cdf0e10cSrcweir } 251cdf0e10cSrcweir 252cdf0e10cSrcweir // ____________________ 253cdf0e10cSrcweir 254cdf0e10cSrcweir /** 255cdf0e10cSrcweir * Indicates using of us as an interceptor. 256cdf0e10cSrcweir * Now we have to react for the requests, we are registered. 257cdf0e10cSrcweir * That means: load new empty documents - triggered by the new menu of the office. 258cdf0e10cSrcweir * Because it's oneway - use thread for loading! 259cdf0e10cSrcweir * 260cdf0e10cSrcweir * @seealso impl_dispatch() 261cdf0e10cSrcweir * 262cdf0e10cSrcweir * @param aURL 263cdf0e10cSrcweir * describes the document, which should be loaded 264cdf0e10cSrcweir * 265cdf0e10cSrcweir * @param lArguments 266cdf0e10cSrcweir * optional parameters for loading 267cdf0e10cSrcweir */ 268cdf0e10cSrcweir public /*ONEWAY*/ void dispatch(/*IN*/ com.sun.star.util.URL aURL,/*IN*/ com.sun.star.beans.PropertyValue[] lArguments) 269cdf0e10cSrcweir { 270cdf0e10cSrcweir synchronized(this) 271cdf0e10cSrcweir { 272cdf0e10cSrcweir if (m_bDead) 273cdf0e10cSrcweir return; 274cdf0e10cSrcweir } 275cdf0e10cSrcweir 276cdf0e10cSrcweir Vector[] lOutParams = new Vector[1]; 277cdf0e10cSrcweir com.sun.star.util.URL[] lInURL = new com.sun.star.util.URL[1]; 278cdf0e10cSrcweir com.sun.star.beans.PropertyValue[][] lInArguments = new com.sun.star.beans.PropertyValue[1][]; 279cdf0e10cSrcweir lInURL[0] = aURL ; 280cdf0e10cSrcweir lInArguments[0] = lArguments; 281cdf0e10cSrcweir 282cdf0e10cSrcweir OnewayExecutor.codeDispatch( OnewayExecutor.ENCODE_PARAMS , 283cdf0e10cSrcweir lOutParams , 284cdf0e10cSrcweir lInURL , 285cdf0e10cSrcweir lInArguments ); 286cdf0e10cSrcweir OnewayExecutor aExecutor = new OnewayExecutor( (IOnewayLink)this , 287cdf0e10cSrcweir OnewayExecutor.REQUEST_DISPATCH , 288cdf0e10cSrcweir lOutParams[0] ); 289cdf0e10cSrcweir aExecutor.start(); 290cdf0e10cSrcweir } 291cdf0e10cSrcweir 292cdf0e10cSrcweir 293cdf0e10cSrcweir //_____________________ 294cdf0e10cSrcweir 295cdf0e10cSrcweir /** 296cdf0e10cSrcweir * Internal call back for frame action events, triggered by the used 297cdf0e10cSrcweir * OnewayExecutor thread we started in frameAction(). 298cdf0e10cSrcweir * We use it to update our interception on the internal saved frame. 299cdf0e10cSrcweir * 300cdf0e10cSrcweir * @param aEvent 301cdf0e10cSrcweir * describes the action 302cdf0e10cSrcweir */ 303cdf0e10cSrcweir public void impl_frameAction(/*IN*/ com.sun.star.frame.FrameActionEvent aEvent) 304cdf0e10cSrcweir { 305cdf0e10cSrcweir synchronized(this) 306cdf0e10cSrcweir { 307cdf0e10cSrcweir if (m_bDead) 308cdf0e10cSrcweir return; 309cdf0e10cSrcweir } 310cdf0e10cSrcweir 311cdf0e10cSrcweir // deregistration will be done everytime ... 312cdf0e10cSrcweir // But may it's not neccessary to establish a new registration! 313cdf0e10cSrcweir // Don't look for ignoring actions - it was done already inside original frameAction() call! 314cdf0e10cSrcweir boolean bRegister = false; 315cdf0e10cSrcweir 316cdf0e10cSrcweir // analyze the event and decide which reaction is usefull 317cdf0e10cSrcweir switch(aEvent.Action.getValue()) 318cdf0e10cSrcweir { 319cdf0e10cSrcweir case com.sun.star.frame.FrameAction.COMPONENT_ATTACHED_value : bRegister = true ; break; 320cdf0e10cSrcweir case com.sun.star.frame.FrameAction.COMPONENT_REATTACHED_value : bRegister = true ; break; 321cdf0e10cSrcweir case com.sun.star.frame.FrameAction.COMPONENT_DETACHING_value : bRegister = false; break; 322cdf0e10cSrcweir } 323cdf0e10cSrcweir 324cdf0e10cSrcweir com.sun.star.frame.XFrame xFrame = null ; 325cdf0e10cSrcweir boolean bIsRegistered = false; 326cdf0e10cSrcweir synchronized(this) 327cdf0e10cSrcweir { 328cdf0e10cSrcweir bIsRegistered = m_bIsRegistered; 329cdf0e10cSrcweir m_bIsRegistered = false; 330cdf0e10cSrcweir xFrame = m_xFrame; 331cdf0e10cSrcweir } 332cdf0e10cSrcweir 333cdf0e10cSrcweir com.sun.star.frame.XDispatchProviderInterception xRegistration = (com.sun.star.frame.XDispatchProviderInterception)UnoRuntime.queryInterface( 334cdf0e10cSrcweir com.sun.star.frame.XDispatchProviderInterception.class, 335cdf0e10cSrcweir xFrame); 336cdf0e10cSrcweir 337cdf0e10cSrcweir if(xRegistration==null) 338cdf0e10cSrcweir return; 339cdf0e10cSrcweir 340cdf0e10cSrcweir if (bIsRegistered) 341cdf0e10cSrcweir xRegistration.releaseDispatchProviderInterceptor(this); 342cdf0e10cSrcweir 343cdf0e10cSrcweir if (! bRegister) 344cdf0e10cSrcweir return; 345cdf0e10cSrcweir 346cdf0e10cSrcweir xRegistration.registerDispatchProviderInterceptor(this); 347cdf0e10cSrcweir synchronized(this) 348cdf0e10cSrcweir { 349cdf0e10cSrcweir m_bIsRegistered = true; 350cdf0e10cSrcweir } 351cdf0e10cSrcweir } 352cdf0e10cSrcweir 353cdf0e10cSrcweir // ____________________ 354cdf0e10cSrcweir 355cdf0e10cSrcweir /** 356cdf0e10cSrcweir * Implementation of interface XDispatchProviderInterceptor 357cdf0e10cSrcweir * These functions are used to build a list of interceptor objects 358cdf0e10cSrcweir * connected in both ways. 359cdf0e10cSrcweir * Searching for a right interceptor is made by forwarding any request 360cdf0e10cSrcweir * from toppest master to lowest slave of this hierarchy. 361cdf0e10cSrcweir * If an interceptor whish to handle the request he can break that 362cdf0e10cSrcweir * and return himself as a dispatcher. 363cdf0e10cSrcweir */ 364cdf0e10cSrcweir public com.sun.star.frame.XDispatchProvider getSlaveDispatchProvider() 365cdf0e10cSrcweir { 366cdf0e10cSrcweir synchronized(this) 367cdf0e10cSrcweir { 368cdf0e10cSrcweir return m_xSlave; 369cdf0e10cSrcweir } 370cdf0e10cSrcweir } 371cdf0e10cSrcweir 372cdf0e10cSrcweir // ____________________ 373cdf0e10cSrcweir 374cdf0e10cSrcweir public void setSlaveDispatchProvider(com.sun.star.frame.XDispatchProvider xSlave) 375cdf0e10cSrcweir { 376cdf0e10cSrcweir synchronized(this) 377cdf0e10cSrcweir { 378cdf0e10cSrcweir m_xSlave = xSlave; 379cdf0e10cSrcweir } 380cdf0e10cSrcweir } 381cdf0e10cSrcweir 382cdf0e10cSrcweir // ____________________ 383cdf0e10cSrcweir 384cdf0e10cSrcweir public com.sun.star.frame.XDispatchProvider getMasterDispatchProvider() 385cdf0e10cSrcweir { 386cdf0e10cSrcweir synchronized(this) 387cdf0e10cSrcweir { 388cdf0e10cSrcweir return m_xMaster; 389cdf0e10cSrcweir } 390cdf0e10cSrcweir } 391cdf0e10cSrcweir 392cdf0e10cSrcweir // ____________________ 393cdf0e10cSrcweir 394cdf0e10cSrcweir public void setMasterDispatchProvider(com.sun.star.frame.XDispatchProvider xMaster) 395cdf0e10cSrcweir { 396cdf0e10cSrcweir synchronized(this) 397cdf0e10cSrcweir { 398cdf0e10cSrcweir m_xMaster = xMaster; 399cdf0e10cSrcweir } 400cdf0e10cSrcweir } 401cdf0e10cSrcweir 402cdf0e10cSrcweir // ____________________ 403cdf0e10cSrcweir 404cdf0e10cSrcweir /** 405cdf0e10cSrcweir * Implementation of interface XDispatchProvider 406cdf0e10cSrcweir * These functions are called from our master if he willn't handle the outstanding request. 407cdf0e10cSrcweir * Given parameter should be checked if they are right for us. If it's true, the returned 408cdf0e10cSrcweir * dispatcher should be this implementation himself; otherwise call should be forwarded 409cdf0e10cSrcweir * to the slave. 410cdf0e10cSrcweir * 411cdf0e10cSrcweir * @param aURL 412cdf0e10cSrcweir * describes the request, which should be handled 413cdf0e10cSrcweir * 414cdf0e10cSrcweir * @param sTarget 415cdf0e10cSrcweir * specifies the target frame for this request 416cdf0e10cSrcweir * 417cdf0e10cSrcweir * @param nSearchFlags 418cdf0e10cSrcweir * optional search flags, if sTarget isn't a special one 419cdf0e10cSrcweir * 420cdf0e10cSrcweir * @return [XDispatch] 421cdf0e10cSrcweir * a dispatch object, which can handle the given URL 422cdf0e10cSrcweir * May be NULL! 423cdf0e10cSrcweir */ 424cdf0e10cSrcweir public com.sun.star.frame.XDispatch queryDispatch(/*IN*/ com.sun.star.util.URL aURL,/*IN*/ String sTarget,/*IN*/ int nSearchFlags) 425cdf0e10cSrcweir { 426cdf0e10cSrcweir synchronized(this) 427cdf0e10cSrcweir { 428cdf0e10cSrcweir if (m_bDead) 429cdf0e10cSrcweir return null; 430cdf0e10cSrcweir } 431cdf0e10cSrcweir 432cdf0e10cSrcweir // intercept loading empty documents into new created frames 433cdf0e10cSrcweir if( 434cdf0e10cSrcweir (sTarget.compareTo ("_blank" ) == 0 ) && 435cdf0e10cSrcweir (aURL.Complete.startsWith("private:factory") == true) 436cdf0e10cSrcweir ) 437cdf0e10cSrcweir { 438cdf0e10cSrcweir System.out.println("intercept private:factory"); 439cdf0e10cSrcweir return this; 440cdf0e10cSrcweir } 441cdf0e10cSrcweir 442cdf0e10cSrcweir // intercept opening the SaveAs dialog 443cdf0e10cSrcweir if (aURL.Complete.startsWith(".uno:SaveAs") == true) 444cdf0e10cSrcweir { 445cdf0e10cSrcweir System.out.println("intercept SaveAs by returning null!"); 446cdf0e10cSrcweir return null; 447cdf0e10cSrcweir } 448cdf0e10cSrcweir 449cdf0e10cSrcweir // intercept "File->Exit" inside the menu 450cdf0e10cSrcweir if ( 451cdf0e10cSrcweir (aURL.Complete.startsWith("slot:5300") == true) || 452cdf0e10cSrcweir (aURL.Complete.startsWith(".uno:Quit") == true) 453cdf0e10cSrcweir ) 454cdf0e10cSrcweir { 455cdf0e10cSrcweir System.out.println("intercept File->Exit"); 456cdf0e10cSrcweir return this; 457cdf0e10cSrcweir } 458cdf0e10cSrcweir 459cdf0e10cSrcweir synchronized(this) 460cdf0e10cSrcweir { 461cdf0e10cSrcweir if (m_xSlave!=null) 462cdf0e10cSrcweir return m_xSlave.queryDispatch(aURL, sTarget, nSearchFlags); 463cdf0e10cSrcweir } 464cdf0e10cSrcweir 465cdf0e10cSrcweir return null; 466cdf0e10cSrcweir } 467cdf0e10cSrcweir 468cdf0e10cSrcweir // ____________________ 469cdf0e10cSrcweir 470cdf0e10cSrcweir public com.sun.star.frame.XDispatch[] queryDispatches(/*IN*/ com.sun.star.frame.DispatchDescriptor[] lDescriptor) 471cdf0e10cSrcweir { 472cdf0e10cSrcweir synchronized(this) 473cdf0e10cSrcweir { 474cdf0e10cSrcweir if (m_bDead) 475cdf0e10cSrcweir return null; 476cdf0e10cSrcweir } 477cdf0e10cSrcweir // Resolve any request seperatly by using own "dispatch()" method. 478cdf0e10cSrcweir // Note: Don't pack return list if "null" objects occure! 479cdf0e10cSrcweir int nCount = lDescriptor.length; 480cdf0e10cSrcweir com.sun.star.frame.XDispatch[] lDispatcher = new com.sun.star.frame.XDispatch[nCount]; 481cdf0e10cSrcweir for(int i=0; i<nCount; ++i) 482cdf0e10cSrcweir { 483cdf0e10cSrcweir lDispatcher[i] = queryDispatch(lDescriptor[i].FeatureURL , 484cdf0e10cSrcweir lDescriptor[i].FrameName , 485cdf0e10cSrcweir lDescriptor[i].SearchFlags); 486cdf0e10cSrcweir } 487cdf0e10cSrcweir return lDispatcher; 488cdf0e10cSrcweir } 489cdf0e10cSrcweir 490cdf0e10cSrcweir // ____________________ 491cdf0e10cSrcweir 492cdf0e10cSrcweir /** 493cdf0e10cSrcweir * This method is called if this interceptor "wins the request". 494cdf0e10cSrcweir * We intercepted creation of new frames and loading of empty documents. 495cdf0e10cSrcweir * Do it now. 496cdf0e10cSrcweir * 497cdf0e10cSrcweir * @param aURL 498cdf0e10cSrcweir * describes the document 499cdf0e10cSrcweir * 500cdf0e10cSrcweir * @param lArguments 501cdf0e10cSrcweir * optional arguments for loading 502cdf0e10cSrcweir */ 503cdf0e10cSrcweir public void impl_dispatch(/*IN*/ com.sun.star.util.URL aURL,/*IN*/ com.sun.star.beans.PropertyValue[] lArguments) 504cdf0e10cSrcweir { 505cdf0e10cSrcweir synchronized(this) 506cdf0e10cSrcweir { 507cdf0e10cSrcweir if (m_bDead) 508cdf0e10cSrcweir return; 509cdf0e10cSrcweir } 510cdf0e10cSrcweir 511cdf0e10cSrcweir if ( 512cdf0e10cSrcweir (aURL.Complete.startsWith("slot:5300") == true) || 513cdf0e10cSrcweir (aURL.Complete.startsWith(".uno:Quit") == true) 514cdf0e10cSrcweir ) 515cdf0e10cSrcweir { 516cdf0e10cSrcweir System.exit(0); 517cdf0e10cSrcweir } 518cdf0e10cSrcweir else 519cdf0e10cSrcweir if (aURL.Complete.startsWith("private:factory") == true) 520cdf0e10cSrcweir { 521cdf0e10cSrcweir // Create view frame for showing loaded documents on demand. 522cdf0e10cSrcweir // The visible state is neccessary for JNI functionality to get the HWND and plug office 523cdf0e10cSrcweir // inside a java window hierarchy! 524cdf0e10cSrcweir DocumentView aNewView = new DocumentView(); 525cdf0e10cSrcweir aNewView.setVisible(true); 526cdf0e10cSrcweir aNewView.createFrame(); 527cdf0e10cSrcweir aNewView.load(aURL.Complete,lArguments); 528cdf0e10cSrcweir } 529cdf0e10cSrcweir } 530cdf0e10cSrcweir 531cdf0e10cSrcweir // ____________________ 532cdf0e10cSrcweir 533cdf0e10cSrcweir /** 534cdf0e10cSrcweir * Notification of status listener isn't guaranteed (instead of listener on XNotifyingDispatch interface). 535cdf0e10cSrcweir * So this interceptor doesn't support that realy ... 536cdf0e10cSrcweir */ 537cdf0e10cSrcweir public /*ONEWAY*/ void addStatusListener(/*IN*/ com.sun.star.frame.XStatusListener xListener,/*IN*/ com.sun.star.util.URL aURL) 538cdf0e10cSrcweir { 539cdf0e10cSrcweir /* if (aURL.Complete.startsWith(".uno:SaveAs")==true) 540cdf0e10cSrcweir { 541cdf0e10cSrcweir com.sun.star.frame.FeatureStateEvent aEvent = new com.sun.star.frame.FeatureStateEvent( 542cdf0e10cSrcweir this, 543cdf0e10cSrcweir aURL, 544cdf0e10cSrcweir "", 545cdf0e10cSrcweir false, 546cdf0e10cSrcweir false, 547cdf0e10cSrcweir null); 548cdf0e10cSrcweir if (xListener!=null) 549cdf0e10cSrcweir { 550cdf0e10cSrcweir System.out.println("interceptor disable SavAs by listener notify"); 551cdf0e10cSrcweir xListener.statusChanged(aEvent); 552cdf0e10cSrcweir } 553cdf0e10cSrcweir }*/ 554cdf0e10cSrcweir } 555cdf0e10cSrcweir 556cdf0e10cSrcweir // ____________________ 557cdf0e10cSrcweir 558cdf0e10cSrcweir public /*ONEWAY*/ void removeStatusListener(/*IN*/ com.sun.star.frame.XStatusListener xListener,/*IN*/ com.sun.star.util.URL aURL) 559cdf0e10cSrcweir { 560cdf0e10cSrcweir } 561cdf0e10cSrcweir 562cdf0e10cSrcweir // ____________________ 563cdf0e10cSrcweir 564cdf0e10cSrcweir /** 565cdf0e10cSrcweir * Implements (optional!) optimization for interceptor mechanism. 566cdf0e10cSrcweir * Any interceptor which provides this special interface is called automaticly 567cdf0e10cSrcweir * at registration time on this method. Returned URL's will be used to 568cdf0e10cSrcweir * call this interceptor directly without calling his masters before, IF(!) 569cdf0e10cSrcweir * following rules will be true: 570cdf0e10cSrcweir * (1) every master supports this optional interface too 571cdf0e10cSrcweir * (2) nobody of these masters whish to intercept same URL then this one 572cdf0e10cSrcweir * This interceptor whish to intercept creation of new documents. 573cdf0e10cSrcweir */ 574cdf0e10cSrcweir public String[] getInterceptedURLs() 575cdf0e10cSrcweir { 576cdf0e10cSrcweir return INTERCEPTED_URLS; 577cdf0e10cSrcweir } 578cdf0e10cSrcweir 579cdf0e10cSrcweir // ____________________ 580cdf0e10cSrcweir 581cdf0e10cSrcweir /** 582cdf0e10cSrcweir * This class listen on the intercepted frame to free all used ressources on closing. 583cdf0e10cSrcweir * We forget the reference to the frame only here. Deregistration 584cdf0e10cSrcweir * isn't neccessary here - because this frame dies and wish to forgoten. 585cdf0e10cSrcweir * 586cdf0e10cSrcweir * @param aSource 587cdf0e10cSrcweir * must be our internal saved frame, on which we listen for frame action events 588cdf0e10cSrcweir */ 589cdf0e10cSrcweir public /*ONEAY*/ void disposing(/*IN*/ com.sun.star.lang.EventObject aSource) 590cdf0e10cSrcweir { 591cdf0e10cSrcweir synchronized(this) 592cdf0e10cSrcweir { 593cdf0e10cSrcweir if (m_bDead) 594cdf0e10cSrcweir return; 595cdf0e10cSrcweir if (m_xFrame!=null && UnoRuntime.areSame(aSource.Source,m_xFrame)) 596cdf0e10cSrcweir { 597cdf0e10cSrcweir m_bIsActionListener = false; 598cdf0e10cSrcweir m_xFrame = null ; 599cdf0e10cSrcweir } 600cdf0e10cSrcweir } 601cdf0e10cSrcweir shutdown(); 602cdf0e10cSrcweir } 603cdf0e10cSrcweir 604cdf0e10cSrcweir // ____________________ 605cdf0e10cSrcweir 606cdf0e10cSrcweir /** 607cdf0e10cSrcweir * If this java application shutdown - we must cancel all current existing 608cdf0e10cSrcweir * listener connections. Otherwhise the office will run into some 609cdf0e10cSrcweir * DisposedExceptions if it tries to use these forgotten listener references. 610cdf0e10cSrcweir * And of course it can die doing that. 611cdf0e10cSrcweir * We are registered at a central object to be informed if the VM will exit. 612cdf0e10cSrcweir * So we can react. 613cdf0e10cSrcweir */ 614cdf0e10cSrcweir public void shutdown() 615cdf0e10cSrcweir { 616cdf0e10cSrcweir com.sun.star.frame.XFrame xFrame = null ; 617cdf0e10cSrcweir boolean bIsRegistered = false; 618cdf0e10cSrcweir boolean bIsActionListener = false; 619cdf0e10cSrcweir synchronized(this) 620cdf0e10cSrcweir { 621cdf0e10cSrcweir // don't react a second time here! 622cdf0e10cSrcweir if (m_bDead) 623cdf0e10cSrcweir return; 624cdf0e10cSrcweir m_bDead = true; 625cdf0e10cSrcweir 626cdf0e10cSrcweir bIsRegistered = m_bIsRegistered; 627cdf0e10cSrcweir m_bIsRegistered = false; 628cdf0e10cSrcweir 629cdf0e10cSrcweir bIsActionListener = m_bIsActionListener; 630cdf0e10cSrcweir m_bIsActionListener = false; 631cdf0e10cSrcweir 632cdf0e10cSrcweir xFrame = m_xFrame; 633cdf0e10cSrcweir m_xFrame = null; 634cdf0e10cSrcweir } 635cdf0e10cSrcweir 636cdf0e10cSrcweir // it's a good idead to cancel listening for frame action events 637cdf0e10cSrcweir // before(!) we deregister us as an interceptor. 638cdf0e10cSrcweir // Because registration and deregistratio nof interceptor objects 639cdf0e10cSrcweir // will force sending of frame action events ...! 640cdf0e10cSrcweir if (bIsActionListener) 641cdf0e10cSrcweir xFrame.removeFrameActionListener(this); 642cdf0e10cSrcweir 643cdf0e10cSrcweir if (bIsRegistered) 644cdf0e10cSrcweir { 645cdf0e10cSrcweir com.sun.star.frame.XDispatchProviderInterception xRegistration = (com.sun.star.frame.XDispatchProviderInterception)UnoRuntime.queryInterface( 646cdf0e10cSrcweir com.sun.star.frame.XDispatchProviderInterception.class, 647cdf0e10cSrcweir xFrame); 648cdf0e10cSrcweir 649cdf0e10cSrcweir if(xRegistration!=null) 650cdf0e10cSrcweir xRegistration.releaseDispatchProviderInterceptor(this); 651cdf0e10cSrcweir } 652cdf0e10cSrcweir 653cdf0e10cSrcweir xFrame = null; 654cdf0e10cSrcweir 655cdf0e10cSrcweir synchronized(this) 656cdf0e10cSrcweir { 657cdf0e10cSrcweir m_xMaster = null; 658cdf0e10cSrcweir m_xSlave = null; 659cdf0e10cSrcweir } 660cdf0e10cSrcweir } 661cdf0e10cSrcweir } 662