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