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