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