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