fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / framework / source / jobs / jobdispatch.cxx
blob06819092b7481771a94f413ed642c6acb8d80bb7
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <jobs/configaccess.hxx>
21 #include <jobs/joburl.hxx>
22 #include <jobs/job.hxx>
23 #include <classes/converter.hxx>
24 #include <general.h>
26 #include <com/sun/star/frame/DispatchResultEvent.hpp>
27 #include <com/sun/star/frame/DispatchResultState.hpp>
28 #include <com/sun/star/frame/ModuleManager.hpp>
29 #include <com/sun/star/frame/XNotifyingDispatch.hpp>
30 #include <com/sun/star/frame/XDispatch.hpp>
31 #include <com/sun/star/frame/XStatusListener.hpp>
32 #include <com/sun/star/frame/XDispatchResultListener.hpp>
33 #include <com/sun/star/frame/XDispatchProvider.hpp>
34 #include <com/sun/star/lang/XInitialization.hpp>
35 #include <com/sun/star/lang/XServiceInfo.hpp>
37 #include <cppuhelper/supportsservice.hxx>
38 #include <cppuhelper/implbase4.hxx>
39 #include <rtl/ref.hxx>
40 #include <rtl/ustrbuf.hxx>
41 #include <unotools/configpaths.hxx>
42 #include <vcl/svapp.hxx>
44 using namespace framework;
46 namespace {
48 /**
49 @short implements a dispatch object for jobs
50 @descr Such dispatch object will be used by the generic dispatch mechanism if
51 an URL "vnd.sun.star.job:alias=<name>" occurs.
52 Then an instance of this class will be created and used.
53 This new instance will be called within his method
54 dispatch() or dispatchWithNotification() for executing the
55 real job. We do it, control the life cycle of this internal
56 wrapped job and inform any interested listener if it finish.
58 class JobDispatch : public ::cppu::WeakImplHelper4<
59 css::lang::XServiceInfo
60 , css::lang::XInitialization
61 , css::frame::XDispatchProvider
62 , css::frame::XNotifyingDispatch > // => XDispatch
64 private:
66 /** reference to the uno service manager */
67 css::uno::Reference< css::uno::XComponentContext > m_xContext;
69 /** reference to the frame, inside which this dispatch is used */
70 css::uno::Reference< css::frame::XFrame > m_xFrame;
72 /** name of module (writer, impress etc.) the frame is for */
73 OUString m_sModuleIdentifier;
75 // native interface methods
77 public:
79 JobDispatch( const css::uno::Reference< css::uno::XComponentContext >& xContext );
80 virtual ~JobDispatch();
82 void impl_dispatchEvent ( const OUString& sEvent ,
83 const css::uno::Sequence< css::beans::PropertyValue >& lArgs ,
84 const css::uno::Reference< css::frame::XDispatchResultListener >& xListener );
85 void impl_dispatchService( const OUString& sService ,
86 const css::uno::Sequence< css::beans::PropertyValue >& lArgs ,
87 const css::uno::Reference< css::frame::XDispatchResultListener >& xListener );
88 void impl_dispatchAlias ( const OUString& sAlias ,
89 const css::uno::Sequence< css::beans::PropertyValue >& lArgs ,
90 const css::uno::Reference< css::frame::XDispatchResultListener >& xListener );
92 public:
93 virtual OUString SAL_CALL getImplementationName()
94 throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
96 return OUString("com.sun.star.comp.framework.jobs.JobDispatch");
99 virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName)
100 throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
102 return cppu::supportsService(this, ServiceName);
105 virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames()
106 throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
108 css::uno::Sequence< OUString > aSeq(1);
109 aSeq[0] = "com.sun.star.frame.ProtocolHandler";
110 return aSeq;
113 // Xinitialization
114 virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& lArguments ) throw(css::uno::Exception ,
115 css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
117 // XDispatchProvider
118 virtual css::uno::Reference< css::frame::XDispatch > SAL_CALL queryDispatch ( const css::util::URL& aURL ,
119 const OUString& sTargetFrameName ,
120 sal_Int32 nSearchFlags ) throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
121 virtual css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL queryDispatches( const css::uno::Sequence< css::frame::DispatchDescriptor >& lDescriptor ) throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
123 // XNotifyingDispatch
124 virtual void SAL_CALL dispatchWithNotification( const css::util::URL& aURL ,
125 const css::uno::Sequence< css::beans::PropertyValue >& lArgs ,
126 const css::uno::Reference< css::frame::XDispatchResultListener >& xListener ) throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
128 // XDispatch
129 virtual void SAL_CALL dispatch ( const css::util::URL& aURL ,
130 const css::uno::Sequence< css::beans::PropertyValue >& lArgs ) throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
131 virtual void SAL_CALL addStatusListener ( const css::uno::Reference< css::frame::XStatusListener >& xListener ,
132 const css::util::URL& aURL ) throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
133 virtual void SAL_CALL removeStatusListener( const css::uno::Reference< css::frame::XStatusListener >& xListener ,
134 const css::util::URL& aURL ) throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
138 @short standard ctor
139 @descr It initialize this new instance.
141 @param xContext
142 reference to the uno service manager
144 JobDispatch::JobDispatch( /*IN*/ const css::uno::Reference< css::uno::XComponentContext >& xContext )
145 : m_xContext (xContext )
150 @short let this instance die
151 @descr We have to release all used resources and free used memory.
153 JobDispatch::~JobDispatch()
155 // release all used resources
156 m_xContext.clear();
157 m_xFrame.clear();
161 @short implementation of XInitalization
162 @descr A protocol handler can provide this functionality, if it wish to get additional information
163 about the context it runs. In this case the frame reference would be given by the outside code.
165 @param lArguments
166 the list of initialization arguments
167 First parameter should be the frame reference we need.
169 void SAL_CALL JobDispatch::initialize( const css::uno::Sequence< css::uno::Any >& lArguments ) throw(css::uno::Exception ,
170 css::uno::RuntimeException, std::exception)
172 SolarMutexGuard g;
174 for (int a=0; a<lArguments.getLength(); ++a)
176 if (a==0)
178 lArguments[a] >>= m_xFrame;
180 css::uno::Reference< css::frame::XModuleManager2 > xModuleManager =
181 css::frame::ModuleManager::create(m_xContext);
184 m_sModuleIdentifier = xModuleManager->identify( m_xFrame );
186 catch( const css::uno::Exception& )
193 @short implementation of XDispatchProvider::queryDispatches()
194 @descr Every protocol handler will be asked for his agreement, if an URL was queried
195 for which this handler is registered. It's the chance for this handler to validate
196 the given URL and return a dispatch object (may be itself) or not.
198 @param aURL
199 the queried URL, which should be checked
201 @param sTargetFrameName
202 describes the target frame, in which context this handler will be used
203 Is mostly set to "", "_self", "_blank", "_default" or a non special one
204 using SELF/CREATE as search flags.
206 @param nSearchFlags
207 Can be SELF or CREATE only and are set only if sTargetFrameName isn't a special target
209 css::uno::Reference< css::frame::XDispatch > SAL_CALL JobDispatch::queryDispatch( /*IN*/ const css::util::URL& aURL ,
210 /*IN*/ const OUString& /*sTargetFrameName*/ ,
211 /*IN*/ sal_Int32 /*nSearchFlags*/ ) throw(css::uno::RuntimeException, std::exception)
213 css::uno::Reference< css::frame::XDispatch > xDispatch;
215 JobURL aAnalyzedURL(aURL.Complete);
216 if (aAnalyzedURL.isValid())
217 xDispatch = css::uno::Reference< css::frame::XDispatch >( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
219 return xDispatch;
223 @short implementation of XDispatchProvider::queryDispatches()
224 @descr It's an optimized access for remote, so you can ask for
225 multiple dispatch objects at the same time.
227 @param lDescriptor
228 a list of queryDispatch() parameter
230 @return A list of corresponding dispatch objects.
231 NULL references are not skipped. Every result
232 match to one given descriptor item.
234 css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL JobDispatch::queryDispatches( const css::uno::Sequence< css::frame::DispatchDescriptor >& lDescriptor ) throw(css::uno::RuntimeException, std::exception)
236 // don't pack resulting list!
237 sal_Int32 nCount = lDescriptor.getLength();
238 css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > lDispatches(nCount);
240 for (sal_Int32 i=0; i<nCount; ++i)
241 lDispatches[i] = queryDispatch( lDescriptor[i].FeatureURL ,
242 lDescriptor[i].FrameName ,
243 lDescriptor[i].SearchFlags );
244 return lDispatches;
248 @short implementation of XNotifyingDispatch::dispatchWithNotification()
249 @descr It creates the job service implementation and call execute on it.
250 Further it starts the life time control of it. (important for async job)
251 For synchonrous job we react for the returned result directly ... for asynchronous
252 ones we do it later inside our callback method. But we use the same impl method
253 doing that to share the code. (see impl_finishJob())
255 If a job is already running, (it can only occur for asynchronous jobs)
256 don't start the same job a second time. Queue in the given dispatch parameter
257 and return immediately. If the current running job call us back, we will start this
258 new dispatch request.
259 If no job is running - queue the parameter too! But then start the new job immediately.
260 We have to queue it every time - because it hold us alive by ref count!
262 @param aURL
263 describe the job(s), which should be started
265 @param lArgs
266 optional arguments for this request
268 @param xListener
269 an interested listener for possible results of this operation
271 void SAL_CALL JobDispatch::dispatchWithNotification( /*IN*/ const css::util::URL& aURL ,
272 /*IN*/ const css::uno::Sequence< css::beans::PropertyValue >& lArgs ,
273 /*IN*/ const css::uno::Reference< css::frame::XDispatchResultListener >& xListener ) throw(css::uno::RuntimeException, std::exception)
275 JobURL aAnalyzedURL(aURL.Complete);
276 if (aAnalyzedURL.isValid())
278 OUString sRequest;
279 if (aAnalyzedURL.getEvent(sRequest))
280 impl_dispatchEvent(sRequest, lArgs, xListener);
281 else
282 if (aAnalyzedURL.getService(sRequest))
283 impl_dispatchService(sRequest, lArgs, xListener);
284 else
285 if (aAnalyzedURL.getAlias(sRequest))
286 impl_dispatchAlias(sRequest, lArgs, xListener);
291 @short dispatch an event
292 @descr We search all registered jobs for this event and execute it.
293 After doing so, we inform the given listener about the results.
294 (There will be one notify for every executed job!)
296 @param sEvent
297 the event, for which jobs can be registered
299 @param lArgs
300 optional arguments for this request
301 Currently not used!
303 @param xListener
304 an interested listener for possible results of this operation
306 void JobDispatch::impl_dispatchEvent( /*IN*/ const OUString& sEvent ,
307 /*IN*/ const css::uno::Sequence< css::beans::PropertyValue >& lArgs ,
308 /*IN*/ const css::uno::Reference< css::frame::XDispatchResultListener >& xListener )
310 // get list of all enabled jobs
311 // The called static helper methods read it from the configuration and
312 // filter disabled jobs using it's time stamp values.
313 /* SAFE { */
314 SolarMutexResettableGuard aReadLock;
315 css::uno::Sequence< OUString > lJobs = JobData::getEnabledJobsForEvent(m_xContext, sEvent);
316 aReadLock.clear();
317 /* } SAFE */
319 css::uno::Reference< css::frame::XDispatchResultListener > xThis( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
321 // no jobs ... no execution
322 // But a may given listener will know something ...
323 // I think this operaton was finished successfully.
324 // It's not really an error, if no registered jobs could be located.
325 // Step over all found jobs and execute it
326 int nExecutedJobs=0;
327 for (int j=0; j<lJobs.getLength(); ++j)
329 /* SAFE { */
330 aReadLock.reset();
332 JobData aCfg(m_xContext);
333 aCfg.setEvent(sEvent, lJobs[j]);
334 aCfg.setEnvironment(JobData::E_DISPATCH);
335 const bool bIsEnabled=aCfg.hasCorrectContext(m_sModuleIdentifier);
337 /*Attention!
338 Jobs implements interfaces and dies by ref count!
339 And freeing of such uno object is done by uno itself.
340 So we have to use dynamic memory everytimes.
342 Job* pJob = new Job(m_xContext, m_xFrame);
343 css::uno::Reference< css::uno::XInterface > xJob(static_cast< ::cppu::OWeakObject* >(pJob), css::uno::UNO_QUERY);
344 pJob->setJobData(aCfg);
346 aReadLock.clear();
347 /* } SAFE */
349 if (!bIsEnabled)
350 continue;
352 // Special mode for listener.
353 // We dont notify it directly here. We delegate that
354 // to the job implementation. But we must set ourself there too.
355 // Because this job must fake the source address of the event.
356 // Otherwise the listener may ignore it.
357 if (xListener.is())
358 pJob->setDispatchResultFake(xListener, xThis);
359 pJob->execute(Converter::convert_seqPropVal2seqNamedVal(lArgs));
360 ++nExecutedJobs;
363 if (nExecutedJobs<1 && xListener.is())
365 css::frame::DispatchResultEvent aEvent;
366 aEvent.Source = xThis;
367 aEvent.State = css::frame::DispatchResultState::SUCCESS;
368 xListener->dispatchFinished(aEvent);
373 @short dispatch a service
374 @descr We use the given name only to create and if possible to initialize
375 it as an uno service. It can be useful for creating (caching?)
376 of e.g. one instance services.
378 @param sService
379 the uno implementation or service name of the job, which should be instantiated
381 @param lArgs
382 optional arguments for this request
383 Currently not used!
385 @param xListener
386 an interested listener for possible results of this operation
388 void JobDispatch::impl_dispatchService( /*IN*/ const OUString& sService ,
389 /*IN*/ const css::uno::Sequence< css::beans::PropertyValue >& lArgs ,
390 /*IN*/ const css::uno::Reference< css::frame::XDispatchResultListener >& xListener )
392 /* SAFE { */
393 SolarMutexClearableGuard aReadLock;
395 JobData aCfg(m_xContext);
396 aCfg.setService(sService);
397 aCfg.setEnvironment(JobData::E_DISPATCH);
399 /*Attention!
400 Jobs implements interfaces and dies by ref count!
401 And freeing of such uno object is done by uno itself.
402 So we have to use dynamic memory everytimes.
404 Job* pJob = new Job(m_xContext, m_xFrame);
405 css::uno::Reference< css::uno::XInterface > xJob(static_cast< ::cppu::OWeakObject* >(pJob), css::uno::UNO_QUERY);
406 pJob->setJobData(aCfg);
408 aReadLock.clear();
409 /* } SAFE */
411 css::uno::Reference< css::frame::XDispatchResultListener > xThis( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
413 // Special mode for listener.
414 // We dont notify it directly here. We delegate that
415 // to the job implementation. But we must set ourself there too.
416 // Because this job must fake the source address of the event.
417 // Otherwise the listener may ignore it.
418 if (xListener.is())
419 pJob->setDispatchResultFake(xListener, xThis);
420 pJob->execute(Converter::convert_seqPropVal2seqNamedVal(lArgs));
424 @short dispatch an alias
425 @descr We use this alias to locate a job inside the configuration
426 and execute it. Further we inform the given listener about the results.
428 @param sAlias
429 the alias name of the configured job
431 @param lArgs
432 optional arguments for this request
433 Currently not used!
435 @param xListener
436 an interested listener for possible results of this operation
438 void JobDispatch::impl_dispatchAlias( /*IN*/ const OUString& sAlias ,
439 /*IN*/ const css::uno::Sequence< css::beans::PropertyValue >& lArgs ,
440 /*IN*/ const css::uno::Reference< css::frame::XDispatchResultListener >& xListener )
442 /* SAFE { */
443 SolarMutexClearableGuard aReadLock;
445 JobData aCfg(m_xContext);
446 aCfg.setAlias(sAlias);
447 aCfg.setEnvironment(JobData::E_DISPATCH);
449 /*Attention!
450 Jobs implements interfaces and dies by ref count!
451 And freeing of such uno object is done by uno itself.
452 So we have to use dynamic memory everytimes.
454 Job* pJob = new Job(m_xContext, m_xFrame);
455 css::uno::Reference< css::uno::XInterface > xJob(static_cast< ::cppu::OWeakObject* >(pJob), css::uno::UNO_QUERY);
456 pJob->setJobData(aCfg);
458 aReadLock.clear();
459 /* } SAFE */
461 css::uno::Reference< css::frame::XDispatchResultListener > xThis( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
463 // Special mode for listener.
464 // We dont notify it directly here. We delegate that
465 // to the job implementation. But we must set ourself there too.
466 // Because this job must fake the source address of the event.
467 // Otherwise the listener may ignore it.
468 if (xListener.is())
469 pJob->setDispatchResultFake(xListener, xThis);
470 pJob->execute(Converter::convert_seqPropVal2seqNamedVal(lArgs));
474 @short implementation of XDispatch::dispatch()
475 @descr Because the methods dispatch() and dispatchWithNotification() are different in her parameters
476 only, we can forward this request to dispatchWithNotification() by using an empty listener!
478 @param aURL
479 describe the job(s), which should be started
481 @param lArgs
482 optional arguments for this request
484 @see dispatchWithNotification()
486 void SAL_CALL JobDispatch::dispatch( /*IN*/ const css::util::URL& aURL ,
487 /*IN*/ const css::uno::Sequence< css::beans::PropertyValue >& lArgs ) throw(css::uno::RuntimeException, std::exception)
489 dispatchWithNotification(aURL, lArgs, css::uno::Reference< css::frame::XDispatchResultListener >());
493 @short not supported
495 void SAL_CALL JobDispatch::addStatusListener( /*IN*/ const css::uno::Reference< css::frame::XStatusListener >&,
496 /*IN*/ const css::util::URL& ) throw(css::uno::RuntimeException, std::exception)
501 @short not supported
503 void SAL_CALL JobDispatch::removeStatusListener( /*IN*/ const css::uno::Reference< css::frame::XStatusListener >&,
504 /*IN*/ const css::util::URL& ) throw(css::uno::RuntimeException, std::exception)
510 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
511 com_sun_star_comp_framework_jobs_JobDispatch_get_implementation(
512 css::uno::XComponentContext *context,
513 css::uno::Sequence<css::uno::Any> const &)
515 return cppu::acquire(new JobDispatch(context));
518 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */