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