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 //_________________________________________________________________________________________________________________ 34 #include <dispatch/mailtodispatcher.hxx> 35 #include <threadhelp/readguard.hxx> 36 #include <general.h> 37 #include <services.h> 38 39 //_________________________________________________________________________________________________________________ 40 // interface includes 41 //_________________________________________________________________________________________________________________ 42 #include <com/sun/star/system/XSystemShellExecute.hpp> 43 #include <com/sun/star/system/SystemShellExecuteFlags.hpp> 44 #include <com/sun/star/frame/DispatchResultState.hpp> 45 46 //_________________________________________________________________________________________________________________ 47 // includes of other projects 48 //_________________________________________________________________________________________________________________ 49 50 #include <vcl/svapp.hxx> 51 52 //_________________________________________________________________________________________________________________ 53 // namespace 54 //_________________________________________________________________________________________________________________ 55 56 namespace framework{ 57 58 //_________________________________________________________________________________________________________________ 59 // non exported const 60 //_________________________________________________________________________________________________________________ 61 62 #define PROTOCOL_VALUE "mailto:" 63 #define PROTOCOL_LENGTH 7 64 65 //_________________________________________________________________________________________________________________ 66 // non exported definitions 67 //_________________________________________________________________________________________________________________ 68 69 //_________________________________________________________________________________________________________________ 70 // declarations 71 //_________________________________________________________________________________________________________________ 72 73 //_________________________________________________________________________________________________________________ 74 // XInterface, XTypeProvider, XServiceInfo 75 76 DEFINE_XINTERFACE_5(MailToDispatcher , 77 OWeakObject , 78 DIRECT_INTERFACE(css::lang::XTypeProvider ), 79 DIRECT_INTERFACE(css::lang::XServiceInfo ), 80 DIRECT_INTERFACE(css::frame::XDispatchProvider ), 81 DIRECT_INTERFACE(css::frame::XNotifyingDispatch), 82 DIRECT_INTERFACE(css::frame::XDispatch )) 83 84 DEFINE_XTYPEPROVIDER_5(MailToDispatcher , 85 css::lang::XTypeProvider , 86 css::lang::XServiceInfo , 87 css::frame::XDispatchProvider , 88 css::frame::XNotifyingDispatch, 89 css::frame::XDispatch ) 90 91 DEFINE_XSERVICEINFO_MULTISERVICE(MailToDispatcher , 92 ::cppu::OWeakObject , 93 SERVICENAME_PROTOCOLHANDLER , 94 IMPLEMENTATIONNAME_MAILTODISPATCHER) 95 96 DEFINE_INIT_SERVICE(MailToDispatcher, 97 { 98 /*Attention 99 I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance() 100 to create a new instance of this class by our own supported service factory. 101 see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations! 102 */ 103 } 104 ) 105 106 //_________________________________________________________________________________________________________________ 107 108 /** 109 @short standard ctor 110 @descr These initialize a new instance of ths class with needed informations for work. 111 112 @param xFactory 113 reference to uno servicemanager for creation of new services 114 115 @modified 30.04.2002 14:10, as96863 116 */ 117 MailToDispatcher::MailToDispatcher( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory ) 118 // Init baseclasses first 119 : ThreadHelpBase( &Application::GetSolarMutex() ) 120 , OWeakObject ( ) 121 // Init member 122 , m_xFactory ( xFactory ) 123 { 124 } 125 126 //_________________________________________________________________________________________________________________ 127 128 /** 129 @short standard dtor 130 @descr - 131 132 @modified 30.04.2002 14:10, as96863 133 */ 134 MailToDispatcher::~MailToDispatcher() 135 { 136 m_xFactory = NULL; 137 } 138 139 //_________________________________________________________________________________________________________________ 140 141 /** 142 @short decide if this dispatch implementation can be used for requested URL or not 143 @descr A protocol handler is registerd for an URL pattern inside configuration and will 144 be asked by the generic dispatch mechanism inside framework, if he can handle this 145 special URL wich match his registration. He can agree by returning of a valid dispatch 146 instance or disagree by returning <NULL/>. 147 We don't create new dispatch instances here realy - we return THIS as result to handle it 148 at the same implementation. 149 150 @modified 02.05.2002 15:25, as96863 151 */ 152 css::uno::Reference< css::frame::XDispatch > SAL_CALL MailToDispatcher::queryDispatch( const css::util::URL& aURL , 153 const ::rtl::OUString& /*sTarget*/ , 154 sal_Int32 /*nFlags*/ ) throw( css::uno::RuntimeException ) 155 { 156 css::uno::Reference< css::frame::XDispatch > xDispatcher; 157 if (aURL.Complete.compareToAscii(PROTOCOL_VALUE,PROTOCOL_LENGTH)==0) 158 xDispatcher = this; 159 return xDispatcher; 160 } 161 162 //_________________________________________________________________________________________________________________ 163 164 /** 165 @short do the same like dispatch() but for multiple requests at the same time 166 @descr - 167 168 @modified 02.05.2002 15:27, as96863 169 */ 170 css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL MailToDispatcher::queryDispatches( const css::uno::Sequence< css::frame::DispatchDescriptor >& lDescriptor ) throw( css::uno::RuntimeException ) 171 { 172 sal_Int32 nCount = lDescriptor.getLength(); 173 css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > lDispatcher( nCount ); 174 for( sal_Int32 i=0; i<nCount; ++i ) 175 { 176 lDispatcher[i] = this->queryDispatch( 177 lDescriptor[i].FeatureURL, 178 lDescriptor[i].FrameName, 179 lDescriptor[i].SearchFlags); 180 } 181 return lDispatcher; 182 } 183 184 //_________________________________________________________________________________________________________________ 185 186 /** 187 @short dispatch URL with arguments 188 @descr We use threadsafe internal method to do so. It returns a state value - but we ignore it. 189 Because we doesn't support status listener notifications here. Status events are not guaranteed - 190 and we call another service internaly which doesn't return any notifications too. 191 192 @param aURL 193 mail URL which should be executed 194 @param lArguments 195 list of optional arguments for this mail request 196 197 @modified 30.04.2002 14:15, as96863 198 */ 199 void SAL_CALL MailToDispatcher::dispatch( const css::util::URL& aURL , 200 const css::uno::Sequence< css::beans::PropertyValue >& lArguments ) throw( css::uno::RuntimeException ) 201 { 202 // dispatch() is an [oneway] call ... and may our user release his reference to us immediatly. 203 // So we should hold us self alive till this call ends. 204 css::uno::Reference< css::frame::XNotifyingDispatch > xSelfHold(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY); 205 implts_dispatch(aURL,lArguments); 206 // No notification for status listener! 207 } 208 209 //_________________________________________________________________________________________________________________ 210 211 /** 212 @short dispatch with guaranteed notifications about success 213 @descr We use threadsafe internal method to do so. Return state of this function will be used 214 for notification if an optional listener is given. 215 216 @param aURL 217 mail URL which should be executed 218 @param lArguments 219 list of optional arguments for this mail request 220 @param xListener 221 reference to a valid listener for state events 222 223 @modified 30.04.2002 14:49, as96863 224 */ 225 void SAL_CALL MailToDispatcher::dispatchWithNotification( const css::util::URL& aURL , 226 const css::uno::Sequence< css::beans::PropertyValue >& lArguments, 227 const css::uno::Reference< css::frame::XDispatchResultListener >& xListener ) throw( css::uno::RuntimeException ) 228 { 229 // This class was designed to die by reference. And if user release his reference to us immediatly after calling this method 230 // we can run into some problems. So we hold us self alive till this method ends. 231 // Another reason: We can use this reference as source of sending event at the end too. 232 css::uno::Reference< css::frame::XNotifyingDispatch > xThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY); 233 234 sal_Bool bState = implts_dispatch(aURL,lArguments); 235 if (xListener.is()) 236 { 237 css::frame::DispatchResultEvent aEvent; 238 if (bState) 239 aEvent.State = css::frame::DispatchResultState::SUCCESS; 240 else 241 aEvent.State = css::frame::DispatchResultState::FAILURE; 242 aEvent.Source = xThis; 243 244 xListener->dispatchFinished( aEvent ); 245 } 246 } 247 248 //_________________________________________________________________________________________________________________ 249 250 /** 251 @short threadsafe helper for dispatch calls 252 @descr We support two interfaces for the same process - dispatch URLs. That the reason for this internal 253 function. It implements the real dispatch operation and returns a state value which inform caller 254 about success. He can notify listener then by using this return value. 255 256 @param aURL 257 mail URL which should be executed 258 @param lArguments 259 list of optional arguments for this mail request 260 261 @return <TRUE/> if dispatch could be started successfully 262 Note: Our internal used shell executor doesn't return any state value - so we must 263 belive that call was successfully. 264 <FALSE/> if neccessary ressource couldn't be created or an exception was thrown. 265 266 @modified 30.04.2002 14:49, as96863 267 */ 268 sal_Bool MailToDispatcher::implts_dispatch( const css::util::URL& aURL , 269 const css::uno::Sequence< css::beans::PropertyValue >& /*lArguments*/ ) throw( css::uno::RuntimeException ) 270 { 271 sal_Bool bSuccess = sal_False; 272 273 css::uno::Reference< css::lang::XMultiServiceFactory > xFactory; 274 /* SAFE */{ 275 ReadGuard aReadLock( m_aLock ); 276 xFactory = m_xFactory; 277 /* SAFE */} 278 279 css::uno::Reference< css::system::XSystemShellExecute > xSystemShellExecute( xFactory->createInstance(SERVICENAME_SYSTEMSHELLEXECUTE), css::uno::UNO_QUERY ); 280 if (xSystemShellExecute.is()) 281 { 282 try 283 { 284 // start mail client 285 // Because there is no notofocation about success - we use case of 286 // no detected exception as SUCCESS - FAILED otherwhise. 287 xSystemShellExecute->execute( aURL.Complete, ::rtl::OUString(), css::system::SystemShellExecuteFlags::DEFAULTS ); 288 bSuccess = sal_True; 289 } 290 catch (css::lang::IllegalArgumentException&) 291 { 292 } 293 catch (css::system::SystemShellExecuteException&) 294 { 295 } 296 } 297 298 return bSuccess; 299 } 300 301 //_________________________________________________________________________________________________________________ 302 303 /** 304 @short add/remove listener for state events 305 @descr Because we use an external process to forward such mail URLs, and this process doesn't 306 return any notifications about success or failed state - we doesn't support such status 307 listener. We have no status to send. 308 309 @param xListener 310 reference to a valid listener for state events 311 @param aURL 312 URL about listener will be informed, if something occured 313 314 @modified 30.04.2002 14:49, as96863 315 */ 316 void SAL_CALL MailToDispatcher::addStatusListener( const css::uno::Reference< css::frame::XStatusListener >& /*xListener*/ , 317 const css::util::URL& /*aURL*/ ) throw( css::uno::RuntimeException ) 318 { 319 // not suported yet 320 } 321 322 //_________________________________________________________________________________________________________________ 323 324 void SAL_CALL MailToDispatcher::removeStatusListener( const css::uno::Reference< css::frame::XStatusListener >& /*xListener*/ , 325 const css::util::URL& /*aURL*/ ) throw( css::uno::RuntimeException ) 326 { 327 // not suported yet 328 } 329 330 } // namespace framework 331