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 { 115 css::uno::Reference< css::uno::XInterface > xTHIS(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY); 116 117 // check for valid parameters 118 if ( 119 (!xDispatchProvider.is()) || 120 (sURL.getLength()<1 ) 121 ) 122 { 123 return css::uno::Any(); 124 } 125 126 // parse given URL 127 /* SAFE { */ 128 ReadGuard aReadLock(m_aLock); 129 css::uno::Reference< css::util::XURLTransformer > xParser(m_xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY); 130 aReadLock.unlock(); 131 /* } SAFE */ 132 133 css::util::URL aURL; 134 aURL.Complete = sURL; 135 xParser->parseStrict(aURL); 136 137 // search dispatcher 138 css::uno::Reference< css::frame::XDispatch > xDispatch = xDispatchProvider->queryDispatch(aURL, sTargetFrameName, nSearchFlags); 139 css::uno::Reference< css::frame::XNotifyingDispatch > xNotifyDispatch (xDispatch, css::uno::UNO_QUERY); 140 141 // make sure that synchronous execution is used (if possible) 142 css::uno::Sequence< css::beans::PropertyValue > aArguments( lArguments ); 143 sal_Int32 nLength = lArguments.getLength(); 144 aArguments.realloc( nLength + 1 ); 145 aArguments[ nLength ].Name = ::rtl::OUString::createFromAscii("SynchronMode"); 146 aArguments[ nLength ].Value <<= (sal_Bool) sal_True; 147 148 css::uno::Any aResult; 149 if (xNotifyDispatch.is()) 150 { 151 // dispatch it with guaranteed notification 152 // Here we can hope for a result ... instead of the normal dispatch. 153 css::uno::Reference< css::frame::XDispatchResultListener > xListener(xTHIS, css::uno::UNO_QUERY); 154 /* SAFE { */ 155 WriteGuard aWriteLock(m_aLock); 156 m_xBroadcaster = css::uno::Reference< css::uno::XInterface >(xNotifyDispatch, css::uno::UNO_QUERY); 157 m_aResult = css::uno::Any(); 158 m_aBlock.reset(); 159 aWriteLock.unlock(); 160 /* } SAFE */ 161 162 // dispatch it and wait for a notification 163 // TODO/MBA: waiting in main thread?! 164 xNotifyDispatch->dispatchWithNotification(aURL, aArguments, xListener); 165 //m_aBlock.wait(); 166 aResult = m_aResult; 167 } 168 else 169 if (xDispatch.is()) 170 { 171 // dispatch it without any chance to get a result 172 xDispatch->dispatch( aURL, aArguments ); 173 } 174 175 return aResult; 176 } 177 178 //_______________________________________________ 179 180 /** callback for started dispatch with guaranteed notifications. 181 182 We must save the result, so the method executeDispatch() can return it. 183 Further we must release the broadcaster (otherwise it can't die) 184 and unblock the waiting executeDispatch() request. 185 186 @param aResult 187 describes the result of the dispatch operation 188 */ 189 void SAL_CALL DispatchHelper::dispatchFinished( const css::frame::DispatchResultEvent& aResult ) 190 { 191 /* SAFE { */ 192 WriteGuard aWriteLock(m_aLock); 193 194 m_aResult <<= aResult; 195 m_aBlock.set(); 196 m_xBroadcaster.clear(); 197 198 /* } SAFE */ 199 } 200 201 //_______________________________________________ 202 203 /** we have to release our broadcaster reference. 204 205 @param aEvent 206 describe the source of this event and MUST be our save broadcaster! 207 */ 208 void SAL_CALL DispatchHelper::disposing( const css::lang::EventObject& ) 209 { 210 /* SAFE { */ 211 WriteGuard aWriteLock(m_aLock); 212 213 m_aResult.clear(); 214 m_aBlock.set(); 215 m_xBroadcaster.clear(); 216 217 /* } SAFE */ 218 } 219 220 } 221