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 *************************************************************************/
29 #include <unordered_map>
30 #include <sal/log.hxx>
31 #include <osl/diagnose.h>
32 #include <rtl/ustrbuf.hxx>
33 #include <rtl/ref.hxx>
34 #include <cppuhelper/interfacecontainer.hxx>
35 #include <comphelper/interfacecontainer2.hxx>
36 #include <comphelper/propertysequence.hxx>
37 #include <com/sun/star/beans/IllegalTypeException.hpp>
38 #include <com/sun/star/beans/NotRemoveableException.hpp>
39 #include <com/sun/star/beans/PropertyAttribute.hpp>
40 #include <com/sun/star/beans/PropertyExistException.hpp>
41 #include <com/sun/star/beans/PropertySetInfoChange.hpp>
42 #include <com/sun/star/configuration/theDefaultProvider.hpp>
43 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
44 #include <com/sun/star/container/XNameContainer.hpp>
45 #include <com/sun/star/container/XNameReplace.hpp>
46 #include <com/sun/star/util/XChangesBatch.hpp>
47 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
48 #include <comphelper/processfactory.hxx>
49 #include <cppuhelper/implbase.hxx>
50 #include <ucbhelper/getcomponentcontext.hxx>
51 #include "ucbstore.hxx"
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
;
64 static OUString
makeHierarchalNameSegment( const OUString
& rIn
)
66 OUStringBuffer aBuffer
;
67 aBuffer
.append( "['" );
69 sal_Int32 nCount
= rIn
.getLength();
70 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
72 const sal_Unicode c
= rIn
[ n
];
76 aBuffer
.append( "&" );
80 aBuffer
.append( """ );
84 aBuffer
.append( "'" );
88 aBuffer
.append( "<" );
92 aBuffer
.append( ">" );
101 aBuffer
.append( "']" );
102 return aBuffer
.makeStringAndClear();
105 #define STORE_CONTENTPROPERTIES_KEY "/org.openoffice.ucb.Store/ContentProperties"
107 // describe path of cfg entry
108 #define CFGPROPERTY_NODEPATH "nodepath"
110 // PropertySetMap_Impl.
111 typedef std::unordered_map
< OUString
, PersistentPropertySet
*> PropertySetMap_Impl
;
113 // class PropertySetInfo_Impl
114 class PropertySetInfo_Impl
: public cppu::WeakImplHelper
< XPropertySetInfo
>
116 std::unique_ptr
<Sequence
< Property
>>
118 PersistentPropertySet
* m_pOwner
;
121 explicit PropertySetInfo_Impl(PersistentPropertySet
* pOwner
);
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
;
128 // Non-interface methods.
129 void reset() { m_pProps
.reset(); }
139 Sequence
< Any
> m_aInitArgs
;
140 Reference
< XPropertySetRegistry
> m_xTheRegistry
;
144 // UcbStore Implementation.
147 UcbStore::UcbStore( const Reference
< XComponentContext
>& xContext
)
148 : m_xContext( xContext
),
149 m_pImpl( new UcbStore_Impl
)
155 UcbStore::~UcbStore()
159 XSERVICEINFO_COMMOM_IMPL( UcbStore
,
160 OUString( "com.sun.star.comp.ucb.UcbStore" ) )
161 /// @throws css::uno::Exception
162 static css::uno::Reference
< css::uno::XInterface
>
163 UcbStore_CreateInstance( const css::uno::Reference
< css::lang::XMultiServiceFactory
> & rSMgr
)
165 css::lang::XServiceInfo
* pX
=
166 static_cast<css::lang::XServiceInfo
*>(new UcbStore( ucbhelper::getComponentContext(rSMgr
) ));
167 return css::uno::Reference
< css::uno::XInterface
>::query( pX
);
170 css::uno::Sequence
< OUString
>
171 UcbStore::getSupportedServiceNames_Static()
173 css::uno::Sequence
< OUString
> aSNS
{ STORE_SERVICE_NAME
};
177 // Service factory implementation.
180 ONE_INSTANCE_SERVICE_FACTORY_IMPL( UcbStore
);
183 // XPropertySetRegistryFactory methods.
187 Reference
< XPropertySetRegistry
> SAL_CALL
188 UcbStore::createPropertySetRegistry( const OUString
& )
190 // The URL parameter is ignored by this interface implementation. It always
191 // uses the configuration server as storage medium.
193 if ( !m_pImpl
->m_xTheRegistry
.is() )
195 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
196 if ( !m_pImpl
->m_xTheRegistry
.is() )
197 m_pImpl
->m_xTheRegistry
= new PropertySetRegistry( m_xContext
, m_pImpl
->m_aInitArgs
);
200 return m_pImpl
->m_xTheRegistry
;
204 // XInitialization methods.
208 void SAL_CALL
UcbStore::initialize( const Sequence
< Any
>& aArguments
)
210 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
211 m_pImpl
->m_aInitArgs
= aArguments
;
216 // PropertySetRegistry_Impl.
219 struct PropertySetRegistry_Impl
221 const Sequence
< Any
> m_aInitArgs
;
222 PropertySetMap_Impl m_aPropSets
;
223 Reference
< XMultiServiceFactory
> m_xConfigProvider
;
224 Reference
< XInterface
> m_xRootReadAccess
;
225 Reference
< XInterface
> m_xRootWriteAccess
;
227 bool m_bTriedToGetRootReadAccess
;
228 bool m_bTriedToGetRootWriteAccess
;
230 explicit PropertySetRegistry_Impl(const Sequence
<Any
> &rInitArgs
)
231 : m_aInitArgs(rInitArgs
)
232 , m_bTriedToGetRootReadAccess(false)
233 , m_bTriedToGetRootWriteAccess(false)
238 // PropertySetRegistry Implementation.
241 PropertySetRegistry::PropertySetRegistry(
242 const Reference
< XComponentContext
>& xContext
,
243 const Sequence
< Any
> &rInitArgs
)
244 : m_xContext( xContext
),
245 m_pImpl( new PropertySetRegistry_Impl( rInitArgs
) )
251 PropertySetRegistry::~PropertySetRegistry()
256 // XServiceInfo methods.
259 OUString SAL_CALL
PropertySetRegistry::getImplementationName()
261 return OUString( "com.sun.star.comp.ucb.PropertySetRegistry" );
264 sal_Bool SAL_CALL
PropertySetRegistry::supportsService( const OUString
& ServiceName
)
266 return cppu::supportsService( this, ServiceName
);
269 css::uno::Sequence
< OUString
> SAL_CALL
PropertySetRegistry::getSupportedServiceNames()
271 return { PROPSET_REG_SERVICE_NAME
};
275 // XPropertySetRegistry methods.
279 Reference
< XPersistentPropertySet
> SAL_CALL
280 PropertySetRegistry::openPropertySet( const OUString
& key
, sal_Bool create
)
282 if ( !key
.isEmpty() )
284 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
286 PropertySetMap_Impl
& rSets
= m_pImpl
->m_aPropSets
;
288 PropertySetMap_Impl::const_iterator it
= rSets
.find( key
);
289 if ( it
!= rSets
.end() )
291 // Already instantiated.
292 return Reference
< XPersistentPropertySet
>( (*it
).second
);
296 // Create new instance.
297 Reference
< XNameAccess
> xRootNameAccess(
298 getRootConfigReadAccess(), UNO_QUERY
);
299 if ( xRootNameAccess
.is() )
301 // Propertyset in registry?
302 if ( xRootNameAccess
->hasByName( key
) )
305 return Reference
< XPersistentPropertySet
>(
306 new PersistentPropertySet(
311 // No. Create entry for propertyset.
313 Reference
< XSingleServiceFactory
> xFac(
314 getConfigWriteAccess( OUString() ), UNO_QUERY
);
315 Reference
< XChangesBatch
> xBatch( xFac
, UNO_QUERY
);
316 Reference
< XNameContainer
> xContainer( xFac
, UNO_QUERY
);
318 OSL_ENSURE( xFac
.is(),
319 "PropertySetRegistry::openPropertySet - "
322 OSL_ENSURE( xBatch
.is(),
323 "PropertySetRegistry::openPropertySet - "
326 OSL_ENSURE( xContainer
.is(),
327 "PropertySetRegistry::openPropertySet - "
330 if ( xFac
.is() && xBatch
.is() && xContainer
.is() )
334 // Create new "Properties" config item.
335 Reference
< XNameReplace
> xNameReplace(
336 xFac
->createInstance(), UNO_QUERY
);
338 if ( xNameReplace
.is() )
343 xContainer
->insertByName(
344 key
, makeAny( xNameReplace
) );
346 xBatch
->commitChanges();
348 return Reference
< XPersistentPropertySet
>(
349 new PersistentPropertySet(
353 catch (const IllegalArgumentException
&)
357 OSL_FAIL( "PropertySetRegistry::openPropertySet - "
358 "caught IllegalArgumentException!" );
360 catch (const ElementExistException
&)
364 OSL_FAIL( "PropertySetRegistry::openPropertySet - "
365 "caught ElementExistException!" );
367 catch (const WrappedTargetException
&)
369 // insertByName, commitChanges
371 OSL_FAIL( "PropertySetRegistry::openPropertySet - "
372 "caught WrappedTargetException!" );
374 catch (const RuntimeException
&)
376 OSL_FAIL( "PropertySetRegistry::openPropertySet - "
377 "caught RuntimeException!" );
379 catch (const Exception
&)
383 OSL_FAIL( "PropertySetRegistry::openPropertySet - "
384 "caught Exception!" );
390 // No entry. Fail, but no error.
391 return Reference
< XPersistentPropertySet
>();
395 SAL_WARN( "ucb", "no root access" );
399 return Reference
< XPersistentPropertySet
>();
404 void SAL_CALL
PropertySetRegistry::removePropertySet( const OUString
& key
)
409 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
411 Reference
< XNameAccess
> xRootNameAccess(
412 getRootConfigReadAccess(), UNO_QUERY
);
413 if ( xRootNameAccess
.is() )
415 // Propertyset in registry?
416 if ( !xRootNameAccess
->hasByName( key
) )
418 Reference
< XChangesBatch
> xBatch(
419 getConfigWriteAccess( OUString() ), UNO_QUERY
);
420 Reference
< XNameContainer
> xContainer( xBatch
, UNO_QUERY
);
422 if ( xBatch
.is() && xContainer
.is() )
427 xContainer
->removeByName( key
);
429 xBatch
->commitChanges();
434 catch (const NoSuchElementException
&)
438 OSL_FAIL( "PropertySetRegistry::removePropertySet - "
439 "caught NoSuchElementException!" );
442 catch (const WrappedTargetException
&)
446 OSL_FAIL( "PropertySetRegistry::removePropertySet - "
447 "caught WrappedTargetException!" );
455 SAL_WARN( "ucb", "no root access" );
459 // XElementAccess methods.
463 css::uno::Type SAL_CALL
PropertySetRegistry::getElementType()
465 return cppu::UnoType
<XPersistentPropertySet
>::get();
470 sal_Bool SAL_CALL
PropertySetRegistry::hasElements()
472 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
474 Reference
< XElementAccess
> xElemAccess(
475 getRootConfigReadAccess(), UNO_QUERY
);
476 if ( xElemAccess
.is() )
477 return xElemAccess
->hasElements();
483 // XNameAccess methods.
487 Any SAL_CALL
PropertySetRegistry::getByName( const OUString
& aName
)
489 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
491 Reference
< XNameAccess
> xNameAccess(
492 getRootConfigReadAccess(), UNO_QUERY
);
493 if ( xNameAccess
.is() )
498 return xNameAccess
->getByName( aName
);
500 catch (const NoSuchElementException
&)
504 catch (const WrappedTargetException
&)
515 Sequence
< OUString
> SAL_CALL
PropertySetRegistry::getElementNames()
517 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
519 Reference
< XNameAccess
> xNameAccess(
520 getRootConfigReadAccess(), UNO_QUERY
);
521 if ( xNameAccess
.is() )
523 return xNameAccess
->getElementNames();
525 return Sequence
< OUString
>( 0 );
530 sal_Bool SAL_CALL
PropertySetRegistry::hasByName( const OUString
& aName
)
532 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
534 Reference
< XNameAccess
> xNameAccess(
535 getRootConfigReadAccess(), UNO_QUERY
);
536 if ( xNameAccess
.is() )
538 return xNameAccess
->hasByName( aName
);
545 void PropertySetRegistry::add( PersistentPropertySet
* pSet
)
547 OUString
key( pSet
->getKey() );
549 if ( !key
.isEmpty() )
551 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
552 m_pImpl
->m_aPropSets
[ key
] = pSet
;
557 void PropertySetRegistry::remove( PersistentPropertySet
* pSet
)
559 OUString
key( pSet
->getKey() );
561 if ( !key
.isEmpty() )
563 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
565 PropertySetMap_Impl
& rSets
= m_pImpl
->m_aPropSets
;
567 PropertySetMap_Impl::iterator it
= rSets
.find( key
);
568 if ( it
!= rSets
.end() )
577 void PropertySetRegistry::renamePropertySet( const OUString
& rOldKey
,
578 const OUString
& rNewKey
)
580 if ( rOldKey
== rNewKey
)
583 Reference
< XNameAccess
> xRootNameAccess(
584 getConfigWriteAccess( OUString() ), UNO_QUERY
);
585 if ( xRootNameAccess
.is() )
588 if ( xRootNameAccess
->hasByName( rOldKey
) )
590 // New key not present?
591 if ( xRootNameAccess
->hasByName( rNewKey
) )
593 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
597 Reference
< XSingleServiceFactory
> xFac(
598 xRootNameAccess
, UNO_QUERY
);
599 Reference
< XChangesBatch
> xBatch( xFac
, UNO_QUERY
);
600 Reference
< XNameContainer
> xContainer( xFac
, UNO_QUERY
);
602 OSL_ENSURE( xFac
.is(),
603 "PropertySetRegistry::renamePropertySet - "
606 OSL_ENSURE( xBatch
.is(),
607 "PropertySetRegistry::renamePropertySet - "
610 OSL_ENSURE( xContainer
.is(),
611 "PropertySetRegistry::renamePropertySet - "
614 if ( xFac
.is() && xBatch
.is() && xContainer
.is() )
617 // Create new "Properties" config item.
622 Reference
< XNameReplace
> xNameReplace(
623 xFac
->createInstance(), UNO_QUERY
);
625 if ( xNameReplace
.is() )
628 xContainer
->insertByName(
629 rNewKey
, makeAny( xNameReplace
) );
631 xBatch
->commitChanges();
634 catch (const IllegalArgumentException
&)
638 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
639 "caught IllegalArgumentException!" );
642 catch (const ElementExistException
&)
646 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
647 "caught ElementExistException!" );
650 catch (const WrappedTargetException
&)
652 // insertByName, commitChanges
654 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
655 "caught WrappedTargetException!" );
658 catch (const RuntimeException
&)
660 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
661 "caught RuntimeException!" );
664 catch (const Exception
&)
668 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
669 "caught Exception!" );
677 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
678 xRootNameAccess
, UNO_QUERY
);
679 if ( !xRootHierNameAccess
.is() )
681 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
682 "No hierarchical name access!" );
688 OUString aOldValuesKey
689 = makeHierarchalNameSegment( rOldKey
);
690 aOldValuesKey
+= "/Values";
692 Reference
< XNameAccess
> xOldNameAccess
;
693 xRootHierNameAccess
->getByHierarchicalName(
696 if ( !xOldNameAccess
.is() )
698 OSL_FAIL( "PersistentPropertySet::renamePropertySet - "
699 "No old name access!" );
703 // Obtain property names.
704 Sequence
< OUString
> aElems
705 = xOldNameAccess
->getElementNames();
706 sal_Int32 nCount
= aElems
.getLength();
709 OUString aNewValuesKey
710 = makeHierarchalNameSegment( rNewKey
);
711 aNewValuesKey
+= "/Values";
713 Reference
< XSingleServiceFactory
> xNewFac
;
714 xRootHierNameAccess
->getByHierarchicalName(
719 OSL_FAIL( "PersistentPropertySet::renamePropertySet - "
724 Reference
< XNameContainer
> xNewContainer(
725 xNewFac
, UNO_QUERY
);
726 if ( !xNewContainer
.is() )
728 OSL_FAIL( "PersistentPropertySet::renamePropertySet - "
729 "No new container!" );
733 aOldValuesKey
+= "/";
735 OUString
const aHandleKey("/Handle");
736 OUString
const aValueKey("/Value");
737 OUString
const aStateKey("/State");
738 OUString
const aAttrKey("/Attributes");
740 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
742 const OUString
& rPropName
= aElems
[ n
];
745 Reference
< XNameReplace
> xNewPropNameReplace(
746 xNewFac
->createInstance(), UNO_QUERY
);
748 if ( !xNewPropNameReplace
.is() )
750 OSL_FAIL( "PersistentPropertySet::renamePropertySet - "
751 "No new prop name replace!" );
758 OUString aKey
= aOldValuesKey
;
759 aKey
+= makeHierarchalNameSegment( rPropName
);
762 OUString aNewKey1
= aKey
+ aHandleKey
;
764 xRootHierNameAccess
->getByHierarchicalName(
766 xNewPropNameReplace
->replaceByName( "Handle", aAny
);
769 aNewKey1
= aKey
+ aValueKey
;
771 xRootHierNameAccess
->getByHierarchicalName(
773 xNewPropNameReplace
->replaceByName( "Value", aAny
);
776 aNewKey1
= aKey
+ aStateKey
;
778 xRootHierNameAccess
->getByHierarchicalName(
780 xNewPropNameReplace
->replaceByName( "State", aAny
);
783 aNewKey1
= aKey
+ aAttrKey
;
785 xRootHierNameAccess
->getByHierarchicalName(
787 xNewPropNameReplace
->replaceByName( "Attributes", aAny
);
790 xNewContainer
->insertByName(
791 rPropName
, makeAny( xNewPropNameReplace
) );
794 xBatch
->commitChanges();
798 catch (const IllegalArgumentException
&)
800 // insertByName, replaceByName
802 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
803 "caught IllegalArgumentException!" );
806 catch (const ElementExistException
&)
810 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
811 "caught ElementExistException!" );
814 catch (const WrappedTargetException
&)
816 // insertByName, replaceByName, commitChanges
818 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
819 "caught WrappedTargetException!" );
822 catch (const NoSuchElementException
&)
824 // getByHierarchicalName, replaceByName
826 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
827 "caught NoSuchElementException!" );
830 catch (const RuntimeException
&)
832 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
833 "caught RuntimeException!" );
836 catch (const Exception
&)
840 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
841 "caught Exception!" );
846 // Remove old entry...
852 xContainer
->removeByName( rOldKey
);
854 xBatch
->commitChanges();
859 catch (const NoSuchElementException
&)
863 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
864 "caught NoSuchElementException!" );
867 catch (const WrappedTargetException
&)
871 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
872 "caught WrappedTargetException!" );
879 OSL_FAIL( "PropertySetRegistry::renamePropertySet - Error!" );
883 Reference
< XMultiServiceFactory
> PropertySetRegistry::getConfigProvider()
885 if ( !m_pImpl
->m_xConfigProvider
.is() )
887 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
888 if ( !m_pImpl
->m_xConfigProvider
.is() )
890 const Sequence
< Any
>& rInitArgs
= m_pImpl
->m_aInitArgs
;
892 if ( rInitArgs
.getLength() > 0 )
894 // Extract config provider from service init args.
895 rInitArgs
[ 0 ] >>= m_pImpl
->m_xConfigProvider
;
897 OSL_ENSURE( m_pImpl
->m_xConfigProvider
.is(),
898 "PropertySetRegistry::getConfigProvider - "
899 "No config provider!" );
905 m_pImpl
->m_xConfigProvider
= theDefaultProvider::get( m_xContext
);
907 catch (const Exception
&)
909 SAL_WARN( "ucb", "caught exception!" );
915 return m_pImpl
->m_xConfigProvider
;
919 Reference
< XInterface
> PropertySetRegistry::getRootConfigReadAccess()
923 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
925 if ( !m_pImpl
->m_xRootReadAccess
.is() )
927 if ( m_pImpl
->m_bTriedToGetRootReadAccess
)
929 OSL_FAIL( "PropertySetRegistry::getRootConfigReadAccess - "
930 "Unable to read any config data! -> #82494#" );
931 return Reference
< XInterface
>();
936 if ( m_pImpl
->m_xConfigProvider
.is() )
938 Sequence
<Any
> aArguments(comphelper::InitAnyPropertySequence(
940 {CFGPROPERTY_NODEPATH
, Any(OUString( STORE_CONTENTPROPERTIES_KEY
))}
943 m_pImpl
->m_bTriedToGetRootReadAccess
= true;
945 m_pImpl
->m_xRootReadAccess
=
946 m_pImpl
->m_xConfigProvider
->createInstanceWithArguments(
947 "com.sun.star.configuration.ConfigurationAccess",
950 if ( m_pImpl
->m_xRootReadAccess
.is() )
951 return m_pImpl
->m_xRootReadAccess
;
955 return m_pImpl
->m_xRootReadAccess
;
957 catch (const RuntimeException
&)
961 catch (const Exception
&)
963 // createInstance, createInstanceWithArguments
965 OSL_FAIL( "PropertySetRegistry::getRootConfigReadAccess - caught Exception!" );
966 return Reference
< XInterface
>();
969 SAL_WARN( "ucb", "Error!" );
970 return Reference
< XInterface
>();
974 Reference
< XInterface
> PropertySetRegistry::getConfigWriteAccess(
975 const OUString
& rPath
)
979 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
981 if ( !m_pImpl
->m_xRootWriteAccess
.is() )
983 if ( m_pImpl
->m_bTriedToGetRootWriteAccess
)
985 OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - "
986 "Unable to write any config data! -> #82494#" );
987 return Reference
< XInterface
>();
992 if ( m_pImpl
->m_xConfigProvider
.is() )
994 Sequence
<Any
> aArguments(comphelper::InitAnyPropertySequence(
996 {CFGPROPERTY_NODEPATH
, Any(OUString( STORE_CONTENTPROPERTIES_KEY
))}
999 m_pImpl
->m_bTriedToGetRootWriteAccess
= true;
1001 m_pImpl
->m_xRootWriteAccess
=
1002 m_pImpl
->m_xConfigProvider
->createInstanceWithArguments(
1003 "com.sun.star.configuration.ConfigurationUpdateAccess",
1006 OSL_ENSURE( m_pImpl
->m_xRootWriteAccess
.is(),
1007 "PropertySetRegistry::getConfigWriteAccess - "
1008 "No config update access!" );
1012 if ( m_pImpl
->m_xRootWriteAccess
.is() )
1014 if ( !rPath
.isEmpty() )
1016 Reference
< XHierarchicalNameAccess
> xNA(
1017 m_pImpl
->m_xRootWriteAccess
, UNO_QUERY
);
1020 Reference
< XInterface
> xInterface
;
1021 xNA
->getByHierarchicalName( rPath
) >>= xInterface
;
1023 if ( xInterface
.is() )
1028 return m_pImpl
->m_xRootWriteAccess
;
1031 catch (const RuntimeException
&)
1035 catch (const NoSuchElementException
&)
1037 // getByHierarchicalName
1039 OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - "
1040 "caught NoSuchElementException!" );
1041 return Reference
< XInterface
>();
1043 catch (const Exception
&)
1045 // createInstance, createInstanceWithArguments
1047 OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - "
1048 "caught Exception!" );
1049 return Reference
< XInterface
>();
1052 OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - Error!" );
1053 return Reference
< XInterface
>();
1056 typedef OMultiTypeInterfaceContainerHelperVar
<OUString
> PropertyListeners_Impl
;
1058 struct PersistentPropertySet_Impl
1060 rtl::Reference
<PropertySetRegistry
> m_pCreator
;
1061 rtl::Reference
<PropertySetInfo_Impl
> m_pInfo
;
1062 OUString
const m_aKey
;
1063 OUString m_aFullKey
;
1064 osl::Mutex m_aMutex
;
1065 std::unique_ptr
<OInterfaceContainerHelper2
> m_pDisposeEventListeners
;
1066 std::unique_ptr
<OInterfaceContainerHelper2
> m_pPropSetChangeListeners
;
1067 std::unique_ptr
<PropertyListeners_Impl
> m_pPropertyChangeListeners
;
1069 PersistentPropertySet_Impl( PropertySetRegistry
& rCreator
,
1070 const OUString
& rKey
)
1071 : m_pCreator( &rCreator
), m_aKey( rKey
)
1077 // PersistentPropertySet Implementation.
1080 PersistentPropertySet::PersistentPropertySet(
1081 PropertySetRegistry
& rCreator
,
1082 const OUString
& rKey
)
1083 : m_pImpl( new PersistentPropertySet_Impl( rCreator
, rKey
) )
1085 // register at creator.
1086 rCreator
.add( this );
1091 PersistentPropertySet::~PersistentPropertySet()
1093 // deregister at creator.
1094 m_pImpl
->m_pCreator
->remove( this );
1097 // XServiceInfo methods.
1099 OUString SAL_CALL
PersistentPropertySet::getImplementationName()
1101 return OUString( "com.sun.star.comp.ucb.PersistentPropertySet" );
1104 sal_Bool SAL_CALL
PersistentPropertySet::supportsService( const OUString
& ServiceName
)
1106 return cppu::supportsService( this, ServiceName
);
1109 css::uno::Sequence
< OUString
> SAL_CALL
1110 PersistentPropertySet::getSupportedServiceNames()
1112 return { PERS_PROPSET_SERVICE_NAME
};
1116 // XComponent methods.
1120 void SAL_CALL
PersistentPropertySet::dispose()
1122 if ( m_pImpl
->m_pDisposeEventListeners
&&
1123 m_pImpl
->m_pDisposeEventListeners
->getLength() )
1126 aEvt
.Source
= static_cast< XComponent
* >( this );
1127 m_pImpl
->m_pDisposeEventListeners
->disposeAndClear( aEvt
);
1130 if ( m_pImpl
->m_pPropSetChangeListeners
&&
1131 m_pImpl
->m_pPropSetChangeListeners
->getLength() )
1134 aEvt
.Source
= static_cast< XPropertySetInfoChangeNotifier
* >( this );
1135 m_pImpl
->m_pPropSetChangeListeners
->disposeAndClear( aEvt
);
1138 if ( m_pImpl
->m_pPropertyChangeListeners
)
1141 aEvt
.Source
= static_cast< XPropertySet
* >( this );
1142 m_pImpl
->m_pPropertyChangeListeners
->disposeAndClear( aEvt
);
1148 void SAL_CALL
PersistentPropertySet::addEventListener(
1149 const Reference
< XEventListener
>& Listener
)
1151 if ( !m_pImpl
->m_pDisposeEventListeners
)
1152 m_pImpl
->m_pDisposeEventListeners
.reset(
1153 new OInterfaceContainerHelper2( m_pImpl
->m_aMutex
) );
1155 m_pImpl
->m_pDisposeEventListeners
->addInterface( Listener
);
1160 void SAL_CALL
PersistentPropertySet::removeEventListener(
1161 const Reference
< XEventListener
>& Listener
)
1163 if ( m_pImpl
->m_pDisposeEventListeners
)
1164 m_pImpl
->m_pDisposeEventListeners
->removeInterface( Listener
);
1166 // Note: Don't want to delete empty container here -> performance.
1170 // XPropertySet methods.
1174 Reference
< XPropertySetInfo
> SAL_CALL
PersistentPropertySet::getPropertySetInfo()
1176 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
1178 if ( !m_pImpl
->m_pInfo
.is() )
1180 m_pImpl
->m_pInfo
= new PropertySetInfo_Impl( this );
1182 return Reference
< XPropertySetInfo
>( m_pImpl
->m_pInfo
.get() );
1187 void SAL_CALL
PersistentPropertySet::setPropertyValue( const OUString
& aPropertyName
,
1190 if ( aPropertyName
.isEmpty() )
1191 throw UnknownPropertyException();
1193 osl::ClearableGuard
< osl::Mutex
> aCGuard( m_pImpl
->m_aMutex
);
1195 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
1196 m_pImpl
->m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1197 if ( xRootHierNameAccess
.is() )
1199 OUString
aFullPropName( getFullKey() );
1200 aFullPropName
+= "/";
1201 aFullPropName
+= makeHierarchalNameSegment( aPropertyName
);
1203 // Does property exist?
1204 if ( xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
) )
1206 Reference
< XNameReplace
> xNameReplace(
1207 m_pImpl
->m_pCreator
->getConfigWriteAccess(
1208 aFullPropName
), UNO_QUERY
);
1209 Reference
< XChangesBatch
> xBatch(
1210 m_pImpl
->m_pCreator
->getConfigWriteAccess(
1211 OUString() ), UNO_QUERY
);
1213 if ( xNameReplace
.is() && xBatch
.is() )
1218 OUString aValueName
= aFullPropName
;
1219 aValueName
+= "/Value";
1221 = xRootHierNameAccess
->getByHierarchicalName(
1223 // Check value type.
1224 if ( aOldValue
.getValueType() != aValue
.getValueType() )
1227 throw IllegalArgumentException();
1231 xNameReplace
->replaceByName( "Value", aValue
);
1233 // Write state ( Now it is a directly set value )
1234 xNameReplace
->replaceByName(
1238 PropertyState_DIRECT_VALUE
) ) );
1241 xBatch
->commitChanges();
1243 PropertyChangeEvent aEvt
;
1244 if ( m_pImpl
->m_pPropertyChangeListeners
)
1247 aValueName
= aFullPropName
;
1248 aValueName
+= "/Handle";
1249 sal_Int32 nHandle
= -1;
1250 xRootHierNameAccess
->getByHierarchicalName( aValueName
)
1253 aEvt
.Source
= static_cast<OWeakObject
*>(this);
1254 aEvt
.PropertyName
= aPropertyName
;
1255 aEvt
.PropertyHandle
= nHandle
;
1256 aEvt
.Further
= false;
1257 aEvt
.OldValue
= aOldValue
;
1258 aEvt
.NewValue
= aValue
;
1260 // Callback follows!
1263 notifyPropertyChangeEvent( aEvt
);
1267 catch (const IllegalArgumentException
&)
1271 catch (const NoSuchElementException
&)
1273 // getByHierarchicalName, replaceByName
1275 catch (const WrappedTargetException
&)
1277 // replaceByName, commitChanges
1283 throw UnknownPropertyException();
1288 Any SAL_CALL
PersistentPropertySet::getPropertyValue(
1289 const OUString
& PropertyName
)
1291 if ( PropertyName
.isEmpty() )
1292 throw UnknownPropertyException();
1294 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
1296 Reference
< XHierarchicalNameAccess
> xNameAccess(
1297 m_pImpl
->m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1298 if ( xNameAccess
.is() )
1300 OUString
aFullPropName( getFullKey() );
1301 aFullPropName
+= "/";
1302 aFullPropName
+= makeHierarchalNameSegment( PropertyName
);
1303 aFullPropName
+= "/Value";
1306 return xNameAccess
->getByHierarchicalName( aFullPropName
);
1308 catch (const NoSuchElementException
&)
1310 throw UnknownPropertyException();
1314 throw UnknownPropertyException();
1319 void SAL_CALL
PersistentPropertySet::addPropertyChangeListener(
1320 const OUString
& aPropertyName
,
1321 const Reference
< XPropertyChangeListener
>& xListener
)
1325 if ( !m_pImpl
->m_pPropertyChangeListeners
)
1326 m_pImpl
->m_pPropertyChangeListeners
.reset(
1327 new PropertyListeners_Impl( m_pImpl
->m_aMutex
) );
1329 m_pImpl
->m_pPropertyChangeListeners
->addInterface(
1330 aPropertyName
, xListener
);
1335 void SAL_CALL
PersistentPropertySet::removePropertyChangeListener(
1336 const OUString
& aPropertyName
,
1337 const Reference
< XPropertyChangeListener
>& aListener
)
1341 if ( m_pImpl
->m_pPropertyChangeListeners
)
1342 m_pImpl
->m_pPropertyChangeListeners
->removeInterface(
1343 aPropertyName
, aListener
);
1345 // Note: Don't want to delete empty container here -> performance.
1350 void SAL_CALL
PersistentPropertySet::addVetoableChangeListener(
1352 const Reference
< XVetoableChangeListener
>& )
1355 // OSL_FAIL( // "PersistentPropertySet::addVetoableChangeListener - N.Y.I." );
1360 void SAL_CALL
PersistentPropertySet::removeVetoableChangeListener(
1362 const Reference
< XVetoableChangeListener
>& )
1365 // OSL_FAIL( // "PersistentPropertySet::removeVetoableChangeListener - N.Y.I." );
1369 // XPersistentPropertySet methods.
1373 Reference
< XPropertySetRegistry
> SAL_CALL
PersistentPropertySet::getRegistry()
1375 return Reference
< XPropertySetRegistry
>( m_pImpl
->m_pCreator
.get() );
1380 OUString SAL_CALL
PersistentPropertySet::getKey()
1382 return m_pImpl
->m_aKey
;
1390 OUString SAL_CALL
PersistentPropertySet::getName()
1393 return m_pImpl
->m_aKey
;
1398 void SAL_CALL
PersistentPropertySet::setName( const OUString
& aName
)
1400 if ( aName
!= m_pImpl
->m_aKey
)
1401 m_pImpl
->m_pCreator
->renamePropertySet( m_pImpl
->m_aKey
, aName
);
1405 // XPropertyContainer methods.
1409 void SAL_CALL
PersistentPropertySet::addProperty(
1410 const OUString
& Name
, sal_Int16 Attributes
, const Any
& DefaultValue
)
1412 if ( Name
.isEmpty() )
1413 throw IllegalArgumentException();
1415 // @@@ What other types can't be written to config server?
1417 // Check type class ( Not all types can be written to storage )
1418 TypeClass eTypeClass
= DefaultValue
.getValueTypeClass();
1419 if ( eTypeClass
== TypeClass_INTERFACE
)
1420 throw IllegalTypeException();
1422 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
1424 // Property already in set?
1426 OUString aFullValuesName
;
1428 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
1429 m_pImpl
->m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1430 if ( xRootHierNameAccess
.is() )
1432 aFullValuesName
= getFullKey();
1433 OUString aFullPropName
= aFullValuesName
;
1434 aFullPropName
+= "/";
1435 aFullPropName
+= makeHierarchalNameSegment( Name
);
1437 if ( xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
) )
1440 throw PropertyExistException();
1444 // Property is always removable.
1445 Attributes
|= PropertyAttribute::REMOVABLE
;
1449 Reference
< XSingleServiceFactory
> xFac(
1450 m_pImpl
->m_pCreator
->getConfigWriteAccess( aFullValuesName
),
1452 Reference
< XNameContainer
> xContainer( xFac
, UNO_QUERY
);
1453 Reference
< XChangesBatch
> xBatch(
1454 m_pImpl
->m_pCreator
->getConfigWriteAccess( OUString() ),
1457 OSL_ENSURE( xFac
.is(),
1458 "PersistentPropertySet::addProperty - No factory!" );
1460 OSL_ENSURE( xBatch
.is(),
1461 "PersistentPropertySet::addProperty - No batch!" );
1463 OSL_ENSURE( xContainer
.is(),
1464 "PersistentPropertySet::addProperty - No container!" );
1466 if ( xFac
.is() && xBatch
.is() && xContainer
.is() )
1470 // Create new "PropertyValue" config item.
1471 Reference
< XNameReplace
> xNameReplace(
1472 xFac
->createInstance(), UNO_QUERY
);
1474 if ( xNameReplace
.is() )
1479 xNameReplace
->replaceByName(
1481 makeAny( sal_Int32( -1 ) ) );
1483 // Set default value
1484 xNameReplace
->replaceByName(
1488 // Set state ( always "default" )
1489 xNameReplace
->replaceByName(
1493 PropertyState_DEFAULT_VALUE
) ) );
1496 xNameReplace
->replaceByName(
1498 makeAny( sal_Int32( Attributes
) ) );
1501 xContainer
->insertByName( Name
, makeAny( xNameReplace
) );
1504 xBatch
->commitChanges();
1506 // Property set info is invalid.
1507 if ( m_pImpl
->m_pInfo
.is() )
1508 m_pImpl
->m_pInfo
->reset();
1510 // Notify propertyset info change listeners.
1511 if ( m_pImpl
->m_pPropSetChangeListeners
&&
1512 m_pImpl
->m_pPropSetChangeListeners
->getLength() )
1514 PropertySetInfoChangeEvent
evt(
1515 static_cast< OWeakObject
* >( this ),
1518 PropertySetInfoChange::PROPERTY_INSERTED
);
1519 notifyPropertySetInfoChange( evt
);
1526 catch (const IllegalArgumentException
&)
1530 OSL_FAIL( "PersistentPropertySet::addProperty - "
1531 "caught IllegalArgumentException!" );
1534 catch (const ElementExistException
&)
1538 OSL_FAIL( "PersistentPropertySet::addProperty - "
1539 "caught ElementExistException!" );
1542 catch (const WrappedTargetException
&)
1544 // replaceByName, insertByName, commitChanges
1546 OSL_FAIL( "PersistentPropertySet::addProperty - "
1547 "caught WrappedTargetException!" );
1550 catch (const RuntimeException
&)
1554 catch (const Exception
&)
1558 OSL_FAIL( "PersistentPropertySet::addProperty - "
1559 "caught Exception!" );
1564 OSL_FAIL( "PersistentPropertySet::addProperty - Error!" );
1569 void SAL_CALL
PersistentPropertySet::removeProperty( const OUString
& Name
)
1571 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
1573 OUString aFullValuesName
;
1574 OUString aFullPropName
;
1576 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
1577 m_pImpl
->m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1578 if ( xRootHierNameAccess
.is() )
1580 aFullValuesName
= getFullKey();
1581 aFullPropName
= aFullValuesName
;
1582 aFullPropName
+= "/";
1583 aFullPropName
+= makeHierarchalNameSegment( Name
);
1586 if ( !xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
) )
1587 throw UnknownPropertyException();
1589 // Property removable?
1592 OUString aFullAttrName
= aFullPropName
;
1593 aFullAttrName
+= "/Attributes";
1595 sal_Int32 nAttribs
= 0;
1596 if ( xRootHierNameAccess
->getByHierarchicalName( aFullAttrName
)
1599 if ( !( nAttribs
& PropertyAttribute::REMOVABLE
) )
1602 throw NotRemoveableException();
1607 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1612 catch (const NoSuchElementException
&)
1614 // getByHierarchicalName
1616 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1617 "caught NoSuchElementException!" );
1620 // Remove property...
1622 Reference
< XNameContainer
> xContainer(
1623 m_pImpl
->m_pCreator
->getConfigWriteAccess( aFullValuesName
),
1625 Reference
< XChangesBatch
> xBatch(
1626 m_pImpl
->m_pCreator
->getConfigWriteAccess( OUString() ),
1629 OSL_ENSURE( xBatch
.is(),
1630 "PersistentPropertySet::removeProperty - No batch!" );
1632 OSL_ENSURE( xContainer
.is(),
1633 "PersistentPropertySet::removeProperty - No container!" );
1635 if ( xBatch
.is() && xContainer
.is() )
1639 sal_Int32 nHandle
= -1;
1641 if ( m_pImpl
->m_pPropSetChangeListeners
&&
1642 m_pImpl
->m_pPropSetChangeListeners
->getLength() )
1644 // Obtain property handle ( needed for propertysetinfo
1645 // change event )...
1649 OUString aFullHandleName
= aFullPropName
;
1653 if ( ! ( xRootHierNameAccess
->getByHierarchicalName(
1654 aFullHandleName
) >>= nHandle
) )
1658 catch (const NoSuchElementException
&)
1660 // getByHierarchicalName
1662 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1663 "caught NoSuchElementException!" );
1668 xContainer
->removeByName( Name
);
1669 xBatch
->commitChanges();
1671 // Property set info is invalid.
1672 if ( m_pImpl
->m_pInfo
.is() )
1673 m_pImpl
->m_pInfo
->reset();
1675 // Notify propertyset info change listeners.
1676 if ( m_pImpl
->m_pPropSetChangeListeners
&&
1677 m_pImpl
->m_pPropSetChangeListeners
->getLength() )
1679 PropertySetInfoChangeEvent
evt(
1680 static_cast< OWeakObject
* >( this ),
1683 PropertySetInfoChange::PROPERTY_REMOVED
);
1684 notifyPropertySetInfoChange( evt
);
1690 catch (const NoSuchElementException
&)
1694 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1695 "caught NoSuchElementException!" );
1698 catch (const WrappedTargetException
&)
1702 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1703 "caught WrappedTargetException!" );
1709 OSL_FAIL( "PersistentPropertySet::removeProperty - Error!" );
1713 // XPropertySetInfoChangeNotifier methods.
1717 void SAL_CALL
PersistentPropertySet::addPropertySetInfoChangeListener(
1718 const Reference
< XPropertySetInfoChangeListener
>& Listener
)
1720 if ( !m_pImpl
->m_pPropSetChangeListeners
)
1721 m_pImpl
->m_pPropSetChangeListeners
.reset(
1722 new OInterfaceContainerHelper2( m_pImpl
->m_aMutex
) );
1724 m_pImpl
->m_pPropSetChangeListeners
->addInterface( Listener
);
1729 void SAL_CALL
PersistentPropertySet::removePropertySetInfoChangeListener(
1730 const Reference
< XPropertySetInfoChangeListener
>& Listener
)
1732 if ( m_pImpl
->m_pPropSetChangeListeners
)
1733 m_pImpl
->m_pPropSetChangeListeners
->removeInterface( Listener
);
1737 // XPropertyAccess methods.
1741 Sequence
< PropertyValue
> SAL_CALL
PersistentPropertySet::getPropertyValues()
1743 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
1745 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
1746 m_pImpl
->m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1747 if ( xRootHierNameAccess
.is() )
1751 Reference
< XNameAccess
> xNameAccess
;
1752 xRootHierNameAccess
->getByHierarchicalName(getFullKey())
1754 if ( xNameAccess
.is() )
1756 // Obtain property names.
1758 Sequence
< OUString
> aElems
= xNameAccess
->getElementNames();
1760 sal_Int32 nCount
= aElems
.getLength();
1763 Reference
< XHierarchicalNameAccess
> xHierNameAccess(
1764 xNameAccess
, UNO_QUERY
);
1766 OSL_ENSURE( xHierNameAccess
.is(),
1767 "PersistentPropertySet::getPropertyValues - "
1768 "No hierarchical name access!" );
1770 if ( xHierNameAccess
.is() )
1772 Sequence
< PropertyValue
> aValues( nCount
);
1774 const OUString
aHandleName("/Handle");
1775 const OUString
aValueName("/Value");
1776 const OUString
aStateName("/State");
1778 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
1780 PropertyValue
& rValue
= aValues
[ n
];
1781 OUString rName
= aElems
[ n
];
1783 = makeHierarchalNameSegment( rName
);
1785 // Set property name.
1787 rValue
.Name
= rName
;
1791 // Obtain and set property handle
1792 OUString aHierName
= aXMLName
;
1793 aHierName
+= aHandleName
;
1795 = xHierNameAccess
->getByHierarchicalName(
1798 if ( !( aKeyValue
>>= rValue
.Handle
) )
1799 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1800 "Error getting property handle!" );
1802 catch (const NoSuchElementException
&)
1804 // getByHierarchicalName
1806 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1807 "NoSuchElementException!" );
1812 // Obtain and set property value
1813 OUString aHierName
= aXMLName
;
1814 aHierName
+= aValueName
;
1816 = xHierNameAccess
->getByHierarchicalName(
1819 // Note: The value may be void if addProperty
1820 // was called with a default value
1823 catch (const NoSuchElementException
&)
1825 // getByHierarchicalName
1827 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1828 "NoSuchElementException!" );
1833 // Obtain and set property state
1834 OUString aHierName
= aXMLName
;
1835 aHierName
+= aStateName
;
1837 = xHierNameAccess
->getByHierarchicalName(
1840 sal_Int32 nState
= 0;
1841 if ( !( aKeyValue
>>= nState
) )
1842 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1843 "Error getting property state!" );
1845 rValue
.State
= PropertyState( nState
);
1847 catch (const NoSuchElementException
&)
1849 // getByHierarchicalName
1851 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1852 "NoSuchElementException!" );
1861 catch (const NoSuchElementException
&)
1863 // getByHierarchicalName
1867 return Sequence
< PropertyValue
>( 0 );
1872 void SAL_CALL
PersistentPropertySet::setPropertyValues(
1873 const Sequence
< PropertyValue
>& aProps
)
1875 sal_Int32 nCount
= aProps
.getLength();
1879 osl::ClearableGuard
< osl::Mutex
> aCGuard( m_pImpl
->m_aMutex
);
1881 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
1882 m_pImpl
->m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1883 if ( xRootHierNameAccess
.is() )
1885 const PropertyValue
* pNewValues
= aProps
.getConstArray();
1887 std::vector
< PropertyChangeEvent
> aEvents
;
1889 OUString
aFullPropNamePrefix( getFullKey() );
1890 aFullPropNamePrefix
+= "/";
1892 // Iterate over given property value sequence.
1893 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
1895 const PropertyValue
& rNewValue
= pNewValues
[ n
];
1896 const OUString
& rName
= rNewValue
.Name
;
1898 OUString aFullPropName
= aFullPropNamePrefix
;
1899 aFullPropName
+= makeHierarchalNameSegment( rName
);
1901 // Does property exist?
1902 if ( xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
) )
1904 Reference
< XNameReplace
> xNameReplace(
1905 m_pImpl
->m_pCreator
->getConfigWriteAccess(
1906 aFullPropName
), UNO_QUERY
);
1907 Reference
< XChangesBatch
> xBatch(
1908 m_pImpl
->m_pCreator
->getConfigWriteAccess(
1909 OUString() ), UNO_QUERY
);
1911 if ( xNameReplace
.is() && xBatch
.is() )
1916 xNameReplace
->replaceByName(
1918 makeAny( rNewValue
.Handle
) );
1921 OUString aValueName
= aFullPropName
;
1922 aValueName
+= "/Value";
1924 = xRootHierNameAccess
->getByHierarchicalName(
1927 xNameReplace
->replaceByName(
1931 // Write state ( Now it is a directly set value )
1932 xNameReplace
->replaceByName(
1936 PropertyState_DIRECT_VALUE
) ) );
1939 xBatch
->commitChanges();
1941 if ( m_pImpl
->m_pPropertyChangeListeners
)
1943 PropertyChangeEvent aEvt
;
1944 aEvt
.Source
= static_cast<OWeakObject
*>(this);
1945 aEvt
.PropertyName
= rNewValue
.Name
;
1946 aEvt
.PropertyHandle
= rNewValue
.Handle
;
1947 aEvt
.Further
= false;
1948 aEvt
.OldValue
= aOldValue
;
1949 aEvt
.NewValue
= rNewValue
.Value
;
1951 aEvents
.push_back( aEvt
);
1954 catch (const IllegalArgumentException
&)
1958 catch (const NoSuchElementException
&)
1960 // getByHierarchicalName, replaceByName
1962 catch (const WrappedTargetException
&)
1964 // replaceByName, commitChanges
1970 // Callback follows!
1973 if ( m_pImpl
->m_pPropertyChangeListeners
)
1975 // Notify property changes.
1976 for (auto const& event
: aEvents
)
1978 notifyPropertyChangeEvent( event
);
1985 OSL_FAIL( "PersistentPropertySet::setPropertyValues - Nothing set!" );
1989 // Non-interface methods
1992 void PersistentPropertySet::notifyPropertyChangeEvent(
1993 const PropertyChangeEvent
& rEvent
) const
1995 // Get "normal" listeners for the property.
1996 OInterfaceContainerHelper
* pContainer
=
1997 m_pImpl
->m_pPropertyChangeListeners
->getContainer(
1998 rEvent
.PropertyName
);
1999 if ( pContainer
&& pContainer
->getLength() )
2001 OInterfaceIteratorHelper
aIter( *pContainer
);
2002 while ( aIter
.hasMoreElements() )
2005 Reference
< XPropertyChangeListener
> xListener(
2006 aIter
.next(), UNO_QUERY
);
2007 if ( xListener
.is() )
2008 xListener
->propertyChange( rEvent
);
2012 // Get "normal" listeners for all properties.
2013 OInterfaceContainerHelper
* pNoNameContainer
=
2014 m_pImpl
->m_pPropertyChangeListeners
->getContainer( OUString() );
2015 if ( pNoNameContainer
&& pNoNameContainer
->getLength() )
2017 OInterfaceIteratorHelper
aIter( *pNoNameContainer
);
2018 while ( aIter
.hasMoreElements() )
2021 Reference
< XPropertyChangeListener
> xListener(
2022 aIter
.next(), UNO_QUERY
);
2023 if ( xListener
.is() )
2024 xListener
->propertyChange( rEvent
);
2030 void PersistentPropertySet::notifyPropertySetInfoChange(
2031 const PropertySetInfoChangeEvent
& evt
) const
2033 if ( !m_pImpl
->m_pPropSetChangeListeners
)
2036 // Notify event listeners.
2037 OInterfaceIteratorHelper2
aIter( *( m_pImpl
->m_pPropSetChangeListeners
) );
2038 while ( aIter
.hasMoreElements() )
2041 Reference
< XPropertySetInfoChangeListener
>
2042 xListener( aIter
.next(), UNO_QUERY
);
2043 if ( xListener
.is() )
2044 xListener
->propertySetInfoChange( evt
);
2049 const OUString
& PersistentPropertySet::getFullKey()
2051 if ( m_pImpl
->m_aFullKey
.isEmpty() )
2053 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
2054 if ( m_pImpl
->m_aFullKey
.isEmpty() )
2057 = makeHierarchalNameSegment( m_pImpl
->m_aKey
);
2063 return m_pImpl
->m_aFullKey
;
2067 PropertySetRegistry
& PersistentPropertySet::getPropertySetRegistry()
2069 return *m_pImpl
->m_pCreator
;
2073 // PropertySetInfo_Impl Implementation.
2076 PropertySetInfo_Impl::PropertySetInfo_Impl(
2077 PersistentPropertySet
* pOwner
)
2078 : m_pOwner( pOwner
)
2083 // XPropertySetInfo methods.
2087 Sequence
< Property
> SAL_CALL
PropertySetInfo_Impl::getProperties()
2091 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
2092 m_pOwner
->getPropertySetRegistry().getRootConfigReadAccess(),
2094 if ( xRootHierNameAccess
.is() )
2098 Reference
< XNameAccess
> xNameAccess
;
2099 xRootHierNameAccess
->getByHierarchicalName(
2100 m_pOwner
->getFullKey() )
2102 if ( xNameAccess
.is() )
2104 // Obtain property names.
2106 Sequence
< OUString
> aElems
2107 = xNameAccess
->getElementNames();
2109 sal_uInt32 nCount
= aElems
.getLength();
2110 Sequence
< Property
>* pPropSeq
2111 = new Sequence
< Property
>( nCount
);
2115 Reference
< XHierarchicalNameAccess
> xHierNameAccess(
2116 xNameAccess
, UNO_QUERY
);
2118 OSL_ENSURE( xHierNameAccess
.is(),
2119 "PropertySetInfo_Impl::getProperties - "
2120 "No hierarchical name access!" );
2122 if ( xHierNameAccess
.is() )
2124 const OUString
aHandleName("/Handle");
2125 const OUString
aValueName("/Value");
2126 const OUString
aAttrName("/Attributes");
2128 Property
* pProps
= pPropSeq
->getArray();
2130 for ( sal_uInt32 n
= 0; n
< nCount
; ++n
)
2132 Property
& rProp
= pProps
[ n
];
2133 OUString rName
= aElems
[ n
];
2135 = makeHierarchalNameSegment( rName
);
2137 // Set property name.
2143 // Obtain and set property handle
2144 OUString aHierName
= aXMLName
;
2145 aHierName
+= aHandleName
;
2147 = xHierNameAccess
->getByHierarchicalName(
2150 if ( !( aKeyValue
>>= rProp
.Handle
) )
2151 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2152 "Error getting property handle!" );
2154 catch (const NoSuchElementException
&)
2156 // getByHierarchicalName
2158 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2159 "NoSuchElementException!" );
2164 // Obtain and set property type
2165 OUString aHierName
= aXMLName
;
2166 aHierName
+= aValueName
;
2168 = xHierNameAccess
->getByHierarchicalName(
2171 // Note: The type may be void if addProperty
2172 // was called with a default value
2175 rProp
.Type
= aKeyValue
.getValueType();
2177 catch (const NoSuchElementException
&)
2179 // getByHierarchicalName
2181 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2182 "NoSuchElementException!" );
2187 // Obtain and set property attributes
2188 OUString aHierName
= aXMLName
;
2189 aHierName
+= aAttrName
;
2191 = xHierNameAccess
->getByHierarchicalName(
2194 sal_Int32 nAttribs
= 0;
2195 if ( aKeyValue
>>= nAttribs
)
2197 = sal_Int16( nAttribs
);
2199 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2200 "Error getting property attributes!" );
2202 catch (const NoSuchElementException
&)
2204 // getByHierarchicalName
2206 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2207 "NoSuchElementException!" );
2214 m_pProps
.reset( pPropSeq
);
2218 catch (const NoSuchElementException
&)
2220 // getByHierarchicalName
2224 OSL_FAIL( "PropertySetInfo_Impl::getProperties - Error!" );
2225 m_pProps
.reset( new Sequence
< Property
>( 0 ) );
2233 Property SAL_CALL
PropertySetInfo_Impl::getPropertyByName(
2234 const OUString
& aName
)
2236 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
2237 m_pOwner
->getPropertySetRegistry().getRootConfigReadAccess(),
2239 if ( xRootHierNameAccess
.is() )
2241 OUString
aFullPropName( m_pOwner
->getFullKey() );
2242 aFullPropName
+= "/";
2243 aFullPropName
+= makeHierarchalNameSegment( aName
);
2245 // Does property exist?
2246 if ( !xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
) )
2247 throw UnknownPropertyException();
2254 OUString aKey
= aFullPropName
;
2257 if ( !( xRootHierNameAccess
->getByHierarchicalName( aKey
)
2258 >>= aProp
.Handle
) )
2260 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2265 // Obtain Value and extract type.
2266 aKey
= aFullPropName
;
2269 Any aValue
= xRootHierNameAccess
->getByHierarchicalName( aKey
);
2270 if ( !aValue
.hasValue() )
2272 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2277 aProp
.Type
= aValue
.getValueType();
2279 // Obtain Attributes.
2280 aKey
= aFullPropName
;
2281 aKey
+= "/Attributes";
2283 sal_Int32 nAttribs
= 0;
2284 if ( xRootHierNameAccess
->getByHierarchicalName( aKey
)
2286 aProp
.Attributes
= sal_Int16( nAttribs
);
2289 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2300 catch (const NoSuchElementException
&)
2302 // getByHierarchicalName
2304 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2305 "caught NoSuchElementException!" );
2310 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - Error!" );
2316 sal_Bool SAL_CALL
PropertySetInfo_Impl::hasPropertyByName(
2317 const OUString
& Name
)
2319 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
2320 m_pOwner
->getPropertySetRegistry().getRootConfigReadAccess(),
2322 if ( xRootHierNameAccess
.is() )
2324 OUString
aFullPropName( m_pOwner
->getFullKey() );
2325 aFullPropName
+= "/";
2326 aFullPropName
+= makeHierarchalNameSegment( Name
);
2328 return xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
);
2334 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */