1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 /**************************************************************************
23 **************************************************************************
25 *************************************************************************/
28 #include <unordered_map>
29 #include <sal/log.hxx>
30 #include <comphelper/diagnose_ex.hxx>
31 #include <rtl/ustrbuf.hxx>
32 #include <rtl/ref.hxx>
33 #include <comphelper/interfacecontainer2.hxx>
34 #include <comphelper/propertysequence.hxx>
35 #include <com/sun/star/beans/IllegalTypeException.hpp>
36 #include <com/sun/star/beans/NotRemoveableException.hpp>
37 #include <com/sun/star/beans/PropertyAttribute.hpp>
38 #include <com/sun/star/beans/PropertyExistException.hpp>
39 #include <com/sun/star/beans/PropertySetInfoChange.hpp>
40 #include <com/sun/star/configuration/theDefaultProvider.hpp>
41 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
42 #include <com/sun/star/container/XNameContainer.hpp>
43 #include <com/sun/star/container/XNameReplace.hpp>
44 #include <com/sun/star/util/XChangesBatch.hpp>
45 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
46 #include <cppuhelper/supportsservice.hxx>
47 #include <cppuhelper/implbase.hxx>
48 #include <cppuhelper/weak.hxx>
50 #include "ucbstore.hxx"
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
;
62 static OUString
makeHierarchalNameSegment( std::u16string_view rIn
)
64 OUStringBuffer
aBuffer( "['" );
66 size_t nCount
= rIn
.size();
67 for ( size_t n
= 0; n
< nCount
; ++n
)
69 const sal_Unicode c
= rIn
[ n
];
73 aBuffer
.append( "&" );
77 aBuffer
.append( """ );
81 aBuffer
.append( "'" );
85 aBuffer
.append( "<" );
89 aBuffer
.append( ">" );
98 aBuffer
.append( "']" );
99 return aBuffer
.makeStringAndClear();
102 constexpr OUString STORE_CONTENTPROPERTIES_KEY
= u
"/org.openoffice.ucb.Store/ContentProperties"_ustr
;
104 // describe path of cfg entry
105 constexpr OUString CFGPROPERTY_NODEPATH
= u
"nodepath"_ustr
;
107 class PropertySetInfo_Impl
: public cppu::WeakImplHelper
< XPropertySetInfo
>
109 std::optional
<Sequence
< Property
>>
111 PersistentPropertySet
* m_pOwner
;
114 explicit PropertySetInfo_Impl(PersistentPropertySet
* pOwner
);
117 virtual Sequence
< Property
> SAL_CALL
getProperties() override
;
118 virtual Property SAL_CALL
getPropertyByName( const OUString
& aName
) override
;
119 virtual sal_Bool SAL_CALL
hasPropertyByName( const OUString
& Name
) override
;
121 // Non-interface methods.
122 void reset() { m_xProps
.reset(); }
126 // UcbStore Implementation.
129 UcbStore::UcbStore( const Reference
< XComponentContext
>& xContext
)
130 : m_xContext( xContext
)
136 UcbStore::~UcbStore()
140 OUString SAL_CALL
UcbStore::getImplementationName()
142 return "com.sun.star.comp.ucb.UcbStore";
144 sal_Bool SAL_CALL
UcbStore::supportsService( const OUString
& ServiceName
)
146 return cppu::supportsService( this, ServiceName
);
148 css::uno::Sequence
< OUString
> SAL_CALL
UcbStore::getSupportedServiceNames()
150 return { "com.sun.star.ucb.Store" };
153 // Service factory implementation.
155 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
156 ucb_UcbStore_get_implementation(
157 css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const&)
159 return cppu::acquire(new UcbStore(context
));
163 // XPropertySetRegistryFactory methods.
167 Reference
< XPropertySetRegistry
> SAL_CALL
168 UcbStore::createPropertySetRegistry( const OUString
& )
170 // The URL parameter is ignored by this interface implementation. It always
171 // uses the configuration server as storage medium.
173 if ( !m_xTheRegistry
.is() )
175 std::unique_lock
aGuard( m_aMutex
);
176 if ( !m_xTheRegistry
.is() )
177 m_xTheRegistry
= new PropertySetRegistry( m_xContext
, m_aInitArgs
);
180 return m_xTheRegistry
;
184 // XInitialization methods.
188 void SAL_CALL
UcbStore::initialize( const Sequence
< Any
>& aArguments
)
190 std::unique_lock
aGuard( m_aMutex
);
191 m_aInitArgs
= aArguments
;
196 // PropertySetRegistry Implementation.
199 PropertySetRegistry::PropertySetRegistry(
200 const Reference
< XComponentContext
>& xContext
,
201 const Sequence
< Any
> &rInitArgs
)
202 : m_xContext( xContext
)
203 , m_aInitArgs(rInitArgs
)
204 , m_bTriedToGetRootReadAccess(false)
205 , m_bTriedToGetRootWriteAccess(false)
211 PropertySetRegistry::~PropertySetRegistry()
216 // XServiceInfo methods.
219 OUString SAL_CALL
PropertySetRegistry::getImplementationName()
221 return "com.sun.star.comp.ucb.PropertySetRegistry";
224 sal_Bool SAL_CALL
PropertySetRegistry::supportsService( const OUString
& ServiceName
)
226 return cppu::supportsService( this, ServiceName
);
229 css::uno::Sequence
< OUString
> SAL_CALL
PropertySetRegistry::getSupportedServiceNames()
231 return { "com.sun.star.ucb.PropertySetRegistry" };
235 // XPropertySetRegistry methods.
239 Reference
< XPersistentPropertySet
> SAL_CALL
240 PropertySetRegistry::openPropertySet( const OUString
& key
, sal_Bool create
)
243 return Reference
< XPersistentPropertySet
>();
245 std::unique_lock
aGuard( m_aMutex
);
247 PropertySetMap_Impl
& rSets
= m_aPropSets
;
249 PropertySetMap_Impl::const_iterator it
= rSets
.find( key
);
250 if ( it
!= rSets
.end() )
251 // Already instantiated.
252 return Reference
< XPersistentPropertySet
>( (*it
).second
);
254 // Create new instance.
255 Reference
< XNameAccess
> xRootNameAccess(
256 getRootConfigReadAccessImpl(aGuard
), UNO_QUERY
);
257 if ( !xRootNameAccess
.is() )
259 SAL_WARN( "ucb", "no root access" );
260 return Reference
< XPersistentPropertySet
>();
263 // Propertyset in registry?
264 if ( xRootNameAccess
->hasByName( key
) )
267 return Reference
< XPersistentPropertySet
>(
268 new PersistentPropertySet(
269 aGuard
, *this, key
) );
273 // No. Create entry for propertyset.
275 Reference
< XSingleServiceFactory
> xFac(
276 getConfigWriteAccessImpl( aGuard
, OUString() ), UNO_QUERY
);
277 Reference
< XChangesBatch
> xBatch( xFac
, UNO_QUERY
);
278 Reference
< XNameContainer
> xContainer( xFac
, UNO_QUERY
);
280 OSL_ENSURE( xFac
.is(),
281 "PropertySetRegistry::openPropertySet - "
284 OSL_ENSURE( xBatch
.is(),
285 "PropertySetRegistry::openPropertySet - "
288 OSL_ENSURE( xContainer
.is(),
289 "PropertySetRegistry::openPropertySet - "
292 if ( xFac
.is() && xBatch
.is() && xContainer
.is() )
296 // Create new "Properties" config item.
297 Reference
< XNameReplace
> xNameReplace(
298 xFac
->createInstance(), UNO_QUERY
);
300 if ( xNameReplace
.is() )
305 xContainer
->insertByName(
306 key
, Any( xNameReplace
) );
308 xBatch
->commitChanges();
310 return Reference
< XPersistentPropertySet
>(
311 new PersistentPropertySet(
312 aGuard
, *this, key
) );
315 catch (const IllegalArgumentException
&)
319 OSL_FAIL( "PropertySetRegistry::openPropertySet - "
320 "caught IllegalArgumentException!" );
322 catch (const ElementExistException
&)
326 OSL_FAIL( "PropertySetRegistry::openPropertySet - "
327 "caught ElementExistException!" );
329 catch (const WrappedTargetException
&)
331 // insertByName, commitChanges
333 OSL_FAIL( "PropertySetRegistry::openPropertySet - "
334 "caught WrappedTargetException!" );
336 catch (const RuntimeException
&)
338 OSL_FAIL( "PropertySetRegistry::openPropertySet - "
339 "caught RuntimeException!" );
341 catch (const Exception
&)
345 OSL_FAIL( "PropertySetRegistry::openPropertySet - "
346 "caught Exception!" );
352 // No entry. Fail, but no error.
353 return Reference
< XPersistentPropertySet
>();
356 SAL_WARN( "ucb", "no root access" );
358 return Reference
< XPersistentPropertySet
>();
363 void SAL_CALL
PropertySetRegistry::removePropertySet( const OUString
& key
)
368 std::unique_lock
aGuard( m_aMutex
);
370 Reference
< XNameAccess
> xRootNameAccess(
371 getRootConfigReadAccessImpl(aGuard
), UNO_QUERY
);
372 if ( xRootNameAccess
.is() )
374 // Propertyset in registry?
375 if ( !xRootNameAccess
->hasByName( key
) )
377 Reference
< XChangesBatch
> xBatch(
378 getConfigWriteAccessImpl( aGuard
, OUString() ), UNO_QUERY
);
379 Reference
< XNameContainer
> xContainer( xBatch
, UNO_QUERY
);
381 if ( xBatch
.is() && xContainer
.is() )
386 xContainer
->removeByName( key
);
388 xBatch
->commitChanges();
393 catch (const NoSuchElementException
&)
397 OSL_FAIL( "PropertySetRegistry::removePropertySet - "
398 "caught NoSuchElementException!" );
401 catch (const WrappedTargetException
&)
405 OSL_FAIL( "PropertySetRegistry::removePropertySet - "
406 "caught WrappedTargetException!" );
414 SAL_WARN( "ucb", "no root access" );
418 // XElementAccess methods.
422 css::uno::Type SAL_CALL
PropertySetRegistry::getElementType()
424 return cppu::UnoType
<XPersistentPropertySet
>::get();
429 sal_Bool SAL_CALL
PropertySetRegistry::hasElements()
431 Reference
< XElementAccess
> xElemAccess(
432 getRootConfigReadAccess(), UNO_QUERY
);
433 if ( xElemAccess
.is() )
434 return xElemAccess
->hasElements();
440 // XNameAccess methods.
444 Any SAL_CALL
PropertySetRegistry::getByName( const OUString
& aName
)
446 Reference
< XNameAccess
> xNameAccess(
447 getRootConfigReadAccess(), UNO_QUERY
);
448 if ( xNameAccess
.is() )
453 return xNameAccess
->getByName( aName
);
455 catch (const NoSuchElementException
&)
459 catch (const WrappedTargetException
&)
470 Sequence
< OUString
> SAL_CALL
PropertySetRegistry::getElementNames()
472 Reference
< XNameAccess
> xNameAccess(
473 getRootConfigReadAccess(), UNO_QUERY
);
474 if ( xNameAccess
.is() )
476 return xNameAccess
->getElementNames();
478 return Sequence
< OUString
>( 0 );
483 sal_Bool SAL_CALL
PropertySetRegistry::hasByName( const OUString
& aName
)
485 Reference
< XNameAccess
> xNameAccess(
486 getRootConfigReadAccess(), UNO_QUERY
);
487 if ( xNameAccess
.is() )
489 return xNameAccess
->hasByName( aName
);
496 void PropertySetRegistry::add(
497 std::unique_lock
<std::mutex
>& /*rCreatorGuard*/,
498 PersistentPropertySet
* pSet
)
500 OUString
key( pSet
->getKey() );
502 if ( !key
.isEmpty() )
504 m_aPropSets
[ key
] = pSet
;
509 void PropertySetRegistry::remove( PersistentPropertySet
* pSet
)
511 OUString
key( pSet
->getKey() );
516 std::unique_lock
aGuard( m_aMutex
);
518 PropertySetMap_Impl
& rSets
= m_aPropSets
;
520 PropertySetMap_Impl::iterator it
= rSets
.find( key
);
521 if ( it
!= rSets
.end() )
529 void PropertySetRegistry::renamePropertySet( const OUString
& rOldKey
,
530 const OUString
& rNewKey
)
532 if ( rOldKey
== rNewKey
)
535 Reference
< XNameAccess
> xRootNameAccess(
536 getConfigWriteAccess( OUString() ), UNO_QUERY
);
537 if ( xRootNameAccess
.is() )
540 if ( xRootNameAccess
->hasByName( rOldKey
) )
542 // New key not present?
543 if ( xRootNameAccess
->hasByName( rNewKey
) )
545 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
549 Reference
< XSingleServiceFactory
> xFac(
550 xRootNameAccess
, UNO_QUERY
);
551 Reference
< XChangesBatch
> xBatch( xFac
, UNO_QUERY
);
552 Reference
< XNameContainer
> xContainer( xFac
, UNO_QUERY
);
554 OSL_ENSURE( xFac
.is(),
555 "PropertySetRegistry::renamePropertySet - "
558 OSL_ENSURE( xBatch
.is(),
559 "PropertySetRegistry::renamePropertySet - "
562 OSL_ENSURE( xContainer
.is(),
563 "PropertySetRegistry::renamePropertySet - "
566 if ( xFac
.is() && xBatch
.is() && xContainer
.is() )
569 // Create new "Properties" config item.
574 Reference
< XNameReplace
> xNameReplace(
575 xFac
->createInstance(), UNO_QUERY
);
577 if ( xNameReplace
.is() )
580 xContainer
->insertByName(
581 rNewKey
, Any( xNameReplace
) );
583 xBatch
->commitChanges();
586 catch (const IllegalArgumentException
&)
590 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
591 "caught IllegalArgumentException!" );
594 catch (const ElementExistException
&)
598 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
599 "caught ElementExistException!" );
602 catch (const WrappedTargetException
&)
604 // insertByName, commitChanges
606 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
607 "caught WrappedTargetException!" );
610 catch (const RuntimeException
&)
612 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
613 "caught RuntimeException!" );
616 catch (const Exception
&)
620 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
621 "caught Exception!" );
629 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
630 xRootNameAccess
, UNO_QUERY
);
631 if ( !xRootHierNameAccess
.is() )
633 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
634 "No hierarchical name access!" );
640 OUString aOldValuesKey
641 = makeHierarchalNameSegment( rOldKey
) + "/Values";
643 Reference
< XNameAccess
> xOldNameAccess
;
644 xRootHierNameAccess
->getByHierarchicalName(
647 if ( !xOldNameAccess
.is() )
649 OSL_FAIL( "PersistentPropertySet::renamePropertySet - "
650 "No old name access!" );
654 // Obtain property names.
655 const Sequence
< OUString
> aElems
656 = xOldNameAccess
->getElementNames();
657 if ( aElems
.hasElements() )
659 OUString aNewValuesKey
660 = makeHierarchalNameSegment( rNewKey
) + "/Values";
662 Reference
< XSingleServiceFactory
> xNewFac
;
663 xRootHierNameAccess
->getByHierarchicalName(
668 OSL_FAIL( "PersistentPropertySet::renamePropertySet - "
673 Reference
< XNameContainer
> xNewContainer(
674 xNewFac
, UNO_QUERY
);
675 if ( !xNewContainer
.is() )
677 OSL_FAIL( "PersistentPropertySet::renamePropertySet - "
678 "No new container!" );
682 aOldValuesKey
+= "/";
684 for ( const OUString
& rPropName
: aElems
)
687 Reference
< XNameReplace
> xNewPropNameReplace(
688 xNewFac
->createInstance(), UNO_QUERY
);
690 if ( !xNewPropNameReplace
.is() )
692 OSL_FAIL( "PersistentPropertySet::renamePropertySet - "
693 "No new prop name replace!" );
700 OUString aKey
= aOldValuesKey
+ makeHierarchalNameSegment( rPropName
);
703 OUString aNewKey1
= aKey
+ "/Handle";
705 xRootHierNameAccess
->getByHierarchicalName(
707 xNewPropNameReplace
->replaceByName( "Handle", aAny
);
710 aNewKey1
= aKey
+ "/Value";
712 xRootHierNameAccess
->getByHierarchicalName(
714 xNewPropNameReplace
->replaceByName( "Value", aAny
);
717 aNewKey1
= aKey
+ "/State";
719 xRootHierNameAccess
->getByHierarchicalName(
721 xNewPropNameReplace
->replaceByName( "State", aAny
);
724 aNewKey1
= aKey
+ "/Attributes";
726 xRootHierNameAccess
->getByHierarchicalName(
728 xNewPropNameReplace
->replaceByName( "Attributes", aAny
);
731 xNewContainer
->insertByName(
732 rPropName
, Any( xNewPropNameReplace
) );
735 xBatch
->commitChanges();
739 catch (const IllegalArgumentException
&)
741 // insertByName, replaceByName
743 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
744 "caught IllegalArgumentException!" );
747 catch (const ElementExistException
&)
751 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
752 "caught ElementExistException!" );
755 catch (const WrappedTargetException
&)
757 // insertByName, replaceByName, commitChanges
759 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
760 "caught WrappedTargetException!" );
763 catch (const NoSuchElementException
&)
765 // getByHierarchicalName, replaceByName
767 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
768 "caught NoSuchElementException!" );
771 catch (const RuntimeException
&)
773 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
774 "caught RuntimeException!" );
777 catch (const Exception
&)
781 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
782 "caught Exception!" );
787 // Remove old entry...
793 xContainer
->removeByName( rOldKey
);
795 xBatch
->commitChanges();
800 catch (const NoSuchElementException
&)
804 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
805 "caught NoSuchElementException!" );
808 catch (const WrappedTargetException
&)
812 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
813 "caught WrappedTargetException!" );
820 OSL_FAIL( "PropertySetRegistry::renamePropertySet - Error!" );
824 Reference
< XMultiServiceFactory
> PropertySetRegistry::getConfigProvider(std::unique_lock
<std::mutex
>& /*rGuard*/)
826 if ( !m_xConfigProvider
.is() )
828 const Sequence
< Any
>& rInitArgs
= m_aInitArgs
;
830 if ( rInitArgs
.hasElements() )
832 // Extract config provider from service init args.
833 rInitArgs
[ 0 ] >>= m_xConfigProvider
;
835 OSL_ENSURE( m_xConfigProvider
.is(),
836 "PropertySetRegistry::getConfigProvider - "
837 "No config provider!" );
843 m_xConfigProvider
= theDefaultProvider::get( m_xContext
);
845 catch (const Exception
&)
847 TOOLS_WARN_EXCEPTION( "ucb", "");
852 return m_xConfigProvider
;
856 Reference
< XInterface
> PropertySetRegistry::getRootConfigReadAccess()
858 std::unique_lock
aGuard( m_aMutex
);
859 return getRootConfigReadAccessImpl(aGuard
);
862 Reference
< XInterface
> PropertySetRegistry::getRootConfigReadAccessImpl(std::unique_lock
<std::mutex
>& rGuard
)
866 if ( !m_xRootReadAccess
.is() )
868 if ( m_bTriedToGetRootReadAccess
)
870 OSL_FAIL( "PropertySetRegistry::getRootConfigReadAccess - "
871 "Unable to read any config data! -> #82494#" );
872 return Reference
< XInterface
>();
875 getConfigProvider(rGuard
);
877 if ( m_xConfigProvider
.is() )
879 Sequence
<Any
> aArguments(comphelper::InitAnyPropertySequence(
881 {CFGPROPERTY_NODEPATH
, Any(STORE_CONTENTPROPERTIES_KEY
)}
884 m_bTriedToGetRootReadAccess
= true;
887 m_xConfigProvider
->createInstanceWithArguments(
888 "com.sun.star.configuration.ConfigurationAccess",
891 if ( m_xRootReadAccess
.is() )
892 return m_xRootReadAccess
;
896 return m_xRootReadAccess
;
898 catch (const RuntimeException
&)
902 catch (const Exception
&)
904 // createInstance, createInstanceWithArguments
906 TOOLS_WARN_EXCEPTION("ucb", "");
907 return Reference
< XInterface
>();
910 SAL_WARN( "ucb", "Error!" );
911 return Reference
< XInterface
>();
915 Reference
< XInterface
> PropertySetRegistry::getConfigWriteAccess(
916 const OUString
& rPath
)
918 std::unique_lock
aGuard( m_aMutex
);
919 return getConfigWriteAccessImpl(aGuard
, rPath
);
922 Reference
< XInterface
> PropertySetRegistry::getConfigWriteAccessImpl(std::unique_lock
<std::mutex
>& rGuard
,
923 const OUString
& rPath
)
927 if ( !m_xRootWriteAccess
.is() )
929 if ( m_bTriedToGetRootWriteAccess
)
931 OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - "
932 "Unable to write any config data! -> #82494#" );
933 return Reference
< XInterface
>();
936 getConfigProvider(rGuard
);
938 if ( m_xConfigProvider
.is() )
940 Sequence
<Any
> aArguments(comphelper::InitAnyPropertySequence(
942 {CFGPROPERTY_NODEPATH
, Any(STORE_CONTENTPROPERTIES_KEY
)}
945 m_bTriedToGetRootWriteAccess
= true;
948 m_xConfigProvider
->createInstanceWithArguments(
949 "com.sun.star.configuration.ConfigurationUpdateAccess",
952 OSL_ENSURE( m_xRootWriteAccess
.is(),
953 "PropertySetRegistry::getConfigWriteAccess - "
954 "No config update access!" );
958 if ( m_xRootWriteAccess
.is() )
960 if ( !rPath
.isEmpty() )
962 Reference
< XHierarchicalNameAccess
> xNA(
963 m_xRootWriteAccess
, UNO_QUERY
);
966 Reference
< XInterface
> xInterface
;
967 xNA
->getByHierarchicalName( rPath
) >>= xInterface
;
969 if ( xInterface
.is() )
974 return m_xRootWriteAccess
;
977 catch (const RuntimeException
&)
981 catch (const NoSuchElementException
&)
983 // getByHierarchicalName
985 OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - "
986 "caught NoSuchElementException!" );
987 return Reference
< XInterface
>();
989 catch (const Exception
&)
991 // createInstance, createInstanceWithArguments
993 OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - "
994 "caught Exception!" );
995 return Reference
< XInterface
>();
998 OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - Error!" );
999 return Reference
< XInterface
>();
1003 // PersistentPropertySet Implementation.
1006 PersistentPropertySet::PersistentPropertySet(
1007 std::unique_lock
<std::mutex
>& rCreatorGuard
,
1008 PropertySetRegistry
& rCreator
,
1010 : m_pCreator( &rCreator
), m_aKey(std::move( aKey
))
1012 // register at creator.
1013 rCreator
.add( rCreatorGuard
, this );
1018 PersistentPropertySet::~PersistentPropertySet()
1020 // deregister at creator.
1021 m_pCreator
->remove( this );
1024 // XServiceInfo methods.
1026 OUString SAL_CALL
PersistentPropertySet::getImplementationName()
1028 return "com.sun.star.comp.ucb.PersistentPropertySet";
1031 sal_Bool SAL_CALL
PersistentPropertySet::supportsService( const OUString
& ServiceName
)
1033 return cppu::supportsService( this, ServiceName
);
1036 css::uno::Sequence
< OUString
> SAL_CALL
PersistentPropertySet::getSupportedServiceNames()
1038 return { "com.sun.star.ucb.PersistentPropertySet" };
1042 // XComponent methods.
1046 void SAL_CALL
PersistentPropertySet::dispose()
1048 std::unique_lock
l(m_aMutex
);
1049 if ( m_aDisposeEventListeners
.getLength(l
) )
1052 aEvt
.Source
= static_cast< XComponent
* >( this );
1053 m_aDisposeEventListeners
.disposeAndClear( l
, aEvt
);
1056 if ( m_aPropSetChangeListeners
.getLength(l
) )
1059 aEvt
.Source
= static_cast< XPropertySetInfoChangeNotifier
* >( this );
1060 m_aPropSetChangeListeners
.disposeAndClear( l
, aEvt
);
1063 if ( m_aPropertyChangeListeners
.hasContainedTypes(l
) )
1066 aEvt
.Source
= static_cast< XPropertySet
* >( this );
1067 m_aPropertyChangeListeners
.disposeAndClear( l
, aEvt
);
1073 void SAL_CALL
PersistentPropertySet::addEventListener(
1074 const Reference
< XEventListener
>& Listener
)
1076 std::unique_lock
l(m_aMutex
);
1078 m_aDisposeEventListeners
.addInterface( l
, Listener
);
1083 void SAL_CALL
PersistentPropertySet::removeEventListener(
1084 const Reference
< XEventListener
>& Listener
)
1086 std::unique_lock
l(m_aMutex
);
1087 m_aDisposeEventListeners
.removeInterface( l
, Listener
);
1089 // Note: Don't want to delete empty container here -> performance.
1093 // XPropertySet methods.
1097 Reference
< XPropertySetInfo
> SAL_CALL
PersistentPropertySet::getPropertySetInfo()
1099 std::unique_lock
l(m_aMutex
);
1101 if ( !m_pInfo
.is() )
1103 m_pInfo
= new PropertySetInfo_Impl( this );
1110 void SAL_CALL
PersistentPropertySet::setPropertyValue( const OUString
& aPropertyName
,
1113 std::unique_lock
aCGuard(m_aMutex
);
1115 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
1116 m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1117 if ( xRootHierNameAccess
.is() )
1119 OUString
aFullPropName( getFullKeyImpl(aCGuard
) + "/" +
1120 makeHierarchalNameSegment( aPropertyName
) );
1122 // Does property exist?
1123 if ( xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
) )
1125 Reference
< XNameReplace
> xNameReplace(
1126 m_pCreator
->getConfigWriteAccess(
1127 aFullPropName
), UNO_QUERY
);
1128 Reference
< XChangesBatch
> xBatch(
1129 m_pCreator
->getConfigWriteAccess(
1130 OUString() ), UNO_QUERY
);
1132 if ( xNameReplace
.is() && xBatch
.is() )
1137 OUString aValueName
= aFullPropName
+ "/Value";
1139 = xRootHierNameAccess
->getByHierarchicalName(
1141 // Check value type.
1142 if ( aOldValue
.getValueType() != aValue
.getValueType() )
1144 throw IllegalArgumentException();
1148 xNameReplace
->replaceByName( "Value", aValue
);
1150 // Write state ( Now it is a directly set value )
1151 xNameReplace
->replaceByName(
1155 PropertyState_DIRECT_VALUE
) ) );
1158 xBatch
->commitChanges();
1160 PropertyChangeEvent aEvt
;
1161 if ( m_aPropertyChangeListeners
.hasContainedTypes(aCGuard
) )
1164 aValueName
= aFullPropName
+ "/Handle";
1165 sal_Int32 nHandle
= -1;
1166 xRootHierNameAccess
->getByHierarchicalName( aValueName
)
1169 aEvt
.Source
= getXWeak();
1170 aEvt
.PropertyName
= aPropertyName
;
1171 aEvt
.PropertyHandle
= nHandle
;
1172 aEvt
.Further
= false;
1173 aEvt
.OldValue
= aOldValue
;
1174 aEvt
.NewValue
= aValue
;
1176 notifyPropertyChangeEvent( aCGuard
, aEvt
);
1180 catch (const IllegalArgumentException
&)
1184 catch (const NoSuchElementException
&)
1186 // getByHierarchicalName, replaceByName
1188 catch (const WrappedTargetException
&)
1190 // replaceByName, commitChanges
1196 throw UnknownPropertyException(aPropertyName
);
1201 Any SAL_CALL
PersistentPropertySet::getPropertyValue(
1202 const OUString
& PropertyName
)
1204 std::unique_lock
aGuard(m_aMutex
);
1206 Reference
< XHierarchicalNameAccess
> xNameAccess(
1207 m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1208 if ( xNameAccess
.is() )
1210 OUString
aFullPropName( getFullKeyImpl(aGuard
) + "/" +
1211 makeHierarchalNameSegment( PropertyName
) + "/Value" );
1214 return xNameAccess
->getByHierarchicalName( aFullPropName
);
1216 catch (const NoSuchElementException
&)
1218 throw UnknownPropertyException(aFullPropName
);
1222 throw UnknownPropertyException(PropertyName
);
1227 void SAL_CALL
PersistentPropertySet::addPropertyChangeListener(
1228 const OUString
& aPropertyName
,
1229 const Reference
< XPropertyChangeListener
>& xListener
)
1233 std::unique_lock
aGuard(m_aMutex
);
1235 m_aPropertyChangeListeners
.addInterface(aGuard
, aPropertyName
, xListener
);
1240 void SAL_CALL
PersistentPropertySet::removePropertyChangeListener(
1241 const OUString
& aPropertyName
,
1242 const Reference
< XPropertyChangeListener
>& aListener
)
1246 std::unique_lock
aGuard(m_aMutex
);
1248 m_aPropertyChangeListeners
.removeInterface(aGuard
,
1249 aPropertyName
, aListener
);
1251 // Note: Don't want to delete empty container here -> performance.
1256 void SAL_CALL
PersistentPropertySet::addVetoableChangeListener(
1258 const Reference
< XVetoableChangeListener
>& )
1261 // OSL_FAIL( // "PersistentPropertySet::addVetoableChangeListener - N.Y.I." );
1266 void SAL_CALL
PersistentPropertySet::removeVetoableChangeListener(
1268 const Reference
< XVetoableChangeListener
>& )
1271 // OSL_FAIL( // "PersistentPropertySet::removeVetoableChangeListener - N.Y.I." );
1275 // XPersistentPropertySet methods.
1279 Reference
< XPropertySetRegistry
> SAL_CALL
PersistentPropertySet::getRegistry()
1286 OUString SAL_CALL
PersistentPropertySet::getKey()
1296 OUString SAL_CALL
PersistentPropertySet::getName()
1304 void SAL_CALL
PersistentPropertySet::setName( const OUString
& aName
)
1306 if ( aName
!= m_aKey
)
1307 m_pCreator
->renamePropertySet( m_aKey
, aName
);
1311 // XPropertyContainer methods.
1315 void SAL_CALL
PersistentPropertySet::addProperty(
1316 const OUString
& Name
, sal_Int16 Attributes
, const Any
& DefaultValue
)
1318 if ( Name
.isEmpty() )
1319 throw IllegalArgumentException();
1321 // @@@ What other types can't be written to config server?
1323 // Check type class ( Not all types can be written to storage )
1324 TypeClass eTypeClass
= DefaultValue
.getValueTypeClass();
1325 if ( eTypeClass
== TypeClass_INTERFACE
)
1326 throw IllegalTypeException();
1328 std::unique_lock
aGuard(m_aMutex
);
1330 // Property already in set?
1332 OUString aFullValuesName
;
1334 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
1335 m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1336 if ( xRootHierNameAccess
.is() )
1338 aFullValuesName
= getFullKeyImpl(aGuard
);
1339 OUString aFullPropName
= aFullValuesName
+ "/" +
1340 makeHierarchalNameSegment( Name
);
1342 if ( xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
) )
1345 throw PropertyExistException();
1349 // Property is always removable.
1350 Attributes
|= PropertyAttribute::REMOVABLE
;
1354 Reference
< XSingleServiceFactory
> xFac(
1355 m_pCreator
->getConfigWriteAccess( aFullValuesName
),
1357 Reference
< XNameContainer
> xContainer( xFac
, UNO_QUERY
);
1358 Reference
< XChangesBatch
> xBatch(
1359 m_pCreator
->getConfigWriteAccess( OUString() ),
1362 OSL_ENSURE( xFac
.is(),
1363 "PersistentPropertySet::addProperty - No factory!" );
1365 OSL_ENSURE( xBatch
.is(),
1366 "PersistentPropertySet::addProperty - No batch!" );
1368 OSL_ENSURE( xContainer
.is(),
1369 "PersistentPropertySet::addProperty - No container!" );
1371 if ( xFac
.is() && xBatch
.is() && xContainer
.is() )
1375 // Create new "PropertyValue" config item.
1376 Reference
< XNameReplace
> xNameReplace(
1377 xFac
->createInstance(), UNO_QUERY
);
1379 if ( xNameReplace
.is() )
1384 xNameReplace
->replaceByName(
1386 Any( sal_Int32( -1 ) ) );
1388 // Set default value
1389 xNameReplace
->replaceByName(
1393 // Set state ( always "default" )
1394 xNameReplace
->replaceByName(
1398 PropertyState_DEFAULT_VALUE
) ) );
1401 xNameReplace
->replaceByName(
1403 Any( sal_Int32( Attributes
) ) );
1406 xContainer
->insertByName( Name
, Any( xNameReplace
) );
1409 xBatch
->commitChanges();
1411 // Property set info is invalid.
1415 // Notify propertyset info change listeners.
1416 if ( m_aPropSetChangeListeners
.getLength(aGuard
) )
1418 PropertySetInfoChangeEvent
evt(
1422 PropertySetInfoChange::PROPERTY_INSERTED
);
1423 notifyPropertySetInfoChange(aGuard
, evt
);
1430 catch (const IllegalArgumentException
&)
1434 OSL_FAIL( "PersistentPropertySet::addProperty - "
1435 "caught IllegalArgumentException!" );
1438 catch (const ElementExistException
&)
1442 OSL_FAIL( "PersistentPropertySet::addProperty - "
1443 "caught ElementExistException!" );
1446 catch (const WrappedTargetException
&)
1448 // replaceByName, insertByName, commitChanges
1450 OSL_FAIL( "PersistentPropertySet::addProperty - "
1451 "caught WrappedTargetException!" );
1454 catch (const RuntimeException
&)
1458 catch (const Exception
&)
1462 OSL_FAIL( "PersistentPropertySet::addProperty - "
1463 "caught Exception!" );
1468 OSL_FAIL( "PersistentPropertySet::addProperty - Error!" );
1473 void SAL_CALL
PersistentPropertySet::removeProperty( const OUString
& Name
)
1475 std::unique_lock
aGuard(m_aMutex
);
1477 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
1478 m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1479 if ( xRootHierNameAccess
.is() )
1481 OUString aFullValuesName
= getFullKeyImpl(aGuard
);
1482 OUString aFullPropName
= aFullValuesName
+ "/" +
1483 makeHierarchalNameSegment( Name
);
1486 if ( !xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
) )
1487 throw UnknownPropertyException(aFullPropName
);
1489 // Property removable?
1492 OUString aFullAttrName
= aFullPropName
+ "/Attributes";
1494 sal_Int32 nAttribs
= 0;
1495 if ( xRootHierNameAccess
->getByHierarchicalName( aFullAttrName
)
1498 if ( !( nAttribs
& PropertyAttribute::REMOVABLE
) )
1501 throw NotRemoveableException();
1506 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1511 catch (const NoSuchElementException
&)
1513 // getByHierarchicalName
1515 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1516 "caught NoSuchElementException!" );
1519 // Remove property...
1521 Reference
< XNameContainer
> xContainer(
1522 m_pCreator
->getConfigWriteAccess( aFullValuesName
),
1524 Reference
< XChangesBatch
> xBatch(
1525 m_pCreator
->getConfigWriteAccess( OUString() ),
1528 OSL_ENSURE( xBatch
.is(),
1529 "PersistentPropertySet::removeProperty - No batch!" );
1531 OSL_ENSURE( xContainer
.is(),
1532 "PersistentPropertySet::removeProperty - No container!" );
1534 if ( xBatch
.is() && xContainer
.is() )
1538 sal_Int32 nHandle
= -1;
1540 if ( m_aPropSetChangeListeners
.getLength(aGuard
) )
1542 // Obtain property handle ( needed for propertysetinfo
1543 // change event )...
1547 OUString aFullHandleName
= aFullPropName
+ "/Handle";
1549 if ( ! ( xRootHierNameAccess
->getByHierarchicalName(
1550 aFullHandleName
) >>= nHandle
) )
1554 catch (const NoSuchElementException
&)
1556 // getByHierarchicalName
1558 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1559 "caught NoSuchElementException!" );
1564 xContainer
->removeByName( Name
);
1565 xBatch
->commitChanges();
1567 // Property set info is invalid.
1571 // Notify propertyset info change listeners.
1572 if ( m_aPropSetChangeListeners
.getLength(aGuard
) )
1574 PropertySetInfoChangeEvent
evt(
1578 PropertySetInfoChange::PROPERTY_REMOVED
);
1579 notifyPropertySetInfoChange( aGuard
, evt
);
1585 catch (const NoSuchElementException
&)
1589 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1590 "caught NoSuchElementException!" );
1593 catch (const WrappedTargetException
&)
1597 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1598 "caught WrappedTargetException!" );
1604 OSL_FAIL( "PersistentPropertySet::removeProperty - Error!" );
1608 // XPropertySetInfoChangeNotifier methods.
1612 void SAL_CALL
PersistentPropertySet::addPropertySetInfoChangeListener(
1613 const Reference
< XPropertySetInfoChangeListener
>& Listener
)
1615 std::unique_lock
aGuard(m_aMutex
);
1617 m_aPropSetChangeListeners
.addInterface( aGuard
, Listener
);
1622 void SAL_CALL
PersistentPropertySet::removePropertySetInfoChangeListener(
1623 const Reference
< XPropertySetInfoChangeListener
>& Listener
)
1625 std::unique_lock
aGuard(m_aMutex
);
1626 m_aPropSetChangeListeners
.removeInterface( aGuard
, Listener
);
1630 // XPropertyAccess methods.
1634 Sequence
< PropertyValue
> SAL_CALL
PersistentPropertySet::getPropertyValues()
1636 std::unique_lock
aGuard(m_aMutex
);
1638 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
1639 m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1640 if ( xRootHierNameAccess
.is() )
1644 Reference
< XNameAccess
> xNameAccess
;
1645 xRootHierNameAccess
->getByHierarchicalName(getFullKeyImpl(aGuard
))
1647 if ( xNameAccess
.is() )
1649 // Obtain property names.
1651 Sequence
< OUString
> aElems
= xNameAccess
->getElementNames();
1653 sal_Int32 nCount
= aElems
.getLength();
1656 Reference
< XHierarchicalNameAccess
> xHierNameAccess(
1657 xNameAccess
, UNO_QUERY
);
1659 OSL_ENSURE( xHierNameAccess
.is(),
1660 "PersistentPropertySet::getPropertyValues - "
1661 "No hierarchical name access!" );
1663 if ( xHierNameAccess
.is() )
1665 Sequence
< PropertyValue
> aValues( nCount
);
1666 auto pValues
= aValues
.getArray();
1668 static constexpr OUStringLiteral
aHandleName(u
"/Handle");
1669 static constexpr OUStringLiteral
aValueName(u
"/Value");
1670 static constexpr OUStringLiteral
aStateName(u
"/State");
1672 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
1674 PropertyValue
& rValue
= pValues
[ n
];
1675 OUString rName
= aElems
[ n
];
1677 = makeHierarchalNameSegment( rName
);
1679 // Set property name.
1681 rValue
.Name
= rName
;
1685 // Obtain and set property handle
1686 OUString aHierName
= aXMLName
+ aHandleName
;
1688 = xHierNameAccess
->getByHierarchicalName(
1691 if ( !( aKeyValue
>>= rValue
.Handle
) )
1692 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1693 "Error getting property handle!" );
1695 catch (const NoSuchElementException
&)
1697 // getByHierarchicalName
1699 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1700 "NoSuchElementException!" );
1705 // Obtain and set property value
1706 OUString aHierName
= aXMLName
+ aValueName
;
1708 = xHierNameAccess
->getByHierarchicalName(
1711 // Note: The value may be void if addProperty
1712 // was called with a default value
1715 catch (const NoSuchElementException
&)
1717 // getByHierarchicalName
1719 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1720 "NoSuchElementException!" );
1725 // Obtain and set property state
1726 OUString aHierName
= aXMLName
+aStateName
;
1728 = xHierNameAccess
->getByHierarchicalName(
1731 sal_Int32 nState
= 0;
1732 if ( !( aKeyValue
>>= nState
) )
1733 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1734 "Error getting property state!" );
1736 rValue
.State
= PropertyState( nState
);
1738 catch (const NoSuchElementException
&)
1740 // getByHierarchicalName
1742 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1743 "NoSuchElementException!" );
1752 catch (const NoSuchElementException
&)
1754 // getByHierarchicalName
1758 return Sequence
< PropertyValue
>( 0 );
1763 void SAL_CALL
PersistentPropertySet::setPropertyValues(
1764 const Sequence
< PropertyValue
>& aProps
)
1766 if ( !aProps
.hasElements() )
1769 std::unique_lock
aCGuard(m_aMutex
);
1771 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
1772 m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1773 if ( xRootHierNameAccess
.is() )
1775 std::vector
< PropertyChangeEvent
> aEvents
;
1777 OUString
aFullPropNamePrefix( getFullKeyImpl(aCGuard
) + "/" );
1779 // Iterate over given property value sequence.
1780 for ( const PropertyValue
& rNewValue
: aProps
)
1782 const OUString
& rName
= rNewValue
.Name
;
1784 OUString aFullPropName
= aFullPropNamePrefix
+
1785 makeHierarchalNameSegment( rName
);
1787 // Does property exist?
1788 if ( xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
) )
1790 Reference
< XNameReplace
> xNameReplace(
1791 m_pCreator
->getConfigWriteAccess(
1792 aFullPropName
), UNO_QUERY
);
1793 Reference
< XChangesBatch
> xBatch(
1794 m_pCreator
->getConfigWriteAccess(
1795 OUString() ), UNO_QUERY
);
1797 if ( xNameReplace
.is() && xBatch
.is() )
1802 xNameReplace
->replaceByName(
1804 Any( rNewValue
.Handle
) );
1807 OUString aValueName
= aFullPropName
+"/Value";
1809 = xRootHierNameAccess
->getByHierarchicalName(
1812 xNameReplace
->replaceByName(
1816 // Write state ( Now it is a directly set value )
1817 xNameReplace
->replaceByName(
1821 PropertyState_DIRECT_VALUE
) ) );
1824 xBatch
->commitChanges();
1826 if ( m_aPropertyChangeListeners
.hasContainedTypes(aCGuard
) )
1828 PropertyChangeEvent aEvt
;
1829 aEvt
.Source
= getXWeak();
1830 aEvt
.PropertyName
= rNewValue
.Name
;
1831 aEvt
.PropertyHandle
= rNewValue
.Handle
;
1832 aEvt
.Further
= false;
1833 aEvt
.OldValue
= std::move(aOldValue
);
1834 aEvt
.NewValue
= rNewValue
.Value
;
1836 aEvents
.push_back( aEvt
);
1839 catch (const IllegalArgumentException
&)
1843 catch (const NoSuchElementException
&)
1845 // getByHierarchicalName, replaceByName
1847 catch (const WrappedTargetException
&)
1849 // replaceByName, commitChanges
1855 if ( m_aPropertyChangeListeners
.hasContainedTypes(aCGuard
) )
1857 // Notify property changes.
1858 for (auto const& event
: aEvents
)
1860 notifyPropertyChangeEvent( aCGuard
, event
);
1867 OSL_FAIL( "PersistentPropertySet::setPropertyValues - Nothing set!" );
1871 // Non-interface methods
1874 void PersistentPropertySet::notifyPropertyChangeEvent(
1875 std::unique_lock
<std::mutex
>& rGuard
,
1876 const PropertyChangeEvent
& rEvent
) const
1878 // Get "normal" listeners for the property.
1879 OInterfaceContainerHelper4
<XPropertyChangeListener
>* pContainer
=
1880 m_aPropertyChangeListeners
.getContainer( rGuard
, rEvent
.PropertyName
);
1881 if ( pContainer
&& pContainer
->getLength(rGuard
) )
1883 pContainer
->notifyEach( rGuard
, &XPropertyChangeListener::propertyChange
, rEvent
);
1886 // Get "normal" listeners for all properties.
1887 OInterfaceContainerHelper4
<XPropertyChangeListener
>* pNoNameContainer
=
1888 m_aPropertyChangeListeners
.getContainer( rGuard
, OUString() );
1889 if ( pNoNameContainer
&& pNoNameContainer
->getLength(rGuard
) )
1891 pNoNameContainer
->notifyEach( rGuard
, &XPropertyChangeListener::propertyChange
, rEvent
);
1896 void PersistentPropertySet::notifyPropertySetInfoChange(
1897 std::unique_lock
<std::mutex
>& rGuard
,
1898 const PropertySetInfoChangeEvent
& evt
) const
1900 // Notify event listeners.
1901 m_aPropSetChangeListeners
.notifyEach( rGuard
, &XPropertySetInfoChangeListener::propertySetInfoChange
, evt
);
1905 OUString
PersistentPropertySet::getFullKey()
1907 std::unique_lock
aGuard(m_aMutex
);
1908 return getFullKeyImpl(aGuard
);
1911 const OUString
& PersistentPropertySet::getFullKeyImpl(std::unique_lock
<std::mutex
>& )
1913 if ( m_aFullKey
.isEmpty() )
1915 m_aFullKey
= makeHierarchalNameSegment( m_aKey
);
1916 m_aFullKey
+= "/Values";
1923 PropertySetRegistry
& PersistentPropertySet::getPropertySetRegistry()
1929 // PropertySetInfo_Impl Implementation.
1932 PropertySetInfo_Impl::PropertySetInfo_Impl(
1933 PersistentPropertySet
* pOwner
)
1934 : m_pOwner( pOwner
)
1939 // XPropertySetInfo methods.
1943 Sequence
< Property
> SAL_CALL
PropertySetInfo_Impl::getProperties()
1947 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
1948 m_pOwner
->getPropertySetRegistry().getRootConfigReadAccess(),
1950 if ( xRootHierNameAccess
.is() )
1954 Reference
< XNameAccess
> xNameAccess
;
1955 xRootHierNameAccess
->getByHierarchicalName(
1956 m_pOwner
->getFullKey() )
1958 if ( xNameAccess
.is() )
1960 // Obtain property names.
1962 Sequence
< OUString
> aElems
1963 = xNameAccess
->getElementNames();
1965 sal_uInt32 nCount
= aElems
.getLength();
1966 Sequence
< Property
> aPropSeq( nCount
);
1970 Reference
< XHierarchicalNameAccess
> xHierNameAccess(
1971 xNameAccess
, UNO_QUERY
);
1973 OSL_ENSURE( xHierNameAccess
.is(),
1974 "PropertySetInfo_Impl::getProperties - "
1975 "No hierarchical name access!" );
1977 if ( xHierNameAccess
.is() )
1979 static constexpr OUStringLiteral
aHandleName(u
"/Handle");
1980 static constexpr OUStringLiteral
aValueName(u
"/Value");
1981 static constexpr OUStringLiteral
aAttrName(u
"/Attributes");
1983 Property
* pProps
= aPropSeq
.getArray();
1985 for ( sal_uInt32 n
= 0; n
< nCount
; ++n
)
1987 Property
& rProp
= pProps
[ n
];
1988 OUString rName
= aElems
[ n
];
1990 = makeHierarchalNameSegment( rName
);
1992 // Set property name.
1998 // Obtain and set property handle
1999 OUString aHierName
= aXMLName
+ aHandleName
;
2001 = xHierNameAccess
->getByHierarchicalName(
2004 if ( !( aKeyValue
>>= rProp
.Handle
) )
2005 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2006 "Error getting property handle!" );
2008 catch (const NoSuchElementException
&)
2010 // getByHierarchicalName
2012 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2013 "NoSuchElementException!" );
2018 // Obtain and set property type
2019 OUString aHierName
= aXMLName
+ aValueName
;
2021 = xHierNameAccess
->getByHierarchicalName(
2024 // Note: The type may be void if addProperty
2025 // was called with a default value
2028 rProp
.Type
= aKeyValue
.getValueType();
2030 catch (const NoSuchElementException
&)
2032 // getByHierarchicalName
2034 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2035 "NoSuchElementException!" );
2040 // Obtain and set property attributes
2041 OUString aHierName
= aXMLName
+ aAttrName
;
2043 = xHierNameAccess
->getByHierarchicalName(
2046 sal_Int32 nAttribs
= 0;
2047 if ( aKeyValue
>>= nAttribs
)
2049 = sal_Int16( nAttribs
);
2051 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2052 "Error getting property attributes!" );
2054 catch (const NoSuchElementException
&)
2056 // getByHierarchicalName
2058 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2059 "NoSuchElementException!" );
2066 m_xProps
= std::move(aPropSeq
);
2070 catch (const NoSuchElementException
&)
2072 // getByHierarchicalName
2076 OSL_FAIL( "PropertySetInfo_Impl::getProperties - Error!" );
2085 Property SAL_CALL
PropertySetInfo_Impl::getPropertyByName(
2086 const OUString
& aName
)
2088 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
2089 m_pOwner
->getPropertySetRegistry().getRootConfigReadAccess(),
2091 if ( xRootHierNameAccess
.is() )
2093 OUString
aFullPropName( m_pOwner
->getFullKey() + "/" +
2094 makeHierarchalNameSegment( aName
) );
2096 // Does property exist?
2097 if ( !xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
) )
2098 throw UnknownPropertyException(aFullPropName
);
2105 OUString aKey
= aFullPropName
+ "/Handle";
2107 if ( !( xRootHierNameAccess
->getByHierarchicalName( aKey
)
2108 >>= aProp
.Handle
) )
2110 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2115 // Obtain Value and extract type.
2116 aKey
= aFullPropName
+ "/Value";
2118 Any aValue
= xRootHierNameAccess
->getByHierarchicalName( aKey
);
2119 if ( !aValue
.hasValue() )
2121 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2126 aProp
.Type
= aValue
.getValueType();
2128 // Obtain Attributes.
2129 aKey
= aFullPropName
+ "/Attributes";
2131 sal_Int32 nAttribs
= 0;
2132 if ( xRootHierNameAccess
->getByHierarchicalName( aKey
)
2134 aProp
.Attributes
= sal_Int16( nAttribs
);
2137 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2148 catch (const NoSuchElementException
&)
2150 // getByHierarchicalName
2152 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2153 "caught NoSuchElementException!" );
2158 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - Error!" );
2164 sal_Bool SAL_CALL
PropertySetInfo_Impl::hasPropertyByName(
2165 const OUString
& Name
)
2167 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
2168 m_pOwner
->getPropertySetRegistry().getRootConfigReadAccess(),
2170 if ( xRootHierNameAccess
.is() )
2172 OUString
aFullPropName( m_pOwner
->getFullKey() + "/" +
2173 makeHierarchalNameSegment( Name
) );
2175 return xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
);
2181 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */