merged tag ooo/OOO330_m14
[LibreOffice.git] / framework / source / jobs / jobdispatch.cxx
blobb2c5399d02164b69f7eea1e474b9b727ff0d72ab
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_framework.hxx"
31 //________________________________
32 // my own includes
33 #include <jobs/jobdispatch.hxx>
34 #include <jobs/joburl.hxx>
35 #include <jobs/job.hxx>
36 #include <threadhelp/readguard.hxx>
37 #include <threadhelp/writeguard.hxx>
38 #include <threadhelp/resetableguard.hxx>
39 #include <classes/converter.hxx>
40 #include <general.h>
41 #include <services.h>
43 //________________________________
44 // interface includes
45 #include <com/sun/star/beans/XPropertySet.hpp>
46 #include <com/sun/star/frame/DispatchResultState.hpp>
48 //________________________________
49 // includes of other projects
50 #include <rtl/ustrbuf.hxx>
51 #include <vcl/svapp.hxx>
53 //________________________________
54 // namespace
56 namespace framework{
58 //________________________________
59 // non exported const
61 //________________________________
62 // non exported definitions
64 //________________________________
65 // declarations
67 DEFINE_XINTERFACE_6( JobDispatch ,
68 OWeakObject ,
69 DIRECT_INTERFACE(css::lang::XTypeProvider ),
70 DIRECT_INTERFACE(css::frame::XDispatchProvider ),
71 DIRECT_INTERFACE(css::lang::XInitialization ),
72 DIRECT_INTERFACE(css::lang::XServiceInfo),
73 DIRECT_INTERFACE(css::frame::XNotifyingDispatch),
74 DIRECT_INTERFACE(css::frame::XDispatch )
77 DEFINE_XTYPEPROVIDER_6( JobDispatch ,
78 css::lang::XTypeProvider ,
79 css::frame::XDispatchProvider ,
80 css::frame::XNotifyingDispatch,
81 css::lang::XInitialization,
82 css::lang::XServiceInfo,
83 css::frame::XDispatch
86 DEFINE_XSERVICEINFO_MULTISERVICE( JobDispatch ,
87 ::cppu::OWeakObject ,
88 SERVICENAME_PROTOCOLHANDLER ,
89 IMPLEMENTATIONNAME_JOBDISPATCH
92 DEFINE_INIT_SERVICE( JobDispatch,
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!
102 //________________________________
104 @short standard ctor
105 @descr It initialize this new instance.
107 @param xSMGR
108 reference to the uno service manager
110 JobDispatch::JobDispatch( /*IN*/ const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR )
111 : ThreadHelpBase(&Application::GetSolarMutex())
112 , OWeakObject ( )
113 , m_xSMGR (xSMGR )
117 //________________________________
119 @short let this instance die
120 @descr We have to release all used ressources and free used memory.
122 JobDispatch::~JobDispatch()
124 // release all used ressources
125 m_xSMGR = css::uno::Reference< css::lang::XMultiServiceFactory >();
126 m_xFrame = css::uno::Reference< css::frame::XFrame >();
129 //________________________________
131 @short implementation of XInitalization
132 @descr A protocol handler can provide this functionality, if it wish to get additional informations
133 about the context it runs. In this case the frame reference would be given by the outside code.
135 @param lArguments
136 the list of initialization arguments
137 First parameter should be the frame reference we need.
139 void SAL_CALL JobDispatch::initialize( const css::uno::Sequence< css::uno::Any >& lArguments ) throw(css::uno::Exception ,
140 css::uno::RuntimeException)
142 /* SAFE { */
143 WriteGuard aWriteLock(m_aLock);
145 for (int a=0; a<lArguments.getLength(); ++a)
147 if (a==0)
148 lArguments[a] >>= m_xFrame;
151 aWriteLock.unlock();
152 /* } SAFE */
155 //________________________________
157 @short implementation of XDispatchProvider::queryDispatches()
158 @descr Every protocol handler will be asked for his agreement, if an URL was queried
159 for which this handler is registered. It's the chance for this handler to validate
160 the given URL and return a dispatch object (may be itself) or not.
162 @param aURL
163 the queried URL, which should be checked
165 @param sTargetFrameName
166 describes the target frame, in which context this handler will be used
167 Is mostly set to "", "_self", "_blank", "_default" or a non special one
168 using SELF/CREATE as search flags.
170 @param nSearchFlags
171 Can be SELF or CREATE only and are set only if sTargetFrameName isn't a special target
173 css::uno::Reference< css::frame::XDispatch > SAL_CALL JobDispatch::queryDispatch( /*IN*/ const css::util::URL& aURL ,
174 /*IN*/ const ::rtl::OUString& /*sTargetFrameName*/ ,
175 /*IN*/ sal_Int32 /*nSearchFlags*/ ) throw(css::uno::RuntimeException)
177 css::uno::Reference< css::frame::XDispatch > xDispatch;
179 JobURL aAnalyzedURL(aURL.Complete);
180 if (aAnalyzedURL.isValid())
181 xDispatch = css::uno::Reference< css::frame::XDispatch >( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
183 return xDispatch;
186 //________________________________
188 @short implementation of XDispatchProvider::queryDispatches()
189 @descr It's an optimized access for remote, so you can ask for
190 multiple dispatch objects at the same time.
192 @param lDescriptor
193 a list of queryDispatch() parameter
195 @return A list of corresponding dispatch objects.
196 NULL references are not skipped. Every result
197 match to one given descriptor item.
199 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)
201 // don't pack resulting list!
202 sal_Int32 nCount = lDescriptor.getLength();
203 css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > lDispatches(nCount);
205 for (sal_Int32 i=0; i<nCount; ++i)
206 lDispatches[i] = queryDispatch( lDescriptor[i].FeatureURL ,
207 lDescriptor[i].FrameName ,
208 lDescriptor[i].SearchFlags );
209 return lDispatches;
212 //________________________________
214 @short implementation of XNotifyingDispatch::dispatchWithNotification()
215 @descr It creates the job service implementation and call execute on it.
216 Further it starts the life time control of it. (important for async job)
217 For synchonrous job we react for the returned result directly ... for asynchronous
218 ones we do it later inside our callback method. But we use the same impl method
219 doing that to share the code. (see impl_finishJob())
221 If a job is already running, (it can only occure for asynchronous jobs)
222 don't start the same job a second time. Queue in the given dispatch parameter
223 and return immediatly. If the current running job call us back, we will start this
224 new dispatch request.
225 If no job is running - queue the parameter too! But then start the new job immediatly.
226 We have to queue it every time - because it hold us alive by ref count!
228 @param aURL
229 describe the job(s), which should be started
231 @param lArgs
232 optional arguments for this request
234 @param xListener
235 an interested listener for possible results of this operation
237 void SAL_CALL JobDispatch::dispatchWithNotification( /*IN*/ const css::util::URL& aURL ,
238 /*IN*/ const css::uno::Sequence< css::beans::PropertyValue >& lArgs ,
239 /*IN*/ const css::uno::Reference< css::frame::XDispatchResultListener >& xListener ) throw(css::uno::RuntimeException)
241 JobURL aAnalyzedURL(aURL.Complete);
242 if (aAnalyzedURL.isValid())
244 ::rtl::OUString sRequest;
245 if (aAnalyzedURL.getEvent(sRequest))
246 impl_dispatchEvent(sRequest, lArgs, xListener);
247 else
248 if (aAnalyzedURL.getService(sRequest))
249 impl_dispatchService(sRequest, lArgs, xListener);
250 else
251 if (aAnalyzedURL.getAlias(sRequest))
252 impl_dispatchAlias(sRequest, lArgs, xListener);
256 //________________________________
258 @short dispatch an event
259 @descr We search all registered jobs for this event and execute it.
260 After doing so, we inform the given listener about the results.
261 (There will be one notify for every executed job!)
263 @param sEvent
264 the event, for which jobs can be registered
266 @param lArgs
267 optional arguments for this request
268 Currently not used!
270 @param xListener
271 an interested listener for possible results of this operation
273 void JobDispatch::impl_dispatchEvent( /*IN*/ const ::rtl::OUString& sEvent ,
274 /*IN*/ const css::uno::Sequence< css::beans::PropertyValue >& lArgs ,
275 /*IN*/ const css::uno::Reference< css::frame::XDispatchResultListener >& xListener )
277 // get list of all enabled jobs
278 // The called static helper methods read it from the configuration and
279 // filter disabled jobs using it's time stamp values.
280 /* SAFE { */
281 ReadGuard aReadLock(m_aLock);
282 css::uno::Sequence< ::rtl::OUString > lJobs = JobData::getEnabledJobsForEvent(m_xSMGR, sEvent);
283 aReadLock.unlock();
284 /* } SAFE */
286 css::uno::Reference< css::frame::XDispatchResultListener > xThis( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
288 // no jobs ... no execution
289 // But a may given listener will know something ...
290 // I think this operaton was finished successfully.
291 // It's not realy an error, if no registered jobs could be located.
292 if (lJobs.getLength()<1 && xListener.is())
294 css::frame::DispatchResultEvent aEvent;
295 aEvent.Source = xThis;
296 aEvent.State = css::frame::DispatchResultState::SUCCESS;
297 xListener->dispatchFinished(aEvent);
298 return;
301 // Step over all found jobs and execute it
302 for (int j=0; j<lJobs.getLength(); ++j)
304 /* SAFE { */
305 aReadLock.lock();
307 JobData aCfg(m_xSMGR);
308 aCfg.setEvent(sEvent, lJobs[j]);
309 aCfg.setEnvironment(JobData::E_DISPATCH);
311 /*Attention!
312 Jobs implements interfaces and dies by ref count!
313 And freeing of such uno object is done by uno itself.
314 So we have to use dynamic memory everytimes.
316 Job* pJob = new Job(m_xSMGR, m_xFrame);
317 css::uno::Reference< css::uno::XInterface > xJob(static_cast< ::cppu::OWeakObject* >(pJob), css::uno::UNO_QUERY);
318 pJob->setJobData(aCfg);
320 aReadLock.unlock();
321 /* } SAFE */
323 // Special mode for listener.
324 // We dont notify it directly here. We delegate that
325 // to the job implementation. But we must set ourself there too.
326 // Because this job must fake the source adress of the event.
327 // Otherwhise the listener may will ignore it.
328 if (xListener.is())
329 pJob->setDispatchResultFake(xListener, xThis);
330 pJob->execute(Converter::convert_seqPropVal2seqNamedVal(lArgs));
334 //________________________________
336 @short dispatch a service
337 @descr We use the given name only to create and if possible to initialize
338 it as an uno service. It can be usefully for creating (caching?)
339 of e.g. one instance services.
341 @param sService
342 the uno implementation or service name of the job, which should be instanciated
344 @param lArgs
345 optional arguments for this request
346 Currently not used!
348 @param xListener
349 an interested listener for possible results of this operation
351 void JobDispatch::impl_dispatchService( /*IN*/ const ::rtl::OUString& sService ,
352 /*IN*/ const css::uno::Sequence< css::beans::PropertyValue >& lArgs ,
353 /*IN*/ const css::uno::Reference< css::frame::XDispatchResultListener >& xListener )
355 /* SAFE { */
356 ReadGuard aReadLock(m_aLock);
358 JobData aCfg(m_xSMGR);
359 aCfg.setService(sService);
360 aCfg.setEnvironment(JobData::E_DISPATCH);
362 /*Attention!
363 Jobs implements interfaces and dies by ref count!
364 And freeing of such uno object is done by uno itself.
365 So we have to use dynamic memory everytimes.
367 Job* pJob = new Job(m_xSMGR, m_xFrame);
368 css::uno::Reference< css::uno::XInterface > xJob(static_cast< ::cppu::OWeakObject* >(pJob), css::uno::UNO_QUERY);
369 pJob->setJobData(aCfg);
371 aReadLock.unlock();
372 /* } SAFE */
374 css::uno::Reference< css::frame::XDispatchResultListener > xThis( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
376 // Special mode for listener.
377 // We dont notify it directly here. We delegate that
378 // to the job implementation. But we must set ourself there too.
379 // Because this job must fake the source adress of the event.
380 // Otherwhise the listener may will ignore it.
381 if (xListener.is())
382 pJob->setDispatchResultFake(xListener, xThis);
383 pJob->execute(Converter::convert_seqPropVal2seqNamedVal(lArgs));
386 //________________________________
388 @short dispatch an alias
389 @descr We use this alias to locate a job inside the configuration
390 and execute it. Further we inform the given listener about the results.
392 @param sAlias
393 the alias name of the configured job
395 @param lArgs
396 optional arguments for this request
397 Currently not used!
399 @param xListener
400 an interested listener for possible results of this operation
402 void JobDispatch::impl_dispatchAlias( /*IN*/ const ::rtl::OUString& sAlias ,
403 /*IN*/ const css::uno::Sequence< css::beans::PropertyValue >& lArgs ,
404 /*IN*/ const css::uno::Reference< css::frame::XDispatchResultListener >& xListener )
406 /* SAFE { */
407 ReadGuard aReadLock(m_aLock);
409 JobData aCfg(m_xSMGR);
410 aCfg.setAlias(sAlias);
411 aCfg.setEnvironment(JobData::E_DISPATCH);
413 /*Attention!
414 Jobs implements interfaces and dies by ref count!
415 And freeing of such uno object is done by uno itself.
416 So we have to use dynamic memory everytimes.
418 Job* pJob = new Job(m_xSMGR, m_xFrame);
419 css::uno::Reference< css::uno::XInterface > xJob(static_cast< ::cppu::OWeakObject* >(pJob), css::uno::UNO_QUERY);
420 pJob->setJobData(aCfg);
422 aReadLock.unlock();
423 /* } SAFE */
425 css::uno::Reference< css::frame::XDispatchResultListener > xThis( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
427 // Special mode for listener.
428 // We dont notify it directly here. We delegate that
429 // to the job implementation. But we must set ourself there too.
430 // Because this job must fake the source adress of the event.
431 // Otherwhise the listener may will ignore it.
432 if (xListener.is())
433 pJob->setDispatchResultFake(xListener, xThis);
434 pJob->execute(Converter::convert_seqPropVal2seqNamedVal(lArgs));
437 //________________________________
439 @short implementation of XDispatch::dispatch()
440 @descr Because the methods dispatch() and dispatchWithNotification() are different in her parameters
441 only, we can forward this request to dispatchWithNotification() by using an empty listener!
443 @param aURL
444 describe the job(s), which should be started
446 @param lArgs
447 optional arguments for this request
449 @see dispatchWithNotification()
451 void SAL_CALL JobDispatch::dispatch( /*IN*/ const css::util::URL& aURL ,
452 /*IN*/ const css::uno::Sequence< css::beans::PropertyValue >& lArgs ) throw(css::uno::RuntimeException)
454 dispatchWithNotification(aURL, lArgs, css::uno::Reference< css::frame::XDispatchResultListener >());
457 //________________________________
459 @short not supported
461 void SAL_CALL JobDispatch::addStatusListener( /*IN*/ const css::uno::Reference< css::frame::XStatusListener >&,
462 /*IN*/ const css::util::URL& ) throw(css::uno::RuntimeException)
466 //________________________________
468 @short not supported
470 void SAL_CALL JobDispatch::removeStatusListener( /*IN*/ const css::uno::Reference< css::frame::XStatusListener >&,
471 /*IN*/ const css::util::URL& ) throw(css::uno::RuntimeException)
475 } // namespace framework