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 <osl/diagnose.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 <ucbhelper/getcomponentcontext.hxx>
49 #include <ucbhelper/macros.hxx>
50 #include <tools/diagnose_ex.h>
51 #include "ucbstore.hxx"
52
53 using namespace com::sun::star::beans;
54 using namespace com::sun::star::configuration;
55 using namespace com::sun::star::container;
56 using namespace com::sun::star::lang;
57 using namespace com::sun::star::ucb;
58 using namespace com::sun::star::uno;
59 using namespace com::sun::star::util;
60 using namespace comphelper;
61 using namespace cppu;
62
63
makeHierarchalNameSegment(const OUString & rIn)64 static OUString makeHierarchalNameSegment( const OUString & rIn )
65 {
66 OUStringBuffer aBuffer;
67 aBuffer.append( "['" );
68
69 sal_Int32 nCount = rIn.getLength();
70 for ( sal_Int32 n = 0; n < nCount; ++n )
71 {
72 const sal_Unicode c = rIn[ n ];
73 switch ( c )
74 {
75 case '&':
76 aBuffer.append( "&" );
77 break;
78
79 case '"':
80 aBuffer.append( """ );
81 break;
82
83 case '\'':
84 aBuffer.append( "'" );
85 break;
86
87 case '<':
88 aBuffer.append( "<" );
89 break;
90
91 case '>':
92 aBuffer.append( ">" );
93 break;
94
95 default:
96 aBuffer.append( c );
97 break;
98 }
99 }
100
101 aBuffer.append( "']" );
102 return aBuffer.makeStringAndClear();
103 }
104
105 #define STORE_CONTENTPROPERTIES_KEY "/org.openoffice.ucb.Store/ContentProperties"
106
107 // describe path of cfg entry
108 #define CFGPROPERTY_NODEPATH "nodepath"
109
110 // PropertySetMap_Impl.
111 typedef std::unordered_map< OUString, PersistentPropertySet*> PropertySetMap_Impl;
112
113 // class PropertySetInfo_Impl
114 class PropertySetInfo_Impl : public cppu::WeakImplHelper < XPropertySetInfo >
115 {
116 std::unique_ptr<Sequence< Property >>
117 m_pProps;
118 PersistentPropertySet* m_pOwner;
119
120 public:
121 explicit PropertySetInfo_Impl(PersistentPropertySet* pOwner);
122
123 // XPropertySetInfo
124 virtual Sequence< Property > SAL_CALL getProperties() override;
125 virtual Property SAL_CALL getPropertyByName( const OUString& aName ) override;
126 virtual sal_Bool SAL_CALL hasPropertyByName( const OUString& Name ) override;
127
128 // Non-interface methods.
reset()129 void reset() { m_pProps.reset(); }
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 : m_xContext( xContext ),
149 m_pImpl( new UcbStore_Impl )
150 {
151 }
152
153
154 // virtual
~UcbStore()155 UcbStore::~UcbStore()
156 {
157 }
158
159 XSERVICEINFO_COMMOM_IMPL( UcbStore,
160 "com.sun.star.comp.ucb.UcbStore" )
161 /// @throws css::uno::Exception
162 static css::uno::Reference< css::uno::XInterface >
UcbStore_CreateInstance(const css::uno::Reference<css::lang::XMultiServiceFactory> & rSMgr)163 UcbStore_CreateInstance( const css::uno::Reference< css::lang::XMultiServiceFactory> & rSMgr )
164 {
165 return static_cast<css::lang::XServiceInfo*>(
166 new UcbStore(ucbhelper::getComponentContext(rSMgr)));
167 }
168
169 css::uno::Sequence< OUString >
getSupportedServiceNames_Static()170 UcbStore::getSupportedServiceNames_Static()
171 {
172 css::uno::Sequence< OUString > aSNS { STORE_SERVICE_NAME };
173 return aSNS;
174 }
175
176 // Service factory implementation.
177
178
179 ONE_INSTANCE_SERVICE_FACTORY_IMPL( UcbStore );
180
181
182 // XPropertySetRegistryFactory methods.
183
184
185 // virtual
186 Reference< XPropertySetRegistry > SAL_CALL
createPropertySetRegistry(const OUString &)187 UcbStore::createPropertySetRegistry( const OUString& )
188 {
189 // The URL parameter is ignored by this interface implementation. It always
190 // uses the configuration server as storage medium.
191
192 if ( !m_pImpl->m_xTheRegistry.is() )
193 {
194 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
195 if ( !m_pImpl->m_xTheRegistry.is() )
196 m_pImpl->m_xTheRegistry = new PropertySetRegistry( m_xContext, m_pImpl->m_aInitArgs );
197 }
198
199 return m_pImpl->m_xTheRegistry;
200 }
201
202
203 // XInitialization methods.
204
205
206 // virtual
initialize(const Sequence<Any> & aArguments)207 void SAL_CALL UcbStore::initialize( const Sequence< Any >& aArguments )
208 {
209 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
210 m_pImpl->m_aInitArgs = aArguments;
211 }
212
213
214
215 // PropertySetRegistry_Impl.
216
217
218 struct PropertySetRegistry_Impl
219 {
220 const Sequence< Any > m_aInitArgs;
221 PropertySetMap_Impl m_aPropSets;
222 Reference< XMultiServiceFactory > m_xConfigProvider;
223 Reference< XInterface > m_xRootReadAccess;
224 Reference< XInterface > m_xRootWriteAccess;
225 osl::Mutex m_aMutex;
226 bool m_bTriedToGetRootReadAccess;
227 bool m_bTriedToGetRootWriteAccess;
228
PropertySetRegistry_ImplPropertySetRegistry_Impl229 explicit PropertySetRegistry_Impl(const Sequence<Any> &rInitArgs)
230 : m_aInitArgs(rInitArgs)
231 , m_bTriedToGetRootReadAccess(false)
232 , m_bTriedToGetRootWriteAccess(false)
233 {
234 }
235 };
236
237 // PropertySetRegistry Implementation.
238
239
PropertySetRegistry(const Reference<XComponentContext> & xContext,const Sequence<Any> & rInitArgs)240 PropertySetRegistry::PropertySetRegistry(
241 const Reference< XComponentContext >& xContext,
242 const Sequence< Any > &rInitArgs )
243 : m_xContext( xContext ),
244 m_pImpl( new PropertySetRegistry_Impl( rInitArgs ) )
245 {
246 }
247
248
249 // virtual
~PropertySetRegistry()250 PropertySetRegistry::~PropertySetRegistry()
251 {
252 }
253
254
255 // XServiceInfo methods.
256
257
getImplementationName()258 OUString SAL_CALL PropertySetRegistry::getImplementationName()
259 {
260 return "com.sun.star.comp.ucb.PropertySetRegistry";
261 }
262
supportsService(const OUString & ServiceName)263 sal_Bool SAL_CALL PropertySetRegistry::supportsService( const OUString& ServiceName )
264 {
265 return cppu::supportsService( this, ServiceName );
266 }
267
getSupportedServiceNames()268 css::uno::Sequence< OUString > SAL_CALL PropertySetRegistry::getSupportedServiceNames()
269 {
270 return { PROPSET_REG_SERVICE_NAME };
271 }
272
273
274 // XPropertySetRegistry methods.
275
276
277 // virtual
278 Reference< XPersistentPropertySet > SAL_CALL
openPropertySet(const OUString & key,sal_Bool create)279 PropertySetRegistry::openPropertySet( const OUString& key, sal_Bool create )
280 {
281 if ( !key.isEmpty() )
282 {
283 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
284
285 PropertySetMap_Impl& rSets = m_pImpl->m_aPropSets;
286
287 PropertySetMap_Impl::const_iterator it = rSets.find( key );
288 if ( it != rSets.end() )
289 {
290 // Already instantiated.
291 return Reference< XPersistentPropertySet >( (*it).second );
292 }
293 else
294 {
295 // Create new instance.
296 Reference< XNameAccess > xRootNameAccess(
297 getRootConfigReadAccess(), UNO_QUERY );
298 if ( xRootNameAccess.is() )
299 {
300 // Propertyset in registry?
301 if ( xRootNameAccess->hasByName( key ) )
302 {
303 // Yep!
304 return Reference< XPersistentPropertySet >(
305 new PersistentPropertySet(
306 *this, key ) );
307 }
308 else if ( create )
309 {
310 // No. Create entry for propertyset.
311
312 Reference< XSingleServiceFactory > xFac(
313 getConfigWriteAccess( OUString() ), UNO_QUERY );
314 Reference< XChangesBatch > xBatch( xFac, UNO_QUERY );
315 Reference< XNameContainer > xContainer( xFac, UNO_QUERY );
316
317 OSL_ENSURE( xFac.is(),
318 "PropertySetRegistry::openPropertySet - "
319 "No factory!" );
320
321 OSL_ENSURE( xBatch.is(),
322 "PropertySetRegistry::openPropertySet - "
323 "No batch!" );
324
325 OSL_ENSURE( xContainer.is(),
326 "PropertySetRegistry::openPropertySet - "
327 "No container!" );
328
329 if ( xFac.is() && xBatch.is() && xContainer.is() )
330 {
331 try
332 {
333 // Create new "Properties" config item.
334 Reference< XNameReplace > xNameReplace(
335 xFac->createInstance(), UNO_QUERY );
336
337 if ( xNameReplace.is() )
338 {
339 // Fill new item...
340
341 // Insert new item.
342 xContainer->insertByName(
343 key, makeAny( xNameReplace ) );
344 // Commit changes.
345 xBatch->commitChanges();
346
347 return Reference< XPersistentPropertySet >(
348 new PersistentPropertySet(
349 *this, key ) );
350 }
351 }
352 catch (const IllegalArgumentException&)
353 {
354 // insertByName
355
356 OSL_FAIL( "PropertySetRegistry::openPropertySet - "
357 "caught IllegalArgumentException!" );
358 }
359 catch (const ElementExistException&)
360 {
361 // insertByName
362
363 OSL_FAIL( "PropertySetRegistry::openPropertySet - "
364 "caught ElementExistException!" );
365 }
366 catch (const WrappedTargetException&)
367 {
368 // insertByName, commitChanges
369
370 OSL_FAIL( "PropertySetRegistry::openPropertySet - "
371 "caught WrappedTargetException!" );
372 }
373 catch (const RuntimeException&)
374 {
375 OSL_FAIL( "PropertySetRegistry::openPropertySet - "
376 "caught RuntimeException!" );
377 }
378 catch (const Exception&)
379 {
380 // createInstance
381
382 OSL_FAIL( "PropertySetRegistry::openPropertySet - "
383 "caught Exception!" );
384 }
385 }
386 }
387 else
388 {
389 // No entry. Fail, but no error.
390 return Reference< XPersistentPropertySet >();
391 }
392 }
393
394 SAL_WARN( "ucb", "no root access" );
395 }
396 }
397
398 return Reference< XPersistentPropertySet >();
399 }
400
401
402 // virtual
removePropertySet(const OUString & key)403 void SAL_CALL PropertySetRegistry::removePropertySet( const OUString& key )
404 {
405 if ( key.isEmpty() )
406 return;
407
408 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
409
410 Reference< XNameAccess > xRootNameAccess(
411 getRootConfigReadAccess(), UNO_QUERY );
412 if ( xRootNameAccess.is() )
413 {
414 // Propertyset in registry?
415 if ( !xRootNameAccess->hasByName( key ) )
416 return;
417 Reference< XChangesBatch > xBatch(
418 getConfigWriteAccess( OUString() ), UNO_QUERY );
419 Reference< XNameContainer > xContainer( xBatch, UNO_QUERY );
420
421 if ( xBatch.is() && xContainer.is() )
422 {
423 try
424 {
425 // Remove item.
426 xContainer->removeByName( key );
427 // Commit changes.
428 xBatch->commitChanges();
429
430 // Success.
431 return;
432 }
433 catch (const NoSuchElementException&)
434 {
435 // removeByName
436
437 OSL_FAIL( "PropertySetRegistry::removePropertySet - "
438 "caught NoSuchElementException!" );
439 return;
440 }
441 catch (const WrappedTargetException&)
442 {
443 // commitChanges
444
445 OSL_FAIL( "PropertySetRegistry::removePropertySet - "
446 "caught WrappedTargetException!" );
447 return;
448 }
449 }
450
451 return;
452 }
453
454 SAL_WARN( "ucb", "no root access" );
455 }
456
457
458 // XElementAccess methods.
459
460
461 // virtual
getElementType()462 css::uno::Type SAL_CALL PropertySetRegistry::getElementType()
463 {
464 return cppu::UnoType<XPersistentPropertySet>::get();
465 }
466
467
468 // virtual
hasElements()469 sal_Bool SAL_CALL PropertySetRegistry::hasElements()
470 {
471 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
472
473 Reference< XElementAccess > xElemAccess(
474 getRootConfigReadAccess(), UNO_QUERY );
475 if ( xElemAccess.is() )
476 return xElemAccess->hasElements();
477
478 return false;
479 }
480
481
482 // XNameAccess methods.
483
484
485 // virtual
getByName(const OUString & aName)486 Any SAL_CALL PropertySetRegistry::getByName( const OUString& aName )
487 {
488 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
489
490 Reference< XNameAccess > xNameAccess(
491 getRootConfigReadAccess(), UNO_QUERY );
492 if ( xNameAccess.is() )
493 {
494
495 try
496 {
497 return xNameAccess->getByName( aName );
498 }
499 catch (const NoSuchElementException&)
500 {
501 // getByName
502 }
503 catch (const WrappedTargetException&)
504 {
505 // getByName
506 }
507 }
508
509 return Any();
510 }
511
512
513 // virtual
getElementNames()514 Sequence< OUString > SAL_CALL PropertySetRegistry::getElementNames()
515 {
516 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
517
518 Reference< XNameAccess > xNameAccess(
519 getRootConfigReadAccess(), UNO_QUERY );
520 if ( xNameAccess.is() )
521 {
522 return xNameAccess->getElementNames();
523 }
524 return Sequence< OUString >( 0 );
525 }
526
527
528 // virtual
hasByName(const OUString & aName)529 sal_Bool SAL_CALL PropertySetRegistry::hasByName( const OUString& aName )
530 {
531 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
532
533 Reference< XNameAccess > xNameAccess(
534 getRootConfigReadAccess(), UNO_QUERY );
535 if ( xNameAccess.is() )
536 {
537 return xNameAccess->hasByName( aName );
538 }
539
540 return false;
541 }
542
543
add(PersistentPropertySet * pSet)544 void PropertySetRegistry::add( PersistentPropertySet* pSet )
545 {
546 OUString key( pSet->getKey() );
547
548 if ( !key.isEmpty() )
549 {
550 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
551 m_pImpl->m_aPropSets[ key ] = pSet;
552 }
553 }
554
555
remove(PersistentPropertySet * pSet)556 void PropertySetRegistry::remove( PersistentPropertySet* pSet )
557 {
558 OUString key( pSet->getKey() );
559
560 if ( !key.isEmpty() )
561 {
562 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
563
564 PropertySetMap_Impl& rSets = m_pImpl->m_aPropSets;
565
566 PropertySetMap_Impl::iterator it = rSets.find( key );
567 if ( it != rSets.end() )
568 {
569 // Found.
570 rSets.erase( it );
571 }
572 }
573 }
574
575
renamePropertySet(const OUString & rOldKey,const OUString & rNewKey)576 void PropertySetRegistry::renamePropertySet( const OUString& rOldKey,
577 const OUString& rNewKey )
578 {
579 if ( rOldKey == rNewKey )
580 return;
581
582 Reference< XNameAccess > xRootNameAccess(
583 getConfigWriteAccess( OUString() ), UNO_QUERY );
584 if ( xRootNameAccess.is() )
585 {
586 // Old key present?
587 if ( xRootNameAccess->hasByName( rOldKey ) )
588 {
589 // New key not present?
590 if ( xRootNameAccess->hasByName( rNewKey ) )
591 {
592 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
593 "New key exists!" );
594 return;
595 }
596 Reference< XSingleServiceFactory > xFac(
597 xRootNameAccess, UNO_QUERY );
598 Reference< XChangesBatch > xBatch( xFac, UNO_QUERY );
599 Reference< XNameContainer > xContainer( xFac, UNO_QUERY );
600
601 OSL_ENSURE( xFac.is(),
602 "PropertySetRegistry::renamePropertySet - "
603 "No factory!" );
604
605 OSL_ENSURE( xBatch.is(),
606 "PropertySetRegistry::renamePropertySet - "
607 "No batch!" );
608
609 OSL_ENSURE( xContainer.is(),
610 "PropertySetRegistry::renamePropertySet - "
611 "No container!" );
612
613 if ( xFac.is() && xBatch.is() && xContainer.is() )
614 {
615
616 // Create new "Properties" config item.
617
618
619 try
620 {
621 Reference< XNameReplace > xNameReplace(
622 xFac->createInstance(), UNO_QUERY );
623
624 if ( xNameReplace.is() )
625 {
626 // Insert new item.
627 xContainer->insertByName(
628 rNewKey, makeAny( xNameReplace ) );
629 // Commit changes.
630 xBatch->commitChanges();
631 }
632 }
633 catch (const IllegalArgumentException&)
634 {
635 // insertByName
636
637 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
638 "caught IllegalArgumentException!" );
639 return;
640 }
641 catch (const ElementExistException&)
642 {
643 // insertByName
644
645 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
646 "caught ElementExistException!" );
647 return;
648 }
649 catch (const WrappedTargetException&)
650 {
651 // insertByName, commitChanges
652
653 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
654 "caught WrappedTargetException!" );
655 return;
656 }
657 catch (const RuntimeException&)
658 {
659 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
660 "caught RuntimeException!" );
661 return;
662 }
663 catch (const Exception&)
664 {
665 // createInstance
666
667 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
668 "caught Exception!" );
669 return;
670 }
671
672
673 // Copy data...
674
675
676 Reference< XHierarchicalNameAccess > xRootHierNameAccess(
677 xRootNameAccess, UNO_QUERY );
678 if ( !xRootHierNameAccess.is() )
679 {
680 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
681 "No hierarchical name access!" );
682 return;
683 }
684
685 try
686 {
687 OUString aOldValuesKey
688 = makeHierarchalNameSegment( rOldKey ) + "/Values";
689
690 Reference< XNameAccess > xOldNameAccess;
691 xRootHierNameAccess->getByHierarchicalName(
692 aOldValuesKey )
693 >>= xOldNameAccess;
694 if ( !xOldNameAccess.is() )
695 {
696 OSL_FAIL( "PersistentPropertySet::renamePropertySet - "
697 "No old name access!" );
698 return;
699 }
700
701 // Obtain property names.
702 const Sequence< OUString > aElems
703 = xOldNameAccess->getElementNames();
704 if ( aElems.hasElements() )
705 {
706 OUString aNewValuesKey
707 = makeHierarchalNameSegment( rNewKey ) + "/Values";
708
709 Reference< XSingleServiceFactory > xNewFac;
710 xRootHierNameAccess->getByHierarchicalName(
711 aNewValuesKey )
712 >>= xNewFac;
713 if ( !xNewFac.is() )
714 {
715 OSL_FAIL( "PersistentPropertySet::renamePropertySet - "
716 "No new factory!" );
717 return;
718 }
719
720 Reference< XNameContainer > xNewContainer(
721 xNewFac, UNO_QUERY );
722 if ( !xNewContainer.is() )
723 {
724 OSL_FAIL( "PersistentPropertySet::renamePropertySet - "
725 "No new container!" );
726 return;
727 }
728
729 aOldValuesKey += "/";
730
731 OUString const aHandleKey("/Handle");
732 OUString const aValueKey("/Value");
733 OUString const aStateKey("/State");
734 OUString const aAttrKey("/Attributes");
735
736 for ( const OUString& rPropName : aElems )
737 {
738 // Create new item.
739 Reference< XNameReplace > xNewPropNameReplace(
740 xNewFac->createInstance(), UNO_QUERY );
741
742 if ( !xNewPropNameReplace.is() )
743 {
744 OSL_FAIL( "PersistentPropertySet::renamePropertySet - "
745 "No new prop name replace!" );
746 return;
747 }
748
749 // Fill new item...
750
751 // Set Values
752 OUString aKey = aOldValuesKey;
753 aKey += makeHierarchalNameSegment( rPropName );
754
755 // ... handle
756 OUString aNewKey1 = aKey + aHandleKey;
757 Any aAny =
758 xRootHierNameAccess->getByHierarchicalName(
759 aNewKey1 );
760 xNewPropNameReplace->replaceByName( "Handle", aAny );
761
762 // ... value
763 aNewKey1 = aKey + aValueKey;
764 aAny =
765 xRootHierNameAccess->getByHierarchicalName(
766 aNewKey1 );
767 xNewPropNameReplace->replaceByName( "Value", aAny );
768
769 // ... state
770 aNewKey1 = aKey + aStateKey;
771 aAny =
772 xRootHierNameAccess->getByHierarchicalName(
773 aNewKey1 );
774 xNewPropNameReplace->replaceByName( "State", aAny );
775
776 // ... attributes
777 aNewKey1 = aKey + aAttrKey;
778 aAny =
779 xRootHierNameAccess->getByHierarchicalName(
780 aNewKey1 );
781 xNewPropNameReplace->replaceByName( "Attributes", aAny );
782
783 // Insert new item.
784 xNewContainer->insertByName(
785 rPropName, makeAny( xNewPropNameReplace ) );
786
787 // Commit changes.
788 xBatch->commitChanges();
789 }
790 }
791 }
792 catch (const IllegalArgumentException&)
793 {
794 // insertByName, replaceByName
795
796 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
797 "caught IllegalArgumentException!" );
798 return;
799 }
800 catch (const ElementExistException&)
801 {
802 // insertByName
803
804 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
805 "caught ElementExistException!" );
806 return;
807 }
808 catch (const WrappedTargetException&)
809 {
810 // insertByName, replaceByName, commitChanges
811
812 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
813 "caught WrappedTargetException!" );
814 return;
815 }
816 catch (const NoSuchElementException&)
817 {
818 // getByHierarchicalName, replaceByName
819
820 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
821 "caught NoSuchElementException!" );
822 return;
823 }
824 catch (const RuntimeException&)
825 {
826 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
827 "caught RuntimeException!" );
828 return;
829 }
830 catch (const Exception&)
831 {
832 // createInstance
833
834 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
835 "caught Exception!" );
836 return;
837 }
838
839
840 // Remove old entry...
841
842
843 try
844 {
845 // Remove item.
846 xContainer->removeByName( rOldKey );
847 // Commit changes.
848 xBatch->commitChanges();
849
850 // Success.
851 return;
852 }
853 catch (const NoSuchElementException&)
854 {
855 // removeByName
856
857 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
858 "caught NoSuchElementException!" );
859 return;
860 }
861 catch (const WrappedTargetException&)
862 {
863 // commitChanges
864
865 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
866 "caught WrappedTargetException!" );
867 return;
868 }
869 }
870 }
871 }
872
873 OSL_FAIL( "PropertySetRegistry::renamePropertySet - Error!" );
874 }
875
876
getConfigProvider()877 Reference< XMultiServiceFactory > PropertySetRegistry::getConfigProvider()
878 {
879 if ( !m_pImpl->m_xConfigProvider.is() )
880 {
881 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
882 if ( !m_pImpl->m_xConfigProvider.is() )
883 {
884 const Sequence< Any >& rInitArgs = m_pImpl->m_aInitArgs;
885
886 if ( rInitArgs.hasElements() )
887 {
888 // Extract config provider from service init args.
889 rInitArgs[ 0 ] >>= m_pImpl->m_xConfigProvider;
890
891 OSL_ENSURE( m_pImpl->m_xConfigProvider.is(),
892 "PropertySetRegistry::getConfigProvider - "
893 "No config provider!" );
894 }
895 else
896 {
897 try
898 {
899 m_pImpl->m_xConfigProvider = theDefaultProvider::get( m_xContext );
900 }
901 catch (const Exception&)
902 {
903 TOOLS_WARN_EXCEPTION( "ucb", "");
904 }
905 }
906 }
907 }
908
909 return m_pImpl->m_xConfigProvider;
910 }
911
912
getRootConfigReadAccess()913 Reference< XInterface > PropertySetRegistry::getRootConfigReadAccess()
914 {
915 try
916 {
917 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
918
919 if ( !m_pImpl->m_xRootReadAccess.is() )
920 {
921 if ( m_pImpl->m_bTriedToGetRootReadAccess )
922 {
923 OSL_FAIL( "PropertySetRegistry::getRootConfigReadAccess - "
924 "Unable to read any config data! -> #82494#" );
925 return Reference< XInterface >();
926 }
927
928 getConfigProvider();
929
930 if ( m_pImpl->m_xConfigProvider.is() )
931 {
932 Sequence<Any> aArguments(comphelper::InitAnyPropertySequence(
933 {
934 {CFGPROPERTY_NODEPATH, Any(OUString( STORE_CONTENTPROPERTIES_KEY ))}
935 }));
936
937 m_pImpl->m_bTriedToGetRootReadAccess = true;
938
939 m_pImpl->m_xRootReadAccess =
940 m_pImpl->m_xConfigProvider->createInstanceWithArguments(
941 "com.sun.star.configuration.ConfigurationAccess",
942 aArguments );
943
944 if ( m_pImpl->m_xRootReadAccess.is() )
945 return m_pImpl->m_xRootReadAccess;
946 }
947 }
948 else
949 return m_pImpl->m_xRootReadAccess;
950 }
951 catch (const RuntimeException&)
952 {
953 throw;
954 }
955 catch (const Exception&)
956 {
957 // createInstance, createInstanceWithArguments
958
959 OSL_FAIL( "PropertySetRegistry::getRootConfigReadAccess - caught Exception!" );
960 return Reference< XInterface >();
961 }
962
963 SAL_WARN( "ucb", "Error!" );
964 return Reference< XInterface >();
965 }
966
967
getConfigWriteAccess(const OUString & rPath)968 Reference< XInterface > PropertySetRegistry::getConfigWriteAccess(
969 const OUString& rPath )
970 {
971 try
972 {
973 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
974
975 if ( !m_pImpl->m_xRootWriteAccess.is() )
976 {
977 if ( m_pImpl->m_bTriedToGetRootWriteAccess )
978 {
979 OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - "
980 "Unable to write any config data! -> #82494#" );
981 return Reference< XInterface >();
982 }
983
984 getConfigProvider();
985
986 if ( m_pImpl->m_xConfigProvider.is() )
987 {
988 Sequence<Any> aArguments(comphelper::InitAnyPropertySequence(
989 {
990 {CFGPROPERTY_NODEPATH, Any(OUString( STORE_CONTENTPROPERTIES_KEY ))}
991 }));
992
993 m_pImpl->m_bTriedToGetRootWriteAccess = true;
994
995 m_pImpl->m_xRootWriteAccess =
996 m_pImpl->m_xConfigProvider->createInstanceWithArguments(
997 "com.sun.star.configuration.ConfigurationUpdateAccess",
998 aArguments );
999
1000 OSL_ENSURE( m_pImpl->m_xRootWriteAccess.is(),
1001 "PropertySetRegistry::getConfigWriteAccess - "
1002 "No config update access!" );
1003 }
1004 }
1005
1006 if ( m_pImpl->m_xRootWriteAccess.is() )
1007 {
1008 if ( !rPath.isEmpty() )
1009 {
1010 Reference< XHierarchicalNameAccess > xNA(
1011 m_pImpl->m_xRootWriteAccess, UNO_QUERY );
1012 if ( xNA.is() )
1013 {
1014 Reference< XInterface > xInterface;
1015 xNA->getByHierarchicalName( rPath ) >>= xInterface;
1016
1017 if ( xInterface.is() )
1018 return xInterface;
1019 }
1020 }
1021 else
1022 return m_pImpl->m_xRootWriteAccess;
1023 }
1024 }
1025 catch (const RuntimeException&)
1026 {
1027 throw;
1028 }
1029 catch (const NoSuchElementException&)
1030 {
1031 // getByHierarchicalName
1032
1033 OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - "
1034 "caught NoSuchElementException!" );
1035 return Reference< XInterface >();
1036 }
1037 catch (const Exception&)
1038 {
1039 // createInstance, createInstanceWithArguments
1040
1041 OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - "
1042 "caught Exception!" );
1043 return Reference< XInterface >();
1044 }
1045
1046 OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - Error!" );
1047 return Reference< XInterface >();
1048 }
1049
1050 typedef OMultiTypeInterfaceContainerHelperVar<OUString> PropertyListeners_Impl;
1051
1052 struct PersistentPropertySet_Impl
1053 {
1054 rtl::Reference<PropertySetRegistry> m_pCreator;
1055 rtl::Reference<PropertySetInfo_Impl> m_pInfo;
1056 OUString const m_aKey;
1057 OUString m_aFullKey;
1058 osl::Mutex m_aMutex;
1059 std::unique_ptr<OInterfaceContainerHelper2> m_pDisposeEventListeners;
1060 std::unique_ptr<OInterfaceContainerHelper2> m_pPropSetChangeListeners;
1061 std::unique_ptr<PropertyListeners_Impl> m_pPropertyChangeListeners;
1062
PersistentPropertySet_ImplPersistentPropertySet_Impl1063 PersistentPropertySet_Impl( PropertySetRegistry& rCreator,
1064 const OUString& rKey )
1065 : m_pCreator( &rCreator ), m_aKey( rKey )
1066 {
1067 }
1068 };
1069
1070
1071 // PersistentPropertySet Implementation.
1072
1073
PersistentPropertySet(PropertySetRegistry & rCreator,const OUString & rKey)1074 PersistentPropertySet::PersistentPropertySet(
1075 PropertySetRegistry& rCreator,
1076 const OUString& rKey )
1077 : m_pImpl( new PersistentPropertySet_Impl( rCreator, rKey ) )
1078 {
1079 // register at creator.
1080 rCreator.add( this );
1081 }
1082
1083
1084 // virtual
~PersistentPropertySet()1085 PersistentPropertySet::~PersistentPropertySet()
1086 {
1087 // deregister at creator.
1088 m_pImpl->m_pCreator->remove( this );
1089 }
1090
1091 // XServiceInfo methods.
1092
getImplementationName()1093 OUString SAL_CALL PersistentPropertySet::getImplementationName()
1094 {
1095 return "com.sun.star.comp.ucb.PersistentPropertySet";
1096 }
1097
supportsService(const OUString & ServiceName)1098 sal_Bool SAL_CALL PersistentPropertySet::supportsService( const OUString& ServiceName )
1099 {
1100 return cppu::supportsService( this, ServiceName );
1101 }
1102
1103 css::uno::Sequence< OUString > SAL_CALL
getSupportedServiceNames()1104 PersistentPropertySet::getSupportedServiceNames()
1105 {
1106 return { PERS_PROPSET_SERVICE_NAME };
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 Reference< XPropertySetInfo >( m_pImpl->m_pInfo.get() );
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 Reference< XPropertySetRegistry >( m_pImpl->m_pCreator.get() );
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 OUString aFullValuesName;
1556 OUString aFullPropName;
1557
1558 Reference< XHierarchicalNameAccess > xRootHierNameAccess(
1559 m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY );
1560 if ( xRootHierNameAccess.is() )
1561 {
1562 aFullValuesName = getFullKey();
1563 aFullPropName = aFullValuesName + "/";
1564 aFullPropName += makeHierarchalNameSegment( Name );
1565
1566 // Property in set?
1567 if ( !xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) )
1568 throw UnknownPropertyException(aFullPropName);
1569
1570 // Property removable?
1571 try
1572 {
1573 OUString aFullAttrName = aFullPropName + "/Attributes";
1574
1575 sal_Int32 nAttribs = 0;
1576 if ( xRootHierNameAccess->getByHierarchicalName( aFullAttrName )
1577 >>= nAttribs )
1578 {
1579 if ( !( nAttribs & PropertyAttribute::REMOVABLE ) )
1580 {
1581 // Not removable!
1582 throw NotRemoveableException();
1583 }
1584 }
1585 else
1586 {
1587 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1588 "No attributes!" );
1589 return;
1590 }
1591 }
1592 catch (const NoSuchElementException&)
1593 {
1594 // getByHierarchicalName
1595
1596 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1597 "caught NoSuchElementException!" );
1598 }
1599
1600 // Remove property...
1601
1602 Reference< XNameContainer > xContainer(
1603 m_pImpl->m_pCreator->getConfigWriteAccess( aFullValuesName ),
1604 UNO_QUERY );
1605 Reference< XChangesBatch > xBatch(
1606 m_pImpl->m_pCreator->getConfigWriteAccess( OUString() ),
1607 UNO_QUERY );
1608
1609 OSL_ENSURE( xBatch.is(),
1610 "PersistentPropertySet::removeProperty - No batch!" );
1611
1612 OSL_ENSURE( xContainer.is(),
1613 "PersistentPropertySet::removeProperty - No container!" );
1614
1615 if ( xBatch.is() && xContainer.is() )
1616 {
1617 try
1618 {
1619 sal_Int32 nHandle = -1;
1620
1621 if ( m_pImpl->m_pPropSetChangeListeners &&
1622 m_pImpl->m_pPropSetChangeListeners->getLength() )
1623 {
1624 // Obtain property handle ( needed for propertysetinfo
1625 // change event )...
1626
1627 try
1628 {
1629 OUString aFullHandleName = aFullPropName + "/Handle";
1630
1631 if ( ! ( xRootHierNameAccess->getByHierarchicalName(
1632 aFullHandleName ) >>= nHandle ) )
1633 nHandle = -1;
1634
1635 }
1636 catch (const NoSuchElementException&)
1637 {
1638 // getByHierarchicalName
1639
1640 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1641 "caught NoSuchElementException!" );
1642 nHandle = -1;
1643 }
1644 }
1645
1646 xContainer->removeByName( Name );
1647 xBatch->commitChanges();
1648
1649 // Property set info is invalid.
1650 if ( m_pImpl->m_pInfo.is() )
1651 m_pImpl->m_pInfo->reset();
1652
1653 // Notify propertyset info change listeners.
1654 if ( m_pImpl->m_pPropSetChangeListeners &&
1655 m_pImpl->m_pPropSetChangeListeners->getLength() )
1656 {
1657 PropertySetInfoChangeEvent evt(
1658 static_cast< OWeakObject * >( this ),
1659 Name,
1660 nHandle,
1661 PropertySetInfoChange::PROPERTY_REMOVED );
1662 notifyPropertySetInfoChange( evt );
1663 }
1664
1665 // Success.
1666 return;
1667 }
1668 catch (const NoSuchElementException&)
1669 {
1670 // removeByName
1671
1672 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1673 "caught NoSuchElementException!" );
1674 return;
1675 }
1676 catch (const WrappedTargetException&)
1677 {
1678 // commitChanges
1679
1680 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1681 "caught WrappedTargetException!" );
1682 return;
1683 }
1684 }
1685 }
1686
1687 OSL_FAIL( "PersistentPropertySet::removeProperty - Error!" );
1688 }
1689
1690
1691 // XPropertySetInfoChangeNotifier methods.
1692
1693
1694 // virtual
addPropertySetInfoChangeListener(const Reference<XPropertySetInfoChangeListener> & Listener)1695 void SAL_CALL PersistentPropertySet::addPropertySetInfoChangeListener(
1696 const Reference< XPropertySetInfoChangeListener >& Listener )
1697 {
1698 if ( !m_pImpl->m_pPropSetChangeListeners )
1699 m_pImpl->m_pPropSetChangeListeners.reset(
1700 new OInterfaceContainerHelper2( m_pImpl->m_aMutex ) );
1701
1702 m_pImpl->m_pPropSetChangeListeners->addInterface( Listener );
1703 }
1704
1705
1706 // virtual
removePropertySetInfoChangeListener(const Reference<XPropertySetInfoChangeListener> & Listener)1707 void SAL_CALL PersistentPropertySet::removePropertySetInfoChangeListener(
1708 const Reference< XPropertySetInfoChangeListener >& Listener )
1709 {
1710 if ( m_pImpl->m_pPropSetChangeListeners )
1711 m_pImpl->m_pPropSetChangeListeners->removeInterface( Listener );
1712 }
1713
1714
1715 // XPropertyAccess methods.
1716
1717
1718 // virtual
getPropertyValues()1719 Sequence< PropertyValue > SAL_CALL PersistentPropertySet::getPropertyValues()
1720 {
1721 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
1722
1723 Reference< XHierarchicalNameAccess > xRootHierNameAccess(
1724 m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY );
1725 if ( xRootHierNameAccess.is() )
1726 {
1727 try
1728 {
1729 Reference< XNameAccess > xNameAccess;
1730 xRootHierNameAccess->getByHierarchicalName(getFullKey())
1731 >>= xNameAccess;
1732 if ( xNameAccess.is() )
1733 {
1734 // Obtain property names.
1735
1736 Sequence< OUString > aElems = xNameAccess->getElementNames();
1737
1738 sal_Int32 nCount = aElems.getLength();
1739 if ( nCount )
1740 {
1741 Reference< XHierarchicalNameAccess > xHierNameAccess(
1742 xNameAccess, UNO_QUERY );
1743
1744 OSL_ENSURE( xHierNameAccess.is(),
1745 "PersistentPropertySet::getPropertyValues - "
1746 "No hierarchical name access!" );
1747
1748 if ( xHierNameAccess.is() )
1749 {
1750 Sequence< PropertyValue > aValues( nCount );
1751
1752 const OUString aHandleName("/Handle");
1753 const OUString aValueName("/Value");
1754 const OUString aStateName("/State");
1755
1756 for ( sal_Int32 n = 0; n < nCount; ++n )
1757 {
1758 PropertyValue& rValue = aValues[ n ];
1759 OUString rName = aElems[ n ];
1760 OUString aXMLName
1761 = makeHierarchalNameSegment( rName );
1762
1763 // Set property name.
1764
1765 rValue.Name = rName;
1766
1767 try
1768 {
1769 // Obtain and set property handle
1770 OUString aHierName = aXMLName + aHandleName;
1771 Any aKeyValue
1772 = xHierNameAccess->getByHierarchicalName(
1773 aHierName );
1774
1775 if ( !( aKeyValue >>= rValue.Handle ) )
1776 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1777 "Error getting property handle!" );
1778 }
1779 catch (const NoSuchElementException&)
1780 {
1781 // getByHierarchicalName
1782
1783 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1784 "NoSuchElementException!" );
1785 }
1786
1787 try
1788 {
1789 // Obtain and set property value
1790 OUString aHierName = aXMLName + aValueName;
1791 rValue.Value
1792 = xHierNameAccess->getByHierarchicalName(
1793 aHierName );
1794
1795 // Note: The value may be void if addProperty
1796 // was called with a default value
1797 // of type void.
1798 }
1799 catch (const NoSuchElementException&)
1800 {
1801 // getByHierarchicalName
1802
1803 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1804 "NoSuchElementException!" );
1805 }
1806
1807 try
1808 {
1809 // Obtain and set property state
1810 OUString aHierName = aXMLName +aStateName;
1811 Any aKeyValue
1812 = xHierNameAccess->getByHierarchicalName(
1813 aHierName );
1814
1815 sal_Int32 nState = 0;
1816 if ( !( aKeyValue >>= nState ) )
1817 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1818 "Error getting property state!" );
1819 else
1820 rValue.State = PropertyState( nState );
1821 }
1822 catch (const NoSuchElementException&)
1823 {
1824 // getByHierarchicalName
1825
1826 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1827 "NoSuchElementException!" );
1828 }
1829 }
1830
1831 return aValues;
1832 }
1833 }
1834 }
1835 }
1836 catch (const NoSuchElementException&)
1837 {
1838 // getByHierarchicalName
1839 }
1840 }
1841
1842 return Sequence< PropertyValue >( 0 );
1843 }
1844
1845
1846 // virtual
setPropertyValues(const Sequence<PropertyValue> & aProps)1847 void SAL_CALL PersistentPropertySet::setPropertyValues(
1848 const Sequence< PropertyValue >& aProps )
1849 {
1850 if ( !aProps.hasElements() )
1851 return;
1852
1853 osl::ClearableGuard< osl::Mutex > aCGuard( m_pImpl->m_aMutex );
1854
1855 Reference< XHierarchicalNameAccess > xRootHierNameAccess(
1856 m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY );
1857 if ( xRootHierNameAccess.is() )
1858 {
1859 std::vector< PropertyChangeEvent > aEvents;
1860
1861 OUString aFullPropNamePrefix( getFullKey() + "/" );
1862
1863 // Iterate over given property value sequence.
1864 for ( const PropertyValue& rNewValue : aProps )
1865 {
1866 const OUString& rName = rNewValue.Name;
1867
1868 OUString aFullPropName = aFullPropNamePrefix;
1869 aFullPropName += makeHierarchalNameSegment( rName );
1870
1871 // Does property exist?
1872 if ( xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) )
1873 {
1874 Reference< XNameReplace > xNameReplace(
1875 m_pImpl->m_pCreator->getConfigWriteAccess(
1876 aFullPropName ), UNO_QUERY );
1877 Reference< XChangesBatch > xBatch(
1878 m_pImpl->m_pCreator->getConfigWriteAccess(
1879 OUString() ), UNO_QUERY );
1880
1881 if ( xNameReplace.is() && xBatch.is() )
1882 {
1883 try
1884 {
1885 // Write handle
1886 xNameReplace->replaceByName(
1887 "Handle",
1888 makeAny( rNewValue.Handle ) );
1889
1890 // Save old value
1891 OUString aValueName = aFullPropName +"/Value";
1892 Any aOldValue
1893 = xRootHierNameAccess->getByHierarchicalName(
1894 aValueName );
1895 // Write value
1896 xNameReplace->replaceByName(
1897 "Value",
1898 rNewValue.Value );
1899
1900 // Write state ( Now it is a directly set value )
1901 xNameReplace->replaceByName(
1902 "State",
1903 makeAny(
1904 sal_Int32(
1905 PropertyState_DIRECT_VALUE ) ) );
1906
1907 // Commit changes.
1908 xBatch->commitChanges();
1909
1910 if ( m_pImpl->m_pPropertyChangeListeners )
1911 {
1912 PropertyChangeEvent aEvt;
1913 aEvt.Source = static_cast<OWeakObject*>(this);
1914 aEvt.PropertyName = rNewValue.Name;
1915 aEvt.PropertyHandle = rNewValue.Handle;
1916 aEvt.Further = false;
1917 aEvt.OldValue = aOldValue;
1918 aEvt.NewValue = rNewValue.Value;
1919
1920 aEvents.push_back( aEvt );
1921 }
1922 }
1923 catch (const IllegalArgumentException&)
1924 {
1925 // replaceByName
1926 }
1927 catch (const NoSuchElementException&)
1928 {
1929 // getByHierarchicalName, replaceByName
1930 }
1931 catch (const WrappedTargetException&)
1932 {
1933 // replaceByName, commitChanges
1934 }
1935 }
1936 }
1937 }
1938
1939 // Callback follows!
1940 aCGuard.clear();
1941
1942 if ( m_pImpl->m_pPropertyChangeListeners )
1943 {
1944 // Notify property changes.
1945 for (auto const& event : aEvents)
1946 {
1947 notifyPropertyChangeEvent( event );
1948 }
1949 }
1950
1951 return;
1952 }
1953
1954 OSL_FAIL( "PersistentPropertySet::setPropertyValues - Nothing set!" );
1955 }
1956
1957
1958 // Non-interface methods
1959
1960
notifyPropertyChangeEvent(const PropertyChangeEvent & rEvent) const1961 void PersistentPropertySet::notifyPropertyChangeEvent(
1962 const PropertyChangeEvent& rEvent ) const
1963 {
1964 // Get "normal" listeners for the property.
1965 OInterfaceContainerHelper* pContainer =
1966 m_pImpl->m_pPropertyChangeListeners->getContainer(
1967 rEvent.PropertyName );
1968 if ( pContainer && pContainer->getLength() )
1969 {
1970 OInterfaceIteratorHelper aIter( *pContainer );
1971 while ( aIter.hasMoreElements() )
1972 {
1973 // Propagate event.
1974 Reference< XPropertyChangeListener > xListener(
1975 aIter.next(), UNO_QUERY );
1976 if ( xListener.is() )
1977 xListener->propertyChange( rEvent );
1978 }
1979 }
1980
1981 // Get "normal" listeners for all properties.
1982 OInterfaceContainerHelper* pNoNameContainer =
1983 m_pImpl->m_pPropertyChangeListeners->getContainer( OUString() );
1984 if ( pNoNameContainer && pNoNameContainer->getLength() )
1985 {
1986 OInterfaceIteratorHelper aIter( *pNoNameContainer );
1987 while ( aIter.hasMoreElements() )
1988 {
1989 // Propagate event.
1990 Reference< XPropertyChangeListener > xListener(
1991 aIter.next(), UNO_QUERY );
1992 if ( xListener.is() )
1993 xListener->propertyChange( rEvent );
1994 }
1995 }
1996 }
1997
1998
notifyPropertySetInfoChange(const PropertySetInfoChangeEvent & evt) const1999 void PersistentPropertySet::notifyPropertySetInfoChange(
2000 const PropertySetInfoChangeEvent& evt ) const
2001 {
2002 if ( !m_pImpl->m_pPropSetChangeListeners )
2003 return;
2004
2005 // Notify event listeners.
2006 OInterfaceIteratorHelper2 aIter( *( m_pImpl->m_pPropSetChangeListeners ) );
2007 while ( aIter.hasMoreElements() )
2008 {
2009 // Propagate event.
2010 Reference< XPropertySetInfoChangeListener >
2011 xListener( aIter.next(), UNO_QUERY );
2012 if ( xListener.is() )
2013 xListener->propertySetInfoChange( evt );
2014 }
2015 }
2016
2017
getFullKey()2018 const OUString& PersistentPropertySet::getFullKey()
2019 {
2020 if ( m_pImpl->m_aFullKey.isEmpty() )
2021 {
2022 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
2023 if ( m_pImpl->m_aFullKey.isEmpty() )
2024 {
2025 m_pImpl->m_aFullKey
2026 = makeHierarchalNameSegment( m_pImpl->m_aKey );
2027 m_pImpl->m_aFullKey
2028 += "/Values";
2029 }
2030 }
2031
2032 return m_pImpl->m_aFullKey;
2033 }
2034
2035
getPropertySetRegistry()2036 PropertySetRegistry& PersistentPropertySet::getPropertySetRegistry()
2037 {
2038 return *m_pImpl->m_pCreator;
2039 }
2040
2041
2042 // PropertySetInfo_Impl Implementation.
2043
2044
PropertySetInfo_Impl(PersistentPropertySet * pOwner)2045 PropertySetInfo_Impl::PropertySetInfo_Impl(
2046 PersistentPropertySet* pOwner )
2047 : m_pOwner( pOwner )
2048 {
2049 }
2050
2051
2052 // XPropertySetInfo methods.
2053
2054
2055 // virtual
getProperties()2056 Sequence< Property > SAL_CALL PropertySetInfo_Impl::getProperties()
2057 {
2058 if ( !m_pProps )
2059 {
2060 Reference< XHierarchicalNameAccess > xRootHierNameAccess(
2061 m_pOwner->getPropertySetRegistry().getRootConfigReadAccess(),
2062 UNO_QUERY );
2063 if ( xRootHierNameAccess.is() )
2064 {
2065 try
2066 {
2067 Reference< XNameAccess > xNameAccess;
2068 xRootHierNameAccess->getByHierarchicalName(
2069 m_pOwner->getFullKey() )
2070 >>= xNameAccess;
2071 if ( xNameAccess.is() )
2072 {
2073 // Obtain property names.
2074
2075 Sequence< OUString > aElems
2076 = xNameAccess->getElementNames();
2077
2078 sal_uInt32 nCount = aElems.getLength();
2079 Sequence< Property >* pPropSeq
2080 = new Sequence< Property >( nCount );
2081
2082 if ( nCount )
2083 {
2084 Reference< XHierarchicalNameAccess > xHierNameAccess(
2085 xNameAccess, UNO_QUERY );
2086
2087 OSL_ENSURE( xHierNameAccess.is(),
2088 "PropertySetInfo_Impl::getProperties - "
2089 "No hierarchical name access!" );
2090
2091 if ( xHierNameAccess.is() )
2092 {
2093 const OUString aHandleName("/Handle");
2094 const OUString aValueName("/Value");
2095 const OUString aAttrName("/Attributes");
2096
2097 Property* pProps = pPropSeq->getArray();
2098
2099 for ( sal_uInt32 n = 0; n < nCount; ++n )
2100 {
2101 Property& rProp = pProps[ n ];
2102 OUString rName = aElems[ n ];
2103 OUString aXMLName
2104 = makeHierarchalNameSegment( rName );
2105
2106 // Set property name.
2107
2108 rProp.Name = rName;
2109
2110 try
2111 {
2112 // Obtain and set property handle
2113 OUString aHierName = aXMLName + aHandleName;
2114 Any aKeyValue
2115 = xHierNameAccess->getByHierarchicalName(
2116 aHierName );
2117
2118 if ( !( aKeyValue >>= rProp.Handle ) )
2119 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2120 "Error getting property handle!" );
2121 }
2122 catch (const NoSuchElementException&)
2123 {
2124 // getByHierarchicalName
2125
2126 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2127 "NoSuchElementException!" );
2128 }
2129
2130 try
2131 {
2132 // Obtain and set property type
2133 OUString aHierName = aXMLName + aValueName;
2134 Any aKeyValue
2135 = xHierNameAccess->getByHierarchicalName(
2136 aHierName );
2137
2138 // Note: The type may be void if addProperty
2139 // was called with a default value
2140 // of type void.
2141
2142 rProp.Type = aKeyValue.getValueType();
2143 }
2144 catch (const NoSuchElementException&)
2145 {
2146 // getByHierarchicalName
2147
2148 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2149 "NoSuchElementException!" );
2150 }
2151
2152 try
2153 {
2154 // Obtain and set property attributes
2155 OUString aHierName = aXMLName + aAttrName;
2156 Any aKeyValue
2157 = xHierNameAccess->getByHierarchicalName(
2158 aHierName );
2159
2160 sal_Int32 nAttribs = 0;
2161 if ( aKeyValue >>= nAttribs )
2162 rProp.Attributes
2163 = sal_Int16( nAttribs );
2164 else
2165 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2166 "Error getting property attributes!" );
2167 }
2168 catch (const NoSuchElementException&)
2169 {
2170 // getByHierarchicalName
2171
2172 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2173 "NoSuchElementException!" );
2174 }
2175 }
2176 }
2177 }
2178
2179 // Success.
2180 m_pProps.reset( pPropSeq );
2181 return *m_pProps;
2182 }
2183 }
2184 catch (const NoSuchElementException&)
2185 {
2186 // getByHierarchicalName
2187 }
2188 }
2189
2190 OSL_FAIL( "PropertySetInfo_Impl::getProperties - Error!" );
2191 m_pProps.reset( new Sequence< Property >( 0 ) );
2192 }
2193
2194 return *m_pProps;
2195 }
2196
2197
2198 // virtual
getPropertyByName(const OUString & aName)2199 Property SAL_CALL PropertySetInfo_Impl::getPropertyByName(
2200 const OUString& aName )
2201 {
2202 Reference< XHierarchicalNameAccess > xRootHierNameAccess(
2203 m_pOwner->getPropertySetRegistry().getRootConfigReadAccess(),
2204 UNO_QUERY );
2205 if ( xRootHierNameAccess.is() )
2206 {
2207 OUString aFullPropName( m_pOwner->getFullKey() + "/" );
2208 aFullPropName += makeHierarchalNameSegment( aName );
2209
2210 // Does property exist?
2211 if ( !xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) )
2212 throw UnknownPropertyException(aFullPropName);
2213
2214 try
2215 {
2216 Property aProp;
2217
2218 // Obtain handle.
2219 OUString aKey = aFullPropName + "/Handle";
2220
2221 if ( !( xRootHierNameAccess->getByHierarchicalName( aKey )
2222 >>= aProp.Handle ) )
2223 {
2224 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2225 "No handle!" );
2226 return Property();
2227 }
2228
2229 // Obtain Value and extract type.
2230 aKey = aFullPropName + "/Value";
2231
2232 Any aValue = xRootHierNameAccess->getByHierarchicalName( aKey );
2233 if ( !aValue.hasValue() )
2234 {
2235 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2236 "No Value!" );
2237 return Property();
2238 }
2239
2240 aProp.Type = aValue.getValueType();
2241
2242 // Obtain Attributes.
2243 aKey = aFullPropName + "/Attributes";
2244
2245 sal_Int32 nAttribs = 0;
2246 if ( xRootHierNameAccess->getByHierarchicalName( aKey )
2247 >>= nAttribs )
2248 aProp.Attributes = sal_Int16( nAttribs );
2249 else
2250 {
2251 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2252 "No attributes!" );
2253 return Property();
2254 }
2255
2256 // set name.
2257 aProp.Name = aName;
2258
2259 // Success.
2260 return aProp;
2261 }
2262 catch (const NoSuchElementException&)
2263 {
2264 // getByHierarchicalName
2265
2266 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2267 "caught NoSuchElementException!" );
2268 }
2269
2270 }
2271
2272 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - Error!" );
2273 return Property();
2274 }
2275
2276
2277 // virtual
hasPropertyByName(const OUString & Name)2278 sal_Bool SAL_CALL PropertySetInfo_Impl::hasPropertyByName(
2279 const OUString& Name )
2280 {
2281 Reference< XHierarchicalNameAccess > xRootHierNameAccess(
2282 m_pOwner->getPropertySetRegistry().getRootConfigReadAccess(),
2283 UNO_QUERY );
2284 if ( xRootHierNameAccess.is() )
2285 {
2286 OUString aFullPropName( m_pOwner->getFullKey() + "/" );
2287 aFullPropName += makeHierarchalNameSegment( Name );
2288
2289 return xRootHierNameAccess->hasByHierarchicalName( aFullPropName );
2290 }
2291
2292 return false;
2293 }
2294
2295 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
2296