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 <osl/diagnose.h>
30 #include <rtl/ustrbuf.hxx>
31 #include <cppuhelper/interfacecontainer.hxx>
32 #include <com/sun/star/beans/PropertyAttribute.hpp>
33 #include <com/sun/star/beans/PropertySetInfoChange.hpp>
34 #include <com/sun/star/configuration/theDefaultProvider.hpp>
35 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
36 #include <com/sun/star/container/XNameContainer.hpp>
37 #include <com/sun/star/container/XNameReplace.hpp>
38 #include <com/sun/star/util/XChangesBatch.hpp>
39 #include <comphelper/processfactory.hxx>
40 #include <cppuhelper/implbase1.hxx>
41 #include "ucbstore.hxx"
43 using namespace com::sun::star::beans
;
44 using namespace com::sun::star::configuration
;
45 using namespace com::sun::star::container
;
46 using namespace com::sun::star::lang
;
47 using namespace com::sun::star::ucb
;
48 using namespace com::sun::star::uno
;
49 using namespace com::sun::star::util
;
54 OUString
makeHierarchalNameSegment( const OUString
& rIn
)
56 OUStringBuffer aBuffer
;
57 aBuffer
.appendAscii( "['" );
59 sal_Int32 nCount
= rIn
.getLength();
60 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
62 const sal_Unicode c
= rIn
[ n
];
66 aBuffer
.appendAscii( "&" );
70 aBuffer
.appendAscii( """ );
74 aBuffer
.appendAscii( "'" );
78 aBuffer
.appendAscii( "<" );
82 aBuffer
.appendAscii( ">" );
91 aBuffer
.appendAscii( "']" );
92 return OUString( aBuffer
.makeStringAndClear() );
95 #define STORE_CONTENTPROPERTIES_KEY "/org.openoffice.ucb.Store/ContentProperties"
97 // describe path of cfg entry
98 #define CFGPROPERTY_NODEPATH "nodepath"
99 // true->async. update; false->sync. update
100 #define CFGPROPERTY_LAZYWRITE "lazywrite"
102 // PropertySetMap_Impl.
103 typedef std::unordered_map
106 PersistentPropertySet
*,
111 // class PropertySetInfo_Impl
112 class PropertySetInfo_Impl
: public cppu::WeakImplHelper1
< XPropertySetInfo
>
114 Reference
< XComponentContext
> m_xContext
;
115 Sequence
< Property
>* m_pProps
;
116 PersistentPropertySet
* m_pOwner
;
119 PropertySetInfo_Impl( const Reference
< XComponentContext
>& xContext
,
120 PersistentPropertySet
* pOwner
);
121 virtual ~PropertySetInfo_Impl();
124 virtual Sequence
< Property
> SAL_CALL
getProperties()
125 throw( RuntimeException
, std::exception
) SAL_OVERRIDE
;
126 virtual Property SAL_CALL
getPropertyByName( const OUString
& aName
)
127 throw( UnknownPropertyException
, RuntimeException
, std::exception
) SAL_OVERRIDE
;
128 virtual sal_Bool SAL_CALL
hasPropertyByName( const OUString
& Name
)
129 throw( RuntimeException
, std::exception
) SAL_OVERRIDE
;
131 // Non-interface methods.
132 void reset() { delete m_pProps
; m_pProps
= 0; }
144 Sequence
< Any
> m_aInitArgs
;
145 Reference
< XPropertySetRegistry
> m_xTheRegistry
;
152 // UcbStore Implementation.
158 UcbStore::UcbStore( const Reference
< XComponentContext
>& xContext
)
159 : m_xContext( xContext
),
160 m_pImpl( new UcbStore_Impl() )
166 UcbStore::~UcbStore()
172 XSERVICEINFO_IMPL_1_CTX( UcbStore
,
173 OUString( "com.sun.star.comp.ucb.UcbStore" ),
174 STORE_SERVICE_NAME
);
178 // Service factory implementation.
182 ONE_INSTANCE_SERVICE_FACTORY_IMPL( UcbStore
);
186 // XPropertySetRegistryFactory methods.
191 Reference
< XPropertySetRegistry
> SAL_CALL
192 UcbStore::createPropertySetRegistry( const OUString
& )
193 throw( RuntimeException
, std::exception
)
195 // The URL parameter is ignored by this interface implementation. It always
196 // uses the configuration server as storage medium.
198 if ( !m_pImpl
->m_xTheRegistry
.is() )
200 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
201 if ( !m_pImpl
->m_xTheRegistry
.is() )
202 m_pImpl
->m_xTheRegistry
= new PropertySetRegistry( m_xContext
, getInitArgs() );
205 return m_pImpl
->m_xTheRegistry
;
210 // XInitialization methods.
215 void SAL_CALL
UcbStore::initialize( const Sequence
< Any
>& aArguments
)
216 throw( Exception
, RuntimeException
, std::exception
)
218 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
219 m_pImpl
->m_aInitArgs
= aArguments
;
223 const Sequence
< Any
>& UcbStore::getInitArgs() const
225 return m_pImpl
->m_aInitArgs
;
230 // PropertySetRegistry_Impl.
234 struct PropertySetRegistry_Impl
236 const Sequence
< Any
> m_aInitArgs
;
237 PropertySetMap_Impl m_aPropSets
;
238 Reference
< XMultiServiceFactory
> m_xConfigProvider
;
239 Reference
< XInterface
> m_xRootReadAccess
;
240 Reference
< XInterface
> m_xRootWriteAccess
;
242 bool m_bTriedToGetRootReadAccess
; // #82494#
243 bool m_bTriedToGetRootWriteAccess
; // #82494#
245 PropertySetRegistry_Impl( const Sequence
< Any
> &rInitArgs
)
246 : m_aInitArgs( rInitArgs
),
247 m_bTriedToGetRootReadAccess( false ),
248 m_bTriedToGetRootWriteAccess( false )
257 // PropertySetRegistry Implementation.
263 PropertySetRegistry::PropertySetRegistry(
264 const Reference
< XComponentContext
>& xContext
,
265 const Sequence
< Any
> &rInitArgs
)
266 : m_xContext( xContext
),
267 m_pImpl( new PropertySetRegistry_Impl( rInitArgs
) )
273 PropertySetRegistry::~PropertySetRegistry()
280 // XServiceInfo methods.
284 XSERVICEINFO_NOFACTORY_IMPL_1( PropertySetRegistry
,
285 OUString( "com.sun.star.comp.ucb.PropertySetRegistry" ),
286 PROPSET_REG_SERVICE_NAME
);
290 // XPropertySetRegistry methods.
295 Reference
< XPersistentPropertySet
> SAL_CALL
296 PropertySetRegistry::openPropertySet( const OUString
& key
, sal_Bool create
)
297 throw( RuntimeException
, std::exception
)
299 if ( !key
.isEmpty() )
301 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
303 PropertySetMap_Impl
& rSets
= m_pImpl
->m_aPropSets
;
305 PropertySetMap_Impl::const_iterator it
= rSets
.find( key
);
306 if ( it
!= rSets
.end() )
308 // Already instantiated.
309 return Reference
< XPersistentPropertySet
>( (*it
).second
);
313 // Create new instance.
314 Reference
< XNameAccess
> xRootNameAccess(
315 getRootConfigReadAccess(), UNO_QUERY
);
316 if ( xRootNameAccess
.is() )
318 // Propertyset in registry?
319 if ( xRootNameAccess
->hasByName( key
) )
322 return Reference
< XPersistentPropertySet
>(
323 new PersistentPropertySet(
324 m_xContext
, *this, key
) );
328 // No. Create entry for propertyset.
330 Reference
< XSingleServiceFactory
> xFac(
331 getConfigWriteAccess( OUString() ), UNO_QUERY
);
332 Reference
< XChangesBatch
> xBatch( xFac
, UNO_QUERY
);
333 Reference
< XNameContainer
> xContainer( xFac
, UNO_QUERY
);
335 OSL_ENSURE( xFac
.is(),
336 "PropertySetRegistry::openPropertySet - "
339 OSL_ENSURE( xBatch
.is(),
340 "PropertySetRegistry::openPropertySet - "
343 OSL_ENSURE( xContainer
.is(),
344 "PropertySetRegistry::openPropertySet - "
347 if ( xFac
.is() && xBatch
.is() && xContainer
.is() )
351 // Create new "Properties" config item.
352 Reference
< XNameReplace
> xNameReplace(
353 xFac
->createInstance(), UNO_QUERY
);
355 if ( xNameReplace
.is() )
360 // xNameReplace->replaceByName(
361 // OUString("Values"),
365 xContainer
->insertByName(
366 key
, makeAny( xNameReplace
) );
368 xBatch
->commitChanges();
370 return Reference
< XPersistentPropertySet
>(
371 new PersistentPropertySet(
372 m_xContext
, *this, key
) );
375 catch (const IllegalArgumentException
&)
379 OSL_FAIL( "PropertySetRegistry::openPropertySet - "
380 "caught IllegalArgumentException!" );
382 catch (const ElementExistException
&)
386 OSL_FAIL( "PropertySetRegistry::openPropertySet - "
387 "caught ElementExistException!" );
389 catch (const WrappedTargetException
&)
391 // insertByName, commitChanges
393 OSL_FAIL( "PropertySetRegistry::openPropertySet - "
394 "caught WrappedTargetException!" );
396 catch (const RuntimeException
&)
398 OSL_FAIL( "PropertySetRegistry::openPropertySet - "
399 "caught RuntimeException!" );
401 catch (const Exception
&)
405 OSL_FAIL( "PropertySetRegistry::openPropertySet - "
406 "caught Exception!" );
412 // No entry. Fail, but no error.
413 return Reference
< XPersistentPropertySet
>();
417 OSL_TRACE( "PropertySetRegistry::openPropertySet no root access" );
421 return Reference
< XPersistentPropertySet
>();
426 void SAL_CALL
PropertySetRegistry::removePropertySet( const OUString
& key
)
427 throw( RuntimeException
, std::exception
)
432 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
434 Reference
< XNameAccess
> xRootNameAccess(
435 getRootConfigReadAccess(), UNO_QUERY
);
436 if ( xRootNameAccess
.is() )
438 // Propertyset in registry?
439 if ( !xRootNameAccess
->hasByName( key
) )
441 Reference
< XChangesBatch
> xBatch(
442 getConfigWriteAccess( OUString() ), UNO_QUERY
);
443 Reference
< XNameContainer
> xContainer( xBatch
, UNO_QUERY
);
445 if ( xBatch
.is() && xContainer
.is() )
450 xContainer
->removeByName( key
);
452 xBatch
->commitChanges();
457 catch (const NoSuchElementException
&)
461 OSL_FAIL( "PropertySetRegistry::removePropertySet - "
462 "caught NoSuchElementException!" );
465 catch (const WrappedTargetException
&)
469 OSL_FAIL( "PropertySetRegistry::removePropertySet - "
470 "caught WrappedTargetException!" );
478 OSL_TRACE( "PropertySetRegistry::removePropertySet - no root access" );
483 // XElementAccess methods.
488 com::sun::star::uno::Type SAL_CALL
PropertySetRegistry::getElementType()
489 throw( RuntimeException
, std::exception
)
491 return cppu::UnoType
<XPersistentPropertySet
>::get();
496 sal_Bool SAL_CALL
PropertySetRegistry::hasElements()
497 throw( RuntimeException
, std::exception
)
499 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
501 Reference
< XElementAccess
> xElemAccess(
502 getRootConfigReadAccess(), UNO_QUERY
);
503 if ( xElemAccess
.is() )
504 return xElemAccess
->hasElements();
511 // XNameAccess methods.
516 Any SAL_CALL
PropertySetRegistry::getByName( const OUString
& aName
)
517 throw( NoSuchElementException
, WrappedTargetException
, RuntimeException
, std::exception
)
519 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
521 Reference
< XNameAccess
> xNameAccess(
522 getRootConfigReadAccess(), UNO_QUERY
);
523 if ( xNameAccess
.is() )
528 return xNameAccess
->getByName( aName
);
530 catch (const NoSuchElementException
&)
534 catch (const WrappedTargetException
&)
545 Sequence
< OUString
> SAL_CALL
PropertySetRegistry::getElementNames()
546 throw( RuntimeException
, std::exception
)
548 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
550 Reference
< XNameAccess
> xNameAccess(
551 getRootConfigReadAccess(), UNO_QUERY
);
552 if ( xNameAccess
.is() )
554 return xNameAccess
->getElementNames();
556 return Sequence
< OUString
>( 0 );
561 sal_Bool SAL_CALL
PropertySetRegistry::hasByName( const OUString
& aName
)
562 throw( RuntimeException
, std::exception
)
564 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
566 Reference
< XNameAccess
> xNameAccess(
567 getRootConfigReadAccess(), UNO_QUERY
);
568 if ( xNameAccess
.is() )
570 return xNameAccess
->hasByName( aName
);
577 void PropertySetRegistry::add( PersistentPropertySet
* pSet
)
579 OUString
key( pSet
->getKey() );
581 if ( !key
.isEmpty() )
583 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
584 m_pImpl
->m_aPropSets
[ key
] = pSet
;
589 void PropertySetRegistry::remove( PersistentPropertySet
* pSet
)
591 OUString
key( pSet
->getKey() );
593 if ( !key
.isEmpty() )
595 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
597 PropertySetMap_Impl
& rSets
= m_pImpl
->m_aPropSets
;
599 PropertySetMap_Impl::iterator it
= rSets
.find( key
);
600 if ( it
!= rSets
.end() )
609 void PropertySetRegistry::renamePropertySet( const OUString
& rOldKey
,
610 const OUString
& rNewKey
)
612 if ( rOldKey
== rNewKey
)
615 Reference
< XNameAccess
> xRootNameAccess(
616 getConfigWriteAccess( OUString() ), UNO_QUERY
);
617 if ( xRootNameAccess
.is() )
620 if ( xRootNameAccess
->hasByName( rOldKey
) )
622 // New key not present?
623 if ( xRootNameAccess
->hasByName( rNewKey
) )
625 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
629 Reference
< XSingleServiceFactory
> xFac(
630 xRootNameAccess
, UNO_QUERY
);
631 Reference
< XChangesBatch
> xBatch( xFac
, UNO_QUERY
);
632 Reference
< XNameContainer
> xContainer( xFac
, UNO_QUERY
);
634 OSL_ENSURE( xFac
.is(),
635 "PropertySetRegistry::renamePropertySet - "
638 OSL_ENSURE( xBatch
.is(),
639 "PropertySetRegistry::renamePropertySet - "
642 OSL_ENSURE( xContainer
.is(),
643 "PropertySetRegistry::renamePropertySet - "
646 if ( xFac
.is() && xBatch
.is() && xContainer
.is() )
649 // Create new "Properties" config item.
654 Reference
< XNameReplace
> xNameReplace(
655 xFac
->createInstance(), UNO_QUERY
);
657 if ( xNameReplace
.is() )
660 xContainer
->insertByName(
661 rNewKey
, makeAny( xNameReplace
) );
663 xBatch
->commitChanges();
666 catch (const IllegalArgumentException
&)
670 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
671 "caught IllegalArgumentException!" );
674 catch (const ElementExistException
&)
678 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
679 "caught ElementExistException!" );
682 catch (const WrappedTargetException
&)
684 // insertByName, commitChanges
686 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
687 "caught WrappedTargetException!" );
690 catch (const RuntimeException
&)
692 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
693 "caught RuntimeException!" );
696 catch (const Exception
&)
700 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
701 "caught Exception!" );
709 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
710 xRootNameAccess
, UNO_QUERY
);
711 if ( !xRootHierNameAccess
.is() )
713 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
714 "No hierarchical name access!" );
720 OUString aOldValuesKey
721 = makeHierarchalNameSegment( rOldKey
);
722 aOldValuesKey
+= "/Values";
724 Reference
< XNameAccess
> xOldNameAccess
;
725 xRootHierNameAccess
->getByHierarchicalName(
728 if ( !xOldNameAccess
.is() )
730 OSL_FAIL( "PersistentPropertySet::renamePropertySet - "
731 "No old name access!" );
735 // Obtain property names.
736 Sequence
< OUString
> aElems
737 = xOldNameAccess
->getElementNames();
738 sal_Int32 nCount
= aElems
.getLength();
741 OUString aNewValuesKey
742 = makeHierarchalNameSegment( rNewKey
);
743 aNewValuesKey
+= "/Values";
745 Reference
< XSingleServiceFactory
> xNewFac
;
746 xRootHierNameAccess
->getByHierarchicalName(
751 OSL_FAIL( "PersistentPropertySet::renamePropertySet - "
756 Reference
< XNameContainer
> xNewContainer(
757 xNewFac
, UNO_QUERY
);
758 if ( !xNewContainer
.is() )
760 OSL_FAIL( "PersistentPropertySet::renamePropertySet - "
761 "No new container!" );
765 aOldValuesKey
+= "/";
767 OUString
aHandleKey("/Handle");
768 OUString
aValueKey("/Value");
769 OUString
aStateKey("/State");
770 OUString
aAttrKey("/Attributes");
772 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
774 const OUString
& rPropName
= aElems
[ n
];
777 Reference
< XNameReplace
> xNewPropNameReplace(
778 xNewFac
->createInstance(), UNO_QUERY
);
780 if ( !xNewPropNameReplace
.is() )
782 OSL_FAIL( "PersistentPropertySet::renamePropertySet - "
783 "No new prop name replace!" );
790 OUString aKey
= aOldValuesKey
;
791 aKey
+= makeHierarchalNameSegment( rPropName
);
794 OUString aNewKey1
= aKey
;
795 aNewKey1
+= aHandleKey
;
797 xRootHierNameAccess
->getByHierarchicalName(
799 xNewPropNameReplace
->replaceByName(
805 aNewKey1
+= aValueKey
;
807 xRootHierNameAccess
->getByHierarchicalName(
809 xNewPropNameReplace
->replaceByName(
815 aNewKey1
+= aStateKey
;
817 xRootHierNameAccess
->getByHierarchicalName(
819 xNewPropNameReplace
->replaceByName(
825 aNewKey1
+= aAttrKey
;
827 xRootHierNameAccess
->getByHierarchicalName(
829 xNewPropNameReplace
->replaceByName(
830 OUString("Attributes"),
834 xNewContainer
->insertByName(
835 rPropName
, makeAny( xNewPropNameReplace
) );
838 xBatch
->commitChanges();
842 catch (const IllegalArgumentException
&)
844 // insertByName, replaceByName
846 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
847 "caught IllegalArgumentException!" );
850 catch (const ElementExistException
&)
854 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
855 "caught ElementExistException!" );
858 catch (const WrappedTargetException
&)
860 // insertByName, replaceByName, commitChanges
862 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
863 "caught WrappedTargetException!" );
866 catch (const NoSuchElementException
&)
868 // getByHierarchicalName, replaceByName
870 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
871 "caught NoSuchElementException!" );
874 catch (const RuntimeException
&)
876 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
877 "caught RuntimeException!" );
880 catch (const Exception
&)
884 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
885 "caught Exception!" );
890 // Remove old entry...
896 xContainer
->removeByName( rOldKey
);
898 xBatch
->commitChanges();
903 catch (const NoSuchElementException
&)
907 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
908 "caught NoSuchElementException!" );
911 catch (const WrappedTargetException
&)
915 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
916 "caught WrappedTargetException!" );
923 OSL_FAIL( "PropertySetRegistry::renamePropertySet - Error!" );
927 Reference
< XMultiServiceFactory
> PropertySetRegistry::getConfigProvider()
929 if ( !m_pImpl
->m_xConfigProvider
.is() )
931 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
932 if ( !m_pImpl
->m_xConfigProvider
.is() )
934 const Sequence
< Any
>& rInitArgs
= m_pImpl
->m_aInitArgs
;
936 if ( rInitArgs
.getLength() > 0 )
938 // Extract config provider from service init args.
939 rInitArgs
[ 0 ] >>= m_pImpl
->m_xConfigProvider
;
941 OSL_ENSURE( m_pImpl
->m_xConfigProvider
.is(),
942 "PropertySetRegistry::getConfigProvider - "
943 "No config provider!" );
949 m_pImpl
->m_xConfigProvider
= theDefaultProvider::get( m_xContext
);
951 catch (const Exception
&)
953 OSL_TRACE( "PropertySetRegistry::getConfigProvider - "
954 "caught exception!" );
960 return m_pImpl
->m_xConfigProvider
;
964 Reference
< XInterface
> PropertySetRegistry::getRootConfigReadAccess()
968 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
970 if ( !m_pImpl
->m_xRootReadAccess
.is() )
972 if ( m_pImpl
->m_bTriedToGetRootReadAccess
) // #82494#
974 OSL_FAIL( "PropertySetRegistry::getRootConfigReadAccess - "
975 "Unable to read any config data! -> #82494#" );
976 return Reference
< XInterface
>();
981 if ( m_pImpl
->m_xConfigProvider
.is() )
983 Sequence
< Any
> aArguments( 1 );
984 PropertyValue aProperty
;
985 aProperty
.Name
= CFGPROPERTY_NODEPATH
;
987 <<= OUString( STORE_CONTENTPROPERTIES_KEY
);
988 aArguments
[ 0 ] <<= aProperty
;
990 m_pImpl
->m_bTriedToGetRootReadAccess
= true;
992 m_pImpl
->m_xRootReadAccess
=
993 m_pImpl
->m_xConfigProvider
->createInstanceWithArguments(
994 OUString( "com.sun.star.configuration.ConfigurationAccess" ),
997 if ( m_pImpl
->m_xRootReadAccess
.is() )
998 return m_pImpl
->m_xRootReadAccess
;
1002 return m_pImpl
->m_xRootReadAccess
;
1004 catch (const RuntimeException
&)
1008 catch (const Exception
&)
1010 // createInstance, createInstanceWithArguments
1012 OSL_FAIL( "PropertySetRegistry::getRootConfigReadAccess - caught Exception!" );
1013 return Reference
< XInterface
>();
1016 OSL_TRACE( "PropertySetRegistry::getRootConfigReadAccess - Error!" );
1017 return Reference
< XInterface
>();
1021 Reference
< XInterface
> PropertySetRegistry::getConfigWriteAccess(
1022 const OUString
& rPath
)
1026 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
1028 if ( !m_pImpl
->m_xRootWriteAccess
.is() )
1030 if ( m_pImpl
->m_bTriedToGetRootWriteAccess
) // #82494#
1032 OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - "
1033 "Unable to write any config data! -> #82494#" );
1034 return Reference
< XInterface
>();
1037 getConfigProvider();
1039 if ( m_pImpl
->m_xConfigProvider
.is() )
1041 Sequence
< Any
> aArguments( 2 );
1042 PropertyValue aProperty
;
1044 aProperty
.Name
= CFGPROPERTY_NODEPATH
;
1045 aProperty
.Value
<<= OUString( STORE_CONTENTPROPERTIES_KEY
);
1046 aArguments
[ 0 ] <<= aProperty
;
1048 aProperty
.Name
= CFGPROPERTY_LAZYWRITE
;
1049 aProperty
.Value
<<= sal_True
;
1050 aArguments
[ 1 ] <<= aProperty
;
1052 m_pImpl
->m_bTriedToGetRootWriteAccess
= true;
1054 m_pImpl
->m_xRootWriteAccess
=
1055 m_pImpl
->m_xConfigProvider
->createInstanceWithArguments(
1056 OUString( "com.sun.star.configuration.ConfigurationUpdateAccess" ),
1059 OSL_ENSURE( m_pImpl
->m_xRootWriteAccess
.is(),
1060 "PropertySetRegistry::getConfigWriteAccess - "
1061 "No config update access!" );
1065 if ( m_pImpl
->m_xRootWriteAccess
.is() )
1067 if ( !rPath
.isEmpty() )
1069 Reference
< XHierarchicalNameAccess
> xNA(
1070 m_pImpl
->m_xRootWriteAccess
, UNO_QUERY
);
1073 Reference
< XInterface
> xInterface
;
1074 xNA
->getByHierarchicalName( rPath
) >>= xInterface
;
1076 if ( xInterface
.is() )
1081 return m_pImpl
->m_xRootWriteAccess
;
1084 catch (const RuntimeException
&)
1088 catch (const NoSuchElementException
&)
1090 // getByHierarchicalName
1092 OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - "
1093 "caught NoSuchElementException!" );
1094 return Reference
< XInterface
>();
1096 catch (const Exception
&)
1098 // createInstance, createInstanceWithArguments
1100 OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - "
1101 "caught Exception!" );
1102 return Reference
< XInterface
>();
1105 OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - Error!" );
1106 return Reference
< XInterface
>();
1109 typedef OMultiTypeInterfaceContainerHelperVar
<OUString
> PropertyListeners_Impl
;
1111 struct PersistentPropertySet_Impl
1113 PropertySetRegistry
* m_pCreator
;
1114 PropertySetInfo_Impl
* m_pInfo
;
1116 OUString m_aFullKey
;
1117 osl::Mutex m_aMutex
;
1118 OInterfaceContainerHelper
* m_pDisposeEventListeners
;
1119 OInterfaceContainerHelper
* m_pPropSetChangeListeners
;
1120 PropertyListeners_Impl
* m_pPropertyChangeListeners
;
1122 PersistentPropertySet_Impl( PropertySetRegistry
& rCreator
,
1123 const OUString
& rKey
)
1124 : m_pCreator( &rCreator
), m_pInfo( NULL
), m_aKey( rKey
),
1125 m_pDisposeEventListeners( NULL
), m_pPropSetChangeListeners( NULL
),
1126 m_pPropertyChangeListeners( NULL
)
1128 m_pCreator
->acquire();
1131 ~PersistentPropertySet_Impl()
1133 m_pCreator
->release();
1138 delete m_pDisposeEventListeners
;
1139 delete m_pPropSetChangeListeners
;
1140 delete m_pPropertyChangeListeners
;
1148 // PersistentPropertySet Implementation.
1154 PersistentPropertySet::PersistentPropertySet(
1155 const Reference
< XComponentContext
>& xContext
,
1156 PropertySetRegistry
& rCreator
,
1157 const OUString
& rKey
)
1158 : m_xContext( xContext
),
1159 m_pImpl( new PersistentPropertySet_Impl( rCreator
, rKey
) )
1161 // register at creator.
1162 rCreator
.add( this );
1167 PersistentPropertySet::~PersistentPropertySet()
1169 // deregister at creator.
1170 m_pImpl
->m_pCreator
->remove( this );
1175 // XServiceInfo methods.
1179 XSERVICEINFO_NOFACTORY_IMPL_1( PersistentPropertySet
,
1180 OUString( "com.sun.star.comp.ucb.PersistentPropertySet" ),
1181 PERS_PROPSET_SERVICE_NAME
);
1185 // XComponent methods.
1190 void SAL_CALL
PersistentPropertySet::dispose()
1191 throw( RuntimeException
, std::exception
)
1193 if ( m_pImpl
->m_pDisposeEventListeners
&&
1194 m_pImpl
->m_pDisposeEventListeners
->getLength() )
1197 aEvt
.Source
= static_cast< XComponent
* >( this );
1198 m_pImpl
->m_pDisposeEventListeners
->disposeAndClear( aEvt
);
1201 if ( m_pImpl
->m_pPropSetChangeListeners
&&
1202 m_pImpl
->m_pPropSetChangeListeners
->getLength() )
1205 aEvt
.Source
= static_cast< XPropertySetInfoChangeNotifier
* >( this );
1206 m_pImpl
->m_pPropSetChangeListeners
->disposeAndClear( aEvt
);
1209 if ( m_pImpl
->m_pPropertyChangeListeners
)
1212 aEvt
.Source
= static_cast< XPropertySet
* >( this );
1213 m_pImpl
->m_pPropertyChangeListeners
->disposeAndClear( aEvt
);
1219 void SAL_CALL
PersistentPropertySet::addEventListener(
1220 const Reference
< XEventListener
>& Listener
)
1221 throw( RuntimeException
, std::exception
)
1223 if ( !m_pImpl
->m_pDisposeEventListeners
)
1224 m_pImpl
->m_pDisposeEventListeners
=
1225 new OInterfaceContainerHelper( m_pImpl
->m_aMutex
);
1227 m_pImpl
->m_pDisposeEventListeners
->addInterface( Listener
);
1232 void SAL_CALL
PersistentPropertySet::removeEventListener(
1233 const Reference
< XEventListener
>& Listener
)
1234 throw( RuntimeException
, std::exception
)
1236 if ( m_pImpl
->m_pDisposeEventListeners
)
1237 m_pImpl
->m_pDisposeEventListeners
->removeInterface( Listener
);
1239 // Note: Don't want to delete empty container here -> performance.
1244 // XPropertySet methods.
1249 Reference
< XPropertySetInfo
> SAL_CALL
PersistentPropertySet::getPropertySetInfo()
1250 throw( RuntimeException
, std::exception
)
1252 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
1254 PropertySetInfo_Impl
*& rpInfo
= m_pImpl
->m_pInfo
;
1257 rpInfo
= new PropertySetInfo_Impl( m_xContext
, this );
1260 return Reference
< XPropertySetInfo
>( rpInfo
);
1265 void SAL_CALL
PersistentPropertySet::setPropertyValue( const OUString
& aPropertyName
,
1267 throw( UnknownPropertyException
,
1268 PropertyVetoException
,
1269 IllegalArgumentException
,
1270 WrappedTargetException
,
1274 if ( aPropertyName
.isEmpty() )
1275 throw UnknownPropertyException();
1277 osl::ClearableGuard
< osl::Mutex
> aCGuard( m_pImpl
->m_aMutex
);
1279 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
1280 m_pImpl
->m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1281 if ( xRootHierNameAccess
.is() )
1283 OUString
aFullPropName( getFullKey() );
1284 aFullPropName
+= "/";
1285 aFullPropName
+= makeHierarchalNameSegment( aPropertyName
);
1287 // Does property exist?
1288 if ( xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
) )
1290 Reference
< XNameReplace
> xNameReplace(
1291 m_pImpl
->m_pCreator
->getConfigWriteAccess(
1292 aFullPropName
), UNO_QUERY
);
1293 Reference
< XChangesBatch
> xBatch(
1294 m_pImpl
->m_pCreator
->getConfigWriteAccess(
1295 OUString() ), UNO_QUERY
);
1297 if ( xNameReplace
.is() && xBatch
.is() )
1302 OUString aValueName
= aFullPropName
;
1303 aValueName
+= "/Value";
1305 = xRootHierNameAccess
->getByHierarchicalName(
1307 // Check value type.
1308 if ( aOldValue
.getValueType() != aValue
.getValueType() )
1311 throw IllegalArgumentException();
1315 xNameReplace
->replaceByName(
1319 // Write state ( Now it is a directly set value )
1320 xNameReplace
->replaceByName(
1324 PropertyState_DIRECT_VALUE
) ) );
1327 xBatch
->commitChanges();
1329 PropertyChangeEvent aEvt
;
1330 if ( m_pImpl
->m_pPropertyChangeListeners
)
1333 aValueName
= aFullPropName
;
1334 aValueName
+= "/Handle";
1335 sal_Int32 nHandle
= -1;
1336 xRootHierNameAccess
->getByHierarchicalName( aValueName
)
1339 aEvt
.Source
= (OWeakObject
*)this;
1340 aEvt
.PropertyName
= aPropertyName
;
1341 aEvt
.PropertyHandle
= nHandle
;
1342 aEvt
.Further
= sal_False
;
1343 aEvt
.OldValue
= aOldValue
;
1344 aEvt
.NewValue
= aValue
;
1346 // Callback follows!
1349 notifyPropertyChangeEvent( aEvt
);
1353 catch (const IllegalArgumentException
&)
1357 catch (const NoSuchElementException
&)
1359 // getByHierarchicalName, replaceByName
1361 catch (const WrappedTargetException
&)
1363 // replaceByName, commitChanges
1369 throw UnknownPropertyException();
1374 Any SAL_CALL
PersistentPropertySet::getPropertyValue(
1375 const OUString
& PropertyName
)
1376 throw( UnknownPropertyException
,
1377 WrappedTargetException
,
1378 RuntimeException
, std::exception
)
1380 if ( PropertyName
.isEmpty() )
1381 throw UnknownPropertyException();
1383 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
1385 Reference
< XHierarchicalNameAccess
> xNameAccess(
1386 m_pImpl
->m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1387 if ( xNameAccess
.is() )
1389 OUString
aFullPropName( getFullKey() );
1390 aFullPropName
+= "/";
1391 aFullPropName
+= makeHierarchalNameSegment( PropertyName
);
1392 aFullPropName
+= "/Value";
1395 return xNameAccess
->getByHierarchicalName( aFullPropName
);
1397 catch (const NoSuchElementException
&)
1399 throw UnknownPropertyException();
1403 throw UnknownPropertyException();
1408 void SAL_CALL
PersistentPropertySet::addPropertyChangeListener(
1409 const OUString
& aPropertyName
,
1410 const Reference
< XPropertyChangeListener
>& xListener
)
1411 throw( UnknownPropertyException
,
1412 WrappedTargetException
,
1413 RuntimeException
, std::exception
)
1417 if ( !m_pImpl
->m_pPropertyChangeListeners
)
1418 m_pImpl
->m_pPropertyChangeListeners
=
1419 new PropertyListeners_Impl( m_pImpl
->m_aMutex
);
1421 m_pImpl
->m_pPropertyChangeListeners
->addInterface(
1422 aPropertyName
, xListener
);
1427 void SAL_CALL
PersistentPropertySet::removePropertyChangeListener(
1428 const OUString
& aPropertyName
,
1429 const Reference
< XPropertyChangeListener
>& aListener
)
1430 throw( UnknownPropertyException
,
1431 WrappedTargetException
,
1432 RuntimeException
, std::exception
)
1436 if ( m_pImpl
->m_pPropertyChangeListeners
)
1437 m_pImpl
->m_pPropertyChangeListeners
->removeInterface(
1438 aPropertyName
, aListener
);
1440 // Note: Don't want to delete empty container here -> performance.
1445 void SAL_CALL
PersistentPropertySet::addVetoableChangeListener(
1447 const Reference
< XVetoableChangeListener
>& )
1448 throw( UnknownPropertyException
,
1449 WrappedTargetException
,
1450 RuntimeException
, std::exception
)
1453 // OSL_FAIL( // "PersistentPropertySet::addVetoableChangeListener - N.Y.I." );
1458 void SAL_CALL
PersistentPropertySet::removeVetoableChangeListener(
1460 const Reference
< XVetoableChangeListener
>& )
1461 throw( UnknownPropertyException
,
1462 WrappedTargetException
,
1463 RuntimeException
, std::exception
)
1466 // OSL_FAIL( // "PersistentPropertySet::removeVetoableChangeListener - N.Y.I." );
1471 // XPersistentPropertySet methods.
1476 Reference
< XPropertySetRegistry
> SAL_CALL
PersistentPropertySet::getRegistry()
1477 throw( RuntimeException
, std::exception
)
1479 return Reference
< XPropertySetRegistry
>( m_pImpl
->m_pCreator
);
1484 OUString SAL_CALL
PersistentPropertySet::getKey()
1485 throw( RuntimeException
, std::exception
)
1487 return m_pImpl
->m_aKey
;
1497 OUString SAL_CALL
PersistentPropertySet::getName()
1498 throw( RuntimeException
, std::exception
)
1501 return m_pImpl
->m_aKey
;
1506 void SAL_CALL
PersistentPropertySet::setName( const OUString
& aName
)
1507 throw( RuntimeException
, std::exception
)
1509 if ( aName
!= m_pImpl
->m_aKey
)
1510 m_pImpl
->m_pCreator
->renamePropertySet( m_pImpl
->m_aKey
, aName
);
1515 // XPropertyContainer methods.
1520 void SAL_CALL
PersistentPropertySet::addProperty(
1521 const OUString
& Name
, sal_Int16 Attributes
, const Any
& DefaultValue
)
1522 throw( PropertyExistException
,
1523 IllegalTypeException
,
1524 IllegalArgumentException
,
1525 RuntimeException
, std::exception
)
1527 if ( Name
.isEmpty() )
1528 throw IllegalArgumentException();
1530 // @@@ What other types can't be written to config server?
1532 // Check type class ( Not all types can be written to storage )
1533 TypeClass eTypeClass
= DefaultValue
.getValueTypeClass();
1534 if ( eTypeClass
== TypeClass_INTERFACE
)
1535 throw IllegalTypeException();
1537 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
1539 // Property already in set?
1541 OUString aFullValuesName
;
1543 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
1544 m_pImpl
->m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1545 if ( xRootHierNameAccess
.is() )
1547 aFullValuesName
= getFullKey();
1548 OUString aFullPropName
= aFullValuesName
;
1549 aFullPropName
+= "/";
1550 aFullPropName
+= makeHierarchalNameSegment( Name
);
1552 if ( xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
) )
1555 throw PropertyExistException();
1559 // Property is always removable.
1560 Attributes
|= PropertyAttribute::REMOVABLE
;
1564 Reference
< XSingleServiceFactory
> xFac(
1565 m_pImpl
->m_pCreator
->getConfigWriteAccess( aFullValuesName
),
1567 Reference
< XNameContainer
> xContainer( xFac
, UNO_QUERY
);
1568 Reference
< XChangesBatch
> xBatch(
1569 m_pImpl
->m_pCreator
->getConfigWriteAccess( OUString() ),
1572 OSL_ENSURE( xFac
.is(),
1573 "PersistentPropertySet::addProperty - No factory!" );
1575 OSL_ENSURE( xBatch
.is(),
1576 "PersistentPropertySet::addProperty - No batch!" );
1578 OSL_ENSURE( xContainer
.is(),
1579 "PersistentPropertySet::addProperty - No container!" );
1581 if ( xFac
.is() && xBatch
.is() && xContainer
.is() )
1585 // Create new "PropertyValue" config item.
1586 Reference
< XNameReplace
> xNameReplace(
1587 xFac
->createInstance(), UNO_QUERY
);
1589 if ( xNameReplace
.is() )
1594 xNameReplace
->replaceByName(
1596 makeAny( sal_Int32( -1 ) ) );
1598 // Set default value
1599 xNameReplace
->replaceByName(
1603 // Set state ( always "default" )
1604 xNameReplace
->replaceByName(
1608 PropertyState_DEFAULT_VALUE
) ) );
1611 xNameReplace
->replaceByName(
1612 OUString("Attributes"),
1613 makeAny( sal_Int32( Attributes
) ) );
1616 xContainer
->insertByName( Name
, makeAny( xNameReplace
) );
1619 xBatch
->commitChanges();
1621 // Property set info is invalid.
1622 if ( m_pImpl
->m_pInfo
)
1623 m_pImpl
->m_pInfo
->reset();
1625 // Notify propertyset info change listeners.
1626 if ( m_pImpl
->m_pPropSetChangeListeners
&&
1627 m_pImpl
->m_pPropSetChangeListeners
->getLength() )
1629 PropertySetInfoChangeEvent
evt(
1630 static_cast< OWeakObject
* >( this ),
1633 PropertySetInfoChange::PROPERTY_INSERTED
);
1634 notifyPropertySetInfoChange( evt
);
1641 catch (const IllegalArgumentException
&)
1645 OSL_FAIL( "PersistentPropertySet::addProperty - "
1646 "caught IllegalArgumentException!" );
1649 catch (const ElementExistException
&)
1653 OSL_FAIL( "PersistentPropertySet::addProperty - "
1654 "caught ElementExistException!" );
1657 catch (const WrappedTargetException
&)
1659 // replaceByName, insertByName, commitChanges
1661 OSL_FAIL( "PersistentPropertySet::addProperty - "
1662 "caught WrappedTargetException!" );
1665 catch (const RuntimeException
&)
1669 catch (const Exception
&)
1673 OSL_FAIL( "PersistentPropertySet::addProperty - "
1674 "caught Exception!" );
1679 OSL_FAIL( "PersistentPropertySet::addProperty - Error!" );
1684 void SAL_CALL
PersistentPropertySet::removeProperty( const OUString
& Name
)
1685 throw( UnknownPropertyException
,
1686 NotRemoveableException
,
1687 RuntimeException
, std::exception
)
1689 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
1691 OUString aFullValuesName
;
1692 OUString aFullPropName
;
1694 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
1695 m_pImpl
->m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1696 if ( xRootHierNameAccess
.is() )
1698 aFullValuesName
= getFullKey();
1699 aFullPropName
= aFullValuesName
;
1700 aFullPropName
+= "/";
1701 aFullPropName
+= makeHierarchalNameSegment( Name
);
1704 if ( !xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
) )
1705 throw UnknownPropertyException();
1707 // Property removable?
1710 OUString aFullAttrName
= aFullPropName
;
1711 aFullAttrName
+= "/Attributes";
1713 sal_Int32 nAttribs
= 0;
1714 if ( xRootHierNameAccess
->getByHierarchicalName( aFullAttrName
)
1717 if ( !( nAttribs
& PropertyAttribute::REMOVABLE
) )
1720 throw NotRemoveableException();
1725 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1730 catch (const NoSuchElementException
&)
1732 // getByHierarchicalName
1734 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1735 "caught NoSuchElementException!" );
1738 // Remove property...
1740 Reference
< XNameContainer
> xContainer(
1741 m_pImpl
->m_pCreator
->getConfigWriteAccess( aFullValuesName
),
1743 Reference
< XChangesBatch
> xBatch(
1744 m_pImpl
->m_pCreator
->getConfigWriteAccess( OUString() ),
1747 OSL_ENSURE( xBatch
.is(),
1748 "PersistentPropertySet::removeProperty - No batch!" );
1750 OSL_ENSURE( xContainer
.is(),
1751 "PersistentPropertySet::removeProperty - No container!" );
1753 if ( xBatch
.is() && xContainer
.is() )
1757 sal_Int32 nHandle
= -1;
1759 if ( m_pImpl
->m_pPropSetChangeListeners
&&
1760 m_pImpl
->m_pPropSetChangeListeners
->getLength() )
1762 // Obtain property handle ( needed for propertysetinfo
1763 // change event )...
1767 OUString aFullHandleName
= aFullPropName
;
1771 if ( ! ( xRootHierNameAccess
->getByHierarchicalName(
1772 aFullHandleName
) >>= nHandle
) )
1776 catch (const NoSuchElementException
&)
1778 // getByHierarchicalName
1780 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1781 "caught NoSuchElementException!" );
1786 xContainer
->removeByName( Name
);
1787 xBatch
->commitChanges();
1789 // Property set info is invalid.
1790 if ( m_pImpl
->m_pInfo
)
1791 m_pImpl
->m_pInfo
->reset();
1793 // Notify propertyset info change listeners.
1794 if ( m_pImpl
->m_pPropSetChangeListeners
&&
1795 m_pImpl
->m_pPropSetChangeListeners
->getLength() )
1797 PropertySetInfoChangeEvent
evt(
1798 static_cast< OWeakObject
* >( this ),
1801 PropertySetInfoChange::PROPERTY_REMOVED
);
1802 notifyPropertySetInfoChange( evt
);
1808 catch (const NoSuchElementException
&)
1812 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1813 "caught NoSuchElementException!" );
1816 catch (const WrappedTargetException
&)
1820 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1821 "caught WrappedTargetException!" );
1827 OSL_FAIL( "PersistentPropertySet::removeProperty - Error!" );
1832 // XPropertySetInfoChangeNotifier methods.
1837 void SAL_CALL
PersistentPropertySet::addPropertySetInfoChangeListener(
1838 const Reference
< XPropertySetInfoChangeListener
>& Listener
)
1839 throw( RuntimeException
, std::exception
)
1841 if ( !m_pImpl
->m_pPropSetChangeListeners
)
1842 m_pImpl
->m_pPropSetChangeListeners
=
1843 new OInterfaceContainerHelper( m_pImpl
->m_aMutex
);
1845 m_pImpl
->m_pPropSetChangeListeners
->addInterface( Listener
);
1850 void SAL_CALL
PersistentPropertySet::removePropertySetInfoChangeListener(
1851 const Reference
< XPropertySetInfoChangeListener
>& Listener
)
1852 throw( RuntimeException
, std::exception
)
1854 if ( m_pImpl
->m_pPropSetChangeListeners
)
1855 m_pImpl
->m_pPropSetChangeListeners
->removeInterface( Listener
);
1860 // XPropertyAccess methods.
1865 Sequence
< PropertyValue
> SAL_CALL
PersistentPropertySet::getPropertyValues()
1866 throw( RuntimeException
, std::exception
)
1868 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
1870 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
1871 m_pImpl
->m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1872 if ( xRootHierNameAccess
.is() )
1876 Reference
< XNameAccess
> xNameAccess
;
1877 xRootHierNameAccess
->getByHierarchicalName(getFullKey())
1879 if ( xNameAccess
.is() )
1881 // Obtain property names.
1883 Sequence
< OUString
> aElems
= xNameAccess
->getElementNames();
1885 sal_Int32 nCount
= aElems
.getLength();
1888 Reference
< XHierarchicalNameAccess
> xHierNameAccess(
1889 xNameAccess
, UNO_QUERY
);
1891 OSL_ENSURE( xHierNameAccess
.is(),
1892 "PersistentPropertySet::getPropertyValues - "
1893 "No hierarchical name access!" );
1895 if ( xHierNameAccess
.is() )
1897 Sequence
< PropertyValue
> aValues( nCount
);
1899 const OUString
aHandleName("/Handle");
1900 const OUString
aValueName("/Value");
1901 const OUString
aStateName("/State");
1903 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
1905 PropertyValue
& rValue
= aValues
[ n
];
1906 OUString rName
= aElems
[ n
];
1908 = makeHierarchalNameSegment( rName
);
1910 // Set property name.
1912 rValue
.Name
= rName
;
1916 // Obtain and set property handle
1917 OUString aHierName
= aXMLName
;
1918 aHierName
+= aHandleName
;
1920 = xHierNameAccess
->getByHierarchicalName(
1923 if ( !( aKeyValue
>>= rValue
.Handle
) )
1924 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1925 "Error getting property handle!" );
1927 catch (const NoSuchElementException
&)
1929 // getByHierarchicalName
1931 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1932 "NoSuchElementException!" );
1937 // Obtain and set property value
1938 OUString aHierName
= aXMLName
;
1939 aHierName
+= aValueName
;
1941 = xHierNameAccess
->getByHierarchicalName(
1944 // Note: The value may be void if addProperty
1945 // was called with a default value
1948 catch (const NoSuchElementException
&)
1950 // getByHierarchicalName
1952 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1953 "NoSuchElementException!" );
1958 // Obtain and set property state
1959 OUString aHierName
= aXMLName
;
1960 aHierName
+= aStateName
;
1962 = xHierNameAccess
->getByHierarchicalName(
1965 sal_Int32 nState
= 0;
1966 if ( !( aKeyValue
>>= nState
) )
1967 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1968 "Error getting property state!" );
1970 rValue
.State
= PropertyState( nState
);
1972 catch (const NoSuchElementException
&)
1974 // getByHierarchicalName
1976 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1977 "NoSuchElementException!" );
1986 catch (const NoSuchElementException
&)
1988 // getByHierarchicalName
1992 return Sequence
< PropertyValue
>( 0 );
1997 void SAL_CALL
PersistentPropertySet::setPropertyValues(
1998 const Sequence
< PropertyValue
>& aProps
)
1999 throw( UnknownPropertyException
,
2000 PropertyVetoException
,
2001 IllegalArgumentException
,
2002 WrappedTargetException
,
2003 RuntimeException
, std::exception
)
2005 sal_Int32 nCount
= aProps
.getLength();
2009 osl::ClearableGuard
< osl::Mutex
> aCGuard( m_pImpl
->m_aMutex
);
2011 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
2012 m_pImpl
->m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
2013 if ( xRootHierNameAccess
.is() )
2015 const PropertyValue
* pNewValues
= aProps
.getConstArray();
2017 typedef std::list
< PropertyChangeEvent
> Events
;
2020 OUString
aFullPropNamePrefix( getFullKey() );
2021 aFullPropNamePrefix
+= "/";
2023 // Iterate over given property value sequence.
2024 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
2026 const PropertyValue
& rNewValue
= pNewValues
[ n
];
2027 const OUString
& rName
= rNewValue
.Name
;
2029 OUString aFullPropName
= aFullPropNamePrefix
;
2030 aFullPropName
+= makeHierarchalNameSegment( rName
);
2032 // Does property exist?
2033 if ( xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
) )
2035 Reference
< XNameReplace
> xNameReplace(
2036 m_pImpl
->m_pCreator
->getConfigWriteAccess(
2037 aFullPropName
), UNO_QUERY
);
2038 Reference
< XChangesBatch
> xBatch(
2039 m_pImpl
->m_pCreator
->getConfigWriteAccess(
2040 OUString() ), UNO_QUERY
);
2042 if ( xNameReplace
.is() && xBatch
.is() )
2047 xNameReplace
->replaceByName(
2049 makeAny( rNewValue
.Handle
) );
2052 OUString aValueName
= aFullPropName
;
2053 aValueName
+= "/Value";
2055 = xRootHierNameAccess
->getByHierarchicalName(
2058 xNameReplace
->replaceByName(
2062 // Write state ( Now it is a directly set value )
2063 xNameReplace
->replaceByName(
2067 PropertyState_DIRECT_VALUE
) ) );
2070 xBatch
->commitChanges();
2072 if ( m_pImpl
->m_pPropertyChangeListeners
)
2074 PropertyChangeEvent aEvt
;
2075 aEvt
.Source
= (OWeakObject
*)this;
2076 aEvt
.PropertyName
= rNewValue
.Name
;
2077 aEvt
.PropertyHandle
= rNewValue
.Handle
;
2078 aEvt
.Further
= sal_False
;
2079 aEvt
.OldValue
= aOldValue
;
2080 aEvt
.NewValue
= rNewValue
.Value
;
2082 aEvents
.push_back( aEvt
);
2085 catch (const IllegalArgumentException
&)
2089 catch (const NoSuchElementException
&)
2091 // getByHierarchicalName, replaceByName
2093 catch (const WrappedTargetException
&)
2095 // replaceByName, commitChanges
2101 // Callback follows!
2104 if ( m_pImpl
->m_pPropertyChangeListeners
)
2106 // Notify property changes.
2107 Events::const_iterator it
= aEvents
.begin();
2108 Events::const_iterator end
= aEvents
.end();
2112 notifyPropertyChangeEvent( (*it
) );
2120 OSL_FAIL( "PersistentPropertySet::setPropertyValues - Nothing set!" );
2125 // Non-interface methods
2129 void PersistentPropertySet::notifyPropertyChangeEvent(
2130 const PropertyChangeEvent
& rEvent
) const
2132 // Get "normal" listeners for the property.
2133 OInterfaceContainerHelper
* pContainer
=
2134 m_pImpl
->m_pPropertyChangeListeners
->getContainer(
2135 rEvent
.PropertyName
);
2136 if ( pContainer
&& pContainer
->getLength() )
2138 OInterfaceIteratorHelper
aIter( *pContainer
);
2139 while ( aIter
.hasMoreElements() )
2142 Reference
< XPropertyChangeListener
> xListener(
2143 aIter
.next(), UNO_QUERY
);
2144 if ( xListener
.is() )
2145 xListener
->propertyChange( rEvent
);
2149 // Get "normal" listeners for all properties.
2150 OInterfaceContainerHelper
* pNoNameContainer
=
2151 m_pImpl
->m_pPropertyChangeListeners
->getContainer( OUString() );
2152 if ( pNoNameContainer
&& pNoNameContainer
->getLength() )
2154 OInterfaceIteratorHelper
aIter( *pNoNameContainer
);
2155 while ( aIter
.hasMoreElements() )
2158 Reference
< XPropertyChangeListener
> xListener(
2159 aIter
.next(), UNO_QUERY
);
2160 if ( xListener
.is() )
2161 xListener
->propertyChange( rEvent
);
2167 void PersistentPropertySet::notifyPropertySetInfoChange(
2168 const PropertySetInfoChangeEvent
& evt
) const
2170 if ( !m_pImpl
->m_pPropSetChangeListeners
)
2173 // Notify event listeners.
2174 OInterfaceIteratorHelper
aIter( *( m_pImpl
->m_pPropSetChangeListeners
) );
2175 while ( aIter
.hasMoreElements() )
2178 Reference
< XPropertySetInfoChangeListener
>
2179 xListener( aIter
.next(), UNO_QUERY
);
2180 if ( xListener
.is() )
2181 xListener
->propertySetInfoChange( evt
);
2186 const OUString
& PersistentPropertySet::getFullKey()
2188 if ( m_pImpl
->m_aFullKey
.isEmpty() )
2190 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
2191 if ( m_pImpl
->m_aFullKey
.isEmpty() )
2194 = makeHierarchalNameSegment( m_pImpl
->m_aKey
);
2200 return m_pImpl
->m_aFullKey
;
2204 PropertySetRegistry
& PersistentPropertySet::getPropertySetRegistry()
2206 return *m_pImpl
->m_pCreator
;
2212 // PropertySetInfo_Impl Implementation.
2217 PropertySetInfo_Impl::PropertySetInfo_Impl(
2218 const Reference
< XComponentContext
>& xContext
,
2219 PersistentPropertySet
* pOwner
)
2220 : m_xContext( xContext
),
2228 PropertySetInfo_Impl::~PropertySetInfo_Impl()
2232 // !!! Do not delete m_pOwner !!!
2235 // XPropertySetInfo methods.
2240 Sequence
< Property
> SAL_CALL
PropertySetInfo_Impl::getProperties()
2241 throw( RuntimeException
, std::exception
)
2245 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
2246 m_pOwner
->getPropertySetRegistry().getRootConfigReadAccess(),
2248 if ( xRootHierNameAccess
.is() )
2252 Reference
< XNameAccess
> xNameAccess
;
2253 xRootHierNameAccess
->getByHierarchicalName(
2254 m_pOwner
->getFullKey() )
2256 if ( xNameAccess
.is() )
2258 // Obtain property names.
2260 Sequence
< OUString
> aElems
2261 = xNameAccess
->getElementNames();
2263 sal_uInt32 nCount
= aElems
.getLength();
2264 Sequence
< Property
>* pPropSeq
2265 = new Sequence
< Property
>( nCount
);
2269 Reference
< XHierarchicalNameAccess
> xHierNameAccess(
2270 xNameAccess
, UNO_QUERY
);
2272 OSL_ENSURE( xHierNameAccess
.is(),
2273 "PropertySetInfo_Impl::getProperties - "
2274 "No hierarchical name access!" );
2276 if ( xHierNameAccess
.is() )
2278 const OUString
aHandleName("/Handle");
2279 const OUString
aValueName("/Value");
2280 const OUString
aAttrName("/Attributes");
2282 Property
* pProps
= pPropSeq
->getArray();
2284 for ( sal_uInt32 n
= 0; n
< nCount
; ++n
)
2286 Property
& rProp
= pProps
[ n
];
2287 OUString rName
= aElems
[ n
];
2289 = makeHierarchalNameSegment( rName
);
2291 // Set property name.
2297 // Obtain and set property handle
2298 OUString aHierName
= aXMLName
;
2299 aHierName
+= aHandleName
;
2301 = xHierNameAccess
->getByHierarchicalName(
2304 if ( !( aKeyValue
>>= rProp
.Handle
) )
2305 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2306 "Error getting property handle!" );
2308 catch (const NoSuchElementException
&)
2310 // getByHierarchicalName
2312 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2313 "NoSuchElementException!" );
2318 // Obtain and set property type
2319 OUString aHierName
= aXMLName
;
2320 aHierName
+= aValueName
;
2322 = xHierNameAccess
->getByHierarchicalName(
2325 // Note: The type may be void if addProperty
2326 // was called with a default value
2329 rProp
.Type
= aKeyValue
.getValueType();
2331 catch (const NoSuchElementException
&)
2333 // getByHierarchicalName
2335 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2336 "NoSuchElementException!" );
2341 // Obtain and set property attributes
2342 OUString aHierName
= aXMLName
;
2343 aHierName
+= aAttrName
;
2345 = xHierNameAccess
->getByHierarchicalName(
2348 sal_Int32 nAttribs
= 0;
2349 if ( aKeyValue
>>= nAttribs
)
2351 = sal_Int16( nAttribs
);
2353 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2354 "Error getting property attributes!" );
2356 catch (const NoSuchElementException
&)
2358 // getByHierarchicalName
2360 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2361 "NoSuchElementException!" );
2368 m_pProps
= pPropSeq
;
2372 catch (const NoSuchElementException
&)
2374 // getByHierarchicalName
2378 OSL_FAIL( "PropertySetInfo_Impl::getProperties - Error!" );
2379 m_pProps
= new Sequence
< Property
>( 0 );
2387 Property SAL_CALL
PropertySetInfo_Impl::getPropertyByName(
2388 const OUString
& aName
)
2389 throw( UnknownPropertyException
, RuntimeException
, std::exception
)
2391 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
2392 m_pOwner
->getPropertySetRegistry().getRootConfigReadAccess(),
2394 if ( xRootHierNameAccess
.is() )
2396 OUString
aFullPropName( m_pOwner
->getFullKey() );
2397 aFullPropName
+= "/";
2398 aFullPropName
+= makeHierarchalNameSegment( aName
);
2400 // Does property exist?
2401 if ( !xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
) )
2402 throw UnknownPropertyException();
2409 OUString aKey
= aFullPropName
;
2412 if ( !( xRootHierNameAccess
->getByHierarchicalName( aKey
)
2413 >>= aProp
.Handle
) )
2415 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2420 // Obtain Value and extract type.
2421 aKey
= aFullPropName
;
2424 Any aValue
= xRootHierNameAccess
->getByHierarchicalName( aKey
);
2425 if ( !aValue
.hasValue() )
2427 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2432 aProp
.Type
= aValue
.getValueType();
2434 // Obtain Attributes.
2435 aKey
= aFullPropName
;
2436 aKey
+= "/Attributes";
2438 sal_Int32 nAttribs
= 0;
2439 if ( xRootHierNameAccess
->getByHierarchicalName( aKey
)
2441 aProp
.Attributes
= sal_Int16( nAttribs
);
2444 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2455 catch (const NoSuchElementException
&)
2457 // getByHierarchicalName
2459 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2460 "caught NoSuchElementException!" );
2465 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - Error!" );
2471 sal_Bool SAL_CALL
PropertySetInfo_Impl::hasPropertyByName(
2472 const OUString
& Name
)
2473 throw( RuntimeException
, std::exception
)
2475 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
2476 m_pOwner
->getPropertySetRegistry().getRootConfigReadAccess(),
2478 if ( xRootHierNameAccess
.is() )
2480 OUString
aFullPropName( m_pOwner
->getFullKey() );
2481 aFullPropName
+= "/";
2482 aFullPropName
+= makeHierarchalNameSegment( Name
);
2484 return xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
);
2490 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */