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