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_DISPATCH_BASEDISPATCHER_HXX_ 25 #define __FRAMEWORK_DISPATCH_BASEDISPATCHER_HXX_ 26 27 //_________________________________________________________________________________________________________________ 28 // my own includes 29 //_________________________________________________________________________________________________________________ 30 31 #include <classes/taskcreator.hxx> 32 #include <threadhelp/resetableguard.hxx> 33 #include <threadhelp/threadhelpbase.hxx> 34 35 #ifndef __FRAMEWORK_THREADHELP_TRANSACTIONBASE_HXX_ 36 #include <threadhelp/transactionbase.hxx> 37 #endif 38 #include <macros/xinterface.hxx> 39 #include <macros/xtypeprovider.hxx> 40 #include <macros/debug.hxx> 41 #include <macros/generic.hxx> 42 #include <stdtypes.h> 43 44 //_________________________________________________________________________________________________________________ 45 // interface includes 46 //_________________________________________________________________________________________________________________ 47 #include <com/sun/star/lang/XTypeProvider.hpp> 48 #include <com/sun/star/frame/XNotifyingDispatch.hpp> 49 #include <com/sun/star/util/URL.hpp> 50 #include <com/sun/star/frame/DispatchDescriptor.hpp> 51 #include <com/sun/star/beans/PropertyValue.hpp> 52 #include <com/sun/star/frame/XDispatchResultListener.hpp> 53 #include <com/sun/star/frame/XFrameLoader.hpp> 54 #include <com/sun/star/frame/XLoadEventListener.hpp> 55 #include <com/sun/star/frame/XDesktop.hpp> 56 #include <com/sun/star/frame/FeatureStateEvent.hpp> 57 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 58 59 //_________________________________________________________________________________________________________________ 60 // other includes 61 //_________________________________________________________________________________________________________________ 62 #include <cppuhelper/weak.hxx> 63 #include <cppuhelper/weakref.hxx> 64 #include <cppuhelper/interfacecontainer.h> 65 /*DRAFT 66 #include <unotools/historyoptions.hxx> 67 */ 68 69 //_________________________________________________________________________________________________________________ 70 // namespace 71 //_________________________________________________________________________________________________________________ 72 73 namespace framework{ 74 75 //_________________________________________________________________________________________________________________ 76 // exported const 77 //_________________________________________________________________________________________________________________ 78 79 //_________________________________________________________________________________________________________________ 80 // exported definitions 81 //_________________________________________________________________________________________________________________ 82 83 /*-************************************************************************************************************//** 84 @descr We must support loading of different URLs with different handler or loader into different tasks simultaniously. 85 They call us back to return state of operation. We need some informations to distinguish 86 between these different "loading threads". 87 This is the reason to implement this dynamicly list. 88 89 @attention I maked class LoaderThreads threadsafe! Using will be easier in a multithreaded environment. 90 struct DispatchBinding doesn't need that! 91 *//*-*************************************************************************************************************/ 92 struct LoadBinding 93 { 94 //------------------------------------------------------------------------------------------------------------- 95 public: 96 97 //--------------------------------------------------------------------------------------------------------- LoadBindingframework::LoadBinding98 inline LoadBinding() 99 { 100 free(); 101 } 102 103 //--------------------------------------------------------------------------------------------------------- 104 // use to initialize struct for asynchronous dispatching by using handler LoadBindingframework::LoadBinding105 inline LoadBinding( const css::util::URL& aNewURL , 106 const css::uno::Sequence< css::beans::PropertyValue > lNewDescriptor , 107 const css::uno::Reference< css::frame::XDispatch >& xNewHandler , 108 const css::uno::Any& aNewAsyncInfo ) 109 { 110 free(); 111 xHandler = xNewHandler ; 112 aURL = aNewURL ; 113 lDescriptor = lNewDescriptor; 114 aAsyncInfo = aNewAsyncInfo ; 115 } 116 117 //--------------------------------------------------------------------------------------------------------- 118 // use to initialize struct for asynchronous loading by using frame loader LoadBindingframework::LoadBinding119 inline LoadBinding( const css::util::URL& aNewURL , 120 const css::uno::Sequence< css::beans::PropertyValue > lNewDescriptor , 121 const css::uno::Reference< css::frame::XFrame >& xNewFrame , 122 const css::uno::Reference< css::frame::XFrameLoader >& xNewLoader , 123 const css::uno::Any& aNewAsyncInfo ) 124 { 125 free(); 126 xLoader = xNewLoader ; 127 xFrame = xNewFrame ; 128 aURL = aNewURL ; 129 lDescriptor = lNewDescriptor; 130 aAsyncInfo = aNewAsyncInfo ; 131 } 132 133 //--------------------------------------------------------------------------------------------------------- 134 // dont forget toe release used references ~LoadBindingframework::LoadBinding135 inline ~LoadBinding() 136 { 137 free(); 138 } 139 140 //--------------------------------------------------------------------------------------------------------- freeframework::LoadBinding141 inline void free() 142 { 143 xHandler = css::uno::Reference< css::frame::XDispatch >() ; 144 xLoader = css::uno::Reference< css::frame::XFrameLoader >(); 145 xFrame = css::uno::Reference< css::frame::XFrame >() ; 146 aURL = css::util::URL() ; 147 lDescriptor = css::uno::Sequence< css::beans::PropertyValue >(); 148 aAsyncInfo = css::uno::Any() ; 149 } 150 151 //------------------------------------------------------------------------------------------------------------- 152 public: 153 css::uno::Reference< css::frame::XDispatch > xHandler ; // if handler was used, this reference will be valid 154 css::uno::Reference< css::frame::XFrameLoader > xLoader ; // if loader was used, this reference will be valid 155 css::uno::Reference< css::frame::XFrame > xFrame ; // Target of loading 156 css::util::URL aURL ; // dispatched URL - neccessary to find listener for status event! 157 css::uno::Sequence< css::beans::PropertyValue > lDescriptor ; // dispatched arguments - neccessary for "reactForLoadingState()"! 158 css::uno::Any aAsyncInfo ; // superclasses could use them to save her own user specific data for these asynchron call-info 159 css::uno::Reference< css::frame::XDispatchResultListener > xListener; 160 }; 161 162 //***************************************************************************************************************** 163 class LoaderThreads : private ::std::vector< LoadBinding > 164 , private ThreadHelpBase 165 { 166 //------------------------------------------------------------------------------------------------------------- 167 public: 168 169 //--------------------------------------------------------------------------------------------------------- LoaderThreads()170 inline LoaderThreads() 171 : ThreadHelpBase() 172 { 173 } 174 175 //--------------------------------------------------------------------------------------------------------- append(const LoadBinding & aBinding)176 inline void append( const LoadBinding& aBinding ) 177 { 178 ResetableGuard aGuard( m_aLock ); 179 push_back( aBinding ); 180 } 181 182 //--------------------------------------------------------------------------------------------------------- 183 /// search for handler thread in list wich match given parameter and delete it searchAndForget(const css::uno::Reference<css::frame::XDispatchResultListener> & rListener,LoadBinding & aBinding)184 inline sal_Bool searchAndForget( const css::uno::Reference < css::frame::XDispatchResultListener >& rListener, LoadBinding& aBinding ) 185 { 186 ResetableGuard aGuard( m_aLock ); 187 sal_Bool bFound = sal_False; 188 for( iterator pItem=begin(); pItem!=end(); ++pItem ) 189 { 190 if( pItem->xListener == rListener ) 191 { 192 aBinding = *pItem; 193 erase( pItem ); 194 bFound = sal_True; 195 break; 196 } 197 } 198 return bFound; 199 } 200 201 //--------------------------------------------------------------------------------------------------------- 202 /// search for loader thread in list wich match given parameter and delete it searchAndForget(const css::uno::Reference<css::frame::XFrameLoader> xLoader,LoadBinding & aBinding)203 inline sal_Bool searchAndForget( const css::uno::Reference< css::frame::XFrameLoader > xLoader, LoadBinding& aBinding ) 204 { 205 ResetableGuard aGuard( m_aLock ); 206 sal_Bool bFound = sal_False; 207 for( iterator pItem=begin(); pItem!=end(); ++pItem ) 208 { 209 if( pItem->xLoader == xLoader ) 210 { 211 aBinding = *pItem; 212 erase( pItem ); 213 bFound = sal_True; 214 break; 215 } 216 } 217 return bFound; 218 } 219 220 //--------------------------------------------------------------------------------------------------------- 221 // free ALL memory ... I hope it free()222 inline void free() 223 { 224 ResetableGuard aGuard( m_aLock ); 225 LoaderThreads().swap( *this ); 226 } 227 }; 228 229 /*-************************************************************************************************************//** 230 @short base class for dispatcher implementations 231 @descr Most of our dispatch implementations do everytime the same. They try to handle or load 232 somethinmg into a target ... normaly a frame/task/pluginframe! 233 They must do it synchron or sometimes asynchron. They must wait for callbacks and 234 notify registered listener with right status events. 235 All these things are implemented by this baseclass. You should override some methods 236 to change something. 237 238 "dispatch()" => should be you dispatch algorithm 239 "reactForLoadingState()" => do something depending from loading state ... 240 241 @implements XInterface 242 XDispatch 243 XLoadEventListener 244 XEventListener 245 246 @base ThreadHelpBase 247 TransactionBase 248 OWeakObject 249 250 @devstatus ready to use 251 @threadsafe yes 252 *//*-*************************************************************************************************************/ 253 class BaseDispatcher : // interfaces 254 public css::lang::XTypeProvider , 255 public css::frame::XNotifyingDispatch , 256 public css::frame::XLoadEventListener , // => XEventListener too! 257 // baseclasses 258 // Order is neccessary for right initialization! 259 protected ThreadHelpBase , 260 protected TransactionBase , 261 public ::cppu::OWeakObject 262 { 263 //------------------------------------------------------------------------------------------------------------- 264 // public methods 265 //------------------------------------------------------------------------------------------------------------- 266 public: 267 268 // constructor / destructor 269 BaseDispatcher( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory , 270 const css::uno::Reference< css::frame::XFrame >& xOwnerFrame ); 271 272 void dispatchFinished ( const css::frame::DispatchResultEvent& aEvent, const css::uno::Reference < css::frame::XDispatchResultListener >& rListener ); 273 274 // XInterface 275 DECLARE_XINTERFACE 276 DECLARE_XTYPEPROVIDER 277 278 // XNotifyingDispatch 279 virtual void SAL_CALL dispatchWithNotification ( const css::util::URL& aURL, 280 const css::uno::Sequence< css::beans::PropertyValue >& aArgs, 281 const css::uno::Reference< css::frame::XDispatchResultListener >& Listener ) throw ( css::uno::RuntimeException); 282 283 // XDispatch 284 virtual void SAL_CALL dispatch ( const css::util::URL& aURL , 285 const css::uno::Sequence< css::beans::PropertyValue >& lArguments ) throw( css::uno::RuntimeException ) = 0; 286 virtual void SAL_CALL addStatusListener ( const css::uno::Reference< css::frame::XStatusListener >& xListener , 287 const css::util::URL& aURL ) throw( css::uno::RuntimeException ); 288 virtual void SAL_CALL removeStatusListener ( const css::uno::Reference< css::frame::XStatusListener >& xListener , 289 const css::util::URL& aURL ) throw( css::uno::RuntimeException ); 290 291 // XLoadEventListener 292 virtual void SAL_CALL loadFinished ( const css::uno::Reference< css::frame::XFrameLoader >& xLoader ) throw( css::uno::RuntimeException ); 293 virtual void SAL_CALL loadCancelled ( const css::uno::Reference< css::frame::XFrameLoader >& xLoader ) throw( css::uno::RuntimeException ); 294 295 // XEventListener 296 virtual void SAL_CALL disposing ( const css::lang::EventObject& aEvent ) throw( css::uno::RuntimeException ); 297 298 //------------------------------------------------------------------------------------------------------------- 299 // protected methods 300 //------------------------------------------------------------------------------------------------------------- 301 protected: 302 virtual ~BaseDispatcher(); 303 304 /*-****************************************************************************************************//** 305 @short you should react for successfully or failed load/handle operations. 306 @descr These baseclass implement handling of dispatched URLs and synchronous/asynchronous loading 307 of it into a target frame. It implement the complete listener mechanism to get events from 308 used loader or handler and sending of status events to registered listener too! 309 But we couldn't react for this events in all cases. 310 May be - you wish to reactivate suspended controllers or wish to delete a new created 311 task if operation failed ...!? 312 By overwriting these pure virtual methods it's possible to do such things. 313 We call you with all available informations ... you should react for it. 314 BUT - don't send any status events to your listener! We will do it everytime. 315 (other listener could be informed as well!) 316 317 You will called back in: a) "reactForLoadingState()" , if URL was loaded into a frame 318 b) "reactForHandlingState()", if URL was handled by a registered content handler 319 (without using a target frame!) 320 321 @seealso method statusChanged() 322 @seealso method loadFinished() 323 @seealso method loadCancelled() 324 325 @param "aURL" , original dispatched URL 326 @param "lDescriptor" , original dispatched arguments 327 @param "xTarget" , target of operation (could be NULL if URL was handled not loaded!) 328 @param "bState" , state of operation 329 @return - 330 331 @onerror - 332 @threadsafe - 333 *//*-*****************************************************************************************************/ 334 virtual void SAL_CALL reactForLoadingState ( const css::util::URL& aURL , 335 const css::uno::Sequence< css::beans::PropertyValue >& lDescriptor , 336 const css::uno::Reference< css::frame::XFrame >& xTarget , 337 sal_Bool bState , 338 const css::uno::Any& aAsyncInfo ) = 0; 339 340 virtual void SAL_CALL reactForHandlingState( const css::util::URL& aURL , 341 const css::uno::Sequence< css::beans::PropertyValue >& lDescriptor , 342 sal_Bool bState , 343 const css::uno::Any& aAsyncInfo ) = 0; 344 345 //------------------------------------------------------------------------------------------------------------- 346 // protected methods 347 //------------------------------------------------------------------------------------------------------------- 348 protected: 349 ::rtl::OUString implts_detectType ( const css::util::URL& aURL , 350 css::uno::Sequence< css::beans::PropertyValue >& lDescriptor , 351 sal_Bool bDeep ); 352 sal_Bool implts_handleIt ( const css::util::URL& aURL , 353 css::uno::Sequence< css::beans::PropertyValue >& lDescriptor , 354 const ::rtl::OUString& sTypeName , 355 const css::uno::Any& aAsyncInfo = css::uno::Any() ); 356 sal_Bool implts_loadIt ( const css::util::URL& aURL , 357 css::uno::Sequence< css::beans::PropertyValue >& lDescriptor , 358 const ::rtl::OUString& sTypeName , 359 const css::uno::Reference< css::frame::XFrame >& xTarget , 360 const css::uno::Any& aAsyncInfo = css::uno::Any() ); 361 void implts_enableFrame ( const css::uno::Reference< css::frame::XFrame >& xFrame , 362 const css::uno::Sequence< css::beans::PropertyValue >& lDescriptor ); 363 void implts_disableFrame ( const css::uno::Reference< css::frame::XFrame >& xFrame ); 364 sal_Bool implts_deactivateController ( const css::uno::Reference< css::frame::XController >& xController ); 365 sal_Bool implts_reactivateController ( const css::uno::Reference< css::frame::XController >& xController ); 366 void implts_sendResultEvent ( const css::uno::Reference< css::frame::XFrame >& xEventSource , 367 const ::rtl::OUString& sURL , 368 sal_Bool bLoadState ); 369 370 //------------------------------------------------------------------------------------------------------------- 371 // variables 372 // - should be private normaly ... 373 // - but some super classes need access to some of them => protected! 374 //------------------------------------------------------------------------------------------------------------- 375 protected: 376 css::uno::Reference< css::lang::XMultiServiceFactory > m_xFactory ; /// global uno service manager to create new services 377 css::uno::WeakReference< css::frame::XFrame > m_xOwner ; /// weakreference to owner (Don't use a hard reference. Owner can't delete us then!) 378 379 private: 380 LoaderThreads m_aLoaderThreads ; /// list of bindings between handler/loader, tasks and loaded URLs 381 ListenerHash m_aListenerContainer ; /// hash table for listener at specified URLs 382 383 }; // class BaseDispatcher 384 385 } // namespace framework 386 387 #endif // #ifndef __FRAMEWORK_DISPATCH_BASEDISPATCHER_HXX_ 388