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