xref: /aoo42x/main/framework/source/jobs/jobdata.cxx (revision 30acf5e8)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_framework.hxx"
26 
27 //________________________________
28 //	my own includes
29 #include <jobs/jobdata.hxx>
30 #include <threadhelp/readguard.hxx>
31 #include <threadhelp/writeguard.hxx>
32 #include <classes/converter.hxx>
33 #include <general.h>
34 #include <services.h>
35 
36 //________________________________
37 //	interface includes
38 #include <com/sun/star/beans/XPropertySet.hpp>
39 #include <com/sun/star/beans/XMultiHierarchicalPropertySet.hpp>
40 #include <com/sun/star/container/XNameAccess.hpp>
41 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
42 
43 //________________________________
44 //	includes of other projects
45 #include <tools/wldcrd.hxx>
46 #include <unotools/configpathes.hxx>
47 #include <rtl/ustrbuf.hxx>
48 #include <vcl/svapp.hxx>
49 
50 //________________________________
51 //	namespace
52 
53 namespace framework{
54 
55 //________________________________
56 //  exported const
57 
58 const sal_Char* JobData::JOBCFG_ROOT              = "/org.openoffice.Office.Jobs/Jobs/"   ;
59 const sal_Char* JobData::JOBCFG_PROP_SERVICE      = "Service"                             ;
60 const sal_Char* JobData::JOBCFG_PROP_CONTEXT      = "Context"                             ;
61 const sal_Char* JobData::JOBCFG_PROP_ARGUMENTS    = "Arguments"                           ;
62 
63 const sal_Char* JobData::EVENTCFG_ROOT            = "/org.openoffice.Office.Jobs/Events/" ;
64 const sal_Char* JobData::EVENTCFG_PATH_JOBLIST    = "/JobList"                            ;
65 const sal_Char* JobData::EVENTCFG_PROP_ADMINTIME  = "AdminTime"                           ;
66 const sal_Char* JobData::EVENTCFG_PROP_USERTIME   = "UserTime"                            ;
67 
68 const sal_Char* JobData::PROPSET_CONFIG           = "Config"                              ;
69 const sal_Char* JobData::PROPSET_OWNCONFIG        = "JobConfig"                           ;
70 const sal_Char* JobData::PROPSET_ENVIRONMENT      = "Environment"                         ;
71 const sal_Char* JobData::PROPSET_DYNAMICDATA      = "DynamicData"                         ;
72 
73 const sal_Char* JobData::PROP_ALIAS               = "Alias"                               ;
74 const sal_Char* JobData::PROP_EVENTNAME           = "EventName"                           ;
75 const sal_Char* JobData::PROP_ENVTYPE             = "EnvType"                             ;
76 const sal_Char* JobData::PROP_FRAME               = "Frame"                               ;
77 const sal_Char* JobData::PROP_MODEL               = "Model"                               ;
78 const sal_Char* JobData::PROP_SERVICE             = "Service"                             ;
79 const sal_Char* JobData::PROP_CONTEXT             = "Context"                             ;
80 
81 //________________________________
82 //	non exported definitions
83 
84 //________________________________
85 //	declarations
86 
87 //________________________________
88 /**
89     @short      standard ctor
90     @descr      It initialize this new instance.
91                 But for real working it's necessary to call setAlias() or setService() later.
92                 Because we need the job data ...
93 
94     @param      xSMGR
95                     reference to the uno service manager
96 */
97 JobData::JobData( const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR )
98     : ThreadHelpBase(&Application::GetSolarMutex())
99     , m_xSMGR       (xSMGR                        )
100 {
101     // share code for member initialization with defaults!
102     impl_reset();
103 }
104 
105 //________________________________
106 /**
107     @short  copy ctor
108     @descr  Sometimes such job data container must be moved from one using place
109             to another one. Then a copy ctor and copy operator must be available.
110 
111     @param  rCopy
112                 the original instance, from which we must copy all data
113 */
114 JobData::JobData( const JobData& rCopy )
115     : ThreadHelpBase(&Application::GetSolarMutex())
116 {
117     // use the copy operator to share the same code
118     *this = rCopy;
119 }
120 
121 //________________________________
122 /**
123     @short  operator for coping JobData instances
124     @descr  Sometimes such job data container must be moved from one using place
125             to another one. Then a copy ctor and copy operator must be available.
126 
127     @param  rCopy
128                 the original instance, from which we must copy all data
129 */
130 void JobData::operator=( const JobData& rCopy )
131 {
132     /* SAFE { */
133     WriteGuard aWriteLock(m_aLock);
134     // Please don't copy the uno service manager reference.
135     // That can change the uno context, which isn't a good idea!
136     m_eMode                = rCopy.m_eMode               ;
137     m_eEnvironment         = rCopy.m_eEnvironment        ;
138     m_sAlias               = rCopy.m_sAlias              ;
139     m_sService             = rCopy.m_sService            ;
140     m_sContext             = rCopy.m_sContext            ;
141     m_sEvent               = rCopy.m_sEvent              ;
142     m_lArguments           = rCopy.m_lArguments          ;
143     m_aLastExecutionResult = rCopy.m_aLastExecutionResult;
144     aWriteLock.unlock();
145     /* } SAFE */
146 }
147 
148 //________________________________
149 /**
150     @short  let this instance die
151     @descr  There is no chance any longer to work. We have to
152             release all used ressources and free used memory.
153 */
154 JobData::~JobData()
155 {
156     impl_reset();
157 }
158 
159 //________________________________
160 /**
161     @short      initialize this instance as a job with configuration
162     @descr      They given alias can be used to address some configuraton data.
163                 We read it and fill our internal structures. Of course old informations
164                 will be lost doing so.
165 
166     @param      sAlias
167                     the alias name of this job, used to locate job properties inside cfg
168 */
169 void JobData::setAlias( const ::rtl::OUString& sAlias )
170 {
171     /* SAFE { */
172     WriteGuard aWriteLock(m_aLock);
173     // delete all old informations! Otherwhise we mix it with the new one ...
174     impl_reset();
175 
176     // take over the new informations
177     m_sAlias   = sAlias;
178     m_eMode    = E_ALIAS;
179 
180     // try to open the configuration set of this job directly and get a property access to it
181     // We open it readonly here
182     ::rtl::OUString sKey;
183     sKey  = ::rtl::OUString::createFromAscii(JOBCFG_ROOT);
184     sKey += ::utl::wrapConfigurationElementName(m_sAlias);
185 
186     ConfigAccess aConfig(m_xSMGR, sKey);
187     aConfig.open(ConfigAccess::E_READONLY);
188     if (aConfig.getMode()==ConfigAccess::E_CLOSED)
189     {
190         impl_reset();
191         return;
192     }
193 
194     css::uno::Reference< css::beans::XPropertySet > xJobProperties(aConfig.cfg(), css::uno::UNO_QUERY);
195     if (xJobProperties.is())
196     {
197         css::uno::Any aValue;
198 
199         // read uno implementation name
200         aValue   = xJobProperties->getPropertyValue(::rtl::OUString::createFromAscii(JOBCFG_PROP_SERVICE));
201         aValue >>= m_sService;
202 
203         // read module context list
204         aValue   = xJobProperties->getPropertyValue(::rtl::OUString::createFromAscii(JOBCFG_PROP_CONTEXT));
205         aValue >>= m_sContext;
206 
207         // read whole argument list
208         aValue = xJobProperties->getPropertyValue(::rtl::OUString::createFromAscii(JOBCFG_PROP_ARGUMENTS));
209         css::uno::Reference< css::container::XNameAccess > xArgumentList;
210         if (
211             (aValue >>= xArgumentList)  &&
212             (xArgumentList.is()      )
213            )
214         {
215             css::uno::Sequence< ::rtl::OUString > lArgumentNames = xArgumentList->getElementNames();
216             sal_Int32                             nCount         = lArgumentNames.getLength();
217             m_lArguments.realloc(nCount);
218             for (sal_Int32 i=0; i<nCount; ++i)
219             {
220                 m_lArguments[i].Name  = lArgumentNames[i];
221                 m_lArguments[i].Value = xArgumentList->getByName(m_lArguments[i].Name);
222             }
223         }
224     }
225 
226     aConfig.close();
227     aWriteLock.unlock();
228     /* } SAFE */
229 }
230 
231 //________________________________
232 /**
233     @short      initialize this instance as a job without configuration
234     @descr      This job has no configuration data. We have to forget all old informations
235                 and set only some of them new, so this instance can work.
236 
237     @param      sService
238                     the uno service name of this "non configured" job
239 */
240 void JobData::setService( const ::rtl::OUString& sService )
241 {
242     /* SAFE { */
243     WriteGuard aWriteLock(m_aLock);
244 
245     // delete all old informations! Otherwhise we mix it with the new one ...
246     impl_reset();
247     // take over the new informations
248     m_sService = sService;
249     m_eMode    = E_SERVICE;
250 
251     aWriteLock.unlock();
252     /* } SAFE */
253 }
254 
255 //________________________________
256 /**
257     @short      initialize this instance with new job values.
258     @descr      It reads automatically all properties of the specified
259                 job (using it's alias name) and "register it" for the
260                 given event. This registration will not be validated against
261                 the underlying configuration! (That must be done from outside.
262                 Because the caller must have the configuration already open to
263                 get the values for sEvent and sAlias! And doing so it can perform
264                 only, if the time stanp values are readed outside too.
265                 Further it make no sense to initialize and start a disabled job.
266                 So this initialization method will be called for enabled jobs only.)
267 
268     @param      sEvent
269                     the triggered event, for which this job should be started
270 
271     @param      sAlias
272                     mark the required job inside event registration list
273 */
274 void JobData::setEvent( const ::rtl::OUString& sEvent ,
275                         const ::rtl::OUString& sAlias )
276 {
277     // share code to read all job properties!
278     setAlias(sAlias);
279 
280     /* SAFE { */
281     WriteGuard aWriteLock(m_aLock);
282 
283     // take over the new informations - which differ against set on of method setAlias()!
284     m_sEvent = sEvent;
285     m_eMode  = E_EVENT;
286 
287     aWriteLock.unlock();
288     /* } SAFE */
289 }
290 
291 //________________________________
292 /**
293     @short      set the new job specific arguments
294     @descr      If a job finish his work, it can give us a new list of arguments (which
295                 will not interpreted by us). We write it back to the configuration only
296                 (if this job has it's own configuration!).
297                 So a job can have persistent data without implementing anything
298                 or define own config areas for that.
299 
300     @param      lArguments
301                     list of arguments, which should be set for this job
302  */
303 void JobData::setJobConfig( const css::uno::Sequence< css::beans::NamedValue >& lArguments )
304 {
305     /* SAFE { */
306     WriteGuard aWriteLock(m_aLock);
307 
308     // update member
309     m_lArguments = lArguments;
310 
311     // update the configuration ... if possible!
312     if (m_eMode==E_ALIAS)
313     {
314         // It doesn't matter if this config object was already opened before.
315         // It doesn nothing here then ... or it change the mode automatically, if
316         // it was opened using another one before.
317         ::rtl::OUString sKey;
318         sKey  = ::rtl::OUString::createFromAscii(JOBCFG_ROOT);
319         sKey += ::utl::wrapConfigurationElementName(m_sAlias);
320 
321         ConfigAccess aConfig(m_xSMGR, sKey);
322         aConfig.open(ConfigAccess::E_READWRITE);
323         if (aConfig.getMode()==ConfigAccess::E_CLOSED)
324             return;
325 
326         css::uno::Reference< css::beans::XMultiHierarchicalPropertySet > xArgumentList(aConfig.cfg(), css::uno::UNO_QUERY);
327         if (xArgumentList.is())
328         {
329             sal_Int32                             nCount = m_lArguments.getLength();
330             css::uno::Sequence< ::rtl::OUString > lNames (nCount);
331             css::uno::Sequence< css::uno::Any >   lValues(nCount);
332 
333             for (sal_Int32 i=0; i<nCount; ++i)
334             {
335                 lNames [i] = m_lArguments[i].Name ;
336                 lValues[i] = m_lArguments[i].Value;
337             }
338 
339             xArgumentList->setHierarchicalPropertyValues(lNames, lValues);
340         }
341         aConfig.close();
342     }
343 
344     aWriteLock.unlock();
345     /* } SAFE */
346 }
347 
348 //________________________________
349 /**
350     @short      set a new excution result
351     @descr      Every executed job can have returned a result.
352                 We set it here, so our user can use it may be later.
353                 But the outside code can use it too, to analyze it and
354                 adopt the configuration of this job too. Because the
355                 result uses a protocol, which allow that. And we provide
356                 right functionality to save it.
357 
358     @param      aResult
359                     the result of last execution
360  */
361 void JobData::setResult( const JobResult& aResult )
362 {
363     /* SAFE { */
364     WriteGuard aWriteLock(m_aLock);
365 
366     // overwrite the last saved result
367     m_aLastExecutionResult = aResult;
368 
369     // Don't use his informations to update
370     // e.g. the arguments of this job. It must be done
371     // from outside! Here we save this information only.
372 
373     aWriteLock.unlock();
374     /* } SAFE */
375 }
376 
377 //________________________________
378 /**
379     @short  set a new environment descriptor for this job
380     @descr  It must(!) be done every time this container is initialized
381             with new job datas e.g.: setAlias()/setEvent()/setService() ...
382             Otherwhise the environment will be unknown!
383  */
384 void JobData::setEnvironment( EEnvironment eEnvironment )
385 {
386     /* SAFE { */
387     WriteGuard aWriteLock(m_aLock);
388     m_eEnvironment = eEnvironment;
389     aWriteLock.unlock();
390     /* } SAFE */
391 }
392 
393 //________________________________
394 /**
395     @short      these functions provides access to our internal members
396     @descr      These member represent any information about the job
397                 and can be used from outside to e.g. start a job.
398  */
399 JobData::EMode JobData::getMode() const
400 {
401     /* SAFE { */
402     ReadGuard aReadLock(m_aLock);
403     return m_eMode;
404     /* } SAFE */
405 }
406 
407 //________________________________
408 
409 JobData::EEnvironment JobData::getEnvironment() const
410 {
411     /* SAFE { */
412     ReadGuard aReadLock(m_aLock);
413     return m_eEnvironment;
414     /* } SAFE */
415 }
416 
417 //________________________________
418 
419 ::rtl::OUString JobData::getEnvironmentDescriptor() const
420 {
421     ::rtl::OUString sDescriptor;
422     /* SAFE { */
423     ReadGuard aReadLock(m_aLock);
424     switch(m_eEnvironment)
425     {
426         case E_EXECUTION :
427             sDescriptor = ::rtl::OUString::createFromAscii("EXECUTOR");
428             break;
429 
430         case E_DISPATCH :
431             sDescriptor = ::rtl::OUString::createFromAscii("DISPATCH");
432             break;
433 
434         case E_DOCUMENTEVENT :
435             sDescriptor = ::rtl::OUString::createFromAscii("DOCUMENTEVENT");
436             break;
437         default:
438             break;
439     }
440     /* } SAFE */
441     return sDescriptor;
442 }
443 
444 //________________________________
445 
446 ::rtl::OUString JobData::getService() const
447 {
448     /* SAFE { */
449     ReadGuard aReadLock(m_aLock);
450     return m_sService;
451     /* } SAFE */
452 }
453 
454 //________________________________
455 
456 ::rtl::OUString JobData::getEvent() const
457 {
458     /* SAFE { */
459     ReadGuard aReadLock(m_aLock);
460     return m_sEvent;
461     /* } SAFE */
462 }
463 
464 //________________________________
465 
466 css::uno::Sequence< css::beans::NamedValue > JobData::getJobConfig() const
467 {
468     /* SAFE { */
469     ReadGuard aReadLock(m_aLock);
470     return m_lArguments;
471     /* } SAFE */
472 }
473 
474 //________________________________
475 
476 css::uno::Sequence< css::beans::NamedValue > JobData::getConfig() const
477 {
478     /* SAFE { */
479     ReadGuard aReadLock(m_aLock);
480     css::uno::Sequence< css::beans::NamedValue > lConfig;
481     if (m_eMode==E_ALIAS)
482     {
483         lConfig.realloc(3);
484         sal_Int32 i = 0;
485 
486         lConfig[i].Name = ::rtl::OUString::createFromAscii(PROP_ALIAS);
487         lConfig[i].Value <<= m_sAlias;
488         ++i;
489 
490         lConfig[i].Name = ::rtl::OUString::createFromAscii(PROP_SERVICE);
491         lConfig[i].Value <<= m_sService;
492         ++i;
493 
494         lConfig[i].Name = ::rtl::OUString::createFromAscii(PROP_CONTEXT);
495         lConfig[i].Value <<= m_sContext;
496         ++i;
497     }
498     aReadLock.unlock();
499     /* } SAFE */
500     return lConfig;
501 }
502 
503 //________________________________
504 /**
505     @short  return information, if this job is part of the global configuration package
506             org.openoffice.Office.Jobs
507     @descr  Because jobs can be executed by the dispatch framework using an uno service name
508             directly - an executed job must not have any configuration really. Such jobs
509             must provide the right interfaces only! But after finishing jobs can return
510             some informations (e.g. for updating her configuration ...). We must know
511             if such request is valid or not then.
512 
513     @return sal_True if the represented job is part of the underlying configuration package.
514  */
515 sal_Bool JobData::hasConfig() const
516 {
517     /* SAFE { */
518     ReadGuard aReadLock(m_aLock);
519     return (m_eMode==E_ALIAS || m_eMode==E_EVENT);
520     /* } SAFE */
521 }
522 
523 //________________________________
524 /**
525     @short      mark a job as non startable for further requests
526     @descr      We don't remove the configuration entry! We set a timestamp value only.
527                 And there exist two of them: one for an administrator ... and one for the
528                 current user. We change it for the user layer only. So this JobDispatch can't be
529                 started any more ... till the administrator change his timestamp.
530                 That can be useful for post setup scenarios, which must run one time only.
531 
532                 Note: This method don't do anything, if this represented job doesn't have a configuration!
533  */
534 void JobData::disableJob()
535 {
536     /* SAFE { */
537     WriteGuard aWriteLock(m_aLock);
538 
539     // No configuration - not used from EXECUTOR and not triggered from an event => no chance!
540     if (m_eMode!=E_EVENT)
541         return;
542 
543     // update the configuration
544     // It doesn't matter if this config object was already opened before.
545     // It doesn nothing here then ... or it change the mode automatically, if
546     // it was opened using another one before.
547     ::rtl::OUStringBuffer sKey(256);
548     sKey.appendAscii(JobData::EVENTCFG_ROOT                       );
549     sKey.append     (::utl::wrapConfigurationElementName(m_sEvent));
550     sKey.appendAscii(JobData::EVENTCFG_PATH_JOBLIST               );
551     sKey.appendAscii("/"                                          );
552     sKey.append     (::utl::wrapConfigurationElementName(m_sAlias));
553 
554     ConfigAccess aConfig(m_xSMGR, sKey.makeStringAndClear());
555     aConfig.open(ConfigAccess::E_READWRITE);
556     if (aConfig.getMode()==ConfigAccess::E_CLOSED)
557         return;
558 
559     css::uno::Reference< css::beans::XPropertySet > xPropSet(aConfig.cfg(), css::uno::UNO_QUERY);
560     if (xPropSet.is())
561     {
562         // Convert and write the user timestamp to the configuration.
563         css::uno::Any aValue;
564         aValue <<= Converter::convert_DateTime2ISO8601(DateTime());
565         xPropSet->setPropertyValue(::rtl::OUString::createFromAscii(EVENTCFG_PROP_USERTIME), aValue);
566     }
567 
568     aConfig.close();
569 
570     aWriteLock.unlock();
571     /* } SAFE */
572 }
573 
574 //________________________________
575 /**
576  */
577 sal_Bool isEnabled( const ::rtl::OUString& sAdminTime ,
578                     const ::rtl::OUString& sUserTime  )
579 {
580     /*Attention!
581         To prevent interpreting of TriGraphs inside next const string value,
582         we have to encode all '?' signs. Otherwhise e.g. "??-" will be translated
583         to "~" ...
584      */
585     static ::rtl::OUString PATTERN_ISO8601 = ::rtl::OUString::createFromAscii("\?\?\?\?-\?\?-\?\?*\0");
586     WildCard aISOPattern(PATTERN_ISO8601);
587 
588     sal_Bool bValidAdmin = aISOPattern.Matches(sAdminTime);
589     sal_Bool bValidUser  = aISOPattern.Matches(sUserTime );
590 
591     // We check for "isEnabled()" here only.
592     // Note further: ISO8601 formatted strings can be compared as strings directly!
593     return (
594             (!bValidAdmin && !bValidUser                         ) ||
595             ( bValidAdmin &&  bValidUser && sAdminTime>=sUserTime)
596            );
597 }
598 
599 //________________________________
600 /**
601  */
602 void JobData::appendEnabledJobsForEvent( const css::uno::Reference< css::lang::XMultiServiceFactory >&          xSMGR  ,
603                                          const ::rtl::OUString&                                                 sEvent ,
604                                                ::comphelper::SequenceAsVector< JobData::TJob2DocEventBinding >& lJobs  )
605 {
606     css::uno::Sequence< ::rtl::OUString > lAdditionalJobs = JobData::getEnabledJobsForEvent(xSMGR, sEvent);
607     sal_Int32                             c               = lAdditionalJobs.getLength();
608     sal_Int32                             i               = 0;
609 
610     for (i=0; i<c; ++i)
611     {
612         JobData::TJob2DocEventBinding aBinding(lAdditionalJobs[i], sEvent);
613         lJobs.push_back(aBinding);
614     }
615 }
616 
617 //________________________________
618 /**
619  */
620 sal_Bool JobData::hasCorrectContext(const ::rtl::OUString& rModuleIdent) const
621 {
622     sal_Int32 nContextLen  = m_sContext.getLength();
623     sal_Int32 nModuleIdLen = rModuleIdent.getLength();
624 
625     if ( nContextLen == 0 )
626         return sal_True;
627 
628     if ( nModuleIdLen > 0 )
629     {
630         sal_Int32 nIndex = m_sContext.indexOf( rModuleIdent );
631         if ( nIndex >= 0 && ( nIndex+nModuleIdLen <= nContextLen ))
632 	{
633 	    ::rtl::OUString sContextModule = m_sContext.copy( nIndex, nModuleIdLen );
634 	    return sContextModule.equals( rModuleIdent );
635 	}
636     }
637 
638     return sal_False;
639 }
640 
641 //________________________________
642 /**
643  */
644 css::uno::Sequence< ::rtl::OUString > JobData::getEnabledJobsForEvent( const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR  ,
645                                                                        const ::rtl::OUString&                                        sEvent )
646 {
647     // these static values may perform following loop for reading time stamp values ...
648     static ::rtl::OUString ADMINTIME = ::rtl::OUString::createFromAscii(JobData::EVENTCFG_PROP_ADMINTIME);
649     static ::rtl::OUString USERTIME  = ::rtl::OUString::createFromAscii(JobData::EVENTCFG_PROP_USERTIME );
650     static ::rtl::OUString ROOT      = ::rtl::OUString::createFromAscii(JobData::EVENTCFG_ROOT          );
651     static ::rtl::OUString JOBLIST   = ::rtl::OUString::createFromAscii(JobData::EVENTCFG_PATH_JOBLIST  );
652 
653     // create a config access to "/org.openoffice.Office.Jobs/Events"
654     ConfigAccess aConfig(xSMGR,ROOT);
655     aConfig.open(ConfigAccess::E_READONLY);
656     if (aConfig.getMode()==ConfigAccess::E_CLOSED)
657         return css::uno::Sequence< ::rtl::OUString >();
658 
659     css::uno::Reference< css::container::XHierarchicalNameAccess > xEventRegistry(aConfig.cfg(), css::uno::UNO_QUERY);
660     if (!xEventRegistry.is())
661         return css::uno::Sequence< ::rtl::OUString >();
662 
663     // check if the given event exist inside list of registered ones
664     ::rtl::OUString sPath(sEvent);
665     sPath += JOBLIST;
666     if (!xEventRegistry->hasByHierarchicalName(sPath))
667         return css::uno::Sequence< ::rtl::OUString >();
668 
669     // step to the job list, which is a child of the event node inside cfg
670     // e.g. "/org.openoffice.Office.Jobs/Events/<event name>/JobList"
671     css::uno::Any aJobList = xEventRegistry->getByHierarchicalName(sPath);
672     css::uno::Reference< css::container::XNameAccess > xJobList;
673     if (!(aJobList >>= xJobList) || !xJobList.is())
674         return css::uno::Sequence< ::rtl::OUString >();
675 
676     // get all alias names of jobs, which are part of this job list
677     // But Some of them can be disabled by it's time stamp values.
678     // We create an additional job name list with the same size, then the original list ...
679     // step over all job entries ... check her time stamps ... and put only job names to the
680     // destination list, which represent an enabled job.
681     css::uno::Sequence< ::rtl::OUString > lAllJobs = xJobList->getElementNames();
682     ::rtl::OUString* pAllJobs = lAllJobs.getArray();
683     sal_Int32 c = lAllJobs.getLength();
684 
685     css::uno::Sequence< ::rtl::OUString > lEnabledJobs(c);
686     ::rtl::OUString* pEnabledJobs = lEnabledJobs.getArray();
687     sal_Int32 d = 0;
688 
689     for (sal_Int32 s=0; s<c; ++s)
690     {
691         css::uno::Reference< css::beans::XPropertySet > xJob;
692         if (
693             !(xJobList->getByName(pAllJobs[s]) >>= xJob) ||
694             !(xJob.is()     )
695            )
696         {
697            continue;
698         }
699 
700         ::rtl::OUString sAdminTime;
701         xJob->getPropertyValue(ADMINTIME) >>= sAdminTime;
702 
703         ::rtl::OUString sUserTime;
704         xJob->getPropertyValue(USERTIME) >>= sUserTime;
705 
706         if (!isEnabled(sAdminTime, sUserTime))
707             continue;
708 
709         pEnabledJobs[d] = pAllJobs[s];
710         ++d;
711     }
712     lEnabledJobs.realloc(d);
713 
714     aConfig.close();
715 
716     return lEnabledJobs;
717 }
718 
719 //________________________________
720 /**
721     @short      reset all internal structures
722     @descr      If somehwere recycle this instance, he can switch from one
723                 using mode to another one. But then we have to reset all currently
724                 used informations. Otherwhise we mix it and they can make trouble.
725 
726                 But note: that does not set defaults for internal used members, which
727                 does not relate to any job property! e.g. the reference to the global
728                 uno service manager. Such informations are used for internal processes only
729                 and are necessary for our work.
730  */
731 void JobData::impl_reset()
732 {
733     /* SAFE { */
734     WriteGuard aWriteLock(m_aLock);
735     m_eMode        = E_UNKNOWN_MODE;
736     m_eEnvironment = E_UNKNOWN_ENVIRONMENT;
737     m_sAlias       = ::rtl::OUString();
738     m_sService     = ::rtl::OUString();
739     m_sContext     = ::rtl::OUString();
740     m_sEvent       = ::rtl::OUString();
741     m_lArguments   = css::uno::Sequence< css::beans::NamedValue >();
742     aWriteLock.unlock();
743     /* } SAFE */
744 }
745 
746 } // namespace framework
747