LibreOffice Module framework (master) 1
jobdispatch.cxx
Go to the documentation of this file.
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 <jobs/configaccess.hxx>
21#include <jobs/joburl.hxx>
22#include <jobs/job.hxx>
23#include <classes/converter.hxx>
24
25#include <com/sun/star/frame/DispatchResultEvent.hpp>
26#include <com/sun/star/frame/DispatchResultState.hpp>
27#include <com/sun/star/frame/ModuleManager.hpp>
28#include <com/sun/star/frame/XNotifyingDispatch.hpp>
29#include <com/sun/star/frame/XDispatch.hpp>
30#include <com/sun/star/frame/XStatusListener.hpp>
31#include <com/sun/star/frame/XDispatchResultListener.hpp>
32#include <com/sun/star/frame/XDispatchProvider.hpp>
33#include <com/sun/star/lang/XInitialization.hpp>
34#include <com/sun/star/lang/XServiceInfo.hpp>
35
38#include <rtl/ref.hxx>
39#include <utility>
40#include <vcl/svapp.hxx>
41
42using namespace framework;
43
44namespace {
45
56class JobDispatch : public ::cppu::WeakImplHelper<
57 css::lang::XServiceInfo
58 , css::lang::XInitialization
59 , css::frame::XDispatchProvider
60 , css::frame::XNotifyingDispatch > // => XDispatch
61{
62private:
63
65 css::uno::Reference< css::uno::XComponentContext > m_xContext;
66
68 css::uno::Reference< css::frame::XFrame > m_xFrame;
69
71 OUString m_sModuleIdentifier;
72
73// native interface methods
74
75public:
76
77 explicit JobDispatch(css::uno::Reference< css::uno::XComponentContext > xContext);
78 virtual ~JobDispatch() override;
79
80 void impl_dispatchEvent ( const OUString& sEvent ,
81 const css::uno::Sequence< css::beans::PropertyValue >& lArgs ,
82 const css::uno::Reference< css::frame::XDispatchResultListener >& xListener );
83 void impl_dispatchService( const OUString& sService ,
84 const css::uno::Sequence< css::beans::PropertyValue >& lArgs ,
85 const css::uno::Reference< css::frame::XDispatchResultListener >& xListener );
86 void impl_dispatchAlias ( const OUString& sAlias ,
87 const css::uno::Sequence< css::beans::PropertyValue >& lArgs ,
88 const css::uno::Reference< css::frame::XDispatchResultListener >& xListener );
89
90public:
91 virtual OUString SAL_CALL getImplementationName() override
92 {
93 return "com.sun.star.comp.framework.jobs.JobDispatch";
94 }
95
96 virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override
97 {
98 return cppu::supportsService(this, ServiceName);
99 }
100
101 virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override
102 {
103 return {"com.sun.star.frame.ProtocolHandler"};
104 }
105
106 // Xinitialization
107 virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& lArguments ) override;
108
109 // XDispatchProvider
110 virtual css::uno::Reference< css::frame::XDispatch > SAL_CALL queryDispatch ( const css::util::URL& aURL ,
111 const OUString& sTargetFrameName ,
112 sal_Int32 nSearchFlags ) override;
113 virtual css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL queryDispatches( const css::uno::Sequence< css::frame::DispatchDescriptor >& lDescriptor ) override;
114
115 // XNotifyingDispatch
116 virtual void SAL_CALL dispatchWithNotification( const css::util::URL& aURL ,
117 const css::uno::Sequence< css::beans::PropertyValue >& lArgs ,
118 const css::uno::Reference< css::frame::XDispatchResultListener >& xListener ) override;
119
120 // XDispatch
121 virtual void SAL_CALL dispatch ( const css::util::URL& aURL ,
122 const css::uno::Sequence< css::beans::PropertyValue >& lArgs ) override;
123 virtual void SAL_CALL addStatusListener ( const css::uno::Reference< css::frame::XStatusListener >& xListener ,
124 const css::util::URL& aURL ) override;
125 virtual void SAL_CALL removeStatusListener( const css::uno::Reference< css::frame::XStatusListener >& xListener ,
126 const css::util::URL& aURL ) override;
127};
128
136JobDispatch::JobDispatch( /*IN*/ css::uno::Reference< css::uno::XComponentContext > xContext )
137 : m_xContext (std::move(xContext ))
138{
139}
140
145JobDispatch::~JobDispatch()
146{
147 // release all used resources
148 m_xContext.clear();
149 m_xFrame.clear();
150}
151
161void SAL_CALL JobDispatch::initialize( const css::uno::Sequence< css::uno::Any >& lArguments )
162{
164
165 for (int a=0; a<lArguments.getLength(); ++a)
166 {
167 if (a==0)
168 {
169 lArguments[a] >>= m_xFrame;
170
171 css::uno::Reference< css::frame::XModuleManager2 > xModuleManager =
172 css::frame::ModuleManager::create(m_xContext);
173 try
174 {
175 m_sModuleIdentifier = xModuleManager->identify( m_xFrame );
176 }
177 catch( const css::uno::Exception& )
178 {}
179 }
180 }
181}
182
200css::uno::Reference< css::frame::XDispatch > SAL_CALL JobDispatch::queryDispatch( /*IN*/ const css::util::URL& aURL ,
201 /*IN*/ const OUString& /*sTargetFrameName*/ ,
202 /*IN*/ sal_Int32 /*nSearchFlags*/ )
203{
204 css::uno::Reference< css::frame::XDispatch > xDispatch;
205
206 JobURL aAnalyzedURL(aURL.Complete);
207 if (aAnalyzedURL.isValid())
208 xDispatch = this;
209
210 return xDispatch;
211}
212
225css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL JobDispatch::queryDispatches( const css::uno::Sequence< css::frame::DispatchDescriptor >& lDescriptor )
226{
227 // don't pack resulting list!
228 sal_Int32 nCount = lDescriptor.getLength();
229 css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > lDispatches(nCount);
230 auto lDispatchesRange = asNonConstRange(lDispatches);
231 for (sal_Int32 i=0; i<nCount; ++i)
232 lDispatchesRange[i] = queryDispatch( lDescriptor[i].FeatureURL ,
233 lDescriptor[i].FrameName ,
234 lDescriptor[i].SearchFlags );
235 return lDispatches;
236}
237
262void SAL_CALL JobDispatch::dispatchWithNotification( /*IN*/ const css::util::URL& aURL ,
263 /*IN*/ const css::uno::Sequence< css::beans::PropertyValue >& lArgs ,
264 /*IN*/ const css::uno::Reference< css::frame::XDispatchResultListener >& xListener )
265{
266 JobURL aAnalyzedURL(aURL.Complete);
267 if (aAnalyzedURL.isValid())
268 {
269 OUString sRequest;
270 if (aAnalyzedURL.getEvent(sRequest))
271 impl_dispatchEvent(sRequest, lArgs, xListener);
272 else
273 if (aAnalyzedURL.getService(sRequest))
274 impl_dispatchService(sRequest, lArgs, xListener);
275 else
276 if (aAnalyzedURL.getAlias(sRequest))
277 impl_dispatchAlias(sRequest, lArgs, xListener);
278 }
279}
280
297void JobDispatch::impl_dispatchEvent( /*IN*/ const OUString& sEvent ,
298 /*IN*/ const css::uno::Sequence< css::beans::PropertyValue >& lArgs ,
299 /*IN*/ const css::uno::Reference< css::frame::XDispatchResultListener >& xListener )
300{
301 // get list of all enabled jobs
302 // The called static helper methods read it from the configuration and
303 // filter disabled jobs using it's time stamp values.
304 std::vector< OUString > lJobs = JobData::getEnabledJobsForEvent(m_xContext, sEvent);
305
306 css::uno::Reference< css::frame::XDispatchResultListener > xThis( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
307
308 // no jobs... no execution
309 // But a may given listener will know something...
310 // I think this operation was finished successfully.
311 // It's not really an error, if no registered jobs could be located.
312 // Step over all found jobs and execute it
313 int nExecutedJobs=0;
314 for (const OUString & lJob : lJobs)
315 {
316 JobData aCfg(m_xContext);
317 aCfg.setEvent(sEvent, lJob);
318 aCfg.setEnvironment(JobData::E_DISPATCH);
319 const bool bIsEnabled=aCfg.hasCorrectContext(m_sModuleIdentifier);
320
321 rtl::Reference<Job> pJob = new Job(m_xContext, m_xFrame);
322 pJob->setJobData(aCfg);
323
324 if (!bIsEnabled)
325 continue;
326
327 // Special mode for listener.
328 // We don't notify it directly here. We delegate that
329 // to the job implementation. But we must set ourself there too.
330 // Because this job must fake the source address of the event.
331 // Otherwise the listener may ignore it.
332 if (xListener.is())
333 pJob->setDispatchResultFake(xListener, xThis);
334 pJob->execute(Converter::convert_seqPropVal2seqNamedVal(lArgs));
335 ++nExecutedJobs;
336 }
337
338 if (nExecutedJobs<1 && xListener.is())
339 {
340 css::frame::DispatchResultEvent aEvent;
341 aEvent.Source = xThis;
342 aEvent.State = css::frame::DispatchResultState::SUCCESS;
343 xListener->dispatchFinished(aEvent);
344 }
345}
346
363void JobDispatch::impl_dispatchService( /*IN*/ const OUString& sService ,
364 /*IN*/ const css::uno::Sequence< css::beans::PropertyValue >& lArgs ,
365 /*IN*/ const css::uno::Reference< css::frame::XDispatchResultListener >& xListener )
366{
367 JobData aCfg(m_xContext);
368 aCfg.setService(sService);
369 aCfg.setEnvironment(JobData::E_DISPATCH);
370
371 /*Attention!
372 Jobs implements interfaces and dies by ref count!
373 And freeing of such uno object is done by uno itself.
374 So we have to use dynamic memory everytimes.
375 */
376 rtl::Reference<Job> pJob = new Job(m_xContext, m_xFrame);
377 pJob->setJobData(aCfg);
378
379 css::uno::Reference< css::frame::XDispatchResultListener > xThis( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
380
381 // Special mode for listener.
382 // We don't notify it directly here. We delegate that
383 // to the job implementation. But we must set ourself there too.
384 // Because this job must fake the source address of the event.
385 // Otherwise the listener may ignore it.
386 if (xListener.is())
387 pJob->setDispatchResultFake(xListener, xThis);
388 pJob->execute(Converter::convert_seqPropVal2seqNamedVal(lArgs));
389}
390
406void JobDispatch::impl_dispatchAlias( /*IN*/ const OUString& sAlias ,
407 /*IN*/ const css::uno::Sequence< css::beans::PropertyValue >& lArgs ,
408 /*IN*/ const css::uno::Reference< css::frame::XDispatchResultListener >& xListener )
409{
410 JobData aCfg(m_xContext);
411 aCfg.setAlias(sAlias);
412 aCfg.setEnvironment(JobData::E_DISPATCH);
413
414 rtl::Reference<Job> pJob = new Job(m_xContext, m_xFrame);
415 pJob->setJobData(aCfg);
416
417 css::uno::Reference< css::frame::XDispatchResultListener > xThis( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
418
419 // Special mode for listener.
420 // We don't notify it directly here. We delegate that
421 // to the job implementation. But we must set ourself there too.
422 // Because this job must fake the source address of the event.
423 // Otherwise the listener may ignore it.
424 if (xListener.is())
425 pJob->setDispatchResultFake(xListener, xThis);
426 pJob->execute(Converter::convert_seqPropVal2seqNamedVal(lArgs));
427}
428
442void SAL_CALL JobDispatch::dispatch( /*IN*/ const css::util::URL& aURL ,
443 /*IN*/ const css::uno::Sequence< css::beans::PropertyValue >& lArgs )
444{
445 dispatchWithNotification(aURL, lArgs, css::uno::Reference< css::frame::XDispatchResultListener >());
446}
447
451void SAL_CALL JobDispatch::addStatusListener( /*IN*/ const css::uno::Reference< css::frame::XStatusListener >&,
452 /*IN*/ const css::util::URL& )
453{
454}
455
459void SAL_CALL JobDispatch::removeStatusListener( /*IN*/ const css::uno::Reference< css::frame::XStatusListener >&,
460 /*IN*/ const css::util::URL& )
461{
462}
463
464}
465
466extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
468 css::uno::XComponentContext *context,
469 css::uno::Sequence<css::uno::Any> const &)
470{
471 return cppu::acquire(new JobDispatch(context));
472}
473
474/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
css::uno::Reference< css::lang::XComponent > m_xFrame
AnyEventRef aEvent
holds all necessary information about a job and handle it's configuration (if any exist!...
Definition: jobdata.hxx:41
can be used to parse, validate and work with job URL's @descr Job URLs are specified by the following...
Definition: joburl.hxx:46
it represent a job; execute it and control its lifetime
Definition: job.hxx:46
int nCount
Reference< XDispatch > xDispatch
URL aURL
css::uno::Reference< css::uno::XComponentContext > m_xContext
uno_Any a
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_framework_jobs_JobDispatch_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
int i
bool bIsEnabled
unsigned char sal_Bool