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/XSystemShellExecute.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(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 ths class with needed informations for work. 107 108 @param xFactory 109 reference to uno servicemanager for creation of new services 110 111 @modified 30.04.2002 14:10, as96863 112 */ 113 MailToDispatcher::MailToDispatcher( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory ) 114 // Init baseclasses first 115 : ThreadHelpBase( &Application::GetSolarMutex() ) 116 , OWeakObject ( ) 117 // Init member 118 , m_xFactory ( xFactory ) 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_xFactory = 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 wich 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 realy - 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 immediatly. 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 immediatly 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 belive that call was successfully. 260 <FALSE/> if neccessary 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::lang::XMultiServiceFactory > xFactory; 270 /* SAFE */{ 271 ReadGuard aReadLock( m_aLock ); 272 xFactory = m_xFactory; 273 /* SAFE */} 274 275 css::uno::Reference< css::system::XSystemShellExecute > xSystemShellExecute( xFactory->createInstance(SERVICENAME_SYSTEMSHELLEXECUTE), css::uno::UNO_QUERY ); 276 if (xSystemShellExecute.is()) 277 { 278 try 279 { 280 // start mail client 281 // Because there is no notofocation about success - we use case of 282 // no detected exception as SUCCESS - FAILED otherwhise. 283 xSystemShellExecute->execute( aURL.Complete, ::rtl::OUString(), css::system::SystemShellExecuteFlags::DEFAULTS ); 284 bSuccess = sal_True; 285 } 286 catch (css::lang::IllegalArgumentException&) 287 { 288 } 289 catch (css::system::SystemShellExecuteException&) 290 { 291 } 292 } 293 294 return bSuccess; 295 } 296 297 //_________________________________________________________________________________________________________________ 298 299 /** 300 @short add/remove listener for state events 301 @descr Because we use an external process to forward such mail URLs, and this process doesn't 302 return any notifications about success or failed state - we doesn't support such status 303 listener. We have no status to send. 304 305 @param xListener 306 reference to a valid listener for state events 307 @param aURL 308 URL about listener will be informed, if something occured 309 310 @modified 30.04.2002 14:49, as96863 311 */ 312 void SAL_CALL MailToDispatcher::addStatusListener( const css::uno::Reference< css::frame::XStatusListener >& /*xListener*/ , 313 const css::util::URL& /*aURL*/ ) throw( css::uno::RuntimeException ) 314 { 315 // not suported yet 316 } 317 318 //_________________________________________________________________________________________________________________ 319 320 void SAL_CALL MailToDispatcher::removeStatusListener( const css::uno::Reference< css::frame::XStatusListener >& /*xListener*/ , 321 const css::util::URL& /*aURL*/ ) throw( css::uno::RuntimeException ) 322 { 323 // not suported yet 324 } 325 326 } // namespace framework 327