1*6d739b60SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*6d739b60SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*6d739b60SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*6d739b60SAndrew Rist * distributed with this work for additional information 6*6d739b60SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*6d739b60SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*6d739b60SAndrew Rist * "License"); you may not use this file except in compliance 9*6d739b60SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*6d739b60SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*6d739b60SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*6d739b60SAndrew Rist * software distributed under the License is distributed on an 15*6d739b60SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*6d739b60SAndrew Rist * KIND, either express or implied. See the License for the 17*6d739b60SAndrew Rist * specific language governing permissions and limitations 18*6d739b60SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*6d739b60SAndrew Rist *************************************************************/ 21*6d739b60SAndrew Rist 22*6d739b60SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_framework.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir //_______________________________________________ 28cdf0e10cSrcweir // my own includes 29cdf0e10cSrcweir #include <services/dispatchhelper.hxx> 30cdf0e10cSrcweir #include <threadhelp/readguard.hxx> 31cdf0e10cSrcweir #include <threadhelp/writeguard.hxx> 32cdf0e10cSrcweir #include <services.h> 33cdf0e10cSrcweir 34cdf0e10cSrcweir //_______________________________________________ 35cdf0e10cSrcweir // interface includes 36cdf0e10cSrcweir #include <com/sun/star/util/XURLTransformer.hpp> 37cdf0e10cSrcweir #include <com/sun/star/frame/XNotifyingDispatch.hpp> 38cdf0e10cSrcweir 39cdf0e10cSrcweir //_______________________________________________ 40cdf0e10cSrcweir // includes of other projects 41cdf0e10cSrcweir 42cdf0e10cSrcweir //_______________________________________________ 43cdf0e10cSrcweir // namespace 44cdf0e10cSrcweir 45cdf0e10cSrcweir namespace framework{ 46cdf0e10cSrcweir 47cdf0e10cSrcweir //_______________________________________________ 48cdf0e10cSrcweir // non exported const 49cdf0e10cSrcweir 50cdf0e10cSrcweir //_______________________________________________ 51cdf0e10cSrcweir // non exported definitions 52cdf0e10cSrcweir 53cdf0e10cSrcweir //_______________________________________________ 54cdf0e10cSrcweir // declarations 55cdf0e10cSrcweir 56cdf0e10cSrcweir //_______________________________________________ 57cdf0e10cSrcweir // XInterface, XTypeProvider, XServiceInfo 58cdf0e10cSrcweir 59cdf0e10cSrcweir DEFINE_XSERVICEINFO_MULTISERVICE(DispatchHelper , 60cdf0e10cSrcweir ::cppu::OWeakObject , 61cdf0e10cSrcweir SERVICENAME_DISPATCHHELPER , 62cdf0e10cSrcweir IMPLEMENTATIONNAME_DISPATCHHELPER) 63cdf0e10cSrcweir 64cdf0e10cSrcweir DEFINE_INIT_SERVICE( DispatchHelper, {} ) 65cdf0e10cSrcweir 66cdf0e10cSrcweir //_______________________________________________ 67cdf0e10cSrcweir 68cdf0e10cSrcweir /** ctor. 69cdf0e10cSrcweir 70cdf0e10cSrcweir @param xSMGR the global uno service manager, which can be used to create own needed services. 71cdf0e10cSrcweir */ 72cdf0e10cSrcweir DispatchHelper::DispatchHelper( const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ) 73cdf0e10cSrcweir : ThreadHelpBase( ) 74cdf0e10cSrcweir // Init member 75cdf0e10cSrcweir , m_xSMGR (xSMGR) 76cdf0e10cSrcweir { 77cdf0e10cSrcweir } 78cdf0e10cSrcweir 79cdf0e10cSrcweir //_______________________________________________ 80cdf0e10cSrcweir 81cdf0e10cSrcweir /** dtor. 82cdf0e10cSrcweir */ 83cdf0e10cSrcweir DispatchHelper::~DispatchHelper() 84cdf0e10cSrcweir { 85cdf0e10cSrcweir } 86cdf0e10cSrcweir 87cdf0e10cSrcweir //_______________________________________________ 88cdf0e10cSrcweir 89cdf0e10cSrcweir /** capsulate all steps of a dispatch request and provide so an easy way for dispatches. 90cdf0e10cSrcweir 91cdf0e10cSrcweir @param xDispatchProvider 92cdf0e10cSrcweir identifies the object, which provides may be valid dispatch objects for this execute. 93cdf0e10cSrcweir 94cdf0e10cSrcweir @param sURL 95cdf0e10cSrcweir describes the requested feature. 96cdf0e10cSrcweir 97cdf0e10cSrcweir @param sTargetFrameName 98cdf0e10cSrcweir points to the frame, which must be used (or may be created) for this dispatch. 99cdf0e10cSrcweir 100cdf0e10cSrcweir @param nSearchFlags 101cdf0e10cSrcweir in case the <var>sTargetFrameName</var> isn't unique, these flags regulate further searches. 102cdf0e10cSrcweir 103cdf0e10cSrcweir @param lArguments 104cdf0e10cSrcweir optional arguments for this request. 105cdf0e10cSrcweir 106cdf0e10cSrcweir @return An Any which capsulate a possible result of the internal wrapped dispatch. 107cdf0e10cSrcweir */ 108cdf0e10cSrcweir css::uno::Any SAL_CALL DispatchHelper::executeDispatch( 109cdf0e10cSrcweir const css::uno::Reference< css::frame::XDispatchProvider >& xDispatchProvider , 110cdf0e10cSrcweir const ::rtl::OUString& sURL , 111cdf0e10cSrcweir const ::rtl::OUString& sTargetFrameName , 112cdf0e10cSrcweir sal_Int32 nSearchFlags , 113cdf0e10cSrcweir const css::uno::Sequence< css::beans::PropertyValue >& lArguments ) 114cdf0e10cSrcweir throw(css::uno::RuntimeException) 115cdf0e10cSrcweir { 116cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface > xTHIS(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY); 117cdf0e10cSrcweir 118cdf0e10cSrcweir // check for valid parameters 119cdf0e10cSrcweir if ( 120cdf0e10cSrcweir (!xDispatchProvider.is()) || 121cdf0e10cSrcweir (sURL.getLength()<1 ) 122cdf0e10cSrcweir ) 123cdf0e10cSrcweir { 124cdf0e10cSrcweir return css::uno::Any(); 125cdf0e10cSrcweir } 126cdf0e10cSrcweir 127cdf0e10cSrcweir // parse given URL 128cdf0e10cSrcweir /* SAFE { */ 129cdf0e10cSrcweir ReadGuard aReadLock(m_aLock); 130cdf0e10cSrcweir css::uno::Reference< css::util::XURLTransformer > xParser(m_xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY); 131cdf0e10cSrcweir aReadLock.unlock(); 132cdf0e10cSrcweir /* } SAFE */ 133cdf0e10cSrcweir 134cdf0e10cSrcweir css::util::URL aURL; 135cdf0e10cSrcweir aURL.Complete = sURL; 136cdf0e10cSrcweir xParser->parseStrict(aURL); 137cdf0e10cSrcweir 138cdf0e10cSrcweir // search dispatcher 139cdf0e10cSrcweir css::uno::Reference< css::frame::XDispatch > xDispatch = xDispatchProvider->queryDispatch(aURL, sTargetFrameName, nSearchFlags); 140cdf0e10cSrcweir css::uno::Reference< css::frame::XNotifyingDispatch > xNotifyDispatch (xDispatch, css::uno::UNO_QUERY); 141cdf0e10cSrcweir 142cdf0e10cSrcweir // make sure that synchronous execution is used (if possible) 143cdf0e10cSrcweir css::uno::Sequence< css::beans::PropertyValue > aArguments( lArguments ); 144cdf0e10cSrcweir sal_Int32 nLength = lArguments.getLength(); 145cdf0e10cSrcweir aArguments.realloc( nLength + 1 ); 146cdf0e10cSrcweir aArguments[ nLength ].Name = ::rtl::OUString::createFromAscii("SynchronMode"); 147cdf0e10cSrcweir aArguments[ nLength ].Value <<= (sal_Bool) sal_True; 148cdf0e10cSrcweir 149cdf0e10cSrcweir css::uno::Any aResult; 150cdf0e10cSrcweir if (xNotifyDispatch.is()) 151cdf0e10cSrcweir { 152cdf0e10cSrcweir // dispatch it with guaranteed notification 153cdf0e10cSrcweir // Here we can hope for a result ... instead of the normal dispatch. 154cdf0e10cSrcweir css::uno::Reference< css::frame::XDispatchResultListener > xListener(xTHIS, css::uno::UNO_QUERY); 155cdf0e10cSrcweir /* SAFE { */ 156cdf0e10cSrcweir WriteGuard aWriteLock(m_aLock); 157cdf0e10cSrcweir m_xBroadcaster = css::uno::Reference< css::uno::XInterface >(xNotifyDispatch, css::uno::UNO_QUERY); 158cdf0e10cSrcweir m_aResult = css::uno::Any(); 159cdf0e10cSrcweir m_aBlock.reset(); 160cdf0e10cSrcweir aWriteLock.unlock(); 161cdf0e10cSrcweir /* } SAFE */ 162cdf0e10cSrcweir 163cdf0e10cSrcweir // dispatch it and wait for a notification 164cdf0e10cSrcweir // TODO/MBA: waiting in main thread?! 165cdf0e10cSrcweir xNotifyDispatch->dispatchWithNotification(aURL, aArguments, xListener); 166cdf0e10cSrcweir //m_aBlock.wait(); 167cdf0e10cSrcweir aResult = m_aResult; 168cdf0e10cSrcweir } 169cdf0e10cSrcweir else 170cdf0e10cSrcweir if (xDispatch.is()) 171cdf0e10cSrcweir { 172cdf0e10cSrcweir // dispatch it without any chance to get a result 173cdf0e10cSrcweir xDispatch->dispatch( aURL, aArguments ); 174cdf0e10cSrcweir } 175cdf0e10cSrcweir 176cdf0e10cSrcweir return aResult; 177cdf0e10cSrcweir } 178cdf0e10cSrcweir 179cdf0e10cSrcweir //_______________________________________________ 180cdf0e10cSrcweir 181cdf0e10cSrcweir /** callback for started dispatch with guaranteed notifications. 182cdf0e10cSrcweir 183cdf0e10cSrcweir We must save the result, so the method executeDispatch() can return it. 184cdf0e10cSrcweir Further we must release the broadcaster (otherwhise it can't die) 185cdf0e10cSrcweir and unblock the waiting executeDispatch() request. 186cdf0e10cSrcweir 187cdf0e10cSrcweir @param aResult 188cdf0e10cSrcweir describes the result of the dispatch operation 189cdf0e10cSrcweir */ 190cdf0e10cSrcweir void SAL_CALL DispatchHelper::dispatchFinished( const css::frame::DispatchResultEvent& aResult ) 191cdf0e10cSrcweir throw(css::uno::RuntimeException) 192cdf0e10cSrcweir { 193cdf0e10cSrcweir /* SAFE { */ 194cdf0e10cSrcweir WriteGuard aWriteLock(m_aLock); 195cdf0e10cSrcweir 196cdf0e10cSrcweir m_aResult <<= aResult; 197cdf0e10cSrcweir m_aBlock.set(); 198cdf0e10cSrcweir m_xBroadcaster.clear(); 199cdf0e10cSrcweir 200cdf0e10cSrcweir /* } SAFE */ 201cdf0e10cSrcweir } 202cdf0e10cSrcweir 203cdf0e10cSrcweir //_______________________________________________ 204cdf0e10cSrcweir 205cdf0e10cSrcweir /** we has to realease our broadcaster reference. 206cdf0e10cSrcweir 207cdf0e10cSrcweir @param aEvent 208cdf0e10cSrcweir describe the source of this event and MUST be our save broadcaster! 209cdf0e10cSrcweir */ 210cdf0e10cSrcweir void SAL_CALL DispatchHelper::disposing( const css::lang::EventObject& ) 211cdf0e10cSrcweir throw(css::uno::RuntimeException) 212cdf0e10cSrcweir { 213cdf0e10cSrcweir /* SAFE { */ 214cdf0e10cSrcweir WriteGuard aWriteLock(m_aLock); 215cdf0e10cSrcweir 216cdf0e10cSrcweir m_aResult.clear(); 217cdf0e10cSrcweir m_aBlock.set(); 218cdf0e10cSrcweir m_xBroadcaster.clear(); 219cdf0e10cSrcweir 220cdf0e10cSrcweir /* } SAFE */ 221cdf0e10cSrcweir } 222cdf0e10cSrcweir 223cdf0e10cSrcweir } 224