1f8e07b45SAndrew Rist /**************************************************************
2*a97fbb85Smseidel  *
3f8e07b45SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4f8e07b45SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5f8e07b45SAndrew Rist  * distributed with this work for additional information
6f8e07b45SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7f8e07b45SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8f8e07b45SAndrew Rist  * "License"); you may not use this file except in compliance
9f8e07b45SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*a97fbb85Smseidel  *
11f8e07b45SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*a97fbb85Smseidel  *
13f8e07b45SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14f8e07b45SAndrew Rist  * software distributed under the License is distributed on an
15f8e07b45SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16f8e07b45SAndrew Rist  * KIND, either express or implied.  See the License for the
17f8e07b45SAndrew Rist  * specific language governing permissions and limitations
18f8e07b45SAndrew Rist  * under the License.
19*a97fbb85Smseidel  *
20f8e07b45SAndrew Rist  *************************************************************/
21f8e07b45SAndrew Rist 
22f8e07b45SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #ifndef __FRAMEWORK_HELPER_INTERCEPTIONHELPER_HXX_
25cdf0e10cSrcweir #define __FRAMEWORK_HELPER_INTERCEPTIONHELPER_HXX_
26cdf0e10cSrcweir 
27cdf0e10cSrcweir //_________________________________________________________________________________________________________________
28cdf0e10cSrcweir //	my own includes
29cdf0e10cSrcweir //_________________________________________________________________________________________________________________
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #include <services/frame.hxx>
32cdf0e10cSrcweir #include <threadhelp/threadhelpbase.hxx>
33cdf0e10cSrcweir #include <macros/xinterface.hxx>
34cdf0e10cSrcweir #include <macros/generic.hxx>
35cdf0e10cSrcweir #include <macros/debug.hxx>
36cdf0e10cSrcweir #include <general.h>
37cdf0e10cSrcweir 
38cdf0e10cSrcweir //_________________________________________________________________________________________________________________
39cdf0e10cSrcweir //	interface includes
40cdf0e10cSrcweir //_________________________________________________________________________________________________________________
41cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp>
42cdf0e10cSrcweir #include <com/sun/star/frame/XDispatchProviderInterception.hpp>
43cdf0e10cSrcweir #include <com/sun/star/frame/XDispatchProviderInterceptor.hpp>
44cdf0e10cSrcweir #include <com/sun/star/frame/XDispatchProvider.hpp>
45cdf0e10cSrcweir #include <com/sun/star/frame/XDispatch.hpp>
46cdf0e10cSrcweir #include <com/sun/star/frame/XFrame.hpp>
47cdf0e10cSrcweir #include <com/sun/star/frame/DispatchDescriptor.hpp>
48cdf0e10cSrcweir 
49cdf0e10cSrcweir //_________________________________________________________________________________________________________________
50cdf0e10cSrcweir //	other includes
51cdf0e10cSrcweir //_________________________________________________________________________________________________________________
52cdf0e10cSrcweir #include <tools/wldcrd.hxx>
53cdf0e10cSrcweir #include <cppuhelper/weak.hxx>
54cdf0e10cSrcweir #include <cppuhelper/weakref.hxx>
55cdf0e10cSrcweir 
56cdf0e10cSrcweir #ifndef __SGI_STL_DEQUE
57cdf0e10cSrcweir #include <deque>
58cdf0e10cSrcweir #endif
59cdf0e10cSrcweir 
60cdf0e10cSrcweir //_________________________________________________________________________________________________________________
61cdf0e10cSrcweir //	namespace
62cdf0e10cSrcweir //_________________________________________________________________________________________________________________
63cdf0e10cSrcweir 
64cdf0e10cSrcweir namespace framework{
65cdf0e10cSrcweir 
66cdf0e10cSrcweir //_________________________________________________________________________________________________________________
67cdf0e10cSrcweir //	exported const
68cdf0e10cSrcweir //_________________________________________________________________________________________________________________
69cdf0e10cSrcweir 
70cdf0e10cSrcweir //_________________________________________________________
71cdf0e10cSrcweir // definitions
72cdf0e10cSrcweir //_________________________________________________________
73cdf0e10cSrcweir 
74cdf0e10cSrcweir /** @short      implements a helper to support interception with additional functionality.
75cdf0e10cSrcweir 
76cdf0e10cSrcweir     @descr      This helper implements the complete XDispatchProviderInterception interface with
77cdf0e10cSrcweir                 master/slave functionality AND using of optional features like registration of URL pattern!
78cdf0e10cSrcweir 
79*a97fbb85Smseidel     @attention  Don't use this class as direct member - use it dynamically. Do not derive from this class.
80*a97fbb85Smseidel                 We hold a weak reference to our owner not to our superclass.
81cdf0e10cSrcweir  */
82cdf0e10cSrcweir class InterceptionHelper : public  css::frame::XDispatchProvider
83cdf0e10cSrcweir                          , public  css::frame::XDispatchProviderInterception
84cdf0e10cSrcweir                          , public  css::lang::XEventListener
85cdf0e10cSrcweir                            // order of base classes is important for right initialization of mutex member!
86cdf0e10cSrcweir                          , private ThreadHelpBase
87cdf0e10cSrcweir                          , public  ::cppu::OWeakObject
88cdf0e10cSrcweir {
89cdf0e10cSrcweir     //_____________________________________________________
90cdf0e10cSrcweir     // structs, helper
91cdf0e10cSrcweir 
92*a97fbb85Smseidel     /** @short bind an interceptor component to its URL pattern registration. */
93cdf0e10cSrcweir     struct InterceptorInfo
94cdf0e10cSrcweir     {
95cdf0e10cSrcweir         /** @short reference to the interceptor component. */
96cdf0e10cSrcweir         css::uno::Reference< css::frame::XDispatchProvider > xInterceptor;
97cdf0e10cSrcweir 
98*a97fbb85Smseidel         /** @short its registration for URL patterns.
99cdf0e10cSrcweir 
100cdf0e10cSrcweir             @descr If the interceptor component does not support the optional interface
101cdf0e10cSrcweir                    XInterceptorInfo, it will be registered for one pattern "*" by default.
102*a97fbb85Smseidel                    That would make it possible to handle it in the same manner like real
103cdf0e10cSrcweir                    registered interceptor objects and we must not implement any special code. */
104cdf0e10cSrcweir         css::uno::Sequence< ::rtl::OUString > lURLPattern;
105cdf0e10cSrcweir     };
106cdf0e10cSrcweir 
107cdf0e10cSrcweir     //_____________________________________________________
108cdf0e10cSrcweir 
109cdf0e10cSrcweir     /** @short implements a list of items of type InterceptorInfo, and provides some special
110cdf0e10cSrcweir                functions on it.
111cdf0e10cSrcweir 
112cdf0e10cSrcweir         @descr Because interceptor objects can be registered for URL patterns,
113cdf0e10cSrcweir                it supports a wildcard search on all list items.
114cdf0e10cSrcweir      */
115cdf0e10cSrcweir     class InterceptorList : public ::std::deque< InterceptorInfo >
116cdf0e10cSrcweir     {
117cdf0e10cSrcweir         public:
118cdf0e10cSrcweir 
119cdf0e10cSrcweir             //_____________________________________________
120cdf0e10cSrcweir 
121*a97fbb85Smseidel             /** @short search for an interceptor inside this list using its reference.
122cdf0e10cSrcweir 
123cdf0e10cSrcweir                 @param xInterceptor
124cdf0e10cSrcweir                         points to the interceptor object, which should be located inside this list.
125cdf0e10cSrcweir 
126cdf0e10cSrcweir                 @return An iterator object, which points directly to the located item inside this list.
127cdf0e10cSrcweir                         In case no interceptor could be found, it points to the end of this list!
128cdf0e10cSrcweir               */
findByReference(const css::uno::Reference<css::frame::XDispatchProviderInterceptor> & xInterceptor)129cdf0e10cSrcweir             iterator findByReference(const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& xInterceptor)
130cdf0e10cSrcweir             {
131cdf0e10cSrcweir                 css::uno::Reference< css::frame::XDispatchProviderInterceptor > xProviderInterface(xInterceptor, css::uno::UNO_QUERY);
132cdf0e10cSrcweir                 iterator pIt;
133cdf0e10cSrcweir                 for (pIt=begin(); pIt!=end(); ++pIt)
134cdf0e10cSrcweir                 {
135cdf0e10cSrcweir                     if (pIt->xInterceptor == xProviderInterface)
136cdf0e10cSrcweir                         return pIt;
137cdf0e10cSrcweir                 }
138cdf0e10cSrcweir                 return end();
139cdf0e10cSrcweir             }
140cdf0e10cSrcweir 
141cdf0e10cSrcweir             //_____________________________________________
142cdf0e10cSrcweir 
143*a97fbb85Smseidel             /** @short search for an interceptor inside this list using its reference.
144cdf0e10cSrcweir 
145cdf0e10cSrcweir                 @param xInterceptor
146cdf0e10cSrcweir                         points to the interceptor object, which should be located inside this list.
147cdf0e10cSrcweir 
148cdf0e10cSrcweir                 @return An iterator object, which points directly to the located item inside this list.
149cdf0e10cSrcweir                         In case no interceptor could be found, it points to the end of this list!
150cdf0e10cSrcweir               */
findByPattern(const::rtl::OUString & sURL)151cdf0e10cSrcweir             iterator findByPattern(const ::rtl::OUString& sURL)
152cdf0e10cSrcweir             {
153cdf0e10cSrcweir                 iterator pIt;
154cdf0e10cSrcweir                 for (pIt=begin(); pIt!=end(); ++pIt)
155cdf0e10cSrcweir                 {
156cdf0e10cSrcweir                     sal_Int32              c        = pIt->lURLPattern.getLength();
157cdf0e10cSrcweir                     const ::rtl::OUString* pPattern = pIt->lURLPattern.getConstArray();
158cdf0e10cSrcweir 
159cdf0e10cSrcweir                     for (sal_Int32 i=0; i<c; ++i)
160cdf0e10cSrcweir                     {
161cdf0e10cSrcweir                         WildCard aPattern(pPattern[i]);
162cdf0e10cSrcweir                         if (aPattern.Matches(sURL))
163cdf0e10cSrcweir                             return pIt;
164cdf0e10cSrcweir                     }
165cdf0e10cSrcweir                 }
166cdf0e10cSrcweir                 return end();
167cdf0e10cSrcweir             }
168cdf0e10cSrcweir     };
169cdf0e10cSrcweir 
170cdf0e10cSrcweir     //_____________________________________________________
171cdf0e10cSrcweir     // member
172cdf0e10cSrcweir 
173cdf0e10cSrcweir     private:
174cdf0e10cSrcweir 
175*a97fbb85Smseidel         /** @short reference to the frame, which uses this instance to implement its own interception.
176cdf0e10cSrcweir 
177cdf0e10cSrcweir             @descr We hold a weak reference only, to make disposing operations easy. */
178cdf0e10cSrcweir         css::uno::WeakReference< css::frame::XFrame > m_xOwnerWeak;
179cdf0e10cSrcweir 
180*a97fbb85Smseidel         /** @short this interception helper implements the top level master of an interceptor list...
181cdf0e10cSrcweir                    but this member is the lowest possible slave! */
182cdf0e10cSrcweir         css::uno::Reference< css::frame::XDispatchProvider > m_xSlave;
183cdf0e10cSrcweir 
184cdf0e10cSrcweir         /** @short contains all registered interceptor objects. */
185cdf0e10cSrcweir         InterceptorList m_lInterceptionRegs;
186cdf0e10cSrcweir 
187cdf0e10cSrcweir         /** @short it regulates, which interceptor is used first.
188cdf0e10cSrcweir                    The last or the first registered one. */
189cdf0e10cSrcweir         static sal_Bool m_bPreferrFirstInterceptor;
190cdf0e10cSrcweir 
191cdf0e10cSrcweir     //_____________________________________________________
192cdf0e10cSrcweir     // native interface
193cdf0e10cSrcweir 
194cdf0e10cSrcweir     public:
195cdf0e10cSrcweir 
196cdf0e10cSrcweir         //_________________________________________________
197cdf0e10cSrcweir 
198cdf0e10cSrcweir         /** @short creates a new interception helper instance.
199cdf0e10cSrcweir 
200cdf0e10cSrcweir             @param xOwner
201*a97fbb85Smseidel                     points to the frame, which use this instances to support its own interception interfaces.
202cdf0e10cSrcweir 
203cdf0e10cSrcweir             @param xSlave
204cdf0e10cSrcweir                     an outside creates dispatch provider, which has to be used here as lowest slave "interceptor".
205cdf0e10cSrcweir          */
206cdf0e10cSrcweir         InterceptionHelper(const css::uno::Reference< css::frame::XFrame >&            xOwner,
207cdf0e10cSrcweir                            const css::uno::Reference< css::frame::XDispatchProvider >& xSlave);
208cdf0e10cSrcweir 
209cdf0e10cSrcweir     protected:
210cdf0e10cSrcweir 
211cdf0e10cSrcweir         //_________________________________________________
212cdf0e10cSrcweir 
213cdf0e10cSrcweir         /** @short standard destructor.
214cdf0e10cSrcweir 
215cdf0e10cSrcweir             @descr This method destruct an instance of this class and clear some member.
216*a97fbb85Smseidel                    This method is protected, because it's not allowed to use this class as a direct member!
217cdf0e10cSrcweir                    You MUST use a dynamical instance (pointer). That's the reason for a protected dtor.
218cdf0e10cSrcweir          */
219cdf0e10cSrcweir         virtual ~InterceptionHelper();
220cdf0e10cSrcweir 
221cdf0e10cSrcweir     //_____________________________________________________
222cdf0e10cSrcweir     // uno interface
223cdf0e10cSrcweir 
224cdf0e10cSrcweir     public:
225cdf0e10cSrcweir 
226cdf0e10cSrcweir         FWK_DECLARE_XINTERFACE
227cdf0e10cSrcweir 
228cdf0e10cSrcweir         //_________________________________________________
229cdf0e10cSrcweir         // XDispatchProvider
230cdf0e10cSrcweir 
231cdf0e10cSrcweir         /** @short  query for a dispatch, which implements the requested feature.
232cdf0e10cSrcweir 
233cdf0e10cSrcweir             @descr  We search inside our list of interception registrations, to locate
234cdf0e10cSrcweir                     any interested interceptor. In case no interceptor exists or nobody is
235cdf0e10cSrcweir                     interested on this URL our lowest slave will be used.
236cdf0e10cSrcweir 
237cdf0e10cSrcweir             @param  aURL
238cdf0e10cSrcweir                         describes the requested dispatch functionality.
239cdf0e10cSrcweir 
240cdf0e10cSrcweir             @param  sTargetFrameName
241*a97fbb85Smseidel                         the name of the target frame or a special name like "_blank", "_top"...
242*a97fbb85Smseidel                         Won't be used here... but maybe one of our registered interceptor objects
243cdf0e10cSrcweir                         or our slave.
244cdf0e10cSrcweir 
245cdf0e10cSrcweir             @param  nSearchFlags
246cdf0e10cSrcweir                         optional search parameter for targeting, if sTargetFrameName isn't a special one.
247cdf0e10cSrcweir 
248cdf0e10cSrcweir             @return A valid dispatch object, if any interceptor or at least our slave is interested on the given URL;
249*a97fbb85Smseidel                     or NULL otherwise.
250cdf0e10cSrcweir          */
251cdf0e10cSrcweir         virtual css::uno::Reference< css::frame::XDispatch > SAL_CALL queryDispatch(const css::util::URL&  aURL            ,
252cdf0e10cSrcweir                                                                                     const ::rtl::OUString& sTargetFrameName,
253cdf0e10cSrcweir                                                                                           sal_Int32        nSearchFlags    )
254cdf0e10cSrcweir             throw(css::uno::RuntimeException);
255cdf0e10cSrcweir 
256cdf0e10cSrcweir         //_________________________________________________
257cdf0e10cSrcweir         // XDispatchProvider
258cdf0e10cSrcweir 
259cdf0e10cSrcweir         /** @short implements an optimized queryDispatch() for remote.
260cdf0e10cSrcweir 
261*a97fbb85Smseidel             @descr It capsulate more than one queryDispatch() requests and returns a list of dispatched objects
262*a97fbb85Smseidel                    as result. Because both lists (in and out) correspond together, it's not allowed to
26307a3d7f1SPedro Giffuni                    pack it - means suppress NULL references!
264cdf0e10cSrcweir 
265cdf0e10cSrcweir             @param lDescriptor
266cdf0e10cSrcweir                     a list of queryDispatch() arguments.
267cdf0e10cSrcweir 
268cdf0e10cSrcweir             @return A list of dispatch objects.
269cdf0e10cSrcweir          */
270cdf0e10cSrcweir         virtual css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL queryDispatches(const css::uno::Sequence< css::frame::DispatchDescriptor >& lDescriptor)
271cdf0e10cSrcweir             throw(css::uno::RuntimeException);
272cdf0e10cSrcweir 
273cdf0e10cSrcweir         //_________________________________________________
274cdf0e10cSrcweir         // XDispatchProviderInterception
275cdf0e10cSrcweir 
276cdf0e10cSrcweir         /** @short      register an interceptor.
277cdf0e10cSrcweir 
278cdf0e10cSrcweir             @descr      Somebody can register himself to intercept all or some special dispatches.
279cdf0e10cSrcweir                         It's depend from his supported interfaces. If he implement XInterceptorInfo
280cdf0e10cSrcweir                         he his called for some special URLs only - otherwise we call it for every request!
281cdf0e10cSrcweir 
282cdf0e10cSrcweir             @attention  We don't check for double registrations here!
283cdf0e10cSrcweir 
284cdf0e10cSrcweir             @param      xInterceptor
285cdf0e10cSrcweir                         reference to interceptor, which wish to be registered here.
286cdf0e10cSrcweir 
287cdf0e10cSrcweir             @throw      A RuntimeException if the given reference is NULL!
288cdf0e10cSrcweir          */
289cdf0e10cSrcweir         virtual void SAL_CALL registerDispatchProviderInterceptor(const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& xInterceptor)
290cdf0e10cSrcweir             throw(css::uno::RuntimeException);
291cdf0e10cSrcweir 
292cdf0e10cSrcweir         //_________________________________________________
293cdf0e10cSrcweir         // XDispatchProviderInterception
294cdf0e10cSrcweir 
295cdf0e10cSrcweir         /** @short      release an interceptor.
296cdf0e10cSrcweir 
297cdf0e10cSrcweir             @descr      Remove the registered interceptor from our internal list
298cdf0e10cSrcweir                         and delete all special informations about it.
299cdf0e10cSrcweir 
300cdf0e10cSrcweir             @param      xInterceptor
301cdf0e10cSrcweir                         reference to the interceptor, which wish to be deregistered.
302cdf0e10cSrcweir 
303cdf0e10cSrcweir             @throw      A RuntimeException if the given reference is NULL!
304cdf0e10cSrcweir          */
305cdf0e10cSrcweir 		virtual void SAL_CALL releaseDispatchProviderInterceptor( const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& xInterceptor ) throw( css::uno::RuntimeException );
306cdf0e10cSrcweir 
307cdf0e10cSrcweir         //_________________________________________________
308cdf0e10cSrcweir         // XEventListener
309cdf0e10cSrcweir 
310cdf0e10cSrcweir         /** @short      Is called from our owner frame, in case he will be disposed.
311cdf0e10cSrcweir 
312*a97fbb85Smseidel             @descr      We have to release all references to him then.
313*a97fbb85Smseidel                         Normally we will die by ref count too...
314cdf0e10cSrcweir          */
315cdf0e10cSrcweir         virtual void SAL_CALL disposing(const css::lang::EventObject& aEvent)
316cdf0e10cSrcweir             throw(css::uno::RuntimeException);
317cdf0e10cSrcweir 
318cdf0e10cSrcweir }; // class InterceptionHelper
319cdf0e10cSrcweir 
320cdf0e10cSrcweir } // namespace framework
321cdf0e10cSrcweir 
322cdf0e10cSrcweir #endif // #ifndef __FRAMEWORK_HELPER_INTERCEPTIONHELPER_HXX_
323