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