merge the formfield patch from ooo-build
[ooovba.git] / framework / source / dispatch / servicehandler.cxx
blob63a6b625d6fc7f9a57afbc436352fa8f2c77fdc3
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: servicehandler.cxx,v $
10 * $Revision: 1.9 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_framework.hxx"
34 //_________________________________________________________________________________________________________________
35 // my own includes
36 //_________________________________________________________________________________________________________________
37 #include <dispatch/servicehandler.hxx>
38 #include <threadhelp/readguard.hxx>
39 #include <general.h>
40 #include <services.h>
42 //_________________________________________________________________________________________________________________
43 // interface includes
44 //_________________________________________________________________________________________________________________
45 #include <com/sun/star/frame/DispatchResultState.hpp>
46 #include <com/sun/star/task/XJobExecutor.hpp>
48 //_________________________________________________________________________________________________________________
49 // includes of other projects
50 //_________________________________________________________________________________________________________________
52 #include <vcl/svapp.hxx>
54 //_________________________________________________________________________________________________________________
55 // namespace
56 //_________________________________________________________________________________________________________________
58 namespace framework{
60 //_________________________________________________________________________________________________________________
61 // non exported const
62 //_________________________________________________________________________________________________________________
64 #define PROTOCOL_VALUE "service:"
65 #define PROTOCOL_LENGTH 8
67 //_________________________________________________________________________________________________________________
68 // non exported definitions
69 //_________________________________________________________________________________________________________________
71 //_________________________________________________________________________________________________________________
72 // declarations
73 //_________________________________________________________________________________________________________________
75 //_________________________________________________________________________________________________________________
76 // XInterface, XTypeProvider, XServiceInfo
78 DEFINE_XINTERFACE_5(ServiceHandler ,
79 OWeakObject ,
80 DIRECT_INTERFACE(css::lang::XTypeProvider ),
81 DIRECT_INTERFACE(css::lang::XServiceInfo ),
82 DIRECT_INTERFACE(css::frame::XDispatchProvider ),
83 DIRECT_INTERFACE(css::frame::XNotifyingDispatch),
84 DIRECT_INTERFACE(css::frame::XDispatch ))
86 DEFINE_XTYPEPROVIDER_5(ServiceHandler ,
87 css::lang::XTypeProvider ,
88 css::lang::XServiceInfo ,
89 css::frame::XDispatchProvider ,
90 css::frame::XNotifyingDispatch,
91 css::frame::XDispatch )
93 DEFINE_XSERVICEINFO_MULTISERVICE(ServiceHandler ,
94 ::cppu::OWeakObject ,
95 SERVICENAME_PROTOCOLHANDLER ,
96 IMPLEMENTATIONNAME_SERVICEHANDLER)
98 DEFINE_INIT_SERVICE(ServiceHandler,
100 /*Attention
101 I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
102 to create a new instance of this class by our own supported service factory.
103 see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
108 //_________________________________________________________________________________________________________________
111 @short standard ctor
112 @descr These initialize a new instance of ths class with needed informations for work.
114 @param xFactory
115 reference to uno servicemanager for creation of new services
117 @modified 02.05.2002 08:16, as96863
119 ServiceHandler::ServiceHandler( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory )
120 // Init baseclasses first
121 : ThreadHelpBase( &Application::GetSolarMutex() )
122 , OWeakObject ( )
123 // Init member
124 , m_xFactory ( xFactory )
128 //_________________________________________________________________________________________________________________
131 @short standard dtor
132 @descr -
134 @modified 02.05.2002 08:16, as96863
136 ServiceHandler::~ServiceHandler()
138 m_xFactory = NULL;
141 //_________________________________________________________________________________________________________________
144 @short decide if this dispatch implementation can be used for requested URL or not
145 @descr A protocol handler is registerd for an URL pattern inside configuration and will
146 be asked by the generic dispatch mechanism inside framework, if he can handle this
147 special URL wich match his registration. He can agree by returning of a valid dispatch
148 instance or disagree by returning <NULL/>.
149 We don't create new dispatch instances here realy - we return THIS as result to handle it
150 at the same implementation.
152 @modified 02.05.2002 15:25, as96863
154 css::uno::Reference< css::frame::XDispatch > SAL_CALL ServiceHandler::queryDispatch( const css::util::URL& aURL ,
155 const ::rtl::OUString& /*sTarget*/ ,
156 sal_Int32 /*nFlags*/ ) throw( css::uno::RuntimeException )
158 css::uno::Reference< css::frame::XDispatch > xDispatcher;
159 if (aURL.Complete.compareToAscii(PROTOCOL_VALUE,PROTOCOL_LENGTH)==0)
160 xDispatcher = this;
161 return xDispatcher;
164 //_________________________________________________________________________________________________________________
167 @short do the same like dispatch() but for multiple requests at the same time
168 @descr -
170 @modified 02.05.2002 15:27, as96863
172 css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL ServiceHandler::queryDispatches( const css::uno::Sequence< css::frame::DispatchDescriptor >& lDescriptor ) throw( css::uno::RuntimeException )
174 sal_Int32 nCount = lDescriptor.getLength();
175 css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > lDispatcher( nCount );
176 for( sal_Int32 i=0; i<nCount; ++i )
178 lDispatcher[i] = this->queryDispatch(
179 lDescriptor[i].FeatureURL,
180 lDescriptor[i].FrameName,
181 lDescriptor[i].SearchFlags);
183 return lDispatcher;
186 //_________________________________________________________________________________________________________________
189 @short dispatch URL with arguments
190 @descr We use threadsafe internal method to do so. It returns a state value - but we ignore it.
191 Because we doesn't support status listener notifications here.
193 @param aURL
194 uno URL which should be executed
195 @param lArguments
196 list of optional arguments for this request
198 @modified 02.05.2002 08:19, as96863
200 void SAL_CALL ServiceHandler::dispatch( const css::util::URL& aURL ,
201 const css::uno::Sequence< css::beans::PropertyValue >& lArguments ) throw( css::uno::RuntimeException )
203 // dispatch() is an [oneway] call ... and may our user release his reference to us immediatly.
204 // So we should hold us self alive till this call ends.
205 css::uno::Reference< css::frame::XNotifyingDispatch > xSelfHold(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
206 implts_dispatch(aURL,lArguments);
207 // No notification for status listener!
210 //_________________________________________________________________________________________________________________
213 @short dispatch with guaranteed notifications about success
214 @descr We use threadsafe internal method to do so. Return state of this function will be used
215 for notification if an optional listener is given.
217 @param aURL
218 uno URL which should be executed
219 @param lArguments
220 list of optional arguments for this request
221 @param xListener
222 optional listener for state events
224 @modified 30.04.2002 14:49, as96863
226 void SAL_CALL ServiceHandler::dispatchWithNotification( const css::util::URL& aURL ,
227 const css::uno::Sequence< css::beans::PropertyValue >& lArguments,
228 const css::uno::Reference< css::frame::XDispatchResultListener >& xListener ) throw( css::uno::RuntimeException )
230 // This class was designed to die by reference. And if user release his reference to us immediatly after calling this method
231 // we can run into some problems. So we hold us self alive till this method ends.
232 // Another reason: We can use this reference as source of sending event at the end too.
233 css::uno::Reference< css::frame::XNotifyingDispatch > xThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
235 css::uno::Reference< css::uno::XInterface > xService = implts_dispatch(aURL,lArguments);
236 if (xListener.is())
238 css::frame::DispatchResultEvent aEvent;
239 if (xService.is())
240 aEvent.State = css::frame::DispatchResultState::SUCCESS;
241 else
242 aEvent.State = css::frame::DispatchResultState::FAILURE;
243 aEvent.Result <<= xService; // may NULL for state=FAILED!
244 aEvent.Source = xThis;
246 xListener->dispatchFinished( aEvent );
250 //_________________________________________________________________________________________________________________
253 @short threadsafe helper for dispatch calls
254 @descr We support two interfaces for the same process - dispatch URLs. That the reason for this internal
255 function. It implements the real dispatch operation and returns a state value which inform caller
256 about success. He can notify listener then by using this return value.
258 @param aURL
259 uno URL which should be executed
260 @param lArguments
261 list of optional arguments for this request
263 @return <NULL/> if requested service couldn't be created successullfy;
264 a valid reference otherwise. This return value can be used to indicate,
265 if dispatch was successfully or not.
267 @modified 02.05.2002 10:51, as96863
269 css::uno::Reference< css::uno::XInterface > ServiceHandler::implts_dispatch( const css::util::URL& aURL ,
270 const css::uno::Sequence< css::beans::PropertyValue >& /*lArguments*/ ) throw( css::uno::RuntimeException )
272 /* SAFE */
273 ReadGuard aReadLock( m_aLock );
274 css::uno::Reference< css::lang::XMultiServiceFactory > xFactory = m_xFactory;
275 aReadLock.unlock();
276 /* SAFE */
278 if (!xFactory.is())
279 return css::uno::Reference< css::uno::XInterface >();
281 // extract service name and may optional given parameters from given URL
282 // and use it to create and start the component
283 ::rtl::OUString sServiceAndArguments = aURL.Complete.copy(PROTOCOL_LENGTH);
284 ::rtl::OUString sServiceName;
285 ::rtl::OUString sArguments ;
287 sal_Int32 nArgStart = sServiceAndArguments.indexOf('?',0);
288 if (nArgStart!=-1)
290 sServiceName = sServiceAndArguments.copy(0,nArgStart);
291 ++nArgStart; // ignore '?'!
292 sArguments = sServiceAndArguments.copy(nArgStart);
294 else
296 sServiceName = sServiceAndArguments;
299 if (!sServiceName.getLength())
300 return css::uno::Reference< css::uno::XInterface >();
302 // If a service doesnt support an optional job executor interface - he can't get
303 // any given parameters!
304 // Because we can't know if we must call createInstanceWithArguments() or XJobExecutor::trigger() ...
306 css::uno::Reference< css::uno::XInterface > xService;
309 // => a) a service starts running inside his own ctor and we create it only
310 xService = xFactory->createInstance(sServiceName);
311 // or b) he implements the right interface and starts there (may with optional parameters)
312 css::uno::Reference< css::task::XJobExecutor > xExecuteable(xService, css::uno::UNO_QUERY);
313 if (xExecuteable.is())
314 xExecuteable->trigger(sArguments);
316 // ignore all errors - inclusive runtime errors!
317 // E.g. a script based service (written in phyton) could not be executed
318 // because it contains syntax errors, which was detected at runtime ...
319 catch(const css::uno::Exception&)
320 { xService.clear(); }
322 return xService;
325 //_________________________________________________________________________________________________________________
328 @short add/remove listener for state events
329 @descr We use an internal container to hold such registered listener. This container lives if we live.
330 And if call pas registration as non breakable transaction - we can accept the request without
331 any explicit lock. Because we share our mutex with this container.
333 @param xListener
334 reference to a valid listener for state events
335 @param aURL
336 URL about listener will be informed, if something occured
338 @modified 30.04.2002 14:49, as96863
340 void SAL_CALL ServiceHandler::addStatusListener( const css::uno::Reference< css::frame::XStatusListener >& /*xListener*/ ,
341 const css::util::URL& /*aURL*/ ) throw( css::uno::RuntimeException )
343 // not suported yet
346 //_________________________________________________________________________________________________________________
348 void SAL_CALL ServiceHandler::removeStatusListener( const css::uno::Reference< css::frame::XStatusListener >& /*xListener*/ ,
349 const css::util::URL& /*aURL*/ ) throw( css::uno::RuntimeException )
351 // not suported yet
354 } // namespace framework