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             throw(css::uno::RuntimeException);
255 
256         //_________________________________________________
257         // XDispatchProvider
258 
259         /** @short implements an optimized queryDispatch() for remote.
260 
261             @descr It capsulate more than one queryDispatch() requests and returns a list of dispatched objects
262                    as result. Because both lists (in and out) correspond together, it's not allowed to
263                    pack it - means suppress NULL references!
264 
265             @param lDescriptor
266                     a list of queryDispatch() arguments.
267 
268             @return A list of dispatch objects.
269          */
270         virtual css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL queryDispatches(const css::uno::Sequence< css::frame::DispatchDescriptor >& lDescriptor)
271             throw(css::uno::RuntimeException);
272 
273         //_________________________________________________
274         // XDispatchProviderInterception
275 
276         /** @short      register an interceptor.
277 
278             @descr      Somebody can register himself to intercept all or some special dispatches.
279                         It's depend from his supported interfaces. If he implement XInterceptorInfo
280                         he his called for some special URLs only - otherwise we call it for every request!
281 
282             @attention  We don't check for double registrations here!
283 
284             @param      xInterceptor
285                         reference to interceptor, which wish to be registered here.
286 
287             @throw      A RuntimeException if the given reference is NULL!
288          */
289         virtual void SAL_CALL registerDispatchProviderInterceptor(const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& xInterceptor)
290             throw(css::uno::RuntimeException);
291 
292         //_________________________________________________
293         // XDispatchProviderInterception
294 
295         /** @short      release an interceptor.
296 
297             @descr      Remove the registered interceptor from our internal list
298                         and delete all special informations about it.
299 
300             @param      xInterceptor
301                         reference to the interceptor, which wish to be deregistered.
302 
303             @throw      A RuntimeException if the given reference is NULL!
304          */
305 		virtual void SAL_CALL releaseDispatchProviderInterceptor( const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& xInterceptor ) throw( css::uno::RuntimeException );
306 
307         //_________________________________________________
308         // XEventListener
309 
310         /** @short      Is called from our owner frame, in case he will be disposed.
311 
312             @descr      We have to release all references to him then.
313                         Normally we will die by ref count too...
314          */
315         virtual void SAL_CALL disposing(const css::lang::EventObject& aEvent)
316             throw(css::uno::RuntimeException);
317 
318 }; // class InterceptionHelper
319 
320 } // namespace framework
321 
322 #endif // #ifndef __FRAMEWORK_HELPER_INTERCEPTIONHELPER_HXX_
323