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