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