fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / framework / source / jobs / jobdata.cxx
blob3c0adc804a9be103cde1d4629709ab3bbc6ad0b1
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/jobdata.hxx>
21 #include <classes/converter.hxx>
22 #include <general.h>
23 #include <services.h>
25 #include <com/sun/star/beans/XPropertySet.hpp>
26 #include <com/sun/star/beans/XMultiHierarchicalPropertySet.hpp>
27 #include <com/sun/star/container/XNameAccess.hpp>
28 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
30 #include <tools/wldcrd.hxx>
31 #include <unotools/configpaths.hxx>
32 #include <vcl/svapp.hxx>
34 namespace framework{
36 /**
37 @short standard ctor
38 @descr It initialize this new instance.
39 But for real working it's necessary to call setAlias() or setService() later.
40 Because we need the job data ...
42 @param rxContext
43 reference to the uno service manager
45 JobData::JobData( const css::uno::Reference< css::uno::XComponentContext >& rxContext )
46 : m_xContext (rxContext )
48 // share code for member initialization with defaults!
49 impl_reset();
52 /**
53 @short copy ctor
54 @descr Sometimes such job data container must be moved from one using place
55 to another one. Then a copy ctor and copy operator must be available.
57 @param rCopy
58 the original instance, from which we must copy all data
60 JobData::JobData( const JobData& rCopy )
62 // use the copy operator to share the same code
63 *this = rCopy;
66 /**
67 @short operator for coping JobData instances
68 @descr Sometimes such job data container must be moved from one using place
69 to another one. Then a copy ctor and copy operator must be available.
71 @param rCopy
72 the original instance, from which we must copy all data
74 void JobData::operator=( const JobData& rCopy )
76 SolarMutexGuard g;
77 // Please don't copy the uno service manager reference.
78 // That can change the uno context, which isn't a good idea!
79 m_eMode = rCopy.m_eMode;
80 m_eEnvironment = rCopy.m_eEnvironment;
81 m_sAlias = rCopy.m_sAlias;
82 m_sService = rCopy.m_sService;
83 m_sContext = rCopy.m_sContext;
84 m_sEvent = rCopy.m_sEvent;
85 m_lArguments = rCopy.m_lArguments;
86 m_aLastExecutionResult = rCopy.m_aLastExecutionResult;
89 /**
90 @short let this instance die
91 @descr There is no chance any longer to work. We have to
92 release all used resources and free used memory.
94 JobData::~JobData()
96 impl_reset();
99 /**
100 @short initalize this instance as a job with configuration
101 @descr They given alias can be used to address some configuration data.
102 We read it and fill our internal structures. Of course old information
103 will be lost doing so.
105 @param sAlias
106 the alias name of this job, used to locate job properties inside cfg
108 void JobData::setAlias( const OUString& sAlias )
110 SolarMutexGuard g;
111 // delete all old information! Otherwhise we mix it with the new one ...
112 impl_reset();
114 // take over the new information
115 m_sAlias = sAlias;
116 m_eMode = E_ALIAS;
118 // try to open the configuration set of this job directly and get a property access to it
119 // We open it readonly here
120 ConfigAccess aConfig(
121 m_xContext,
122 ("/org.openoffice.Office.Jobs/Jobs/"
123 + utl::wrapConfigurationElementName(m_sAlias)));
124 aConfig.open(ConfigAccess::E_READONLY);
125 if (aConfig.getMode()==ConfigAccess::E_CLOSED)
127 impl_reset();
128 return;
131 css::uno::Reference< css::beans::XPropertySet > xJobProperties(aConfig.cfg(), css::uno::UNO_QUERY);
132 if (xJobProperties.is())
134 css::uno::Any aValue;
136 // read uno implementation name
137 aValue = xJobProperties->getPropertyValue("Service");
138 aValue >>= m_sService;
140 // read module context list
141 aValue = xJobProperties->getPropertyValue("Context");
142 aValue >>= m_sContext;
144 // read whole argument list
145 aValue = xJobProperties->getPropertyValue("Arguments");
146 css::uno::Reference< css::container::XNameAccess > xArgumentList;
147 if (
148 (aValue >>= xArgumentList) &&
149 (xArgumentList.is() )
152 css::uno::Sequence< OUString > lArgumentNames = xArgumentList->getElementNames();
153 sal_Int32 nCount = lArgumentNames.getLength();
154 m_lArguments.realloc(nCount);
155 for (sal_Int32 i=0; i<nCount; ++i)
157 m_lArguments[i].Name = lArgumentNames[i];
158 m_lArguments[i].Value = xArgumentList->getByName(m_lArguments[i].Name);
163 aConfig.close();
167 @short initalize this instance as a job without configuration
168 @descr This job has no configuration data. We have to forget all old information
169 and set only some of them new, so this instance can work.
171 @param sService
172 the uno service name of this "non configured" job
174 void JobData::setService( const OUString& sService )
176 SolarMutexGuard g;
177 // delete all old information! Otherwhise we mix it with the new one ...
178 impl_reset();
179 // take over the new information
180 m_sService = sService;
181 m_eMode = E_SERVICE;
185 @short initialize this instance with new job values.
186 @descr It reads automatically all properties of the specified
187 job (using it's alias name) and "register it" for the
188 given event. This registration will not be validated against
189 the underlying configuration! (That must be done from outside.
190 Because the caller must have the configuration already open to
191 get the values for sEvent and sAlias! And doing so it can perform
192 only, if the time stanp values are readed outside too.
193 Further it make no sense to initialize and start a disabled job.
194 So this initialization method will be called for enabled jobs only.)
196 @param sEvent
197 the triggered event, for which this job should be started
199 @param sAlias
200 mark the required job inside event registration list
202 void JobData::setEvent( const OUString& sEvent ,
203 const OUString& sAlias )
205 // share code to read all job properties!
206 setAlias(sAlias);
208 SolarMutexGuard g;
209 // take over the new information - which differ against set on of method setAlias()!
210 m_sEvent = sEvent;
211 m_eMode = E_EVENT;
215 @short set the new job specific arguments
216 @descr If a job finish his work, it can give us a new list of arguments (which
217 will not interpreted by us). We write it back to the configuration only
218 (if this job has it's own configuration!).
219 So a job can have persistent data without implementing anything
220 or define own config areas for that.
222 @param lArguments
223 list of arguments, which should be set for this job
225 void JobData::setJobConfig( const css::uno::Sequence< css::beans::NamedValue >& lArguments )
227 SolarMutexGuard g;
229 // update member
230 m_lArguments = lArguments;
232 // update the configuration ... if possible!
233 if (m_eMode==E_ALIAS)
235 // It doesn't matter if this config object was already opened before.
236 // It doesn nothing here then ... or it change the mode automatically, if
237 // it was opened using another one before.
238 ConfigAccess aConfig(
239 m_xContext,
240 ("/org.openoffice.Office.Jobs/Jobs/"
241 + utl::wrapConfigurationElementName(m_sAlias)));
242 aConfig.open(ConfigAccess::E_READWRITE);
243 if (aConfig.getMode()==ConfigAccess::E_CLOSED)
244 return;
246 css::uno::Reference< css::beans::XMultiHierarchicalPropertySet > xArgumentList(aConfig.cfg(), css::uno::UNO_QUERY);
247 if (xArgumentList.is())
249 sal_Int32 nCount = m_lArguments.getLength();
250 css::uno::Sequence< OUString > lNames (nCount);
251 css::uno::Sequence< css::uno::Any > lValues(nCount);
253 for (sal_Int32 i=0; i<nCount; ++i)
255 lNames [i] = m_lArguments[i].Name;
256 lValues[i] = m_lArguments[i].Value;
259 xArgumentList->setHierarchicalPropertyValues(lNames, lValues);
261 aConfig.close();
266 @short set a new excution result
267 @descr Every executed job can have returned a result.
268 We set it here, so our user can use it may be later.
269 But the outside code can use it too, to analyze it and
270 adopt the configuration of this job too. Because the
271 result uses a protocol, which allow that. And we provide
272 right functionality to save it.
274 @param aResult
275 the result of last execution
277 void JobData::setResult( const JobResult& aResult )
279 SolarMutexGuard g;
281 // overwrite the last saved result
282 m_aLastExecutionResult = aResult;
284 // Don't use his information to update
285 // e.g. the arguments of this job. It must be done
286 // from outside! Here we save this information only.
290 @short set a new environment descriptor for this job
291 @descr It must(!) be done every time this container is initialized
292 with new job datas e.g.: setAlias()/setEvent()/setService() ...
293 Otherwhise the environment will be unknown!
295 void JobData::setEnvironment( EEnvironment eEnvironment )
297 SolarMutexGuard g;
298 m_eEnvironment = eEnvironment;
302 @short these functions provides access to our internal members
303 @descr These member represent any information about the job
304 and can be used from outside to e.g. start a job.
306 JobData::EMode JobData::getMode() const
308 SolarMutexGuard g;
309 return m_eMode;
312 JobData::EEnvironment JobData::getEnvironment() const
314 SolarMutexGuard g;
315 return m_eEnvironment;
318 OUString JobData::getEnvironmentDescriptor() const
320 OUString sDescriptor;
321 SolarMutexGuard g;
322 switch(m_eEnvironment)
324 case E_EXECUTION :
325 sDescriptor = "EXECUTOR";
326 break;
328 case E_DISPATCH :
329 sDescriptor = "DISPATCH";
330 break;
332 case E_DOCUMENTEVENT :
333 sDescriptor = "DOCUMENTEVENT";
334 break;
335 default:
336 break;
338 return sDescriptor;
341 OUString JobData::getService() const
343 SolarMutexGuard g;
344 return m_sService;
347 OUString JobData::getEvent() const
349 SolarMutexGuard g;
350 return m_sEvent;
353 css::uno::Sequence< css::beans::NamedValue > JobData::getJobConfig() const
355 SolarMutexGuard g;
356 return m_lArguments;
359 css::uno::Sequence< css::beans::NamedValue > JobData::getConfig() const
361 SolarMutexGuard g;
362 css::uno::Sequence< css::beans::NamedValue > lConfig;
363 if (m_eMode==E_ALIAS)
365 lConfig.realloc(3);
366 sal_Int32 i = 0;
368 lConfig[i].Name = "Alias";
369 lConfig[i].Value <<= m_sAlias;
370 ++i;
372 lConfig[i].Name = "Service";
373 lConfig[i].Value <<= m_sService;
374 ++i;
376 lConfig[i].Name = "Context";
377 lConfig[i].Value <<= m_sContext;
378 ++i;
380 return lConfig;
384 @short return information, if this job is part of the global configuration package
385 org.openoffice.Office.Jobs
386 @descr Because jobs can be executed by the dispatch framework using an uno service name
387 directly - an executed job must not have any configuration really. Such jobs
388 must provide the right interfaces only! But after finishing jobs can return
389 some information (e.g. for updating her configuration ...). We must know
390 if such request is valid or not then.
392 @return sal_True if the represented job is part of the underlying configuration package.
394 bool JobData::hasConfig() const
396 SolarMutexGuard g;
397 return (m_eMode==E_ALIAS || m_eMode==E_EVENT);
401 @short mark a job as non startable for further requests
402 @descr We don't remove the configuration entry! We set a timestamp value only.
403 And there exist two of them: one for an administrator ... and one for the
404 current user. We change it for the user layer only. So this JobDispatch can't be
405 started any more ... till the administrator change his timestamp.
406 That can be useful for post setup scenarios, which must run one time only.
408 Note: This method don't do anything, if this represented job doesn't have a configuration!
410 void JobData::disableJob()
412 SolarMutexGuard g;
414 // No configuration - not used from EXECUTOR and not triggered from an event => no chance!
415 if (m_eMode!=E_EVENT)
416 return;
418 // update the configuration
419 // It doesn't matter if this config object was already opened before.
420 // It doesn nothing here then ... or it change the mode automatically, if
421 // it was opened using another one before.
422 ConfigAccess aConfig(
423 m_xContext,
424 ("/org.openoffice.Office.Jobs/Events/"
425 + utl::wrapConfigurationElementName(m_sEvent) + "/JobList/"
426 + utl::wrapConfigurationElementName(m_sAlias)));
427 aConfig.open(ConfigAccess::E_READWRITE);
428 if (aConfig.getMode()==ConfigAccess::E_CLOSED)
429 return;
431 css::uno::Reference< css::beans::XPropertySet > xPropSet(aConfig.cfg(), css::uno::UNO_QUERY);
432 if (xPropSet.is())
434 // Convert and write the user timestamp to the configuration.
435 css::uno::Any aValue;
436 aValue <<= Converter::convert_DateTime2ISO8601(DateTime( DateTime::SYSTEM));
437 xPropSet->setPropertyValue("UserTime", aValue);
440 aConfig.close();
445 bool isEnabled( const OUString& sAdminTime ,
446 const OUString& sUserTime )
448 /*Attention!
449 To prevent interpreting of TriGraphs inside next const string value,
450 we have to encode all '?' signs. Otherwhise e.g. "??-" will be translated
451 to "~" ...
453 static const char PATTERN_ISO8601[] = "\?\?\?\?-\?\?-\?\?*";
454 WildCard aISOPattern(PATTERN_ISO8601);
456 bool bValidAdmin = aISOPattern.Matches(sAdminTime);
457 bool bValidUser = aISOPattern.Matches(sUserTime );
459 // We check for "isEnabled()" here only.
460 // Note further: ISO8601 formatted strings can be compared as strings directly!
461 // FIXME: this is not true! "T1215" is the same time as "T12:15" or "T121500"
462 return (
463 (!bValidAdmin && !bValidUser ) ||
464 ( bValidAdmin && bValidUser && sAdminTime>=sUserTime)
470 void JobData::appendEnabledJobsForEvent( const css::uno::Reference< css::uno::XComponentContext >& rxContext,
471 const OUString& sEvent ,
472 ::std::vector< JobData::TJob2DocEventBinding >& lJobs )
474 css::uno::Sequence< OUString > lAdditionalJobs = JobData::getEnabledJobsForEvent(rxContext, sEvent);
475 sal_Int32 c = lAdditionalJobs.getLength();
476 sal_Int32 i = 0;
478 for (i=0; i<c; ++i)
480 JobData::TJob2DocEventBinding aBinding(lAdditionalJobs[i], sEvent);
481 lJobs.push_back(aBinding);
487 bool JobData::hasCorrectContext(const OUString& rModuleIdent) const
489 sal_Int32 nContextLen = m_sContext.getLength();
490 sal_Int32 nModuleIdLen = rModuleIdent.getLength();
492 if ( nContextLen == 0 )
493 return true;
495 if ( nModuleIdLen > 0 )
497 sal_Int32 nIndex = m_sContext.indexOf( rModuleIdent );
498 if ( nIndex >= 0 && ( nIndex+nModuleIdLen <= nContextLen ))
500 OUString sContextModule = m_sContext.copy( nIndex, nModuleIdLen );
501 return sContextModule.equals( rModuleIdent );
505 return false;
510 css::uno::Sequence< OUString > JobData::getEnabledJobsForEvent( const css::uno::Reference< css::uno::XComponentContext >& rxContext,
511 const OUString& sEvent )
513 // create a config access to "/org.openoffice.Office.Jobs/Events"
514 ConfigAccess aConfig(rxContext, "/org.openoffice.Office.Jobs/Events");
515 aConfig.open(ConfigAccess::E_READONLY);
516 if (aConfig.getMode()==ConfigAccess::E_CLOSED)
517 return css::uno::Sequence< OUString >();
519 css::uno::Reference< css::container::XHierarchicalNameAccess > xEventRegistry(aConfig.cfg(), css::uno::UNO_QUERY);
520 if (!xEventRegistry.is())
521 return css::uno::Sequence< OUString >();
523 // check if the given event exist inside list of registered ones
524 OUString sPath(sEvent + "/JobList");
525 if (!xEventRegistry->hasByHierarchicalName(sPath))
526 return css::uno::Sequence< OUString >();
528 // step to the job list, which is a child of the event node inside cfg
529 // e.g. "/org.openoffice.Office.Jobs/Events/<event name>/JobList"
530 css::uno::Any aJobList = xEventRegistry->getByHierarchicalName(sPath);
531 css::uno::Reference< css::container::XNameAccess > xJobList;
532 if (!(aJobList >>= xJobList) || !xJobList.is())
533 return css::uno::Sequence< OUString >();
535 // get all alias names of jobs, which are part of this job list
536 // But Some of them can be disabled by it's time stamp values.
537 // We create an additional job name list with the same size, then the original list ...
538 // step over all job entries ... check her time stamps ... and put only job names to the
539 // destination list, which represent an enabled job.
540 css::uno::Sequence< OUString > lAllJobs = xJobList->getElementNames();
541 OUString* pAllJobs = lAllJobs.getArray();
542 sal_Int32 c = lAllJobs.getLength();
544 css::uno::Sequence< OUString > lEnabledJobs(c);
545 OUString* pEnabledJobs = lEnabledJobs.getArray();
546 sal_Int32 d = 0;
548 for (sal_Int32 s=0; s<c; ++s)
550 css::uno::Reference< css::beans::XPropertySet > xJob;
551 if (
552 !(xJobList->getByName(pAllJobs[s]) >>= xJob) ||
553 !(xJob.is() )
556 continue;
559 OUString sAdminTime;
560 xJob->getPropertyValue("AdminTime") >>= sAdminTime;
562 OUString sUserTime;
563 xJob->getPropertyValue("UserTime") >>= sUserTime;
565 if (!isEnabled(sAdminTime, sUserTime))
566 continue;
568 pEnabledJobs[d] = pAllJobs[s];
569 ++d;
571 lEnabledJobs.realloc(d);
573 aConfig.close();
575 return lEnabledJobs;
579 @short reset all internal structures
580 @descr If someone recycles this instance, he can switch from one
581 using mode to another one. But then we have to reset all currently
582 used information. Otherwhise we mix it and they can make trouble.
584 But note: that does not set defaults for internal used members, which
585 does not relate to any job property! e.g. the reference to the global
586 uno service manager. Such information is used for internal processes only
587 and are necessary for our work.
589 void JobData::impl_reset()
591 SolarMutexGuard g;
592 m_eMode = E_UNKNOWN_MODE;
593 m_eEnvironment = E_UNKNOWN_ENVIRONMENT;
594 m_sAlias.clear();
595 m_sService.clear();
596 m_sContext.clear();
597 m_sEvent.clear();
598 m_lArguments = css::uno::Sequence< css::beans::NamedValue >();
601 } // namespace framework
603 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */