Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <dispatch/mailtodispatcher.hxx>
21 : #include <threadhelp/readguard.hxx>
22 : #include <general.h>
23 : #include <services.h>
24 :
25 : #include <com/sun/star/system/SystemShellExecute.hpp>
26 : #include <com/sun/star/system/SystemShellExecuteFlags.hpp>
27 : #include <com/sun/star/frame/DispatchResultState.hpp>
28 :
29 : #include <vcl/svapp.hxx>
30 :
31 : namespace framework{
32 :
33 : #define PROTOCOL_VALUE "mailto:"
34 : #define PROTOCOL_LENGTH 7
35 :
36 : //_________________________________________________________________________________________________________________
37 : // XInterface, XTypeProvider, XServiceInfo
38 :
39 0 : DEFINE_XINTERFACE_5(MailToDispatcher ,
40 : OWeakObject ,
41 : DIRECT_INTERFACE(css::lang::XTypeProvider ),
42 : DIRECT_INTERFACE(css::lang::XServiceInfo ),
43 : DIRECT_INTERFACE(css::frame::XDispatchProvider ),
44 : DIRECT_INTERFACE(css::frame::XNotifyingDispatch),
45 : DIRECT_INTERFACE(css::frame::XDispatch ))
46 :
47 0 : DEFINE_XTYPEPROVIDER_5(MailToDispatcher ,
48 : css::lang::XTypeProvider ,
49 : css::lang::XServiceInfo ,
50 : css::frame::XDispatchProvider ,
51 : css::frame::XNotifyingDispatch,
52 : css::frame::XDispatch )
53 :
54 0 : DEFINE_XSERVICEINFO_MULTISERVICE_2(MailToDispatcher ,
55 : ::cppu::OWeakObject ,
56 : SERVICENAME_PROTOCOLHANDLER ,
57 : IMPLEMENTATIONNAME_MAILTODISPATCHER)
58 :
59 0 : DEFINE_INIT_SERVICE(MailToDispatcher,
60 : {
61 : /*Attention
62 : I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
63 : to create a new instance of this class by our own supported service factory.
64 : see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
65 : */
66 : }
67 : )
68 :
69 : //_________________________________________________________________________________________________________________
70 :
71 : /**
72 : @short standard ctor
73 : @descr These initialize a new instance of ths class with needed informations for work.
74 :
75 : @param rxContext
76 : reference to uno servicemanager for creation of new services
77 : */
78 0 : MailToDispatcher::MailToDispatcher( const css::uno::Reference< css::uno::XComponentContext >& rxContext )
79 : // Init baseclasses first
80 0 : : ThreadHelpBase( &Application::GetSolarMutex() )
81 : , OWeakObject ( )
82 : // Init member
83 0 : , m_xContext ( rxContext )
84 : {
85 0 : }
86 :
87 : //_________________________________________________________________________________________________________________
88 :
89 : /**
90 : @short standard dtor
91 : @descr -
92 : */
93 0 : MailToDispatcher::~MailToDispatcher()
94 : {
95 0 : m_xContext = NULL;
96 0 : }
97 :
98 : //_________________________________________________________________________________________________________________
99 :
100 : /**
101 : @short decide if this dispatch implementation can be used for requested URL or not
102 : @descr A protocol handler is registerd for an URL pattern inside configuration and will
103 : be asked by the generic dispatch mechanism inside framework, if he can handle this
104 : special URL wich match his registration. He can agree by returning of a valid dispatch
105 : instance or disagree by returning <NULL/>.
106 : We don't create new dispatch instances here realy - we return THIS as result to handle it
107 : at the same implementation.
108 : */
109 0 : css::uno::Reference< css::frame::XDispatch > SAL_CALL MailToDispatcher::queryDispatch( const css::util::URL& aURL ,
110 : const ::rtl::OUString& /*sTarget*/ ,
111 : sal_Int32 /*nFlags*/ ) throw( css::uno::RuntimeException )
112 : {
113 0 : css::uno::Reference< css::frame::XDispatch > xDispatcher;
114 0 : if (aURL.Complete.compareToAscii(PROTOCOL_VALUE,PROTOCOL_LENGTH)==0)
115 0 : xDispatcher = this;
116 0 : return xDispatcher;
117 : }
118 :
119 : //_________________________________________________________________________________________________________________
120 :
121 : /**
122 : @short do the same like dispatch() but for multiple requests at the same time
123 : @descr -
124 : */
125 0 : 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 )
126 : {
127 0 : sal_Int32 nCount = lDescriptor.getLength();
128 0 : css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > lDispatcher( nCount );
129 0 : for( sal_Int32 i=0; i<nCount; ++i )
130 : {
131 0 : lDispatcher[i] = this->queryDispatch(
132 0 : lDescriptor[i].FeatureURL,
133 0 : lDescriptor[i].FrameName,
134 0 : lDescriptor[i].SearchFlags);
135 : }
136 0 : return lDispatcher;
137 : }
138 :
139 : //_________________________________________________________________________________________________________________
140 :
141 : /**
142 : @short dispatch URL with arguments
143 : @descr We use threadsafe internal method to do so. It returns a state value - but we ignore it.
144 : Because we doesn't support status listener notifications here. Status events are not guaranteed -
145 : and we call another service internaly which doesn't return any notifications too.
146 :
147 : @param aURL
148 : mail URL which should be executed
149 : @param lArguments
150 : list of optional arguments for this mail request
151 : */
152 0 : void SAL_CALL MailToDispatcher::dispatch( const css::util::URL& aURL ,
153 : const css::uno::Sequence< css::beans::PropertyValue >& lArguments ) throw( css::uno::RuntimeException )
154 : {
155 : // dispatch() is an [oneway] call ... and may our user release his reference to us immediatly.
156 : // So we should hold us self alive till this call ends.
157 0 : css::uno::Reference< css::frame::XNotifyingDispatch > xSelfHold(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
158 0 : implts_dispatch(aURL,lArguments);
159 : // No notification for status listener!
160 0 : }
161 :
162 : //_________________________________________________________________________________________________________________
163 :
164 : /**
165 : @short dispatch with guaranteed notifications about success
166 : @descr We use threadsafe internal method to do so. Return state of this function will be used
167 : for notification if an optional listener is given.
168 :
169 : @param aURL
170 : mail URL which should be executed
171 : @param lArguments
172 : list of optional arguments for this mail request
173 : @param xListener
174 : reference to a valid listener for state events
175 : */
176 0 : void SAL_CALL MailToDispatcher::dispatchWithNotification( const css::util::URL& aURL ,
177 : const css::uno::Sequence< css::beans::PropertyValue >& lArguments,
178 : const css::uno::Reference< css::frame::XDispatchResultListener >& xListener ) throw( css::uno::RuntimeException )
179 : {
180 : // This class was designed to die by reference. And if user release his reference to us immediatly after calling this method
181 : // we can run into some problems. So we hold us self alive till this method ends.
182 : // Another reason: We can use this reference as source of sending event at the end too.
183 0 : css::uno::Reference< css::frame::XNotifyingDispatch > xThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
184 :
185 0 : sal_Bool bState = implts_dispatch(aURL,lArguments);
186 0 : if (xListener.is())
187 : {
188 0 : css::frame::DispatchResultEvent aEvent;
189 0 : if (bState)
190 0 : aEvent.State = css::frame::DispatchResultState::SUCCESS;
191 : else
192 0 : aEvent.State = css::frame::DispatchResultState::FAILURE;
193 0 : aEvent.Source = xThis;
194 :
195 0 : xListener->dispatchFinished( aEvent );
196 0 : }
197 0 : }
198 :
199 : //_________________________________________________________________________________________________________________
200 :
201 : /**
202 : @short threadsafe helper for dispatch calls
203 : @descr We support two interfaces for the same process - dispatch URLs. That the reason for this internal
204 : function. It implements the real dispatch operation and returns a state value which inform caller
205 : about success. He can notify listener then by using this return value.
206 :
207 : @param aURL
208 : mail URL which should be executed
209 : @param lArguments
210 : list of optional arguments for this mail request
211 :
212 : @return <TRUE/> if dispatch could be started successfully
213 : Note: Our internal used shell executor doesn't return any state value - so we must
214 : belive that call was successfully.
215 : <FALSE/> if neccessary resource couldn't be created or an exception was thrown.
216 : */
217 0 : sal_Bool MailToDispatcher::implts_dispatch( const css::util::URL& aURL ,
218 : const css::uno::Sequence< css::beans::PropertyValue >& /*lArguments*/ ) throw( css::uno::RuntimeException )
219 : {
220 0 : sal_Bool bSuccess = sal_False;
221 :
222 0 : css::uno::Reference< css::uno::XComponentContext > xContext;
223 : /* SAFE */{
224 0 : ReadGuard aReadLock( m_aLock );
225 0 : xContext = m_xContext;
226 : /* SAFE */}
227 :
228 0 : css::uno::Reference< css::system::XSystemShellExecute > xSystemShellExecute = css::system::SystemShellExecute::create( xContext );
229 :
230 : try
231 : {
232 : // start mail client
233 : // Because there is no notofocation about success - we use case of
234 : // no detected exception as SUCCESS - FAILED otherwhise.
235 0 : xSystemShellExecute->execute( aURL.Complete, ::rtl::OUString(), css::system::SystemShellExecuteFlags::URIS_ONLY );
236 0 : bSuccess = sal_True;
237 : }
238 0 : catch (const css::lang::IllegalArgumentException&)
239 : {
240 : }
241 0 : catch (const css::system::SystemShellExecuteException&)
242 : {
243 : }
244 :
245 0 : return bSuccess;
246 : }
247 :
248 : //_________________________________________________________________________________________________________________
249 :
250 : /**
251 : @short add/remove listener for state events
252 : @descr Because we use an external process to forward such mail URLs, and this process doesn't
253 : return any notifications about success or failed state - we doesn't support such status
254 : listener. We have no status to send.
255 :
256 : @param xListener
257 : reference to a valid listener for state events
258 : @param aURL
259 : URL about listener will be informed, if something occurred
260 : */
261 0 : void SAL_CALL MailToDispatcher::addStatusListener( const css::uno::Reference< css::frame::XStatusListener >& /*xListener*/ ,
262 : const css::util::URL& /*aURL*/ ) throw( css::uno::RuntimeException )
263 : {
264 : // not suported yet
265 0 : }
266 :
267 : //_________________________________________________________________________________________________________________
268 :
269 0 : void SAL_CALL MailToDispatcher::removeStatusListener( const css::uno::Reference< css::frame::XStatusListener >& /*xListener*/ ,
270 : const css::util::URL& /*aURL*/ ) throw( css::uno::RuntimeException )
271 : {
272 : // not suported yet
273 0 : }
274 :
275 : } // namespace framework
276 :
277 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|