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 OUStringLiteral STORE_CONTENTPROPERTIES_KEY
= u
"/org.openoffice.ucb.Store/ContentProperties";
104 // describe path of cfg entry
105 constexpr OUStringLiteral CFGPROPERTY_NODEPATH
= u
"nodepath";
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 OUString
const aHandleKey("/Handle");
685 OUString
const aValueKey("/Value");
686 OUString
const aStateKey("/State");
687 OUString
const aAttrKey("/Attributes");
689 for ( const OUString
& rPropName
: aElems
)
692 Reference
< XNameReplace
> xNewPropNameReplace(
693 xNewFac
->createInstance(), UNO_QUERY
);
695 if ( !xNewPropNameReplace
.is() )
697 OSL_FAIL( "PersistentPropertySet::renamePropertySet - "
698 "No new prop name replace!" );
705 OUString aKey
= aOldValuesKey
+ makeHierarchalNameSegment( rPropName
);
708 OUString aNewKey1
= aKey
+ aHandleKey
;
710 xRootHierNameAccess
->getByHierarchicalName(
712 xNewPropNameReplace
->replaceByName( "Handle", aAny
);
715 aNewKey1
= aKey
+ aValueKey
;
717 xRootHierNameAccess
->getByHierarchicalName(
719 xNewPropNameReplace
->replaceByName( "Value", aAny
);
722 aNewKey1
= aKey
+ aStateKey
;
724 xRootHierNameAccess
->getByHierarchicalName(
726 xNewPropNameReplace
->replaceByName( "State", aAny
);
729 aNewKey1
= aKey
+ aAttrKey
;
731 xRootHierNameAccess
->getByHierarchicalName(
733 xNewPropNameReplace
->replaceByName( "Attributes", aAny
);
736 xNewContainer
->insertByName(
737 rPropName
, Any( xNewPropNameReplace
) );
740 xBatch
->commitChanges();
744 catch (const IllegalArgumentException
&)
746 // insertByName, replaceByName
748 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
749 "caught IllegalArgumentException!" );
752 catch (const ElementExistException
&)
756 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
757 "caught ElementExistException!" );
760 catch (const WrappedTargetException
&)
762 // insertByName, replaceByName, commitChanges
764 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
765 "caught WrappedTargetException!" );
768 catch (const NoSuchElementException
&)
770 // getByHierarchicalName, replaceByName
772 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
773 "caught NoSuchElementException!" );
776 catch (const RuntimeException
&)
778 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
779 "caught RuntimeException!" );
782 catch (const Exception
&)
786 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
787 "caught Exception!" );
792 // Remove old entry...
798 xContainer
->removeByName( rOldKey
);
800 xBatch
->commitChanges();
805 catch (const NoSuchElementException
&)
809 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
810 "caught NoSuchElementException!" );
813 catch (const WrappedTargetException
&)
817 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
818 "caught WrappedTargetException!" );
825 OSL_FAIL( "PropertySetRegistry::renamePropertySet - Error!" );
829 Reference
< XMultiServiceFactory
> PropertySetRegistry::getConfigProvider(std::unique_lock
<std::mutex
>& /*rGuard*/)
831 if ( !m_xConfigProvider
.is() )
833 const Sequence
< Any
>& rInitArgs
= m_aInitArgs
;
835 if ( rInitArgs
.hasElements() )
837 // Extract config provider from service init args.
838 rInitArgs
[ 0 ] >>= m_xConfigProvider
;
840 OSL_ENSURE( m_xConfigProvider
.is(),
841 "PropertySetRegistry::getConfigProvider - "
842 "No config provider!" );
848 m_xConfigProvider
= theDefaultProvider::get( m_xContext
);
850 catch (const Exception
&)
852 TOOLS_WARN_EXCEPTION( "ucb", "");
857 return m_xConfigProvider
;
861 Reference
< XInterface
> PropertySetRegistry::getRootConfigReadAccess()
863 std::unique_lock
aGuard( m_aMutex
);
864 return getRootConfigReadAccessImpl(aGuard
);
867 Reference
< XInterface
> PropertySetRegistry::getRootConfigReadAccessImpl(std::unique_lock
<std::mutex
>& rGuard
)
871 if ( !m_xRootReadAccess
.is() )
873 if ( m_bTriedToGetRootReadAccess
)
875 OSL_FAIL( "PropertySetRegistry::getRootConfigReadAccess - "
876 "Unable to read any config data! -> #82494#" );
877 return Reference
< XInterface
>();
880 getConfigProvider(rGuard
);
882 if ( m_xConfigProvider
.is() )
884 Sequence
<Any
> aArguments(comphelper::InitAnyPropertySequence(
886 {CFGPROPERTY_NODEPATH
, Any(OUString( STORE_CONTENTPROPERTIES_KEY
))}
889 m_bTriedToGetRootReadAccess
= true;
892 m_xConfigProvider
->createInstanceWithArguments(
893 "com.sun.star.configuration.ConfigurationAccess",
896 if ( m_xRootReadAccess
.is() )
897 return m_xRootReadAccess
;
901 return m_xRootReadAccess
;
903 catch (const RuntimeException
&)
907 catch (const Exception
&)
909 // createInstance, createInstanceWithArguments
911 TOOLS_WARN_EXCEPTION("ucb", "");
912 return Reference
< XInterface
>();
915 SAL_WARN( "ucb", "Error!" );
916 return Reference
< XInterface
>();
920 Reference
< XInterface
> PropertySetRegistry::getConfigWriteAccess(
921 const OUString
& rPath
)
923 std::unique_lock
aGuard( m_aMutex
);
924 return getConfigWriteAccessImpl(aGuard
, rPath
);
927 Reference
< XInterface
> PropertySetRegistry::getConfigWriteAccessImpl(std::unique_lock
<std::mutex
>& rGuard
,
928 const OUString
& rPath
)
932 if ( !m_xRootWriteAccess
.is() )
934 if ( m_bTriedToGetRootWriteAccess
)
936 OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - "
937 "Unable to write any config data! -> #82494#" );
938 return Reference
< XInterface
>();
941 getConfigProvider(rGuard
);
943 if ( m_xConfigProvider
.is() )
945 Sequence
<Any
> aArguments(comphelper::InitAnyPropertySequence(
947 {CFGPROPERTY_NODEPATH
, Any(OUString( STORE_CONTENTPROPERTIES_KEY
))}
950 m_bTriedToGetRootWriteAccess
= true;
953 m_xConfigProvider
->createInstanceWithArguments(
954 "com.sun.star.configuration.ConfigurationUpdateAccess",
957 OSL_ENSURE( m_xRootWriteAccess
.is(),
958 "PropertySetRegistry::getConfigWriteAccess - "
959 "No config update access!" );
963 if ( m_xRootWriteAccess
.is() )
965 if ( !rPath
.isEmpty() )
967 Reference
< XHierarchicalNameAccess
> xNA(
968 m_xRootWriteAccess
, UNO_QUERY
);
971 Reference
< XInterface
> xInterface
;
972 xNA
->getByHierarchicalName( rPath
) >>= xInterface
;
974 if ( xInterface
.is() )
979 return m_xRootWriteAccess
;
982 catch (const RuntimeException
&)
986 catch (const NoSuchElementException
&)
988 // getByHierarchicalName
990 OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - "
991 "caught NoSuchElementException!" );
992 return Reference
< XInterface
>();
994 catch (const Exception
&)
996 // createInstance, createInstanceWithArguments
998 OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - "
999 "caught Exception!" );
1000 return Reference
< XInterface
>();
1003 OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - Error!" );
1004 return Reference
< XInterface
>();
1008 // PersistentPropertySet Implementation.
1011 PersistentPropertySet::PersistentPropertySet(
1012 std::unique_lock
<std::mutex
>& rCreatorGuard
,
1013 PropertySetRegistry
& rCreator
,
1015 : m_pCreator( &rCreator
), m_aKey(std::move( aKey
))
1017 // register at creator.
1018 rCreator
.add( rCreatorGuard
, this );
1023 PersistentPropertySet::~PersistentPropertySet()
1025 // deregister at creator.
1026 m_pCreator
->remove( this );
1029 // XServiceInfo methods.
1031 OUString SAL_CALL
PersistentPropertySet::getImplementationName()
1033 return "com.sun.star.comp.ucb.PersistentPropertySet";
1036 sal_Bool SAL_CALL
PersistentPropertySet::supportsService( const OUString
& ServiceName
)
1038 return cppu::supportsService( this, ServiceName
);
1041 css::uno::Sequence
< OUString
> SAL_CALL
PersistentPropertySet::getSupportedServiceNames()
1043 return { "com.sun.star.ucb.PersistentPropertySet" };
1047 // XComponent methods.
1051 void SAL_CALL
PersistentPropertySet::dispose()
1053 std::unique_lock
l(m_aMutex
);
1054 if ( m_aDisposeEventListeners
.getLength(l
) )
1057 aEvt
.Source
= static_cast< XComponent
* >( this );
1058 m_aDisposeEventListeners
.disposeAndClear( l
, aEvt
);
1061 if ( m_aPropSetChangeListeners
.getLength(l
) )
1064 aEvt
.Source
= static_cast< XPropertySetInfoChangeNotifier
* >( this );
1065 m_aPropSetChangeListeners
.disposeAndClear( l
, aEvt
);
1068 if ( m_aPropertyChangeListeners
.hasContainedTypes(l
) )
1071 aEvt
.Source
= static_cast< XPropertySet
* >( this );
1072 m_aPropertyChangeListeners
.disposeAndClear( l
, aEvt
);
1078 void SAL_CALL
PersistentPropertySet::addEventListener(
1079 const Reference
< XEventListener
>& Listener
)
1081 std::unique_lock
l(m_aMutex
);
1083 m_aDisposeEventListeners
.addInterface( l
, Listener
);
1088 void SAL_CALL
PersistentPropertySet::removeEventListener(
1089 const Reference
< XEventListener
>& Listener
)
1091 std::unique_lock
l(m_aMutex
);
1092 m_aDisposeEventListeners
.removeInterface( l
, Listener
);
1094 // Note: Don't want to delete empty container here -> performance.
1098 // XPropertySet methods.
1102 Reference
< XPropertySetInfo
> SAL_CALL
PersistentPropertySet::getPropertySetInfo()
1104 std::unique_lock
l(m_aMutex
);
1106 if ( !m_pInfo
.is() )
1108 m_pInfo
= new PropertySetInfo_Impl( this );
1115 void SAL_CALL
PersistentPropertySet::setPropertyValue( const OUString
& aPropertyName
,
1118 std::unique_lock
aCGuard(m_aMutex
);
1120 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
1121 m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1122 if ( xRootHierNameAccess
.is() )
1124 OUString
aFullPropName( getFullKeyImpl(aCGuard
) + "/" +
1125 makeHierarchalNameSegment( aPropertyName
) );
1127 // Does property exist?
1128 if ( xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
) )
1130 Reference
< XNameReplace
> xNameReplace(
1131 m_pCreator
->getConfigWriteAccess(
1132 aFullPropName
), UNO_QUERY
);
1133 Reference
< XChangesBatch
> xBatch(
1134 m_pCreator
->getConfigWriteAccess(
1135 OUString() ), UNO_QUERY
);
1137 if ( xNameReplace
.is() && xBatch
.is() )
1142 OUString aValueName
= aFullPropName
+ "/Value";
1144 = xRootHierNameAccess
->getByHierarchicalName(
1146 // Check value type.
1147 if ( aOldValue
.getValueType() != aValue
.getValueType() )
1149 throw IllegalArgumentException();
1153 xNameReplace
->replaceByName( "Value", aValue
);
1155 // Write state ( Now it is a directly set value )
1156 xNameReplace
->replaceByName(
1160 PropertyState_DIRECT_VALUE
) ) );
1163 xBatch
->commitChanges();
1165 PropertyChangeEvent aEvt
;
1166 if ( m_aPropertyChangeListeners
.hasContainedTypes(aCGuard
) )
1169 aValueName
= aFullPropName
+ "/Handle";
1170 sal_Int32 nHandle
= -1;
1171 xRootHierNameAccess
->getByHierarchicalName( aValueName
)
1174 aEvt
.Source
= static_cast<OWeakObject
*>(this);
1175 aEvt
.PropertyName
= aPropertyName
;
1176 aEvt
.PropertyHandle
= nHandle
;
1177 aEvt
.Further
= false;
1178 aEvt
.OldValue
= aOldValue
;
1179 aEvt
.NewValue
= aValue
;
1181 notifyPropertyChangeEvent( aCGuard
, aEvt
);
1185 catch (const IllegalArgumentException
&)
1189 catch (const NoSuchElementException
&)
1191 // getByHierarchicalName, replaceByName
1193 catch (const WrappedTargetException
&)
1195 // replaceByName, commitChanges
1201 throw UnknownPropertyException(aPropertyName
);
1206 Any SAL_CALL
PersistentPropertySet::getPropertyValue(
1207 const OUString
& PropertyName
)
1209 std::unique_lock
aGuard(m_aMutex
);
1211 Reference
< XHierarchicalNameAccess
> xNameAccess(
1212 m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1213 if ( xNameAccess
.is() )
1215 OUString
aFullPropName( getFullKeyImpl(aGuard
) + "/" +
1216 makeHierarchalNameSegment( PropertyName
) + "/Value" );
1219 return xNameAccess
->getByHierarchicalName( aFullPropName
);
1221 catch (const NoSuchElementException
&)
1223 throw UnknownPropertyException(aFullPropName
);
1227 throw UnknownPropertyException(PropertyName
);
1232 void SAL_CALL
PersistentPropertySet::addPropertyChangeListener(
1233 const OUString
& aPropertyName
,
1234 const Reference
< XPropertyChangeListener
>& xListener
)
1238 std::unique_lock
aGuard(m_aMutex
);
1240 m_aPropertyChangeListeners
.addInterface(aGuard
, aPropertyName
, xListener
);
1245 void SAL_CALL
PersistentPropertySet::removePropertyChangeListener(
1246 const OUString
& aPropertyName
,
1247 const Reference
< XPropertyChangeListener
>& aListener
)
1251 std::unique_lock
aGuard(m_aMutex
);
1253 m_aPropertyChangeListeners
.removeInterface(aGuard
,
1254 aPropertyName
, aListener
);
1256 // Note: Don't want to delete empty container here -> performance.
1261 void SAL_CALL
PersistentPropertySet::addVetoableChangeListener(
1263 const Reference
< XVetoableChangeListener
>& )
1266 // OSL_FAIL( // "PersistentPropertySet::addVetoableChangeListener - N.Y.I." );
1271 void SAL_CALL
PersistentPropertySet::removeVetoableChangeListener(
1273 const Reference
< XVetoableChangeListener
>& )
1276 // OSL_FAIL( // "PersistentPropertySet::removeVetoableChangeListener - N.Y.I." );
1280 // XPersistentPropertySet methods.
1284 Reference
< XPropertySetRegistry
> SAL_CALL
PersistentPropertySet::getRegistry()
1291 OUString SAL_CALL
PersistentPropertySet::getKey()
1301 OUString SAL_CALL
PersistentPropertySet::getName()
1309 void SAL_CALL
PersistentPropertySet::setName( const OUString
& aName
)
1311 if ( aName
!= m_aKey
)
1312 m_pCreator
->renamePropertySet( m_aKey
, aName
);
1316 // XPropertyContainer methods.
1320 void SAL_CALL
PersistentPropertySet::addProperty(
1321 const OUString
& Name
, sal_Int16 Attributes
, const Any
& DefaultValue
)
1323 if ( Name
.isEmpty() )
1324 throw IllegalArgumentException();
1326 // @@@ What other types can't be written to config server?
1328 // Check type class ( Not all types can be written to storage )
1329 TypeClass eTypeClass
= DefaultValue
.getValueTypeClass();
1330 if ( eTypeClass
== TypeClass_INTERFACE
)
1331 throw IllegalTypeException();
1333 std::unique_lock
aGuard(m_aMutex
);
1335 // Property already in set?
1337 OUString aFullValuesName
;
1339 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
1340 m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1341 if ( xRootHierNameAccess
.is() )
1343 aFullValuesName
= getFullKeyImpl(aGuard
);
1344 OUString aFullPropName
= aFullValuesName
+ "/" +
1345 makeHierarchalNameSegment( Name
);
1347 if ( xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
) )
1350 throw PropertyExistException();
1354 // Property is always removable.
1355 Attributes
|= PropertyAttribute::REMOVABLE
;
1359 Reference
< XSingleServiceFactory
> xFac(
1360 m_pCreator
->getConfigWriteAccess( aFullValuesName
),
1362 Reference
< XNameContainer
> xContainer( xFac
, UNO_QUERY
);
1363 Reference
< XChangesBatch
> xBatch(
1364 m_pCreator
->getConfigWriteAccess( OUString() ),
1367 OSL_ENSURE( xFac
.is(),
1368 "PersistentPropertySet::addProperty - No factory!" );
1370 OSL_ENSURE( xBatch
.is(),
1371 "PersistentPropertySet::addProperty - No batch!" );
1373 OSL_ENSURE( xContainer
.is(),
1374 "PersistentPropertySet::addProperty - No container!" );
1376 if ( xFac
.is() && xBatch
.is() && xContainer
.is() )
1380 // Create new "PropertyValue" config item.
1381 Reference
< XNameReplace
> xNameReplace(
1382 xFac
->createInstance(), UNO_QUERY
);
1384 if ( xNameReplace
.is() )
1389 xNameReplace
->replaceByName(
1391 Any( sal_Int32( -1 ) ) );
1393 // Set default value
1394 xNameReplace
->replaceByName(
1398 // Set state ( always "default" )
1399 xNameReplace
->replaceByName(
1403 PropertyState_DEFAULT_VALUE
) ) );
1406 xNameReplace
->replaceByName(
1408 Any( sal_Int32( Attributes
) ) );
1411 xContainer
->insertByName( Name
, Any( xNameReplace
) );
1414 xBatch
->commitChanges();
1416 // Property set info is invalid.
1420 // Notify propertyset info change listeners.
1421 if ( m_aPropSetChangeListeners
.getLength(aGuard
) )
1423 PropertySetInfoChangeEvent
evt(
1424 static_cast< OWeakObject
* >( this ),
1427 PropertySetInfoChange::PROPERTY_INSERTED
);
1428 notifyPropertySetInfoChange(aGuard
, evt
);
1435 catch (const IllegalArgumentException
&)
1439 OSL_FAIL( "PersistentPropertySet::addProperty - "
1440 "caught IllegalArgumentException!" );
1443 catch (const ElementExistException
&)
1447 OSL_FAIL( "PersistentPropertySet::addProperty - "
1448 "caught ElementExistException!" );
1451 catch (const WrappedTargetException
&)
1453 // replaceByName, insertByName, commitChanges
1455 OSL_FAIL( "PersistentPropertySet::addProperty - "
1456 "caught WrappedTargetException!" );
1459 catch (const RuntimeException
&)
1463 catch (const Exception
&)
1467 OSL_FAIL( "PersistentPropertySet::addProperty - "
1468 "caught Exception!" );
1473 OSL_FAIL( "PersistentPropertySet::addProperty - Error!" );
1478 void SAL_CALL
PersistentPropertySet::removeProperty( const OUString
& Name
)
1480 std::unique_lock
aGuard(m_aMutex
);
1482 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
1483 m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1484 if ( xRootHierNameAccess
.is() )
1486 OUString aFullValuesName
= getFullKeyImpl(aGuard
);
1487 OUString aFullPropName
= aFullValuesName
+ "/" +
1488 makeHierarchalNameSegment( Name
);
1491 if ( !xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
) )
1492 throw UnknownPropertyException(aFullPropName
);
1494 // Property removable?
1497 OUString aFullAttrName
= aFullPropName
+ "/Attributes";
1499 sal_Int32 nAttribs
= 0;
1500 if ( xRootHierNameAccess
->getByHierarchicalName( aFullAttrName
)
1503 if ( !( nAttribs
& PropertyAttribute::REMOVABLE
) )
1506 throw NotRemoveableException();
1511 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1516 catch (const NoSuchElementException
&)
1518 // getByHierarchicalName
1520 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1521 "caught NoSuchElementException!" );
1524 // Remove property...
1526 Reference
< XNameContainer
> xContainer(
1527 m_pCreator
->getConfigWriteAccess( aFullValuesName
),
1529 Reference
< XChangesBatch
> xBatch(
1530 m_pCreator
->getConfigWriteAccess( OUString() ),
1533 OSL_ENSURE( xBatch
.is(),
1534 "PersistentPropertySet::removeProperty - No batch!" );
1536 OSL_ENSURE( xContainer
.is(),
1537 "PersistentPropertySet::removeProperty - No container!" );
1539 if ( xBatch
.is() && xContainer
.is() )
1543 sal_Int32 nHandle
= -1;
1545 if ( m_aPropSetChangeListeners
.getLength(aGuard
) )
1547 // Obtain property handle ( needed for propertysetinfo
1548 // change event )...
1552 OUString aFullHandleName
= aFullPropName
+ "/Handle";
1554 if ( ! ( xRootHierNameAccess
->getByHierarchicalName(
1555 aFullHandleName
) >>= nHandle
) )
1559 catch (const NoSuchElementException
&)
1561 // getByHierarchicalName
1563 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1564 "caught NoSuchElementException!" );
1569 xContainer
->removeByName( Name
);
1570 xBatch
->commitChanges();
1572 // Property set info is invalid.
1576 // Notify propertyset info change listeners.
1577 if ( m_aPropSetChangeListeners
.getLength(aGuard
) )
1579 PropertySetInfoChangeEvent
evt(
1580 static_cast< OWeakObject
* >( this ),
1583 PropertySetInfoChange::PROPERTY_REMOVED
);
1584 notifyPropertySetInfoChange( aGuard
, evt
);
1590 catch (const NoSuchElementException
&)
1594 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1595 "caught NoSuchElementException!" );
1598 catch (const WrappedTargetException
&)
1602 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1603 "caught WrappedTargetException!" );
1609 OSL_FAIL( "PersistentPropertySet::removeProperty - Error!" );
1613 // XPropertySetInfoChangeNotifier methods.
1617 void SAL_CALL
PersistentPropertySet::addPropertySetInfoChangeListener(
1618 const Reference
< XPropertySetInfoChangeListener
>& Listener
)
1620 std::unique_lock
aGuard(m_aMutex
);
1622 m_aPropSetChangeListeners
.addInterface( aGuard
, Listener
);
1627 void SAL_CALL
PersistentPropertySet::removePropertySetInfoChangeListener(
1628 const Reference
< XPropertySetInfoChangeListener
>& Listener
)
1630 std::unique_lock
aGuard(m_aMutex
);
1631 m_aPropSetChangeListeners
.removeInterface( aGuard
, Listener
);
1635 // XPropertyAccess methods.
1639 Sequence
< PropertyValue
> SAL_CALL
PersistentPropertySet::getPropertyValues()
1641 std::unique_lock
aGuard(m_aMutex
);
1643 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
1644 m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1645 if ( xRootHierNameAccess
.is() )
1649 Reference
< XNameAccess
> xNameAccess
;
1650 xRootHierNameAccess
->getByHierarchicalName(getFullKeyImpl(aGuard
))
1652 if ( xNameAccess
.is() )
1654 // Obtain property names.
1656 Sequence
< OUString
> aElems
= xNameAccess
->getElementNames();
1658 sal_Int32 nCount
= aElems
.getLength();
1661 Reference
< XHierarchicalNameAccess
> xHierNameAccess(
1662 xNameAccess
, UNO_QUERY
);
1664 OSL_ENSURE( xHierNameAccess
.is(),
1665 "PersistentPropertySet::getPropertyValues - "
1666 "No hierarchical name access!" );
1668 if ( xHierNameAccess
.is() )
1670 Sequence
< PropertyValue
> aValues( nCount
);
1671 auto pValues
= aValues
.getArray();
1673 static const OUStringLiteral
aHandleName(u
"/Handle");
1674 static const OUStringLiteral
aValueName(u
"/Value");
1675 static const OUStringLiteral
aStateName(u
"/State");
1677 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
1679 PropertyValue
& rValue
= pValues
[ n
];
1680 OUString rName
= aElems
[ n
];
1682 = makeHierarchalNameSegment( rName
);
1684 // Set property name.
1686 rValue
.Name
= rName
;
1690 // Obtain and set property handle
1691 OUString aHierName
= aXMLName
+ aHandleName
;
1693 = xHierNameAccess
->getByHierarchicalName(
1696 if ( !( aKeyValue
>>= rValue
.Handle
) )
1697 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1698 "Error getting property handle!" );
1700 catch (const NoSuchElementException
&)
1702 // getByHierarchicalName
1704 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1705 "NoSuchElementException!" );
1710 // Obtain and set property value
1711 OUString aHierName
= aXMLName
+ aValueName
;
1713 = xHierNameAccess
->getByHierarchicalName(
1716 // Note: The value may be void if addProperty
1717 // was called with a default value
1720 catch (const NoSuchElementException
&)
1722 // getByHierarchicalName
1724 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1725 "NoSuchElementException!" );
1730 // Obtain and set property state
1731 OUString aHierName
= aXMLName
+aStateName
;
1733 = xHierNameAccess
->getByHierarchicalName(
1736 sal_Int32 nState
= 0;
1737 if ( !( aKeyValue
>>= nState
) )
1738 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1739 "Error getting property state!" );
1741 rValue
.State
= PropertyState( nState
);
1743 catch (const NoSuchElementException
&)
1745 // getByHierarchicalName
1747 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1748 "NoSuchElementException!" );
1757 catch (const NoSuchElementException
&)
1759 // getByHierarchicalName
1763 return Sequence
< PropertyValue
>( 0 );
1768 void SAL_CALL
PersistentPropertySet::setPropertyValues(
1769 const Sequence
< PropertyValue
>& aProps
)
1771 if ( !aProps
.hasElements() )
1774 std::unique_lock
aCGuard(m_aMutex
);
1776 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
1777 m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1778 if ( xRootHierNameAccess
.is() )
1780 std::vector
< PropertyChangeEvent
> aEvents
;
1782 OUString
aFullPropNamePrefix( getFullKeyImpl(aCGuard
) + "/" );
1784 // Iterate over given property value sequence.
1785 for ( const PropertyValue
& rNewValue
: aProps
)
1787 const OUString
& rName
= rNewValue
.Name
;
1789 OUString aFullPropName
= aFullPropNamePrefix
+
1790 makeHierarchalNameSegment( rName
);
1792 // Does property exist?
1793 if ( xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
) )
1795 Reference
< XNameReplace
> xNameReplace(
1796 m_pCreator
->getConfigWriteAccess(
1797 aFullPropName
), UNO_QUERY
);
1798 Reference
< XChangesBatch
> xBatch(
1799 m_pCreator
->getConfigWriteAccess(
1800 OUString() ), UNO_QUERY
);
1802 if ( xNameReplace
.is() && xBatch
.is() )
1807 xNameReplace
->replaceByName(
1809 Any( rNewValue
.Handle
) );
1812 OUString aValueName
= aFullPropName
+"/Value";
1814 = xRootHierNameAccess
->getByHierarchicalName(
1817 xNameReplace
->replaceByName(
1821 // Write state ( Now it is a directly set value )
1822 xNameReplace
->replaceByName(
1826 PropertyState_DIRECT_VALUE
) ) );
1829 xBatch
->commitChanges();
1831 if ( m_aPropertyChangeListeners
.hasContainedTypes(aCGuard
) )
1833 PropertyChangeEvent aEvt
;
1834 aEvt
.Source
= static_cast<OWeakObject
*>(this);
1835 aEvt
.PropertyName
= rNewValue
.Name
;
1836 aEvt
.PropertyHandle
= rNewValue
.Handle
;
1837 aEvt
.Further
= false;
1838 aEvt
.OldValue
= aOldValue
;
1839 aEvt
.NewValue
= rNewValue
.Value
;
1841 aEvents
.push_back( aEvt
);
1844 catch (const IllegalArgumentException
&)
1848 catch (const NoSuchElementException
&)
1850 // getByHierarchicalName, replaceByName
1852 catch (const WrappedTargetException
&)
1854 // replaceByName, commitChanges
1860 if ( m_aPropertyChangeListeners
.hasContainedTypes(aCGuard
) )
1862 // Notify property changes.
1863 for (auto const& event
: aEvents
)
1865 notifyPropertyChangeEvent( aCGuard
, event
);
1872 OSL_FAIL( "PersistentPropertySet::setPropertyValues - Nothing set!" );
1876 // Non-interface methods
1879 void PersistentPropertySet::notifyPropertyChangeEvent(
1880 std::unique_lock
<std::mutex
>& rGuard
,
1881 const PropertyChangeEvent
& rEvent
) const
1883 // Get "normal" listeners for the property.
1884 OInterfaceContainerHelper4
<XPropertyChangeListener
>* pContainer
=
1885 m_aPropertyChangeListeners
.getContainer( rGuard
, rEvent
.PropertyName
);
1886 if ( pContainer
&& pContainer
->getLength(rGuard
) )
1888 pContainer
->notifyEach( rGuard
, &XPropertyChangeListener::propertyChange
, rEvent
);
1891 // Get "normal" listeners for all properties.
1892 OInterfaceContainerHelper4
<XPropertyChangeListener
>* pNoNameContainer
=
1893 m_aPropertyChangeListeners
.getContainer( rGuard
, OUString() );
1894 if ( pNoNameContainer
&& pNoNameContainer
->getLength(rGuard
) )
1896 pNoNameContainer
->notifyEach( rGuard
, &XPropertyChangeListener::propertyChange
, rEvent
);
1901 void PersistentPropertySet::notifyPropertySetInfoChange(
1902 std::unique_lock
<std::mutex
>& rGuard
,
1903 const PropertySetInfoChangeEvent
& evt
) const
1905 // Notify event listeners.
1906 m_aPropSetChangeListeners
.notifyEach( rGuard
, &XPropertySetInfoChangeListener::propertySetInfoChange
, evt
);
1910 OUString
PersistentPropertySet::getFullKey()
1912 std::unique_lock
aGuard(m_aMutex
);
1913 return getFullKeyImpl(aGuard
);
1916 const OUString
& PersistentPropertySet::getFullKeyImpl(std::unique_lock
<std::mutex
>& )
1918 if ( m_aFullKey
.isEmpty() )
1920 m_aFullKey
= makeHierarchalNameSegment( m_aKey
);
1921 m_aFullKey
+= "/Values";
1928 PropertySetRegistry
& PersistentPropertySet::getPropertySetRegistry()
1934 // PropertySetInfo_Impl Implementation.
1937 PropertySetInfo_Impl::PropertySetInfo_Impl(
1938 PersistentPropertySet
* pOwner
)
1939 : m_pOwner( pOwner
)
1944 // XPropertySetInfo methods.
1948 Sequence
< Property
> SAL_CALL
PropertySetInfo_Impl::getProperties()
1952 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
1953 m_pOwner
->getPropertySetRegistry().getRootConfigReadAccess(),
1955 if ( xRootHierNameAccess
.is() )
1959 Reference
< XNameAccess
> xNameAccess
;
1960 xRootHierNameAccess
->getByHierarchicalName(
1961 m_pOwner
->getFullKey() )
1963 if ( xNameAccess
.is() )
1965 // Obtain property names.
1967 Sequence
< OUString
> aElems
1968 = xNameAccess
->getElementNames();
1970 sal_uInt32 nCount
= aElems
.getLength();
1971 Sequence
< Property
> aPropSeq( nCount
);
1975 Reference
< XHierarchicalNameAccess
> xHierNameAccess(
1976 xNameAccess
, UNO_QUERY
);
1978 OSL_ENSURE( xHierNameAccess
.is(),
1979 "PropertySetInfo_Impl::getProperties - "
1980 "No hierarchical name access!" );
1982 if ( xHierNameAccess
.is() )
1984 static const OUStringLiteral
aHandleName(u
"/Handle");
1985 static const OUStringLiteral
aValueName(u
"/Value");
1986 static const OUStringLiteral
aAttrName(u
"/Attributes");
1988 Property
* pProps
= aPropSeq
.getArray();
1990 for ( sal_uInt32 n
= 0; n
< nCount
; ++n
)
1992 Property
& rProp
= pProps
[ n
];
1993 OUString rName
= aElems
[ n
];
1995 = makeHierarchalNameSegment( rName
);
1997 // Set property name.
2003 // Obtain and set property handle
2004 OUString aHierName
= aXMLName
+ aHandleName
;
2006 = xHierNameAccess
->getByHierarchicalName(
2009 if ( !( aKeyValue
>>= rProp
.Handle
) )
2010 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2011 "Error getting property handle!" );
2013 catch (const NoSuchElementException
&)
2015 // getByHierarchicalName
2017 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2018 "NoSuchElementException!" );
2023 // Obtain and set property type
2024 OUString aHierName
= aXMLName
+ aValueName
;
2026 = xHierNameAccess
->getByHierarchicalName(
2029 // Note: The type may be void if addProperty
2030 // was called with a default value
2033 rProp
.Type
= aKeyValue
.getValueType();
2035 catch (const NoSuchElementException
&)
2037 // getByHierarchicalName
2039 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2040 "NoSuchElementException!" );
2045 // Obtain and set property attributes
2046 OUString aHierName
= aXMLName
+ aAttrName
;
2048 = xHierNameAccess
->getByHierarchicalName(
2051 sal_Int32 nAttribs
= 0;
2052 if ( aKeyValue
>>= nAttribs
)
2054 = sal_Int16( nAttribs
);
2056 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2057 "Error getting property attributes!" );
2059 catch (const NoSuchElementException
&)
2061 // getByHierarchicalName
2063 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2064 "NoSuchElementException!" );
2071 m_xProps
= std::move(aPropSeq
);
2075 catch (const NoSuchElementException
&)
2077 // getByHierarchicalName
2081 OSL_FAIL( "PropertySetInfo_Impl::getProperties - Error!" );
2090 Property SAL_CALL
PropertySetInfo_Impl::getPropertyByName(
2091 const OUString
& aName
)
2093 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
2094 m_pOwner
->getPropertySetRegistry().getRootConfigReadAccess(),
2096 if ( xRootHierNameAccess
.is() )
2098 OUString
aFullPropName( m_pOwner
->getFullKey() + "/" +
2099 makeHierarchalNameSegment( aName
) );
2101 // Does property exist?
2102 if ( !xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
) )
2103 throw UnknownPropertyException(aFullPropName
);
2110 OUString aKey
= aFullPropName
+ "/Handle";
2112 if ( !( xRootHierNameAccess
->getByHierarchicalName( aKey
)
2113 >>= aProp
.Handle
) )
2115 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2120 // Obtain Value and extract type.
2121 aKey
= aFullPropName
+ "/Value";
2123 Any aValue
= xRootHierNameAccess
->getByHierarchicalName( aKey
);
2124 if ( !aValue
.hasValue() )
2126 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2131 aProp
.Type
= aValue
.getValueType();
2133 // Obtain Attributes.
2134 aKey
= aFullPropName
+ "/Attributes";
2136 sal_Int32 nAttribs
= 0;
2137 if ( xRootHierNameAccess
->getByHierarchicalName( aKey
)
2139 aProp
.Attributes
= sal_Int16( nAttribs
);
2142 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2153 catch (const NoSuchElementException
&)
2155 // getByHierarchicalName
2157 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2158 "caught NoSuchElementException!" );
2163 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - Error!" );
2169 sal_Bool SAL_CALL
PropertySetInfo_Impl::hasPropertyByName(
2170 const OUString
& Name
)
2172 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
2173 m_pOwner
->getPropertySetRegistry().getRootConfigReadAccess(),
2175 if ( xRootHierNameAccess
.is() )
2177 OUString
aFullPropName( m_pOwner
->getFullKey() + "/" +
2178 makeHierarchalNameSegment( Name
) );
2180 return xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
);
2186 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */