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