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