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