Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <sal/config.h>
21 :
22 : #include <cstring>
23 :
24 : #include <jobs/joburl.hxx>
25 : #include <general.h>
26 :
27 : #include <rtl/ustrbuf.hxx>
28 : #include <vcl/svapp.hxx>
29 :
30 : namespace framework{
31 :
32 : /**
33 : @short special ctor
34 : @descr It initialize this new instance with a (hopyfully) valid job URL.
35 : This URL will be parsed. After that we set our members right,
36 : so other interface methods of this class can be used to get
37 : all items of this URL. Of course it will be possible to know,
38 : if this URL was valid too.
39 :
40 : @param sURL
41 : the job URL for parsing
42 : */
43 0 : JobURL::JobURL( /*IN*/ const OUString& sURL )
44 : {
45 : #ifdef ENABLE_COMPONENT_SELF_CHECK
46 : JobURL::impldbg_checkIt();
47 : #endif
48 :
49 0 : m_eRequest = E_UNKNOWN;
50 :
51 : // syntax: vnd.sun.star.job:{[event=<name>],[alias=<name>],[service=<name>]}
52 :
53 : // check for "vnd.sun.star.job:"
54 0 : if (sURL.startsWithIgnoreAsciiCase("vnd.sun.star.job:"))
55 : {
56 0 : sal_Int32 t = std::strlen("vnd.sun.star.job:");
57 0 : do
58 : {
59 : // separate all token of "{[event=<name>],[alias=<name>],[service=<name>]}"
60 0 : OUString sToken = sURL.getToken(0, JOBURL_PART_SEPARATOR, t);
61 0 : OUString sPartValue;
62 0 : OUString sPartArguments;
63 :
64 : // check for "event="
65 0 : if (
66 0 : (JobURL::implst_split(sToken,JOBURL_EVENT_STR,JOBURL_EVENT_LEN,sPartValue,sPartArguments)) &&
67 0 : (!sPartValue.isEmpty())
68 : )
69 : {
70 : // set the part value
71 0 : m_sEvent = sPartValue;
72 0 : m_sEventArgs = sPartArguments;
73 0 : m_eRequest |= E_EVENT;
74 : }
75 : else
76 : // check for "alias="
77 0 : if (
78 0 : (JobURL::implst_split(sToken,JOBURL_ALIAS_STR,JOBURL_ALIAS_LEN,sPartValue,sPartArguments)) &&
79 0 : (!sPartValue.isEmpty())
80 : )
81 : {
82 : // set the part value
83 0 : m_sAlias = sPartValue;
84 0 : m_sAliasArgs = sPartArguments;
85 0 : m_eRequest |= E_ALIAS;
86 : }
87 : else
88 : // check for "service="
89 0 : if (
90 0 : (JobURL::implst_split(sToken,JOBURL_SERVICE_STR,JOBURL_SERVICE_LEN,sPartValue,sPartArguments)) &&
91 0 : (!sPartValue.isEmpty())
92 : )
93 : {
94 : // set the part value
95 0 : m_sService = sPartValue;
96 0 : m_sServiceArgs = sPartArguments;
97 0 : m_eRequest |= E_SERVICE;
98 0 : }
99 : }
100 0 : while(t!=-1);
101 : }
102 0 : }
103 :
104 : /**
105 : @short knows, if this job URL object hold a valid URL inside
106 :
107 : @return <TRUE/> if it represent a valid job URL.
108 : */
109 0 : bool JobURL::isValid() const
110 : {
111 0 : SolarMutexGuard g;
112 0 : return (m_eRequest!=E_UNKNOWN);
113 : }
114 :
115 : /**
116 : @short get the event item of this job URL
117 : @descr Because the three possible parts of such URL (event, alias, service)
118 : can't be combined, this method can(!) return a valid value - but it's
119 : not a must. Thats why the return value must be used too, to detect a missing
120 : event value.
121 :
122 : @param sEvent
123 : returns the possible existing event value
124 : e.g. "vnd.sun.star.job:event=myEvent" returns "myEvent"
125 :
126 : @return <TRUE/> if an event part of the job URL exist and the out parameter
127 : sEvent was filled.
128 :
129 : @attention The out parameter will be reseted every time. Don't use it if method returns <FALSE/>!
130 : */
131 0 : bool JobURL::getEvent( /*OUT*/ OUString& sEvent ) const
132 : {
133 0 : SolarMutexGuard g;
134 :
135 0 : sEvent.clear();
136 0 : bool bSet = ((m_eRequest & E_EVENT) == E_EVENT);
137 0 : if (bSet)
138 0 : sEvent = m_sEvent;
139 :
140 0 : return bSet;
141 : }
142 :
143 : /**
144 : @short get the alias item of this job URL
145 : @descr Because the three possible parts of such URL (event, alias, service)
146 : can't be combined, this method can(!) return a valid value - but it's
147 : not a must. Thats why the return value must be used too, to detect a missing
148 : alias value.
149 :
150 : @param sAlias
151 : returns the possible existing alias value
152 : e.g. "vnd.sun.star.job:alias=myAlias" returns "myAlias"
153 :
154 : @return <TRUE/> if an alias part of the job URL exist and the out parameter
155 : sAlias was filled.
156 :
157 : @attention The out parameter will be reseted every time. Don't use it if method returns <FALSE/>!
158 : */
159 0 : bool JobURL::getAlias( /*OUT*/ OUString& sAlias ) const
160 : {
161 0 : SolarMutexGuard g;
162 :
163 0 : sAlias.clear();
164 0 : bool bSet = ((m_eRequest & E_ALIAS) == E_ALIAS);
165 0 : if (bSet)
166 0 : sAlias = m_sAlias;
167 :
168 0 : return bSet;
169 : }
170 :
171 : /**
172 : @short get the service item of this job URL
173 : @descr Because the three possible parts of such URL (event, service, service)
174 : can't be combined, this method can(!) return a valid value - but it's
175 : not a must. Thats why the return value must be used too, to detect a missing
176 : service value.
177 :
178 : @param sAlias
179 : returns the possible existing service value
180 : e.g. "vnd.sun.star.job:service=com.sun.star.Service" returns "com.sun.star.Service"
181 :
182 : @return <TRUE/> if an service part of the job URL exist and the out parameter
183 : sService was filled.
184 :
185 : @attention The out parameter will be reseted every time. Don't use it if method returns <FALSE/>!
186 : */
187 0 : bool JobURL::getService( /*OUT*/ OUString& sService ) const
188 : {
189 0 : SolarMutexGuard g;
190 :
191 0 : sService.clear();
192 0 : bool bSet = ((m_eRequest & E_SERVICE) == E_SERVICE);
193 0 : if (bSet)
194 0 : sService = m_sService;
195 :
196 0 : return bSet;
197 : }
198 :
199 : /**
200 : @short searches for a special identifier in the given string and split it
201 : @descr If the given identifier could be found at the beginning of the given string,
202 : this method split it into different parts and return it.
203 : Following schema is used: <partidentifier>=<partvalue>[?<partarguments>]
204 :
205 : @param sPart
206 : the string, which should be analyzed
207 :
208 : @param pPartIdentifier
209 : the part identifier value, which must be found at the beginning of the
210 : parameter <var>sPart</var>
211 :
212 : @param nPartLength
213 : the length of the ascii value <var>pPartIdentifier</var>
214 :
215 : @param rPartValue
216 : returns the part value if <var>sPart</var> was splitted successfully
217 :
218 : @param rPartArguments
219 : returns the part arguments if <var>sPart</var> was splitted successfully
220 :
221 : @return <TRUE/> if the identifier could be found and the string was splitted.
222 : <FALSE/> otherwise.
223 : */
224 0 : bool JobURL::implst_split( /*IN*/ const OUString& sPart ,
225 : /*IN*/ const sal_Char* pPartIdentifier ,
226 : /*IN*/ sal_Int32 nPartLength ,
227 : /*OUT*/ OUString& rPartValue ,
228 : /*OUT*/ OUString& rPartArguments )
229 : {
230 : // first search for the given identifier
231 0 : bool bPartFound = (sPart.matchIgnoreAsciiCaseAsciiL(pPartIdentifier,nPartLength,0));
232 :
233 : // If it exist - we can split the part and return sal_True.
234 : // Otherwhise we do nothing and return sal_False.
235 0 : if (bPartFound)
236 : {
237 : // But may the part has optional arguments - separated by a "?".
238 : // Do so - we set the return value with the whole part string.
239 : // Arguments will be set to an empty string as default.
240 : // If we detect the right sign - we split the arguments and overwrite the default.
241 0 : OUString sValueAndArguments = sPart.copy(nPartLength);
242 0 : OUString sValue = sValueAndArguments;
243 0 : OUString sArguments;
244 :
245 0 : sal_Int32 nArgStart = sValueAndArguments.indexOf('?',0);
246 0 : if (nArgStart!=-1)
247 : {
248 0 : sValue = sValueAndArguments.copy(0,nArgStart);
249 0 : ++nArgStart; // ignore '?'!
250 0 : sArguments = sValueAndArguments.copy(nArgStart);
251 : }
252 :
253 0 : rPartValue = sValue;
254 0 : rPartArguments = sArguments;
255 : }
256 :
257 0 : return bPartFound;
258 : }
259 :
260 : /**
261 : @short special debug method
262 : @descr It's the entry point method to start a self component check for this class.
263 : It's used for internal purposes only and never a part of a legal product.
264 : Use it for testing and debug only!
265 : */
266 : #ifdef ENABLE_COMPONENT_SELF_CHECK
267 :
268 :
269 : void JobURL::impldbg_checkIt()
270 : {
271 : // check simple URL's
272 : JobURL::impldbg_checkURL("vnd.sun.star.job:event=onMyEvent" , E_EVENT , "onMyEvent", "" , "" , NULL, NULL, NULL);
273 : JobURL::impldbg_checkURL("vnd.sun.star.job:alias=myAlias" , E_ALIAS , "" , "myAlias", "" , NULL, NULL, NULL);
274 : JobURL::impldbg_checkURL("vnd.sun.star.job:service=css.Service", E_SERVICE, "" , "" , "css.Service", NULL, NULL, NULL);
275 : JobURL::impldbg_checkURL("vnd.sun.star.job:service=;" , E_UNKNOWN, "" , "" , "" , NULL, NULL, NULL);
276 :
277 : // check combinations
278 : // Note: No additional spaces or tabs are allowed after a separator occurred.
279 : // Tab and spaces before a separator will be used as value!
280 : JobURL::impldbg_checkURL("vnd.sun.star.job:event=onMyEvent;alias=myAlias;service=css.Service" , E_EVENT | E_ALIAS | E_SERVICE , "onMyEvent", "myAlias", "css.Service" , NULL, NULL, NULL);
281 : JobURL::impldbg_checkURL("vnd.sun.star.job:service=css.Service;alias=myAlias" , E_ALIAS | E_SERVICE , "" , "myAlias", "css.Service" , NULL, NULL, NULL);
282 : JobURL::impldbg_checkURL("vnd.sun.star.job:service=css.Service;alias=myAlias" , E_ALIAS | E_SERVICE , "" , "myAlias", "css.Service ", NULL, NULL, NULL);
283 : JobURL::impldbg_checkURL("vnd.sun.star.job:service=css.Service; alias=myAlias" , E_UNKNOWN , "" , "" , "" , NULL, NULL, NULL);
284 : JobURL::impldbg_checkURL("vnd.sun.star.job : event=onMyEvent" , E_UNKNOWN , "" , "" , "" , NULL, NULL, NULL);
285 : JobURL::impldbg_checkURL("vnd.sun.star.job:event=onMyEvent;event=onMyEvent;service=css.Service", E_UNKNOWN , "" , "" , "" , NULL, NULL, NULL);
286 :
287 : // check upper/lower case
288 : // fix parts of the URL are case insensitive (e.g. "vnd.SUN.star.job:eVEnt=")
289 : // values are case sensitive (e.g. "myAlias" )
290 : JobURL::impldbg_checkURL("vnd.SUN.star.job:eVEnt=onMyEvent;aliAs=myAlias;serVice=css.Service", E_EVENT | E_ALIAS | E_SERVICE , "onMyEvent", "myAlias", "css.Service" , NULL, NULL, NULL);
291 : JobURL::impldbg_checkURL("vnd.SUN.star.job:eVEnt=onMyEVENT;aliAs=myALIAS;serVice=css.SERVICE", E_EVENT | E_ALIAS | E_SERVICE , "onMyEVENT", "myALIAS", "css.SERVICE" , NULL, NULL, NULL);
292 :
293 : // check stupid URLs
294 : JobURL::impldbg_checkURL("vnd.sun.star.jobs:service=css.Service" , E_UNKNOWN, "", "", "", NULL, NULL, NULL);
295 : JobURL::impldbg_checkURL("vnd.sun.star.job service=css.Service" , E_UNKNOWN, "", "", "", NULL, NULL, NULL);
296 : JobURL::impldbg_checkURL("vnd.sun.star.job:service;css.Service" , E_UNKNOWN, "", "", "", NULL, NULL, NULL);
297 : JobURL::impldbg_checkURL("vnd.sun.star.job:service;" , E_UNKNOWN, "", "", "", NULL, NULL, NULL);
298 : JobURL::impldbg_checkURL("vnd.sun.star.job:;alias;service;event=" , E_UNKNOWN, "", "", "", NULL, NULL, NULL);
299 : JobURL::impldbg_checkURL("vnd.sun.star.job:alias=a;service=s;event=", E_UNKNOWN, "", "", "", NULL, NULL, NULL);
300 :
301 : // check argument handling
302 : JobURL::impldbg_checkURL("vnd.sun.star.job:event=onMyEvent?eventArg1,eventArg2=3,eventArg4," , E_EVENT , "onMyEvent", "" , "" , "eventArg1,eventArg2=3,eventArg4,", NULL , NULL );
303 : JobURL::impldbg_checkURL("vnd.sun.star.job:alias=myAlias?aliasArg1,aliasarg2" , E_EVENT , "" , "myAlias", "" , NULL , "aliasArg1,aliasarg2", NULL );
304 : JobURL::impldbg_checkURL("vnd.sun.star.job:service=css.myService?serviceArg1" , E_EVENT , "" , "" , "css.myService", NULL , NULL , "serviceArg1" );
305 : JobURL::impldbg_checkURL("vnd.sun.star.job:service=css.myService?serviceArg1;alias=myAlias?aliasArg=564", E_EVENT | E_ALIAS, "" , "myAlias", "css.myService", NULL , "aliasArg=564" , "serviceArg1" );
306 : }
307 :
308 : /**
309 : @short helper debug method
310 : @descr It uses the given parameter to create a new instance of a JobURL.
311 : They results will be compared with the exepected ones.
312 : The a log will be written, which contains some detailed information
313 : for this sub test.
314 :
315 : @param pURL
316 : the job URL, which should be checked
317 :
318 : @param eExpectedPart
319 : the expected result
320 :
321 : @param pExpectedEvent
322 : the expected event value
323 :
324 : @param pExpectedAlias
325 : the expected alias value
326 :
327 : @param pExpectedService
328 : the expected service value
329 :
330 : @param pExpectedEventArgs
331 : the expected event arguments
332 :
333 : @param pExpectedAliasArgs
334 : the expected alias arguments
335 :
336 : @param pExpectedServiceArgs
337 : the expected service arguments
338 : */
339 : void JobURL::impldbg_checkURL( /*IN*/ const sal_Char* pURL ,
340 : /*IN*/ sal_uInt32 eExpectedPart ,
341 : /*IN*/ const sal_Char* pExpectedEvent ,
342 : /*IN*/ const sal_Char* pExpectedAlias ,
343 : /*IN*/ const sal_Char* pExpectedService ,
344 : /*IN*/ const sal_Char* pExpectedEventArgs ,
345 : /*IN*/ const sal_Char* pExpectedAliasArgs ,
346 : /*IN*/ const sal_Char* pExpectedServiceArgs )
347 : {
348 : OUString sEvent;
349 : OUString sAlias;
350 : OUString sService;
351 : OUString sEventArgs;
352 : OUString sAliasArgs;
353 : OUString sServiceArgs;
354 : OUString sURL (OUString::createFromAscii(pURL));
355 : sal_Bool bOK = sal_True;
356 :
357 : JobURL aURL(sURL);
358 :
359 : // check if URL is invalid
360 : if (eExpectedPart==E_UNKNOWN)
361 : bOK = !aURL.isValid();
362 :
363 : // check if URL has the expected event part
364 : if (
365 : (bOK ) &&
366 : ((eExpectedPart & E_EVENT) == E_EVENT)
367 : )
368 : {
369 : bOK = (
370 : (aURL.isValid() ) &&
371 : (aURL.getEvent(sEvent) ) &&
372 : (!sEvent.isEmpty() ) &&
373 : (sEvent.equalsAscii(pExpectedEvent))
374 : );
375 :
376 : if (bOK && pExpectedEventArgs!=NULL)
377 : {
378 : bOK = (
379 : (aURL.getEventArgs(sEventArgs) ) &&
380 : (sEventArgs.equalsAscii(pExpectedEventArgs))
381 : );
382 : }
383 : }
384 :
385 : // check if URL has no event part
386 : if (
387 : (bOK ) &&
388 : ((eExpectedPart & E_EVENT) != E_EVENT)
389 : )
390 : {
391 : bOK = (
392 : (!aURL.getEvent(sEvent) ) &&
393 : (sEvent.isEmpty() ) &&
394 : (!aURL.getEventArgs(sEventArgs)) &&
395 : (sEventArgs.isEmpty() )
396 : );
397 : }
398 :
399 : // check if URL has the expected alias part
400 : if (
401 : (bOK ) &&
402 : ((eExpectedPart & E_ALIAS) == E_ALIAS)
403 : )
404 : {
405 : bOK = (
406 : (aURL.isValid() ) &&
407 : (aURL.getAlias(sAlias) ) &&
408 : (!sAlias.isEmpty() ) &&
409 : (sAlias.equalsAscii(pExpectedAlias))
410 : );
411 :
412 : if (bOK && pExpectedAliasArgs!=NULL)
413 : {
414 : bOK = (
415 : (aURL.getAliasArgs(sAliasArgs) ) &&
416 : (sAliasArgs.equalsAscii(pExpectedAliasArgs))
417 : );
418 : }
419 : }
420 :
421 : // check if URL has the no alias part
422 : if (
423 : (bOK ) &&
424 : ((eExpectedPart & E_ALIAS) != E_ALIAS)
425 : )
426 : {
427 : bOK = (
428 : (!aURL.getAlias(sAlias) ) &&
429 : (sAlias.isEmpty() ) &&
430 : (!aURL.getAliasArgs(sAliasArgs)) &&
431 : (sAliasArgs.isEmpty() )
432 : );
433 : }
434 :
435 : // check if URL has the expected service part
436 : if (
437 : (bOK ) &&
438 : ((eExpectedPart & E_SERVICE) == E_SERVICE)
439 : )
440 : {
441 : bOK = (
442 : (aURL.isValid() ) &&
443 : (aURL.getService(sService) ) &&
444 : (!sService.isEmpty() ) &&
445 : (sService.equalsAscii(pExpectedService))
446 : );
447 :
448 : if (bOK && pExpectedServiceArgs!=NULL)
449 : {
450 : bOK = (
451 : (aURL.getServiceArgs(sServiceArgs) ) &&
452 : (sServiceArgs.equalsAscii(pExpectedServiceArgs))
453 : );
454 : }
455 : }
456 :
457 : // check if URL has the no service part
458 : if (
459 : (bOK ) &&
460 : ((eExpectedPart & E_SERVICE) != E_SERVICE)
461 : )
462 : {
463 : bOK = (
464 : (!aURL.getService(sService) ) &&
465 : (sService.isEmpty() ) &&
466 : (!aURL.getServiceArgs(sServiceArgs)) &&
467 : (sServiceArgs.isEmpty() )
468 : );
469 : }
470 :
471 : OUStringBuffer sMsg(256);
472 :
473 : sMsg.append(sURL);
474 : sMsg.appendAscii("\" ");
475 :
476 : if (bOK)
477 : {
478 : sMsg.appendAscii("... OK\n");
479 : }
480 : else
481 : {
482 : sMsg.appendAscii("... failed. ");
483 : sMsg.appendAscii("Expected: ");
484 : if (eExpectedPart==E_UNKNOWN)
485 : sMsg.appendAscii("E_UNKNOWN");
486 : if ((eExpectedPart & E_EVENT) == E_EVENT)
487 : {
488 : sMsg.appendAscii("| E_EVENT e=\"");
489 : sMsg.appendAscii(pExpectedEvent );
490 : sMsg.appendAscii("\"" );
491 : }
492 : if ((eExpectedPart & E_ALIAS) == E_ALIAS)
493 : {
494 : sMsg.appendAscii("| E_ALIAS a=\"");
495 : sMsg.appendAscii(pExpectedAlias );
496 : sMsg.appendAscii("\"" );
497 : }
498 : if ((eExpectedPart & E_SERVICE) == E_SERVICE)
499 : {
500 : sMsg.appendAscii("| E_SERVICE s=\"");
501 : sMsg.appendAscii(pExpectedService );
502 : sMsg.appendAscii("\"" );
503 : }
504 : sMsg.appendAscii(", Actual: " );
505 : sMsg.append (aURL.impldbg_toString());
506 : }
507 :
508 : SAL_INFO("fwk.joburl", OUString(sMsg));
509 : }
510 :
511 : /**
512 : @short helper debug method
513 : @descr It returns a representation of the internal object state
514 : as string notation.
515 :
516 : @returns The formatted string representation.
517 : */
518 : OUString JobURL::impldbg_toString() const
519 : {
520 : SolarMutexGuard g;
521 :
522 : OUStringBuffer sBuffer(256);
523 :
524 : if (m_eRequest==E_UNKNOWN)
525 : sBuffer.appendAscii("E_UNKNOWN");
526 : if ((m_eRequest & E_EVENT) == E_EVENT)
527 : sBuffer.appendAscii("| E_EVENT");
528 : if ((m_eRequest & E_ALIAS) == E_ALIAS)
529 : sBuffer.appendAscii("| E_ALIAS");
530 : if ((m_eRequest & E_SERVICE) == E_SERVICE)
531 : sBuffer.appendAscii("| E_SERVICE");
532 : sBuffer.appendAscii("{ e=\"" );
533 : sBuffer.append (m_sEvent );
534 : sBuffer.appendAscii("\" - a=\"");
535 : sBuffer.append (m_sAlias );
536 : sBuffer.appendAscii("\" - s=\"");
537 : sBuffer.append (m_sService );
538 : sBuffer.appendAscii("\" }" );
539 :
540 : return sBuffer.makeStringAndClear();
541 : }
542 :
543 : sal_Bool JobURL::getServiceArgs( /*OUT*/ OUString& sServiceArgs ) const
544 : {
545 : SolarMutexGuard g;
546 :
547 : sServiceArgs.clear();
548 : sal_Bool bSet = ((m_eRequest & E_SERVICE) == E_SERVICE);
549 : if (bSet)
550 : sServiceArgs = m_sServiceArgs;
551 :
552 : return bSet;
553 : }
554 :
555 : sal_Bool JobURL::getEventArgs( /*OUT*/ OUString& sEventArgs ) const
556 : {
557 : SolarMutexGuard g;
558 :
559 : sEventArgs.clear();
560 : sal_Bool bSet = ((m_eRequest & E_EVENT) == E_EVENT);
561 : if (bSet)
562 : sEventArgs = m_sEventArgs;
563 :
564 : return bSet;
565 : }
566 :
567 : sal_Bool JobURL::getAliasArgs( /*OUT*/ OUString& sAliasArgs ) const
568 : {
569 : SolarMutexGuard g;
570 :
571 : sAliasArgs.clear();
572 : sal_Bool bSet = ((m_eRequest & E_ALIAS) == E_ALIAS);
573 : if (bSet)
574 : sAliasArgs = m_sAliasArgs;
575 :
576 : return bSet;
577 : }
578 :
579 : #endif // ENABLE_COMPONENT_SELF_CHECK
580 :
581 : } // namespace framework
582 :
583 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|