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 :
21 : /**************************************************************************
22 : TODO
23 : **************************************************************************
24 :
25 : *************************************************************************/
26 :
27 : #include <list>
28 : #include <unordered_map>
29 : #include <osl/diagnose.h>
30 : #include <rtl/ustrbuf.hxx>
31 : #include <cppuhelper/interfacecontainer.hxx>
32 : #include <com/sun/star/beans/PropertyAttribute.hpp>
33 : #include <com/sun/star/beans/PropertySetInfoChange.hpp>
34 : #include <com/sun/star/configuration/theDefaultProvider.hpp>
35 : #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
36 : #include <com/sun/star/container/XNameContainer.hpp>
37 : #include <com/sun/star/container/XNameReplace.hpp>
38 : #include <com/sun/star/util/XChangesBatch.hpp>
39 : #include <comphelper/processfactory.hxx>
40 : #include <cppuhelper/implbase1.hxx>
41 : #include "ucbstore.hxx"
42 :
43 : using namespace com::sun::star::beans;
44 : using namespace com::sun::star::configuration;
45 : using namespace com::sun::star::container;
46 : using namespace com::sun::star::lang;
47 : using namespace com::sun::star::ucb;
48 : using namespace com::sun::star::uno;
49 : using namespace com::sun::star::util;
50 : using namespace cppu;
51 :
52 :
53 :
54 0 : OUString makeHierarchalNameSegment( const OUString & rIn )
55 : {
56 0 : OUStringBuffer aBuffer;
57 0 : aBuffer.appendAscii( "['" );
58 :
59 0 : sal_Int32 nCount = rIn.getLength();
60 0 : for ( sal_Int32 n = 0; n < nCount; ++n )
61 : {
62 0 : const sal_Unicode c = rIn[ n ];
63 0 : switch ( c )
64 : {
65 : case '&':
66 0 : aBuffer.appendAscii( "&" );
67 0 : break;
68 :
69 : case '"':
70 0 : aBuffer.appendAscii( """ );
71 0 : break;
72 :
73 : case '\'':
74 0 : aBuffer.appendAscii( "'" );
75 0 : break;
76 :
77 : case '<':
78 0 : aBuffer.appendAscii( "<" );
79 0 : break;
80 :
81 : case '>':
82 0 : aBuffer.appendAscii( ">" );
83 0 : break;
84 :
85 : default:
86 0 : aBuffer.append( c );
87 0 : break;
88 : }
89 : }
90 :
91 0 : aBuffer.appendAscii( "']" );
92 0 : return OUString( aBuffer.makeStringAndClear() );
93 : }
94 :
95 : #define STORE_CONTENTPROPERTIES_KEY "/org.openoffice.ucb.Store/ContentProperties"
96 :
97 : // describe path of cfg entry
98 : #define CFGPROPERTY_NODEPATH "nodepath"
99 : // true->async. update; false->sync. update
100 : #define CFGPROPERTY_LAZYWRITE "lazywrite"
101 :
102 : // PropertySetMap_Impl.
103 : typedef std::unordered_map
104 : <
105 : OUString,
106 : PersistentPropertySet*,
107 : OUStringHash
108 : >
109 : PropertySetMap_Impl;
110 :
111 : // class PropertySetInfo_Impl
112 : class PropertySetInfo_Impl : public cppu::WeakImplHelper1 < XPropertySetInfo >
113 : {
114 : Reference< XComponentContext > m_xContext;
115 : Sequence< Property >* m_pProps;
116 : PersistentPropertySet* m_pOwner;
117 :
118 : public:
119 : PropertySetInfo_Impl( const Reference< XComponentContext >& xContext,
120 : PersistentPropertySet* pOwner );
121 : virtual ~PropertySetInfo_Impl();
122 :
123 : // XPropertySetInfo
124 : virtual Sequence< Property > SAL_CALL getProperties()
125 : throw( RuntimeException, std::exception ) SAL_OVERRIDE;
126 : virtual Property SAL_CALL getPropertyByName( const OUString& aName )
127 : throw( UnknownPropertyException, RuntimeException, std::exception ) SAL_OVERRIDE;
128 : virtual sal_Bool SAL_CALL hasPropertyByName( const OUString& Name )
129 : throw( RuntimeException, std::exception ) SAL_OVERRIDE;
130 :
131 : // Non-interface methods.
132 0 : void reset() { delete m_pProps; m_pProps = 0; }
133 : };
134 :
135 :
136 :
137 : // UcbStore_Impl.
138 :
139 :
140 :
141 426 : struct UcbStore_Impl
142 : {
143 : osl::Mutex m_aMutex;
144 : Sequence< Any > m_aInitArgs;
145 : Reference< XPropertySetRegistry > m_xTheRegistry;
146 : };
147 :
148 :
149 :
150 :
151 :
152 : // UcbStore Implementation.
153 :
154 :
155 :
156 :
157 :
158 214 : UcbStore::UcbStore( const Reference< XComponentContext >& xContext )
159 : : m_xContext( xContext ),
160 214 : m_pImpl( new UcbStore_Impl() )
161 : {
162 214 : }
163 :
164 :
165 : // virtual
166 636 : UcbStore::~UcbStore()
167 : {
168 212 : delete m_pImpl;
169 424 : }
170 :
171 :
172 1186 : XSERVICEINFO_IMPL_1_CTX( UcbStore,
173 : OUString( "com.sun.star.comp.ucb.UcbStore" ),
174 : STORE_SERVICE_NAME );
175 :
176 :
177 :
178 : // Service factory implementation.
179 :
180 :
181 :
182 214 : ONE_INSTANCE_SERVICE_FACTORY_IMPL( UcbStore );
183 :
184 :
185 :
186 : // XPropertySetRegistryFactory methods.
187 :
188 :
189 :
190 : // virtual
191 : Reference< XPropertySetRegistry > SAL_CALL
192 2166 : UcbStore::createPropertySetRegistry( const OUString& )
193 : throw( RuntimeException, std::exception )
194 : {
195 : // The URL parameter is ignored by this interface implementation. It always
196 : // uses the configuration server as storage medium.
197 :
198 2166 : if ( !m_pImpl->m_xTheRegistry.is() )
199 : {
200 214 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
201 214 : if ( !m_pImpl->m_xTheRegistry.is() )
202 214 : m_pImpl->m_xTheRegistry = new PropertySetRegistry( m_xContext, getInitArgs() );
203 : }
204 :
205 2166 : return m_pImpl->m_xTheRegistry;
206 : }
207 :
208 :
209 :
210 : // XInitialization methods.
211 :
212 :
213 :
214 : // virtual
215 0 : void SAL_CALL UcbStore::initialize( const Sequence< Any >& aArguments )
216 : throw( Exception, RuntimeException, std::exception )
217 : {
218 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
219 0 : m_pImpl->m_aInitArgs = aArguments;
220 0 : }
221 :
222 :
223 214 : const Sequence< Any >& UcbStore::getInitArgs() const
224 : {
225 214 : return m_pImpl->m_aInitArgs;
226 : }
227 :
228 :
229 :
230 : // PropertySetRegistry_Impl.
231 :
232 :
233 :
234 199 : struct PropertySetRegistry_Impl
235 : {
236 : const Sequence< Any > m_aInitArgs;
237 : PropertySetMap_Impl m_aPropSets;
238 : Reference< XMultiServiceFactory > m_xConfigProvider;
239 : Reference< XInterface > m_xRootReadAccess;
240 : Reference< XInterface > m_xRootWriteAccess;
241 : osl::Mutex m_aMutex;
242 : bool m_bTriedToGetRootReadAccess; // #82494#
243 : bool m_bTriedToGetRootWriteAccess; // #82494#
244 :
245 214 : explicit PropertySetRegistry_Impl(const Sequence<Any> &rInitArgs)
246 : : m_aInitArgs(rInitArgs)
247 : , m_bTriedToGetRootReadAccess(false)
248 214 : , m_bTriedToGetRootWriteAccess(false)
249 : {
250 214 : }
251 : };
252 :
253 : // PropertySetRegistry Implementation.
254 :
255 :
256 :
257 :
258 :
259 214 : PropertySetRegistry::PropertySetRegistry(
260 : const Reference< XComponentContext >& xContext,
261 : const Sequence< Any > &rInitArgs )
262 : : m_xContext( xContext ),
263 214 : m_pImpl( new PropertySetRegistry_Impl( rInitArgs ) )
264 : {
265 214 : }
266 :
267 :
268 : // virtual
269 597 : PropertySetRegistry::~PropertySetRegistry()
270 : {
271 199 : delete m_pImpl;
272 398 : }
273 :
274 :
275 :
276 : // XServiceInfo methods.
277 :
278 :
279 :
280 0 : XSERVICEINFO_NOFACTORY_IMPL_1( PropertySetRegistry,
281 : OUString( "com.sun.star.comp.ucb.PropertySetRegistry" ),
282 : PROPSET_REG_SERVICE_NAME );
283 :
284 :
285 :
286 : // XPropertySetRegistry methods.
287 :
288 :
289 :
290 : // virtual
291 : Reference< XPersistentPropertySet > SAL_CALL
292 136750 : PropertySetRegistry::openPropertySet( const OUString& key, sal_Bool create )
293 : throw( RuntimeException, std::exception )
294 : {
295 136750 : if ( !key.isEmpty() )
296 : {
297 133421 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
298 :
299 133421 : PropertySetMap_Impl& rSets = m_pImpl->m_aPropSets;
300 :
301 133421 : PropertySetMap_Impl::const_iterator it = rSets.find( key );
302 133421 : if ( it != rSets.end() )
303 : {
304 : // Already instantiated.
305 0 : return Reference< XPersistentPropertySet >( (*it).second );
306 : }
307 : else
308 : {
309 : // Create new instance.
310 : Reference< XNameAccess > xRootNameAccess(
311 133421 : getRootConfigReadAccess(), UNO_QUERY );
312 133421 : if ( xRootNameAccess.is() )
313 : {
314 : // Propertyset in registry?
315 133421 : if ( xRootNameAccess->hasByName( key ) )
316 : {
317 : // Yep!
318 : return Reference< XPersistentPropertySet >(
319 : new PersistentPropertySet(
320 0 : m_xContext, *this, key ) );
321 : }
322 133421 : else if ( create )
323 : {
324 : // No. Create entry for propertyset.
325 :
326 : Reference< XSingleServiceFactory > xFac(
327 0 : getConfigWriteAccess( OUString() ), UNO_QUERY );
328 0 : Reference< XChangesBatch > xBatch( xFac, UNO_QUERY );
329 0 : Reference< XNameContainer > xContainer( xFac, UNO_QUERY );
330 :
331 : OSL_ENSURE( xFac.is(),
332 : "PropertySetRegistry::openPropertySet - "
333 : "No factory!" );
334 :
335 : OSL_ENSURE( xBatch.is(),
336 : "PropertySetRegistry::openPropertySet - "
337 : "No batch!" );
338 :
339 : OSL_ENSURE( xContainer.is(),
340 : "PropertySetRegistry::openPropertySet - "
341 : "No container!" );
342 :
343 0 : if ( xFac.is() && xBatch.is() && xContainer.is() )
344 : {
345 : try
346 : {
347 : // Create new "Properties" config item.
348 : Reference< XNameReplace > xNameReplace(
349 0 : xFac->createInstance(), UNO_QUERY );
350 :
351 0 : if ( xNameReplace.is() )
352 : {
353 : // Fill new item...
354 :
355 : // // Set Values
356 : // xNameReplace->replaceByName(
357 : // OUString("Values"),
358 : // makeAny( ... ) );
359 :
360 : // Insert new item.
361 0 : xContainer->insertByName(
362 0 : key, makeAny( xNameReplace ) );
363 : // Commit changes.
364 0 : xBatch->commitChanges();
365 :
366 : return Reference< XPersistentPropertySet >(
367 : new PersistentPropertySet(
368 0 : m_xContext, *this, key ) );
369 0 : }
370 : }
371 0 : catch (const IllegalArgumentException&)
372 : {
373 : // insertByName
374 :
375 : OSL_FAIL( "PropertySetRegistry::openPropertySet - "
376 : "caught IllegalArgumentException!" );
377 : }
378 0 : catch (const ElementExistException&)
379 : {
380 : // insertByName
381 :
382 : OSL_FAIL( "PropertySetRegistry::openPropertySet - "
383 : "caught ElementExistException!" );
384 : }
385 0 : catch (const WrappedTargetException&)
386 : {
387 : // insertByName, commitChanges
388 :
389 : OSL_FAIL( "PropertySetRegistry::openPropertySet - "
390 : "caught WrappedTargetException!" );
391 : }
392 0 : catch (const RuntimeException&)
393 : {
394 : OSL_FAIL( "PropertySetRegistry::openPropertySet - "
395 : "caught RuntimeException!" );
396 : }
397 0 : catch (const Exception&)
398 : {
399 : // createInstance
400 :
401 : OSL_FAIL( "PropertySetRegistry::openPropertySet - "
402 : "caught Exception!" );
403 : }
404 0 : }
405 : }
406 : else
407 : {
408 : // No entry. Fail, but no error.
409 133421 : return Reference< XPersistentPropertySet >();
410 : }
411 : }
412 :
413 0 : OSL_TRACE( "PropertySetRegistry::openPropertySet no root access" );
414 0 : }
415 : }
416 :
417 3329 : return Reference< XPersistentPropertySet >();
418 : }
419 :
420 :
421 : // virtual
422 9966 : void SAL_CALL PropertySetRegistry::removePropertySet( const OUString& key )
423 : throw( RuntimeException, std::exception )
424 : {
425 9966 : if ( key.isEmpty() )
426 9966 : return;
427 :
428 9966 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
429 :
430 : Reference< XNameAccess > xRootNameAccess(
431 9966 : getRootConfigReadAccess(), UNO_QUERY );
432 9966 : if ( xRootNameAccess.is() )
433 : {
434 : // Propertyset in registry?
435 9966 : if ( !xRootNameAccess->hasByName( key ) )
436 9966 : return;
437 : Reference< XChangesBatch > xBatch(
438 0 : getConfigWriteAccess( OUString() ), UNO_QUERY );
439 0 : Reference< XNameContainer > xContainer( xBatch, UNO_QUERY );
440 :
441 0 : if ( xBatch.is() && xContainer.is() )
442 : {
443 : try
444 : {
445 : // Remove item.
446 0 : xContainer->removeByName( key );
447 : // Commit changes.
448 0 : xBatch->commitChanges();
449 :
450 : // Success.
451 0 : return;
452 : }
453 0 : catch (const NoSuchElementException&)
454 : {
455 : // removeByName
456 :
457 : OSL_FAIL( "PropertySetRegistry::removePropertySet - "
458 : "caught NoSuchElementException!" );
459 0 : return;
460 : }
461 0 : catch (const WrappedTargetException&)
462 : {
463 : // commitChanges
464 :
465 : OSL_FAIL( "PropertySetRegistry::removePropertySet - "
466 : "caught WrappedTargetException!" );
467 0 : return;
468 : }
469 : }
470 :
471 0 : return;
472 : }
473 :
474 0 : OSL_TRACE( "PropertySetRegistry::removePropertySet - no root access" );
475 : }
476 :
477 :
478 :
479 : // XElementAccess methods.
480 :
481 :
482 :
483 : // virtual
484 0 : com::sun::star::uno::Type SAL_CALL PropertySetRegistry::getElementType()
485 : throw( RuntimeException, std::exception )
486 : {
487 0 : return cppu::UnoType<XPersistentPropertySet>::get();
488 : }
489 :
490 :
491 : // virtual
492 0 : sal_Bool SAL_CALL PropertySetRegistry::hasElements()
493 : throw( RuntimeException, std::exception )
494 : {
495 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
496 :
497 : Reference< XElementAccess > xElemAccess(
498 0 : getRootConfigReadAccess(), UNO_QUERY );
499 0 : if ( xElemAccess.is() )
500 0 : return xElemAccess->hasElements();
501 :
502 0 : return sal_False;
503 : }
504 :
505 :
506 :
507 : // XNameAccess methods.
508 :
509 :
510 :
511 : // virtual
512 0 : Any SAL_CALL PropertySetRegistry::getByName( const OUString& aName )
513 : throw( NoSuchElementException, WrappedTargetException, RuntimeException, std::exception )
514 : {
515 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
516 :
517 : Reference< XNameAccess > xNameAccess(
518 0 : getRootConfigReadAccess(), UNO_QUERY );
519 0 : if ( xNameAccess.is() )
520 : {
521 :
522 : try
523 : {
524 0 : return xNameAccess->getByName( aName );
525 : }
526 0 : catch (const NoSuchElementException&)
527 : {
528 : // getByName
529 : }
530 0 : catch (const WrappedTargetException&)
531 : {
532 : // getByName
533 : }
534 : }
535 :
536 0 : return Any();
537 : }
538 :
539 :
540 : // virtual
541 1 : Sequence< OUString > SAL_CALL PropertySetRegistry::getElementNames()
542 : throw( RuntimeException, std::exception )
543 : {
544 1 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
545 :
546 : Reference< XNameAccess > xNameAccess(
547 2 : getRootConfigReadAccess(), UNO_QUERY );
548 1 : if ( xNameAccess.is() )
549 : {
550 1 : return xNameAccess->getElementNames();
551 : }
552 1 : return Sequence< OUString >( 0 );
553 : }
554 :
555 :
556 : // virtual
557 0 : sal_Bool SAL_CALL PropertySetRegistry::hasByName( const OUString& aName )
558 : throw( RuntimeException, std::exception )
559 : {
560 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
561 :
562 : Reference< XNameAccess > xNameAccess(
563 0 : getRootConfigReadAccess(), UNO_QUERY );
564 0 : if ( xNameAccess.is() )
565 : {
566 0 : return xNameAccess->hasByName( aName );
567 : }
568 :
569 0 : return sal_False;
570 : }
571 :
572 :
573 0 : void PropertySetRegistry::add( PersistentPropertySet* pSet )
574 : {
575 0 : OUString key( pSet->getKey() );
576 :
577 0 : if ( !key.isEmpty() )
578 : {
579 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
580 0 : m_pImpl->m_aPropSets[ key ] = pSet;
581 0 : }
582 0 : }
583 :
584 :
585 0 : void PropertySetRegistry::remove( PersistentPropertySet* pSet )
586 : {
587 0 : OUString key( pSet->getKey() );
588 :
589 0 : if ( !key.isEmpty() )
590 : {
591 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
592 :
593 0 : PropertySetMap_Impl& rSets = m_pImpl->m_aPropSets;
594 :
595 0 : PropertySetMap_Impl::iterator it = rSets.find( key );
596 0 : if ( it != rSets.end() )
597 : {
598 : // Found.
599 0 : rSets.erase( it );
600 0 : }
601 0 : }
602 0 : }
603 :
604 :
605 0 : void PropertySetRegistry::renamePropertySet( const OUString& rOldKey,
606 : const OUString& rNewKey )
607 : {
608 0 : if ( rOldKey == rNewKey )
609 0 : return;
610 :
611 : Reference< XNameAccess > xRootNameAccess(
612 0 : getConfigWriteAccess( OUString() ), UNO_QUERY );
613 0 : if ( xRootNameAccess.is() )
614 : {
615 : // Old key present?
616 0 : if ( xRootNameAccess->hasByName( rOldKey ) )
617 : {
618 : // New key not present?
619 0 : if ( xRootNameAccess->hasByName( rNewKey ) )
620 : {
621 : OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
622 : "New key exists!" );
623 0 : return;
624 : }
625 : Reference< XSingleServiceFactory > xFac(
626 0 : xRootNameAccess, UNO_QUERY );
627 0 : Reference< XChangesBatch > xBatch( xFac, UNO_QUERY );
628 0 : Reference< XNameContainer > xContainer( xFac, UNO_QUERY );
629 :
630 : OSL_ENSURE( xFac.is(),
631 : "PropertySetRegistry::renamePropertySet - "
632 : "No factory!" );
633 :
634 : OSL_ENSURE( xBatch.is(),
635 : "PropertySetRegistry::renamePropertySet - "
636 : "No batch!" );
637 :
638 : OSL_ENSURE( xContainer.is(),
639 : "PropertySetRegistry::renamePropertySet - "
640 : "No container!" );
641 :
642 0 : if ( xFac.is() && xBatch.is() && xContainer.is() )
643 : {
644 :
645 : // Create new "Properties" config item.
646 :
647 :
648 : try
649 : {
650 : Reference< XNameReplace > xNameReplace(
651 0 : xFac->createInstance(), UNO_QUERY );
652 :
653 0 : if ( xNameReplace.is() )
654 : {
655 : // Insert new item.
656 0 : xContainer->insertByName(
657 0 : rNewKey, makeAny( xNameReplace ) );
658 : // Commit changes.
659 0 : xBatch->commitChanges();
660 0 : }
661 : }
662 0 : catch (const IllegalArgumentException&)
663 : {
664 : // insertByName
665 :
666 : OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
667 : "caught IllegalArgumentException!" );
668 0 : return;
669 : }
670 0 : catch (const ElementExistException&)
671 : {
672 : // insertByName
673 :
674 : OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
675 : "caught ElementExistException!" );
676 0 : return;
677 : }
678 0 : catch (const WrappedTargetException&)
679 : {
680 : // insertByName, commitChanges
681 :
682 : OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
683 : "caught WrappedTargetException!" );
684 0 : return;
685 : }
686 0 : catch (const RuntimeException&)
687 : {
688 : OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
689 : "caught RuntimeException!" );
690 0 : return;
691 : }
692 0 : catch (const Exception&)
693 : {
694 : // createInstance
695 :
696 : OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
697 : "caught Exception!" );
698 0 : return;
699 : }
700 :
701 :
702 : // Copy data...
703 :
704 :
705 : Reference< XHierarchicalNameAccess > xRootHierNameAccess(
706 0 : xRootNameAccess, UNO_QUERY );
707 0 : if ( !xRootHierNameAccess.is() )
708 : {
709 : OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
710 : "No hierarchical name access!" );
711 0 : return;
712 : }
713 :
714 : try
715 : {
716 : OUString aOldValuesKey
717 0 : = makeHierarchalNameSegment( rOldKey );
718 0 : aOldValuesKey += "/Values";
719 :
720 0 : Reference< XNameAccess > xOldNameAccess;
721 0 : xRootHierNameAccess->getByHierarchicalName(
722 0 : aOldValuesKey )
723 0 : >>= xOldNameAccess;
724 0 : if ( !xOldNameAccess.is() )
725 : {
726 : OSL_FAIL( "PersistentPropertySet::renamePropertySet - "
727 : "No old name access!" );
728 0 : return;
729 : }
730 :
731 : // Obtain property names.
732 : Sequence< OUString > aElems
733 0 : = xOldNameAccess->getElementNames();
734 0 : sal_Int32 nCount = aElems.getLength();
735 0 : if ( nCount )
736 : {
737 : OUString aNewValuesKey
738 0 : = makeHierarchalNameSegment( rNewKey );
739 0 : aNewValuesKey += "/Values";
740 :
741 0 : Reference< XSingleServiceFactory > xNewFac;
742 0 : xRootHierNameAccess->getByHierarchicalName(
743 0 : aNewValuesKey )
744 0 : >>= xNewFac;
745 0 : if ( !xNewFac.is() )
746 : {
747 : OSL_FAIL( "PersistentPropertySet::renamePropertySet - "
748 : "No new factory!" );
749 0 : return;
750 : }
751 :
752 : Reference< XNameContainer > xNewContainer(
753 0 : xNewFac, UNO_QUERY );
754 0 : if ( !xNewContainer.is() )
755 : {
756 : OSL_FAIL( "PersistentPropertySet::renamePropertySet - "
757 : "No new container!" );
758 0 : return;
759 : }
760 :
761 0 : aOldValuesKey += "/";
762 :
763 0 : OUString aHandleKey("/Handle");
764 0 : OUString aValueKey("/Value");
765 0 : OUString aStateKey("/State");
766 0 : OUString aAttrKey("/Attributes");
767 :
768 0 : for ( sal_Int32 n = 0; n < nCount; ++n )
769 : {
770 0 : const OUString& rPropName = aElems[ n ];
771 :
772 : // Create new item.
773 : Reference< XNameReplace > xNewPropNameReplace(
774 0 : xNewFac->createInstance(), UNO_QUERY );
775 :
776 0 : if ( !xNewPropNameReplace.is() )
777 : {
778 : OSL_FAIL( "PersistentPropertySet::renamePropertySet - "
779 : "No new prop name replace!" );
780 0 : return;
781 : }
782 :
783 : // Fill new item...
784 :
785 : // Set Values
786 0 : OUString aKey = aOldValuesKey;
787 0 : aKey += makeHierarchalNameSegment( rPropName );
788 :
789 : // ... handle
790 0 : OUString aNewKey1 = aKey;
791 0 : aNewKey1 += aHandleKey;
792 : Any aAny =
793 0 : xRootHierNameAccess->getByHierarchicalName(
794 0 : aNewKey1 );
795 0 : xNewPropNameReplace->replaceByName(
796 : OUString("Handle"),
797 0 : aAny );
798 :
799 : // ... value
800 0 : aNewKey1 = aKey;
801 0 : aNewKey1 += aValueKey;
802 0 : aAny =
803 0 : xRootHierNameAccess->getByHierarchicalName(
804 0 : aNewKey1 );
805 0 : xNewPropNameReplace->replaceByName(
806 : OUString("Value"),
807 0 : aAny );
808 :
809 : // ... state
810 0 : aNewKey1 = aKey;
811 0 : aNewKey1 += aStateKey;
812 0 : aAny =
813 0 : xRootHierNameAccess->getByHierarchicalName(
814 0 : aNewKey1 );
815 0 : xNewPropNameReplace->replaceByName(
816 : OUString("State"),
817 0 : aAny );
818 :
819 : // ... attributes
820 0 : aNewKey1 = aKey;
821 0 : aNewKey1 += aAttrKey;
822 0 : aAny =
823 0 : xRootHierNameAccess->getByHierarchicalName(
824 0 : aNewKey1 );
825 0 : xNewPropNameReplace->replaceByName(
826 : OUString("Attributes"),
827 0 : aAny );
828 :
829 : // Insert new item.
830 0 : xNewContainer->insertByName(
831 0 : rPropName, makeAny( xNewPropNameReplace ) );
832 :
833 : // Commit changes.
834 0 : xBatch->commitChanges();
835 0 : }
836 0 : }
837 : }
838 0 : catch (const IllegalArgumentException&)
839 : {
840 : // insertByName, replaceByName
841 :
842 : OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
843 : "caught IllegalArgumentException!" );
844 0 : return;
845 : }
846 0 : catch (const ElementExistException&)
847 : {
848 : // insertByName
849 :
850 : OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
851 : "caught ElementExistException!" );
852 0 : return;
853 : }
854 0 : catch (const WrappedTargetException&)
855 : {
856 : // insertByName, replaceByName, commitChanges
857 :
858 : OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
859 : "caught WrappedTargetException!" );
860 0 : return;
861 : }
862 0 : catch (const NoSuchElementException&)
863 : {
864 : // getByHierarchicalName, replaceByName
865 :
866 : OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
867 : "caught NoSuchElementException!" );
868 0 : return;
869 : }
870 0 : catch (const RuntimeException&)
871 : {
872 : OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
873 : "caught RuntimeException!" );
874 0 : return;
875 : }
876 0 : catch (const Exception&)
877 : {
878 : // createInstance
879 :
880 : OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
881 : "caught Exception!" );
882 0 : return;
883 : }
884 :
885 :
886 : // Remove old entry...
887 :
888 :
889 : try
890 : {
891 : // Remove item.
892 0 : xContainer->removeByName( rOldKey );
893 : // Commit changes.
894 0 : xBatch->commitChanges();
895 :
896 : // Success.
897 0 : return;
898 : }
899 0 : catch (const NoSuchElementException&)
900 : {
901 : // removeByName
902 :
903 : OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
904 : "caught NoSuchElementException!" );
905 0 : return;
906 : }
907 0 : catch (const WrappedTargetException&)
908 : {
909 : // commitChanges
910 :
911 : OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
912 : "caught WrappedTargetException!" );
913 0 : return;
914 0 : }
915 0 : }
916 : }
917 : }
918 :
919 0 : OSL_FAIL( "PropertySetRegistry::renamePropertySet - Error!" );
920 : }
921 :
922 :
923 214 : Reference< XMultiServiceFactory > PropertySetRegistry::getConfigProvider()
924 : {
925 214 : if ( !m_pImpl->m_xConfigProvider.is() )
926 : {
927 214 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
928 214 : if ( !m_pImpl->m_xConfigProvider.is() )
929 : {
930 214 : const Sequence< Any >& rInitArgs = m_pImpl->m_aInitArgs;
931 :
932 214 : if ( rInitArgs.getLength() > 0 )
933 : {
934 : // Extract config provider from service init args.
935 0 : rInitArgs[ 0 ] >>= m_pImpl->m_xConfigProvider;
936 :
937 : OSL_ENSURE( m_pImpl->m_xConfigProvider.is(),
938 : "PropertySetRegistry::getConfigProvider - "
939 : "No config provider!" );
940 : }
941 : else
942 : {
943 : try
944 : {
945 214 : m_pImpl->m_xConfigProvider = theDefaultProvider::get( m_xContext );
946 : }
947 0 : catch (const Exception&)
948 : {
949 : OSL_TRACE( "PropertySetRegistry::getConfigProvider - "
950 : "caught exception!" );
951 : }
952 : }
953 214 : }
954 : }
955 :
956 214 : return m_pImpl->m_xConfigProvider;
957 : }
958 :
959 :
960 143388 : Reference< XInterface > PropertySetRegistry::getRootConfigReadAccess()
961 : {
962 : try
963 : {
964 143388 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
965 :
966 143388 : if ( !m_pImpl->m_xRootReadAccess.is() )
967 : {
968 214 : if ( m_pImpl->m_bTriedToGetRootReadAccess ) // #82494#
969 : {
970 : OSL_FAIL( "PropertySetRegistry::getRootConfigReadAccess - "
971 : "Unable to read any config data! -> #82494#" );
972 0 : return Reference< XInterface >();
973 : }
974 :
975 214 : getConfigProvider();
976 :
977 214 : if ( m_pImpl->m_xConfigProvider.is() )
978 : {
979 214 : Sequence< Any > aArguments( 1 );
980 214 : PropertyValue aProperty;
981 214 : aProperty.Name = CFGPROPERTY_NODEPATH;
982 : aProperty.Value
983 214 : <<= OUString( STORE_CONTENTPROPERTIES_KEY );
984 214 : aArguments[ 0 ] <<= aProperty;
985 :
986 214 : m_pImpl->m_bTriedToGetRootReadAccess = true;
987 :
988 428 : m_pImpl->m_xRootReadAccess =
989 214 : m_pImpl->m_xConfigProvider->createInstanceWithArguments(
990 : OUString( "com.sun.star.configuration.ConfigurationAccess" ),
991 428 : aArguments );
992 :
993 214 : if ( m_pImpl->m_xRootReadAccess.is() )
994 214 : return m_pImpl->m_xRootReadAccess;
995 : }
996 : }
997 : else
998 143174 : return m_pImpl->m_xRootReadAccess;
999 : }
1000 0 : catch (const RuntimeException&)
1001 : {
1002 0 : throw;
1003 : }
1004 0 : catch (const Exception&)
1005 : {
1006 : // createInstance, createInstanceWithArguments
1007 :
1008 : OSL_FAIL( "PropertySetRegistry::getRootConfigReadAccess - caught Exception!" );
1009 0 : return Reference< XInterface >();
1010 : }
1011 :
1012 : OSL_TRACE( "PropertySetRegistry::getRootConfigReadAccess - Error!" );
1013 0 : return Reference< XInterface >();
1014 : }
1015 :
1016 :
1017 0 : Reference< XInterface > PropertySetRegistry::getConfigWriteAccess(
1018 : const OUString& rPath )
1019 : {
1020 : try
1021 : {
1022 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
1023 :
1024 0 : if ( !m_pImpl->m_xRootWriteAccess.is() )
1025 : {
1026 0 : if ( m_pImpl->m_bTriedToGetRootWriteAccess ) // #82494#
1027 : {
1028 : OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - "
1029 : "Unable to write any config data! -> #82494#" );
1030 0 : return Reference< XInterface >();
1031 : }
1032 :
1033 0 : getConfigProvider();
1034 :
1035 0 : if ( m_pImpl->m_xConfigProvider.is() )
1036 : {
1037 0 : Sequence< Any > aArguments( 2 );
1038 0 : PropertyValue aProperty;
1039 :
1040 0 : aProperty.Name = CFGPROPERTY_NODEPATH;
1041 0 : aProperty.Value <<= OUString( STORE_CONTENTPROPERTIES_KEY );
1042 0 : aArguments[ 0 ] <<= aProperty;
1043 :
1044 0 : aProperty.Name = CFGPROPERTY_LAZYWRITE;
1045 0 : aProperty.Value <<= sal_True;
1046 0 : aArguments[ 1 ] <<= aProperty;
1047 :
1048 0 : m_pImpl->m_bTriedToGetRootWriteAccess = true;
1049 :
1050 0 : m_pImpl->m_xRootWriteAccess =
1051 0 : m_pImpl->m_xConfigProvider->createInstanceWithArguments(
1052 : OUString( "com.sun.star.configuration.ConfigurationUpdateAccess" ),
1053 0 : aArguments );
1054 :
1055 : OSL_ENSURE( m_pImpl->m_xRootWriteAccess.is(),
1056 : "PropertySetRegistry::getConfigWriteAccess - "
1057 0 : "No config update access!" );
1058 : }
1059 : }
1060 :
1061 0 : if ( m_pImpl->m_xRootWriteAccess.is() )
1062 : {
1063 0 : if ( !rPath.isEmpty() )
1064 : {
1065 : Reference< XHierarchicalNameAccess > xNA(
1066 0 : m_pImpl->m_xRootWriteAccess, UNO_QUERY );
1067 0 : if ( xNA.is() )
1068 : {
1069 0 : Reference< XInterface > xInterface;
1070 0 : xNA->getByHierarchicalName( rPath ) >>= xInterface;
1071 :
1072 0 : if ( xInterface.is() )
1073 0 : return xInterface;
1074 0 : }
1075 : }
1076 : else
1077 0 : return m_pImpl->m_xRootWriteAccess;
1078 0 : }
1079 : }
1080 0 : catch (const RuntimeException&)
1081 : {
1082 0 : throw;
1083 : }
1084 0 : catch (const NoSuchElementException&)
1085 : {
1086 : // getByHierarchicalName
1087 :
1088 : OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - "
1089 : "caught NoSuchElementException!" );
1090 0 : return Reference< XInterface >();
1091 : }
1092 0 : catch (const Exception&)
1093 : {
1094 : // createInstance, createInstanceWithArguments
1095 :
1096 : OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - "
1097 : "caught Exception!" );
1098 0 : return Reference< XInterface >();
1099 : }
1100 :
1101 : OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - Error!" );
1102 0 : return Reference< XInterface >();
1103 : }
1104 :
1105 : typedef OMultiTypeInterfaceContainerHelperVar<OUString> PropertyListeners_Impl;
1106 :
1107 : struct PersistentPropertySet_Impl
1108 : {
1109 : PropertySetRegistry* m_pCreator;
1110 : PropertySetInfo_Impl* m_pInfo;
1111 : OUString m_aKey;
1112 : OUString m_aFullKey;
1113 : osl::Mutex m_aMutex;
1114 : OInterfaceContainerHelper* m_pDisposeEventListeners;
1115 : OInterfaceContainerHelper* m_pPropSetChangeListeners;
1116 : PropertyListeners_Impl* m_pPropertyChangeListeners;
1117 :
1118 0 : PersistentPropertySet_Impl( PropertySetRegistry& rCreator,
1119 : const OUString& rKey )
1120 : : m_pCreator( &rCreator ), m_pInfo( NULL ), m_aKey( rKey ),
1121 : m_pDisposeEventListeners( NULL ), m_pPropSetChangeListeners( NULL ),
1122 0 : m_pPropertyChangeListeners( NULL )
1123 : {
1124 0 : m_pCreator->acquire();
1125 0 : }
1126 :
1127 0 : ~PersistentPropertySet_Impl()
1128 0 : {
1129 0 : m_pCreator->release();
1130 :
1131 0 : if ( m_pInfo )
1132 0 : m_pInfo->release();
1133 :
1134 0 : delete m_pDisposeEventListeners;
1135 0 : delete m_pPropSetChangeListeners;
1136 0 : delete m_pPropertyChangeListeners;
1137 0 : }
1138 : };
1139 :
1140 :
1141 :
1142 :
1143 :
1144 : // PersistentPropertySet Implementation.
1145 :
1146 :
1147 :
1148 :
1149 :
1150 0 : PersistentPropertySet::PersistentPropertySet(
1151 : const Reference< XComponentContext >& xContext,
1152 : PropertySetRegistry& rCreator,
1153 : const OUString& rKey )
1154 : : m_xContext( xContext ),
1155 0 : m_pImpl( new PersistentPropertySet_Impl( rCreator, rKey ) )
1156 : {
1157 : // register at creator.
1158 0 : rCreator.add( this );
1159 0 : }
1160 :
1161 :
1162 : // virtual
1163 0 : PersistentPropertySet::~PersistentPropertySet()
1164 : {
1165 : // deregister at creator.
1166 0 : m_pImpl->m_pCreator->remove( this );
1167 :
1168 0 : delete m_pImpl;
1169 0 : }
1170 :
1171 : // XServiceInfo methods.
1172 :
1173 :
1174 :
1175 0 : XSERVICEINFO_NOFACTORY_IMPL_1( PersistentPropertySet,
1176 : OUString( "com.sun.star.comp.ucb.PersistentPropertySet" ),
1177 : PERS_PROPSET_SERVICE_NAME );
1178 :
1179 :
1180 :
1181 : // XComponent methods.
1182 :
1183 :
1184 :
1185 : // virtual
1186 0 : void SAL_CALL PersistentPropertySet::dispose()
1187 : throw( RuntimeException, std::exception )
1188 : {
1189 0 : if ( m_pImpl->m_pDisposeEventListeners &&
1190 0 : m_pImpl->m_pDisposeEventListeners->getLength() )
1191 : {
1192 0 : EventObject aEvt;
1193 0 : aEvt.Source = static_cast< XComponent * >( this );
1194 0 : m_pImpl->m_pDisposeEventListeners->disposeAndClear( aEvt );
1195 : }
1196 :
1197 0 : if ( m_pImpl->m_pPropSetChangeListeners &&
1198 0 : m_pImpl->m_pPropSetChangeListeners->getLength() )
1199 : {
1200 0 : EventObject aEvt;
1201 0 : aEvt.Source = static_cast< XPropertySetInfoChangeNotifier * >( this );
1202 0 : m_pImpl->m_pPropSetChangeListeners->disposeAndClear( aEvt );
1203 : }
1204 :
1205 0 : if ( m_pImpl->m_pPropertyChangeListeners )
1206 : {
1207 0 : EventObject aEvt;
1208 0 : aEvt.Source = static_cast< XPropertySet * >( this );
1209 0 : m_pImpl->m_pPropertyChangeListeners->disposeAndClear( aEvt );
1210 : }
1211 0 : }
1212 :
1213 :
1214 : // virtual
1215 0 : void SAL_CALL PersistentPropertySet::addEventListener(
1216 : const Reference< XEventListener >& Listener )
1217 : throw( RuntimeException, std::exception )
1218 : {
1219 0 : if ( !m_pImpl->m_pDisposeEventListeners )
1220 : m_pImpl->m_pDisposeEventListeners =
1221 0 : new OInterfaceContainerHelper( m_pImpl->m_aMutex );
1222 :
1223 0 : m_pImpl->m_pDisposeEventListeners->addInterface( Listener );
1224 0 : }
1225 :
1226 :
1227 : // virtual
1228 0 : void SAL_CALL PersistentPropertySet::removeEventListener(
1229 : const Reference< XEventListener >& Listener )
1230 : throw( RuntimeException, std::exception )
1231 : {
1232 0 : if ( m_pImpl->m_pDisposeEventListeners )
1233 0 : m_pImpl->m_pDisposeEventListeners->removeInterface( Listener );
1234 :
1235 : // Note: Don't want to delete empty container here -> performance.
1236 0 : }
1237 :
1238 :
1239 :
1240 : // XPropertySet methods.
1241 :
1242 :
1243 :
1244 : // virtual
1245 0 : Reference< XPropertySetInfo > SAL_CALL PersistentPropertySet::getPropertySetInfo()
1246 : throw( RuntimeException, std::exception )
1247 : {
1248 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
1249 :
1250 0 : PropertySetInfo_Impl*& rpInfo = m_pImpl->m_pInfo;
1251 0 : if ( !rpInfo )
1252 : {
1253 0 : rpInfo = new PropertySetInfo_Impl( m_xContext, this );
1254 0 : rpInfo->acquire();
1255 : }
1256 0 : return Reference< XPropertySetInfo >( rpInfo );
1257 : }
1258 :
1259 :
1260 : // virtual
1261 0 : void SAL_CALL PersistentPropertySet::setPropertyValue( const OUString& aPropertyName,
1262 : const Any& aValue )
1263 : throw( UnknownPropertyException,
1264 : PropertyVetoException,
1265 : IllegalArgumentException,
1266 : WrappedTargetException,
1267 : RuntimeException,
1268 : std::exception )
1269 : {
1270 0 : if ( aPropertyName.isEmpty() )
1271 0 : throw UnknownPropertyException();
1272 :
1273 0 : osl::ClearableGuard< osl::Mutex > aCGuard( m_pImpl->m_aMutex );
1274 :
1275 : Reference< XHierarchicalNameAccess > xRootHierNameAccess(
1276 0 : m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY );
1277 0 : if ( xRootHierNameAccess.is() )
1278 : {
1279 0 : OUString aFullPropName( getFullKey() );
1280 0 : aFullPropName += "/";
1281 0 : aFullPropName += makeHierarchalNameSegment( aPropertyName );
1282 :
1283 : // Does property exist?
1284 0 : if ( xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) )
1285 : {
1286 : Reference< XNameReplace > xNameReplace(
1287 : m_pImpl->m_pCreator->getConfigWriteAccess(
1288 0 : aFullPropName ), UNO_QUERY );
1289 : Reference< XChangesBatch > xBatch(
1290 : m_pImpl->m_pCreator->getConfigWriteAccess(
1291 0 : OUString() ), UNO_QUERY );
1292 :
1293 0 : if ( xNameReplace.is() && xBatch.is() )
1294 : {
1295 : try
1296 : {
1297 : // Obtain old value
1298 0 : OUString aValueName = aFullPropName;
1299 0 : aValueName += "/Value";
1300 : Any aOldValue
1301 0 : = xRootHierNameAccess->getByHierarchicalName(
1302 0 : aValueName );
1303 : // Check value type.
1304 0 : if ( aOldValue.getValueType() != aValue.getValueType() )
1305 : {
1306 0 : aCGuard.clear();
1307 0 : throw IllegalArgumentException();
1308 : }
1309 :
1310 : // Write value
1311 0 : xNameReplace->replaceByName(
1312 : OUString("Value"),
1313 0 : aValue );
1314 :
1315 : // Write state ( Now it is a directly set value )
1316 0 : xNameReplace->replaceByName(
1317 : OUString("State"),
1318 : makeAny(
1319 : sal_Int32(
1320 0 : PropertyState_DIRECT_VALUE ) ) );
1321 :
1322 : // Commit changes.
1323 0 : xBatch->commitChanges();
1324 :
1325 0 : PropertyChangeEvent aEvt;
1326 0 : if ( m_pImpl->m_pPropertyChangeListeners )
1327 : {
1328 : // Obtain handle
1329 0 : aValueName = aFullPropName;
1330 0 : aValueName += "/Handle";
1331 0 : sal_Int32 nHandle = -1;
1332 0 : xRootHierNameAccess->getByHierarchicalName( aValueName )
1333 0 : >>= nHandle;
1334 :
1335 0 : aEvt.Source = static_cast<OWeakObject*>(this);
1336 0 : aEvt.PropertyName = aPropertyName;
1337 0 : aEvt.PropertyHandle = nHandle;
1338 0 : aEvt.Further = sal_False;
1339 0 : aEvt.OldValue = aOldValue;
1340 0 : aEvt.NewValue = aValue;
1341 :
1342 : // Callback follows!
1343 0 : aCGuard.clear();
1344 :
1345 0 : notifyPropertyChangeEvent( aEvt );
1346 : }
1347 0 : return;
1348 : }
1349 0 : catch (const IllegalArgumentException&)
1350 : {
1351 : // replaceByName
1352 : }
1353 0 : catch (const NoSuchElementException&)
1354 : {
1355 : // getByHierarchicalName, replaceByName
1356 : }
1357 0 : catch (const WrappedTargetException&)
1358 : {
1359 : // replaceByName, commitChanges
1360 : }
1361 0 : }
1362 0 : }
1363 : }
1364 :
1365 0 : throw UnknownPropertyException();
1366 : }
1367 :
1368 :
1369 : // virtual
1370 0 : Any SAL_CALL PersistentPropertySet::getPropertyValue(
1371 : const OUString& PropertyName )
1372 : throw( UnknownPropertyException,
1373 : WrappedTargetException,
1374 : RuntimeException, std::exception )
1375 : {
1376 0 : if ( PropertyName.isEmpty() )
1377 0 : throw UnknownPropertyException();
1378 :
1379 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
1380 :
1381 : Reference< XHierarchicalNameAccess > xNameAccess(
1382 0 : m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY );
1383 0 : if ( xNameAccess.is() )
1384 : {
1385 0 : OUString aFullPropName( getFullKey() );
1386 0 : aFullPropName += "/";
1387 0 : aFullPropName += makeHierarchalNameSegment( PropertyName );
1388 0 : aFullPropName += "/Value";
1389 : try
1390 : {
1391 0 : return xNameAccess->getByHierarchicalName( aFullPropName );
1392 : }
1393 0 : catch (const NoSuchElementException&)
1394 : {
1395 0 : throw UnknownPropertyException();
1396 0 : }
1397 : }
1398 :
1399 0 : throw UnknownPropertyException();
1400 : }
1401 :
1402 :
1403 : // virtual
1404 0 : void SAL_CALL PersistentPropertySet::addPropertyChangeListener(
1405 : const OUString& aPropertyName,
1406 : const Reference< XPropertyChangeListener >& xListener )
1407 : throw( UnknownPropertyException,
1408 : WrappedTargetException,
1409 : RuntimeException, std::exception )
1410 : {
1411 : // load();
1412 :
1413 0 : if ( !m_pImpl->m_pPropertyChangeListeners )
1414 : m_pImpl->m_pPropertyChangeListeners =
1415 0 : new PropertyListeners_Impl( m_pImpl->m_aMutex );
1416 :
1417 : m_pImpl->m_pPropertyChangeListeners->addInterface(
1418 0 : aPropertyName, xListener );
1419 0 : }
1420 :
1421 :
1422 : // virtual
1423 0 : void SAL_CALL PersistentPropertySet::removePropertyChangeListener(
1424 : const OUString& aPropertyName,
1425 : const Reference< XPropertyChangeListener >& aListener )
1426 : throw( UnknownPropertyException,
1427 : WrappedTargetException,
1428 : RuntimeException, std::exception )
1429 : {
1430 : // load();
1431 :
1432 0 : if ( m_pImpl->m_pPropertyChangeListeners )
1433 : m_pImpl->m_pPropertyChangeListeners->removeInterface(
1434 0 : aPropertyName, aListener );
1435 :
1436 : // Note: Don't want to delete empty container here -> performance.
1437 0 : }
1438 :
1439 :
1440 : // virtual
1441 0 : void SAL_CALL PersistentPropertySet::addVetoableChangeListener(
1442 : const OUString&,
1443 : const Reference< XVetoableChangeListener >& )
1444 : throw( UnknownPropertyException,
1445 : WrappedTargetException,
1446 : RuntimeException, std::exception )
1447 : {
1448 : // load();
1449 : // OSL_FAIL( // "PersistentPropertySet::addVetoableChangeListener - N.Y.I." );
1450 0 : }
1451 :
1452 :
1453 : // virtual
1454 0 : void SAL_CALL PersistentPropertySet::removeVetoableChangeListener(
1455 : const OUString&,
1456 : const Reference< XVetoableChangeListener >& )
1457 : throw( UnknownPropertyException,
1458 : WrappedTargetException,
1459 : RuntimeException, std::exception )
1460 : {
1461 : // load();
1462 : // OSL_FAIL( // "PersistentPropertySet::removeVetoableChangeListener - N.Y.I." );
1463 0 : }
1464 :
1465 :
1466 :
1467 : // XPersistentPropertySet methods.
1468 :
1469 :
1470 :
1471 : // virtual
1472 0 : Reference< XPropertySetRegistry > SAL_CALL PersistentPropertySet::getRegistry()
1473 : throw( RuntimeException, std::exception )
1474 : {
1475 0 : return Reference< XPropertySetRegistry >( m_pImpl->m_pCreator );
1476 : }
1477 :
1478 :
1479 : // virtual
1480 0 : OUString SAL_CALL PersistentPropertySet::getKey()
1481 : throw( RuntimeException, std::exception )
1482 : {
1483 0 : return m_pImpl->m_aKey;
1484 : }
1485 :
1486 :
1487 :
1488 : // XNamed methods.
1489 :
1490 :
1491 :
1492 : // virtual
1493 0 : OUString SAL_CALL PersistentPropertySet::getName()
1494 : throw( RuntimeException, std::exception )
1495 : {
1496 : // same as getKey()
1497 0 : return m_pImpl->m_aKey;
1498 : }
1499 :
1500 :
1501 : // virtual
1502 0 : void SAL_CALL PersistentPropertySet::setName( const OUString& aName )
1503 : throw( RuntimeException, std::exception )
1504 : {
1505 0 : if ( aName != m_pImpl->m_aKey )
1506 0 : m_pImpl->m_pCreator->renamePropertySet( m_pImpl->m_aKey, aName );
1507 0 : }
1508 :
1509 :
1510 :
1511 : // XPropertyContainer methods.
1512 :
1513 :
1514 :
1515 : // virtual
1516 0 : void SAL_CALL PersistentPropertySet::addProperty(
1517 : const OUString& Name, sal_Int16 Attributes, const Any& DefaultValue )
1518 : throw( PropertyExistException,
1519 : IllegalTypeException,
1520 : IllegalArgumentException,
1521 : RuntimeException, std::exception )
1522 : {
1523 0 : if ( Name.isEmpty() )
1524 0 : throw IllegalArgumentException();
1525 :
1526 : // @@@ What other types can't be written to config server?
1527 :
1528 : // Check type class ( Not all types can be written to storage )
1529 0 : TypeClass eTypeClass = DefaultValue.getValueTypeClass();
1530 0 : if ( eTypeClass == TypeClass_INTERFACE )
1531 0 : throw IllegalTypeException();
1532 :
1533 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
1534 :
1535 : // Property already in set?
1536 :
1537 0 : OUString aFullValuesName;
1538 :
1539 : Reference< XHierarchicalNameAccess > xRootHierNameAccess(
1540 0 : m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY );
1541 0 : if ( xRootHierNameAccess.is() )
1542 : {
1543 0 : aFullValuesName = getFullKey();
1544 0 : OUString aFullPropName = aFullValuesName;
1545 0 : aFullPropName += "/";
1546 0 : aFullPropName += makeHierarchalNameSegment( Name );
1547 :
1548 0 : if ( xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) )
1549 : {
1550 : // Already in set.
1551 0 : throw PropertyExistException();
1552 0 : }
1553 : }
1554 :
1555 : // Property is always removable.
1556 0 : Attributes |= PropertyAttribute::REMOVABLE;
1557 :
1558 : // Add property.
1559 :
1560 : Reference< XSingleServiceFactory > xFac(
1561 : m_pImpl->m_pCreator->getConfigWriteAccess( aFullValuesName ),
1562 0 : UNO_QUERY );
1563 0 : Reference< XNameContainer > xContainer( xFac, UNO_QUERY );
1564 : Reference< XChangesBatch > xBatch(
1565 : m_pImpl->m_pCreator->getConfigWriteAccess( OUString() ),
1566 0 : UNO_QUERY );
1567 :
1568 : OSL_ENSURE( xFac.is(),
1569 : "PersistentPropertySet::addProperty - No factory!" );
1570 :
1571 : OSL_ENSURE( xBatch.is(),
1572 : "PersistentPropertySet::addProperty - No batch!" );
1573 :
1574 : OSL_ENSURE( xContainer.is(),
1575 : "PersistentPropertySet::addProperty - No container!" );
1576 :
1577 0 : if ( xFac.is() && xBatch.is() && xContainer.is() )
1578 : {
1579 : try
1580 : {
1581 : // Create new "PropertyValue" config item.
1582 : Reference< XNameReplace > xNameReplace(
1583 0 : xFac->createInstance(), UNO_QUERY );
1584 :
1585 0 : if ( xNameReplace.is() )
1586 : {
1587 : // Fill new item...
1588 :
1589 : // Set handle
1590 0 : xNameReplace->replaceByName(
1591 : OUString("Handle"),
1592 0 : makeAny( sal_Int32( -1 ) ) );
1593 :
1594 : // Set default value
1595 0 : xNameReplace->replaceByName(
1596 : OUString("Value"),
1597 0 : DefaultValue );
1598 :
1599 : // Set state ( always "default" )
1600 0 : xNameReplace->replaceByName(
1601 : OUString("State"),
1602 : makeAny(
1603 : sal_Int32(
1604 0 : PropertyState_DEFAULT_VALUE ) ) );
1605 :
1606 : // Set attributes
1607 0 : xNameReplace->replaceByName(
1608 : OUString("Attributes"),
1609 0 : makeAny( sal_Int32( Attributes ) ) );
1610 :
1611 : // Insert new item.
1612 0 : xContainer->insertByName( Name, makeAny( xNameReplace ) );
1613 :
1614 : // Commit changes.
1615 0 : xBatch->commitChanges();
1616 :
1617 : // Property set info is invalid.
1618 0 : if ( m_pImpl->m_pInfo )
1619 0 : m_pImpl->m_pInfo->reset();
1620 :
1621 : // Notify propertyset info change listeners.
1622 0 : if ( m_pImpl->m_pPropSetChangeListeners &&
1623 0 : m_pImpl->m_pPropSetChangeListeners->getLength() )
1624 : {
1625 : PropertySetInfoChangeEvent evt(
1626 : static_cast< OWeakObject * >( this ),
1627 : Name,
1628 : -1,
1629 0 : PropertySetInfoChange::PROPERTY_INSERTED );
1630 0 : notifyPropertySetInfoChange( evt );
1631 : }
1632 :
1633 : // Success.
1634 0 : return;
1635 0 : }
1636 : }
1637 0 : catch (const IllegalArgumentException&)
1638 : {
1639 : // insertByName
1640 :
1641 : OSL_FAIL( "PersistentPropertySet::addProperty - "
1642 : "caught IllegalArgumentException!" );
1643 0 : return;
1644 : }
1645 0 : catch (const ElementExistException&)
1646 : {
1647 : // insertByName
1648 :
1649 : OSL_FAIL( "PersistentPropertySet::addProperty - "
1650 : "caught ElementExistException!" );
1651 0 : return;
1652 : }
1653 0 : catch (const WrappedTargetException&)
1654 : {
1655 : // replaceByName, insertByName, commitChanges
1656 :
1657 : OSL_FAIL( "PersistentPropertySet::addProperty - "
1658 : "caught WrappedTargetException!" );
1659 0 : return;
1660 : }
1661 0 : catch (const RuntimeException&)
1662 : {
1663 0 : throw;
1664 : }
1665 0 : catch (const Exception&)
1666 : {
1667 : // createInstance
1668 :
1669 : OSL_FAIL( "PersistentPropertySet::addProperty - "
1670 : "caught Exception!" );
1671 0 : return;
1672 : }
1673 : }
1674 :
1675 0 : OSL_FAIL( "PersistentPropertySet::addProperty - Error!" );
1676 : }
1677 :
1678 :
1679 : // virtual
1680 0 : void SAL_CALL PersistentPropertySet::removeProperty( const OUString& Name )
1681 : throw( UnknownPropertyException,
1682 : NotRemoveableException,
1683 : RuntimeException, std::exception )
1684 : {
1685 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
1686 :
1687 0 : OUString aFullValuesName;
1688 0 : OUString aFullPropName;
1689 :
1690 : Reference< XHierarchicalNameAccess > xRootHierNameAccess(
1691 0 : m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY );
1692 0 : if ( xRootHierNameAccess.is() )
1693 : {
1694 0 : aFullValuesName = getFullKey();
1695 0 : aFullPropName = aFullValuesName;
1696 0 : aFullPropName += "/";
1697 0 : aFullPropName += makeHierarchalNameSegment( Name );
1698 :
1699 : // Property in set?
1700 0 : if ( !xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) )
1701 0 : throw UnknownPropertyException();
1702 :
1703 : // Property removable?
1704 : try
1705 : {
1706 0 : OUString aFullAttrName = aFullPropName;
1707 0 : aFullAttrName += "/Attributes";
1708 :
1709 0 : sal_Int32 nAttribs = 0;
1710 0 : if ( xRootHierNameAccess->getByHierarchicalName( aFullAttrName )
1711 0 : >>= nAttribs )
1712 : {
1713 0 : if ( !( nAttribs & PropertyAttribute::REMOVABLE ) )
1714 : {
1715 : // Not removable!
1716 0 : throw NotRemoveableException();
1717 : }
1718 : }
1719 : else
1720 : {
1721 : OSL_FAIL( "PersistentPropertySet::removeProperty - "
1722 : "No attributes!" );
1723 0 : return;
1724 0 : }
1725 : }
1726 0 : catch (const NoSuchElementException&)
1727 : {
1728 : // getByHierarchicalName
1729 :
1730 : OSL_FAIL( "PersistentPropertySet::removeProperty - "
1731 : "caught NoSuchElementException!" );
1732 : }
1733 :
1734 : // Remove property...
1735 :
1736 : Reference< XNameContainer > xContainer(
1737 : m_pImpl->m_pCreator->getConfigWriteAccess( aFullValuesName ),
1738 0 : UNO_QUERY );
1739 : Reference< XChangesBatch > xBatch(
1740 : m_pImpl->m_pCreator->getConfigWriteAccess( OUString() ),
1741 0 : UNO_QUERY );
1742 :
1743 : OSL_ENSURE( xBatch.is(),
1744 : "PersistentPropertySet::removeProperty - No batch!" );
1745 :
1746 : OSL_ENSURE( xContainer.is(),
1747 : "PersistentPropertySet::removeProperty - No container!" );
1748 :
1749 0 : if ( xBatch.is() && xContainer.is() )
1750 : {
1751 : try
1752 : {
1753 0 : sal_Int32 nHandle = -1;
1754 :
1755 0 : if ( m_pImpl->m_pPropSetChangeListeners &&
1756 0 : m_pImpl->m_pPropSetChangeListeners->getLength() )
1757 : {
1758 : // Obtain property handle ( needed for propertysetinfo
1759 : // change event )...
1760 :
1761 : try
1762 : {
1763 0 : OUString aFullHandleName = aFullPropName;
1764 : aFullHandleName
1765 0 : += "/Handle";
1766 :
1767 0 : if ( ! ( xRootHierNameAccess->getByHierarchicalName(
1768 0 : aFullHandleName ) >>= nHandle ) )
1769 0 : nHandle = -1;
1770 :
1771 : }
1772 0 : catch (const NoSuchElementException&)
1773 : {
1774 : // getByHierarchicalName
1775 :
1776 : OSL_FAIL( "PersistentPropertySet::removeProperty - "
1777 : "caught NoSuchElementException!" );
1778 0 : nHandle = -1;
1779 : }
1780 : }
1781 :
1782 0 : xContainer->removeByName( Name );
1783 0 : xBatch->commitChanges();
1784 :
1785 : // Property set info is invalid.
1786 0 : if ( m_pImpl->m_pInfo )
1787 0 : m_pImpl->m_pInfo->reset();
1788 :
1789 : // Notify propertyset info change listeners.
1790 0 : if ( m_pImpl->m_pPropSetChangeListeners &&
1791 0 : m_pImpl->m_pPropSetChangeListeners->getLength() )
1792 : {
1793 : PropertySetInfoChangeEvent evt(
1794 : static_cast< OWeakObject * >( this ),
1795 : Name,
1796 : nHandle,
1797 0 : PropertySetInfoChange::PROPERTY_REMOVED );
1798 0 : notifyPropertySetInfoChange( evt );
1799 : }
1800 :
1801 : // Success.
1802 0 : return;
1803 : }
1804 0 : catch (const NoSuchElementException&)
1805 : {
1806 : // removeByName
1807 :
1808 : OSL_FAIL( "PersistentPropertySet::removeProperty - "
1809 : "caught NoSuchElementException!" );
1810 0 : return;
1811 : }
1812 0 : catch (const WrappedTargetException&)
1813 : {
1814 : // commitChanges
1815 :
1816 : OSL_FAIL( "PersistentPropertySet::removeProperty - "
1817 : "caught WrappedTargetException!" );
1818 0 : return;
1819 : }
1820 0 : }
1821 : }
1822 :
1823 0 : OSL_FAIL( "PersistentPropertySet::removeProperty - Error!" );
1824 : }
1825 :
1826 :
1827 :
1828 : // XPropertySetInfoChangeNotifier methods.
1829 :
1830 :
1831 :
1832 : // virtual
1833 0 : void SAL_CALL PersistentPropertySet::addPropertySetInfoChangeListener(
1834 : const Reference< XPropertySetInfoChangeListener >& Listener )
1835 : throw( RuntimeException, std::exception )
1836 : {
1837 0 : if ( !m_pImpl->m_pPropSetChangeListeners )
1838 : m_pImpl->m_pPropSetChangeListeners =
1839 0 : new OInterfaceContainerHelper( m_pImpl->m_aMutex );
1840 :
1841 0 : m_pImpl->m_pPropSetChangeListeners->addInterface( Listener );
1842 0 : }
1843 :
1844 :
1845 : // virtual
1846 0 : void SAL_CALL PersistentPropertySet::removePropertySetInfoChangeListener(
1847 : const Reference< XPropertySetInfoChangeListener >& Listener )
1848 : throw( RuntimeException, std::exception )
1849 : {
1850 0 : if ( m_pImpl->m_pPropSetChangeListeners )
1851 0 : m_pImpl->m_pPropSetChangeListeners->removeInterface( Listener );
1852 0 : }
1853 :
1854 :
1855 :
1856 : // XPropertyAccess methods.
1857 :
1858 :
1859 :
1860 : // virtual
1861 0 : Sequence< PropertyValue > SAL_CALL PersistentPropertySet::getPropertyValues()
1862 : throw( RuntimeException, std::exception )
1863 : {
1864 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
1865 :
1866 : Reference< XHierarchicalNameAccess > xRootHierNameAccess(
1867 0 : m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY );
1868 0 : if ( xRootHierNameAccess.is() )
1869 : {
1870 : try
1871 : {
1872 0 : Reference< XNameAccess > xNameAccess;
1873 0 : xRootHierNameAccess->getByHierarchicalName(getFullKey())
1874 0 : >>= xNameAccess;
1875 0 : if ( xNameAccess.is() )
1876 : {
1877 : // Obtain property names.
1878 :
1879 0 : Sequence< OUString > aElems = xNameAccess->getElementNames();
1880 :
1881 0 : sal_Int32 nCount = aElems.getLength();
1882 0 : if ( nCount )
1883 : {
1884 : Reference< XHierarchicalNameAccess > xHierNameAccess(
1885 0 : xNameAccess, UNO_QUERY );
1886 :
1887 : OSL_ENSURE( xHierNameAccess.is(),
1888 : "PersistentPropertySet::getPropertyValues - "
1889 : "No hierarchical name access!" );
1890 :
1891 0 : if ( xHierNameAccess.is() )
1892 : {
1893 0 : Sequence< PropertyValue > aValues( nCount );
1894 :
1895 0 : const OUString aHandleName("/Handle");
1896 0 : const OUString aValueName("/Value");
1897 0 : const OUString aStateName("/State");
1898 :
1899 0 : for ( sal_Int32 n = 0; n < nCount; ++n )
1900 : {
1901 0 : PropertyValue& rValue = aValues[ n ];
1902 0 : OUString rName = aElems[ n ];
1903 : OUString aXMLName
1904 0 : = makeHierarchalNameSegment( rName );
1905 :
1906 : // Set property name.
1907 :
1908 0 : rValue.Name = rName;
1909 :
1910 : try
1911 : {
1912 : // Obtain and set property handle
1913 0 : OUString aHierName = aXMLName;
1914 0 : aHierName += aHandleName;
1915 : Any aKeyValue
1916 0 : = xHierNameAccess->getByHierarchicalName(
1917 0 : aHierName );
1918 :
1919 0 : if ( !( aKeyValue >>= rValue.Handle ) )
1920 : OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1921 0 : "Error getting property handle!" );
1922 : }
1923 0 : catch (const NoSuchElementException&)
1924 : {
1925 : // getByHierarchicalName
1926 :
1927 : OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1928 : "NoSuchElementException!" );
1929 : }
1930 :
1931 : try
1932 : {
1933 : // Obtain and set property value
1934 0 : OUString aHierName = aXMLName;
1935 0 : aHierName += aValueName;
1936 : rValue.Value
1937 0 : = xHierNameAccess->getByHierarchicalName(
1938 0 : aHierName );
1939 :
1940 : // Note: The value may be void if addProperty
1941 : // was called with a default value
1942 : // of type void.
1943 : }
1944 0 : catch (const NoSuchElementException&)
1945 : {
1946 : // getByHierarchicalName
1947 :
1948 : OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1949 : "NoSuchElementException!" );
1950 : }
1951 :
1952 : try
1953 : {
1954 : // Obtain and set property state
1955 0 : OUString aHierName = aXMLName;
1956 0 : aHierName += aStateName;
1957 : Any aKeyValue
1958 0 : = xHierNameAccess->getByHierarchicalName(
1959 0 : aHierName );
1960 :
1961 0 : sal_Int32 nState = 0;
1962 0 : if ( !( aKeyValue >>= nState ) )
1963 : OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1964 : "Error getting property state!" );
1965 : else
1966 0 : rValue.State = PropertyState( nState );
1967 : }
1968 0 : catch (const NoSuchElementException&)
1969 : {
1970 : // getByHierarchicalName
1971 :
1972 : OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1973 : "NoSuchElementException!" );
1974 : }
1975 0 : }
1976 :
1977 0 : return aValues;
1978 0 : }
1979 0 : }
1980 0 : }
1981 : }
1982 0 : catch (const NoSuchElementException&)
1983 : {
1984 : // getByHierarchicalName
1985 : }
1986 : }
1987 :
1988 0 : return Sequence< PropertyValue >( 0 );
1989 : }
1990 :
1991 :
1992 : // virtual
1993 0 : void SAL_CALL PersistentPropertySet::setPropertyValues(
1994 : const Sequence< PropertyValue >& aProps )
1995 : throw( UnknownPropertyException,
1996 : PropertyVetoException,
1997 : IllegalArgumentException,
1998 : WrappedTargetException,
1999 : RuntimeException, std::exception )
2000 : {
2001 0 : sal_Int32 nCount = aProps.getLength();
2002 0 : if ( !nCount )
2003 0 : return;
2004 :
2005 0 : osl::ClearableGuard< osl::Mutex > aCGuard( m_pImpl->m_aMutex );
2006 :
2007 : Reference< XHierarchicalNameAccess > xRootHierNameAccess(
2008 0 : m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY );
2009 0 : if ( xRootHierNameAccess.is() )
2010 : {
2011 0 : const PropertyValue* pNewValues = aProps.getConstArray();
2012 :
2013 : typedef std::list< PropertyChangeEvent > Events;
2014 0 : Events aEvents;
2015 :
2016 0 : OUString aFullPropNamePrefix( getFullKey() );
2017 0 : aFullPropNamePrefix += "/";
2018 :
2019 : // Iterate over given property value sequence.
2020 0 : for ( sal_Int32 n = 0; n < nCount; ++n )
2021 : {
2022 0 : const PropertyValue& rNewValue = pNewValues[ n ];
2023 0 : const OUString& rName = rNewValue.Name;
2024 :
2025 0 : OUString aFullPropName = aFullPropNamePrefix;
2026 0 : aFullPropName += makeHierarchalNameSegment( rName );
2027 :
2028 : // Does property exist?
2029 0 : if ( xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) )
2030 : {
2031 : Reference< XNameReplace > xNameReplace(
2032 : m_pImpl->m_pCreator->getConfigWriteAccess(
2033 0 : aFullPropName ), UNO_QUERY );
2034 : Reference< XChangesBatch > xBatch(
2035 : m_pImpl->m_pCreator->getConfigWriteAccess(
2036 0 : OUString() ), UNO_QUERY );
2037 :
2038 0 : if ( xNameReplace.is() && xBatch.is() )
2039 : {
2040 : try
2041 : {
2042 : // Write handle
2043 0 : xNameReplace->replaceByName(
2044 : OUString("Handle"),
2045 0 : makeAny( rNewValue.Handle ) );
2046 :
2047 : // Save old value
2048 0 : OUString aValueName = aFullPropName;
2049 0 : aValueName += "/Value";
2050 : Any aOldValue
2051 0 : = xRootHierNameAccess->getByHierarchicalName(
2052 0 : aValueName );
2053 : // Write value
2054 0 : xNameReplace->replaceByName(
2055 : OUString("Value"),
2056 0 : rNewValue.Value );
2057 :
2058 : // Write state ( Now it is a directly set value )
2059 0 : xNameReplace->replaceByName(
2060 : OUString("State"),
2061 : makeAny(
2062 : sal_Int32(
2063 0 : PropertyState_DIRECT_VALUE ) ) );
2064 :
2065 : // Commit changes.
2066 0 : xBatch->commitChanges();
2067 :
2068 0 : if ( m_pImpl->m_pPropertyChangeListeners )
2069 : {
2070 0 : PropertyChangeEvent aEvt;
2071 0 : aEvt.Source = static_cast<OWeakObject*>(this);
2072 0 : aEvt.PropertyName = rNewValue.Name;
2073 0 : aEvt.PropertyHandle = rNewValue.Handle;
2074 0 : aEvt.Further = sal_False;
2075 0 : aEvt.OldValue = aOldValue;
2076 0 : aEvt.NewValue = rNewValue.Value;
2077 :
2078 0 : aEvents.push_back( aEvt );
2079 0 : }
2080 : }
2081 0 : catch (const IllegalArgumentException&)
2082 : {
2083 : // replaceByName
2084 : }
2085 0 : catch (const NoSuchElementException&)
2086 : {
2087 : // getByHierarchicalName, replaceByName
2088 : }
2089 0 : catch (const WrappedTargetException&)
2090 : {
2091 : // replaceByName, commitChanges
2092 : }
2093 0 : }
2094 : }
2095 0 : }
2096 :
2097 : // Callback follows!
2098 0 : aCGuard.clear();
2099 :
2100 0 : if ( m_pImpl->m_pPropertyChangeListeners )
2101 : {
2102 : // Notify property changes.
2103 0 : Events::const_iterator it = aEvents.begin();
2104 0 : Events::const_iterator end = aEvents.end();
2105 :
2106 0 : while ( it != end )
2107 : {
2108 0 : notifyPropertyChangeEvent( (*it) );
2109 0 : ++it;
2110 : }
2111 : }
2112 :
2113 0 : return;
2114 : }
2115 :
2116 0 : OSL_FAIL( "PersistentPropertySet::setPropertyValues - Nothing set!" );
2117 : }
2118 :
2119 :
2120 :
2121 : // Non-interface methods
2122 :
2123 :
2124 :
2125 0 : void PersistentPropertySet::notifyPropertyChangeEvent(
2126 : const PropertyChangeEvent& rEvent ) const
2127 : {
2128 : // Get "normal" listeners for the property.
2129 : OInterfaceContainerHelper* pContainer =
2130 : m_pImpl->m_pPropertyChangeListeners->getContainer(
2131 0 : rEvent.PropertyName );
2132 0 : if ( pContainer && pContainer->getLength() )
2133 : {
2134 0 : OInterfaceIteratorHelper aIter( *pContainer );
2135 0 : while ( aIter.hasMoreElements() )
2136 : {
2137 : // Propagate event.
2138 : Reference< XPropertyChangeListener > xListener(
2139 0 : aIter.next(), UNO_QUERY );
2140 0 : if ( xListener.is() )
2141 0 : xListener->propertyChange( rEvent );
2142 0 : }
2143 : }
2144 :
2145 : // Get "normal" listeners for all properties.
2146 : OInterfaceContainerHelper* pNoNameContainer =
2147 0 : m_pImpl->m_pPropertyChangeListeners->getContainer( OUString() );
2148 0 : if ( pNoNameContainer && pNoNameContainer->getLength() )
2149 : {
2150 0 : OInterfaceIteratorHelper aIter( *pNoNameContainer );
2151 0 : while ( aIter.hasMoreElements() )
2152 : {
2153 : // Propagate event.
2154 : Reference< XPropertyChangeListener > xListener(
2155 0 : aIter.next(), UNO_QUERY );
2156 0 : if ( xListener.is() )
2157 0 : xListener->propertyChange( rEvent );
2158 0 : }
2159 : }
2160 0 : }
2161 :
2162 :
2163 0 : void PersistentPropertySet::notifyPropertySetInfoChange(
2164 : const PropertySetInfoChangeEvent& evt ) const
2165 : {
2166 0 : if ( !m_pImpl->m_pPropSetChangeListeners )
2167 0 : return;
2168 :
2169 : // Notify event listeners.
2170 0 : OInterfaceIteratorHelper aIter( *( m_pImpl->m_pPropSetChangeListeners ) );
2171 0 : while ( aIter.hasMoreElements() )
2172 : {
2173 : // Propagate event.
2174 : Reference< XPropertySetInfoChangeListener >
2175 0 : xListener( aIter.next(), UNO_QUERY );
2176 0 : if ( xListener.is() )
2177 0 : xListener->propertySetInfoChange( evt );
2178 0 : }
2179 : }
2180 :
2181 :
2182 0 : const OUString& PersistentPropertySet::getFullKey()
2183 : {
2184 0 : if ( m_pImpl->m_aFullKey.isEmpty() )
2185 : {
2186 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
2187 0 : if ( m_pImpl->m_aFullKey.isEmpty() )
2188 : {
2189 : m_pImpl->m_aFullKey
2190 0 : = makeHierarchalNameSegment( m_pImpl->m_aKey );
2191 : m_pImpl->m_aFullKey
2192 0 : += "/Values";
2193 0 : }
2194 : }
2195 :
2196 0 : return m_pImpl->m_aFullKey;
2197 : }
2198 :
2199 :
2200 0 : PropertySetRegistry& PersistentPropertySet::getPropertySetRegistry()
2201 : {
2202 0 : return *m_pImpl->m_pCreator;
2203 : }
2204 :
2205 :
2206 :
2207 :
2208 : // PropertySetInfo_Impl Implementation.
2209 :
2210 :
2211 :
2212 :
2213 0 : PropertySetInfo_Impl::PropertySetInfo_Impl(
2214 : const Reference< XComponentContext >& xContext,
2215 : PersistentPropertySet* pOwner )
2216 : : m_xContext( xContext ),
2217 : m_pProps( NULL ),
2218 0 : m_pOwner( pOwner )
2219 : {
2220 0 : }
2221 :
2222 :
2223 : // virtual
2224 0 : PropertySetInfo_Impl::~PropertySetInfo_Impl()
2225 : {
2226 0 : delete m_pProps;
2227 :
2228 : // !!! Do not delete m_pOwner !!!
2229 0 : }
2230 :
2231 : // XPropertySetInfo methods.
2232 :
2233 :
2234 :
2235 : // virtual
2236 0 : Sequence< Property > SAL_CALL PropertySetInfo_Impl::getProperties()
2237 : throw( RuntimeException, std::exception )
2238 : {
2239 0 : if ( !m_pProps )
2240 : {
2241 : Reference< XHierarchicalNameAccess > xRootHierNameAccess(
2242 0 : m_pOwner->getPropertySetRegistry().getRootConfigReadAccess(),
2243 0 : UNO_QUERY );
2244 0 : if ( xRootHierNameAccess.is() )
2245 : {
2246 : try
2247 : {
2248 0 : Reference< XNameAccess > xNameAccess;
2249 0 : xRootHierNameAccess->getByHierarchicalName(
2250 0 : m_pOwner->getFullKey() )
2251 0 : >>= xNameAccess;
2252 0 : if ( xNameAccess.is() )
2253 : {
2254 : // Obtain property names.
2255 :
2256 : Sequence< OUString > aElems
2257 0 : = xNameAccess->getElementNames();
2258 :
2259 0 : sal_uInt32 nCount = aElems.getLength();
2260 : Sequence< Property >* pPropSeq
2261 0 : = new Sequence< Property >( nCount );
2262 :
2263 0 : if ( nCount )
2264 : {
2265 : Reference< XHierarchicalNameAccess > xHierNameAccess(
2266 0 : xNameAccess, UNO_QUERY );
2267 :
2268 : OSL_ENSURE( xHierNameAccess.is(),
2269 : "PropertySetInfo_Impl::getProperties - "
2270 : "No hierarchical name access!" );
2271 :
2272 0 : if ( xHierNameAccess.is() )
2273 : {
2274 0 : const OUString aHandleName("/Handle");
2275 0 : const OUString aValueName("/Value");
2276 0 : const OUString aAttrName("/Attributes");
2277 :
2278 0 : Property* pProps = pPropSeq->getArray();
2279 :
2280 0 : for ( sal_uInt32 n = 0; n < nCount; ++n )
2281 : {
2282 0 : Property& rProp = pProps[ n ];
2283 0 : OUString rName = aElems[ n ];
2284 : OUString aXMLName
2285 0 : = makeHierarchalNameSegment( rName );
2286 :
2287 : // Set property name.
2288 :
2289 0 : rProp.Name = rName;
2290 :
2291 : try
2292 : {
2293 : // Obtain and set property handle
2294 0 : OUString aHierName = aXMLName;
2295 0 : aHierName += aHandleName;
2296 : Any aKeyValue
2297 0 : = xHierNameAccess->getByHierarchicalName(
2298 0 : aHierName );
2299 :
2300 0 : if ( !( aKeyValue >>= rProp.Handle ) )
2301 : OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2302 0 : "Error getting property handle!" );
2303 : }
2304 0 : catch (const NoSuchElementException&)
2305 : {
2306 : // getByHierarchicalName
2307 :
2308 : OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2309 : "NoSuchElementException!" );
2310 : }
2311 :
2312 : try
2313 : {
2314 : // Obtain and set property type
2315 0 : OUString aHierName = aXMLName;
2316 0 : aHierName += aValueName;
2317 : Any aKeyValue
2318 0 : = xHierNameAccess->getByHierarchicalName(
2319 0 : aHierName );
2320 :
2321 : // Note: The type may be void if addProperty
2322 : // was called with a default value
2323 : // of type void.
2324 :
2325 0 : rProp.Type = aKeyValue.getValueType();
2326 : }
2327 0 : catch (const NoSuchElementException&)
2328 : {
2329 : // getByHierarchicalName
2330 :
2331 : OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2332 : "NoSuchElementException!" );
2333 : }
2334 :
2335 : try
2336 : {
2337 : // Obtain and set property attributes
2338 0 : OUString aHierName = aXMLName;
2339 0 : aHierName += aAttrName;
2340 : Any aKeyValue
2341 0 : = xHierNameAccess->getByHierarchicalName(
2342 0 : aHierName );
2343 :
2344 0 : sal_Int32 nAttribs = 0;
2345 0 : if ( aKeyValue >>= nAttribs )
2346 : rProp.Attributes
2347 0 : = sal_Int16( nAttribs );
2348 : else
2349 : OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2350 0 : "Error getting property attributes!" );
2351 : }
2352 0 : catch (const NoSuchElementException&)
2353 : {
2354 : // getByHierarchicalName
2355 :
2356 : OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2357 : "NoSuchElementException!" );
2358 : }
2359 0 : }
2360 0 : }
2361 : }
2362 :
2363 : // Success.
2364 0 : m_pProps = pPropSeq;
2365 0 : return *m_pProps;
2366 0 : }
2367 : }
2368 0 : catch (const NoSuchElementException&)
2369 : {
2370 : // getByHierarchicalName
2371 : }
2372 : }
2373 :
2374 : OSL_FAIL( "PropertySetInfo_Impl::getProperties - Error!" );
2375 0 : m_pProps = new Sequence< Property >( 0 );
2376 : }
2377 :
2378 0 : return *m_pProps;
2379 : }
2380 :
2381 :
2382 : // virtual
2383 0 : Property SAL_CALL PropertySetInfo_Impl::getPropertyByName(
2384 : const OUString& aName )
2385 : throw( UnknownPropertyException, RuntimeException, std::exception )
2386 : {
2387 : Reference< XHierarchicalNameAccess > xRootHierNameAccess(
2388 0 : m_pOwner->getPropertySetRegistry().getRootConfigReadAccess(),
2389 0 : UNO_QUERY );
2390 0 : if ( xRootHierNameAccess.is() )
2391 : {
2392 0 : OUString aFullPropName( m_pOwner->getFullKey() );
2393 0 : aFullPropName += "/";
2394 0 : aFullPropName += makeHierarchalNameSegment( aName );
2395 :
2396 : // Does property exist?
2397 0 : if ( !xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) )
2398 0 : throw UnknownPropertyException();
2399 :
2400 : try
2401 : {
2402 0 : Property aProp;
2403 :
2404 : // Obtain handle.
2405 0 : OUString aKey = aFullPropName;
2406 0 : aKey += "/Handle";
2407 :
2408 0 : if ( !( xRootHierNameAccess->getByHierarchicalName( aKey )
2409 0 : >>= aProp.Handle ) )
2410 : {
2411 : OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2412 : "No handle!" );
2413 0 : return Property();
2414 : }
2415 :
2416 : // Obtain Value and extract type.
2417 0 : aKey = aFullPropName;
2418 0 : aKey += "/Value";
2419 :
2420 0 : Any aValue = xRootHierNameAccess->getByHierarchicalName( aKey );
2421 0 : if ( !aValue.hasValue() )
2422 : {
2423 : OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2424 : "No Value!" );
2425 0 : return Property();
2426 : }
2427 :
2428 0 : aProp.Type = aValue.getValueType();
2429 :
2430 : // Obtain Attributes.
2431 0 : aKey = aFullPropName;
2432 0 : aKey += "/Attributes";
2433 :
2434 0 : sal_Int32 nAttribs = 0;
2435 0 : if ( xRootHierNameAccess->getByHierarchicalName( aKey )
2436 0 : >>= nAttribs )
2437 0 : aProp.Attributes = sal_Int16( nAttribs );
2438 : else
2439 : {
2440 : OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2441 : "No attributes!" );
2442 0 : return Property();
2443 : }
2444 :
2445 : // set name.
2446 0 : aProp.Name = aName;
2447 :
2448 : // Success.
2449 0 : return aProp;
2450 : }
2451 0 : catch (const NoSuchElementException&)
2452 : {
2453 : // getByHierarchicalName
2454 :
2455 : OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2456 : "caught NoSuchElementException!" );
2457 0 : }
2458 :
2459 : }
2460 :
2461 : OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - Error!" );
2462 0 : return Property();
2463 : }
2464 :
2465 :
2466 : // virtual
2467 0 : sal_Bool SAL_CALL PropertySetInfo_Impl::hasPropertyByName(
2468 : const OUString& Name )
2469 : throw( RuntimeException, std::exception )
2470 : {
2471 : Reference< XHierarchicalNameAccess > xRootHierNameAccess(
2472 0 : m_pOwner->getPropertySetRegistry().getRootConfigReadAccess(),
2473 0 : UNO_QUERY );
2474 0 : if ( xRootHierNameAccess.is() )
2475 : {
2476 0 : OUString aFullPropName( m_pOwner->getFullKey() );
2477 0 : aFullPropName += "/";
2478 0 : aFullPropName += makeHierarchalNameSegment( Name );
2479 :
2480 0 : return xRootHierNameAccess->hasByHierarchicalName( aFullPropName );
2481 : }
2482 :
2483 0 : return sal_False;
2484 : }
2485 :
2486 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|