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
DEFINE_XINTERFACE_5(MailToDispatcher,OWeakObject,DIRECT_INTERFACE (css::lang::XTypeProvider),DIRECT_INTERFACE (css::lang::XServiceInfo),DIRECT_INTERFACE (css::frame::XDispatchProvider),DIRECT_INTERFACE (css::frame::XNotifyingDispatch),DIRECT_INTERFACE (css::frame::XDispatch))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 */
~MailToDispatcher()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 */
queryDispatch(const css::util::URL & aURL,const::rtl::OUString &,sal_Int32)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 */
queryDispatches(const css::uno::Sequence<css::frame::DispatchDescriptor> & lDescriptor)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 don't support status listener notifications here. Status events are not guaranteed -
186 and we call another service internally 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 */
dispatch(const css::util::URL & aURL,const css::uno::Sequence<css::beans::PropertyValue> & lArguments)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 */
dispatchWithNotification(const css::util::URL & aURL,const css::uno::Sequence<css::beans::PropertyValue> & lArguments,const css::uno::Reference<css::frame::XDispatchResultListener> & xListener)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 */
implts_dispatch(const css::util::URL & aURL,const css::uno::Sequence<css::beans::PropertyValue> &)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 notification about success - we use case of
283 // no detected exception as SUCCESS - FAILED otherwise.
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 */
addStatusListener(const css::uno::Reference<css::frame::XStatusListener> &,const css::util::URL &)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
removeStatusListener(const css::uno::Reference<css::frame::XStatusListener> &,const css::util::URL &)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