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