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 <boost/unordered_map.hpp>
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 "ucbstore.hxx"
42 using namespace com::sun::star::beans
;
43 using namespace com::sun::star::configuration
;
44 using namespace com::sun::star::container
;
45 using namespace com::sun::star::lang
;
46 using namespace com::sun::star::ucb
;
47 using namespace com::sun::star::uno
;
48 using namespace com::sun::star::util
;
52 //=========================================================================
53 OUString
makeHierarchalNameSegment( const OUString
& rIn
)
55 OUStringBuffer aBuffer
;
56 aBuffer
.appendAscii( "['" );
58 sal_Int32 nCount
= rIn
.getLength();
59 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
61 const sal_Unicode c
= rIn
[ n
];
65 aBuffer
.appendAscii( "&" );
69 aBuffer
.appendAscii( """ );
73 aBuffer
.appendAscii( "'" );
77 aBuffer
.appendAscii( "<" );
81 aBuffer
.appendAscii( ">" );
90 aBuffer
.appendAscii( "']" );
91 return OUString( aBuffer
.makeStringAndClear() );
94 //=========================================================================
96 #define STORE_CONTENTPROPERTIES_KEY "/org.openoffice.ucb.Store/ContentProperties"
98 // describe path of cfg entry
99 #define CFGPROPERTY_NODEPATH "nodepath"
100 // true->async. update; false->sync. update
101 #define CFGPROPERTY_LAZYWRITE "lazywrite"
103 //=========================================================================
105 struct equalString_Impl
107 bool operator()( const OUString
& s1
, const OUString
& s2
) const
109 return !!( s1
== s2
);
113 struct hashString_Impl
115 size_t operator()( const OUString
& rName
) const
117 return rName
.hashCode();
121 //=========================================================================
123 // PropertySetMap_Impl.
125 //=========================================================================
127 typedef boost::unordered_map
130 PersistentPropertySet
*,
136 //=========================================================================
138 // class PropertySetInfo_Impl
140 //=========================================================================
142 class PropertySetInfo_Impl
:
143 public OWeakObject
, public XTypeProvider
, public XPropertySetInfo
145 Reference
< XComponentContext
> m_xContext
;
146 Sequence
< Property
>* m_pProps
;
147 PersistentPropertySet
* m_pOwner
;
150 PropertySetInfo_Impl( const Reference
< XComponentContext
>& xContext
,
151 PersistentPropertySet
* pOwner
);
152 virtual ~PropertySetInfo_Impl();
161 virtual Sequence
< Property
> SAL_CALL
getProperties()
162 throw( RuntimeException
);
163 virtual Property SAL_CALL
getPropertyByName( const OUString
& aName
)
164 throw( UnknownPropertyException
, RuntimeException
);
165 virtual sal_Bool SAL_CALL
hasPropertyByName( const OUString
& Name
)
166 throw( RuntimeException
);
168 // Non-interface methods.
169 void reset() { delete m_pProps
; m_pProps
= 0; }
172 //=========================================================================
176 //=========================================================================
181 Sequence
< Any
> m_aInitArgs
;
182 Reference
< XPropertySetRegistry
> m_xTheRegistry
;
185 //=========================================================================
186 //=========================================================================
187 //=========================================================================
189 // UcbStore Implementation.
191 //=========================================================================
192 //=========================================================================
193 //=========================================================================
195 UcbStore::UcbStore( const Reference
< XComponentContext
>& xContext
)
196 : m_xContext( xContext
),
197 m_pImpl( new UcbStore_Impl() )
201 //=========================================================================
203 UcbStore::~UcbStore()
208 //=========================================================================
210 // XInterface methods.
212 //=========================================================================
214 XINTERFACE_IMPL_4( UcbStore
,
217 XPropertySetRegistryFactory
,
220 //=========================================================================
222 // XTypeProvider methods.
224 //=========================================================================
226 XTYPEPROVIDER_IMPL_4( UcbStore
,
229 XPropertySetRegistryFactory
,
232 //=========================================================================
234 // XServiceInfo methods.
236 //=========================================================================
238 XSERVICEINFO_IMPL_1_CTX( UcbStore
,
239 OUString( "com.sun.star.comp.ucb.UcbStore" ),
240 OUString( STORE_SERVICE_NAME
) );
242 //=========================================================================
244 // Service factory implementation.
246 //=========================================================================
248 ONE_INSTANCE_SERVICE_FACTORY_IMPL( UcbStore
);
250 //=========================================================================
252 // XPropertySetRegistryFactory methods.
254 //=========================================================================
257 Reference
< XPropertySetRegistry
> SAL_CALL
258 UcbStore::createPropertySetRegistry( const OUString
& )
259 throw( RuntimeException
)
261 // The URL parameter is ignored by this interface implementation. It always
262 // uses the configuration server as storage medium.
264 if ( !m_pImpl
->m_xTheRegistry
.is() )
266 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
267 if ( !m_pImpl
->m_xTheRegistry
.is() )
268 m_pImpl
->m_xTheRegistry
= new PropertySetRegistry( m_xContext
, getInitArgs() );
271 return m_pImpl
->m_xTheRegistry
;
274 //=========================================================================
276 // XInitialization methods.
278 //=========================================================================
281 void SAL_CALL
UcbStore::initialize( const Sequence
< Any
>& aArguments
)
282 throw( Exception
, RuntimeException
)
284 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
285 m_pImpl
->m_aInitArgs
= aArguments
;
288 //=========================================================================
289 const Sequence
< Any
>& UcbStore::getInitArgs() const
291 return m_pImpl
->m_aInitArgs
;
294 //=========================================================================
296 // PropertySetRegistry_Impl.
298 //=========================================================================
300 struct PropertySetRegistry_Impl
302 const Sequence
< Any
> m_aInitArgs
;
303 PropertySetMap_Impl m_aPropSets
;
304 Reference
< XMultiServiceFactory
> m_xConfigProvider
;
305 Reference
< XInterface
> m_xRootReadAccess
;
306 Reference
< XInterface
> m_xRootWriteAccess
;
308 sal_Bool m_bTriedToGetRootReadAccess
; // #82494#
309 sal_Bool m_bTriedToGetRootWriteAccess
; // #82494#
311 PropertySetRegistry_Impl( const Sequence
< Any
> &rInitArgs
)
312 : m_aInitArgs( rInitArgs
),
313 m_bTriedToGetRootReadAccess( sal_False
),
314 m_bTriedToGetRootWriteAccess( sal_False
)
319 //=========================================================================
320 //=========================================================================
321 //=========================================================================
323 // PropertySetRegistry Implementation.
325 //=========================================================================
326 //=========================================================================
327 //=========================================================================
329 PropertySetRegistry::PropertySetRegistry(
330 const Reference
< XComponentContext
>& xContext
,
331 const Sequence
< Any
> &rInitArgs
)
332 : m_xContext( xContext
),
333 m_pImpl( new PropertySetRegistry_Impl( rInitArgs
) )
337 //=========================================================================
339 PropertySetRegistry::~PropertySetRegistry()
344 //=========================================================================
346 // XInterface methods.
348 //=========================================================================
350 XINTERFACE_IMPL_5( PropertySetRegistry
,
353 XPropertySetRegistry
,
354 XElementAccess
, /* base of XNameAccess */
357 //=========================================================================
359 // XTypeProvider methods.
361 //=========================================================================
363 XTYPEPROVIDER_IMPL_4( PropertySetRegistry
,
366 XPropertySetRegistry
,
369 //=========================================================================
371 // XServiceInfo methods.
373 //=========================================================================
375 XSERVICEINFO_NOFACTORY_IMPL_1( PropertySetRegistry
,
376 OUString( "com.sun.star.comp.ucb.PropertySetRegistry" ),
377 OUString( PROPSET_REG_SERVICE_NAME
) );
379 //=========================================================================
381 // XPropertySetRegistry methods.
383 //=========================================================================
386 Reference
< XPersistentPropertySet
> SAL_CALL
387 PropertySetRegistry::openPropertySet( const OUString
& key
, sal_Bool create
)
388 throw( RuntimeException
)
390 if ( !key
.isEmpty() )
392 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
394 PropertySetMap_Impl
& rSets
= m_pImpl
->m_aPropSets
;
396 PropertySetMap_Impl::const_iterator it
= rSets
.find( key
);
397 if ( it
!= rSets
.end() )
399 // Already instanciated.
400 return Reference
< XPersistentPropertySet
>( (*it
).second
);
404 // Create new instance.
405 Reference
< XNameAccess
> xRootNameAccess(
406 getRootConfigReadAccess(), UNO_QUERY
);
407 if ( xRootNameAccess
.is() )
409 // Propertyset in registry?
410 if ( xRootNameAccess
->hasByName( key
) )
413 return Reference
< XPersistentPropertySet
>(
414 new PersistentPropertySet(
415 m_xContext
, *this, key
) );
419 // No. Create entry for propertyset.
421 Reference
< XSingleServiceFactory
> xFac(
422 getConfigWriteAccess( OUString() ), UNO_QUERY
);
423 Reference
< XChangesBatch
> xBatch( xFac
, UNO_QUERY
);
424 Reference
< XNameContainer
> xContainer( xFac
, UNO_QUERY
);
426 OSL_ENSURE( xFac
.is(),
427 "PropertySetRegistry::openPropertySet - "
430 OSL_ENSURE( xBatch
.is(),
431 "PropertySetRegistry::openPropertySet - "
434 OSL_ENSURE( xContainer
.is(),
435 "PropertySetRegistry::openPropertySet - "
438 if ( xFac
.is() && xBatch
.is() && xContainer
.is() )
442 // Create new "Properties" config item.
443 Reference
< XNameReplace
> xNameReplace(
444 xFac
->createInstance(), UNO_QUERY
);
446 if ( xNameReplace
.is() )
451 // xNameReplace->replaceByName(
452 // OUString("Values"),
456 xContainer
->insertByName(
457 key
, makeAny( xNameReplace
) );
459 xBatch
->commitChanges();
461 return Reference
< XPersistentPropertySet
>(
462 new PersistentPropertySet(
463 m_xContext
, *this, key
) );
466 catch (const IllegalArgumentException
&)
470 OSL_FAIL( "PropertySetRegistry::openPropertySet - "
471 "caught IllegalArgumentException!" );
473 catch (const ElementExistException
&)
477 OSL_FAIL( "PropertySetRegistry::openPropertySet - "
478 "caught ElementExistException!" );
480 catch (const WrappedTargetException
&)
482 // insertByName, commitChanges
484 OSL_FAIL( "PropertySetRegistry::openPropertySet - "
485 "caught WrappedTargetException!" );
487 catch (const RuntimeException
&)
489 OSL_FAIL( "PropertySetRegistry::openPropertySet - "
490 "caught RuntimeException!" );
492 catch (const Exception
&)
496 OSL_FAIL( "PropertySetRegistry::openPropertySet - "
497 "caught Exception!" );
503 // No entry. Fail, but no error.
504 return Reference
< XPersistentPropertySet
>();
508 OSL_TRACE( "PropertySetRegistry::openPropertySet no root access" );
512 return Reference
< XPersistentPropertySet
>();
515 //=========================================================================
517 void SAL_CALL
PropertySetRegistry::removePropertySet( const OUString
& key
)
518 throw( RuntimeException
)
523 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
525 Reference
< XNameAccess
> xRootNameAccess(
526 getRootConfigReadAccess(), UNO_QUERY
);
527 if ( xRootNameAccess
.is() )
529 // Propertyset in registry?
530 if ( !xRootNameAccess
->hasByName( key
) )
532 Reference
< XChangesBatch
> xBatch(
533 getConfigWriteAccess( OUString() ), UNO_QUERY
);
534 Reference
< XNameContainer
> xContainer( xBatch
, UNO_QUERY
);
536 if ( xBatch
.is() && xContainer
.is() )
541 xContainer
->removeByName( key
);
543 xBatch
->commitChanges();
548 catch (const NoSuchElementException
&)
552 OSL_FAIL( "PropertySetRegistry::removePropertySet - "
553 "caught NoSuchElementException!" );
556 catch (const WrappedTargetException
&)
560 OSL_FAIL( "PropertySetRegistry::removePropertySet - "
561 "caught WrappedTargetException!" );
569 OSL_TRACE( "PropertySetRegistry::removePropertySet - no root access" );
572 //=========================================================================
574 // XElementAccess methods.
576 //=========================================================================
579 com::sun::star::uno::Type SAL_CALL
PropertySetRegistry::getElementType()
580 throw( RuntimeException
)
582 return getCppuType( ( Reference
< XPersistentPropertySet
> * ) 0 );
585 //=========================================================================
587 sal_Bool SAL_CALL
PropertySetRegistry::hasElements()
588 throw( RuntimeException
)
590 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
592 Reference
< XElementAccess
> xElemAccess(
593 getRootConfigReadAccess(), UNO_QUERY
);
594 if ( xElemAccess
.is() )
595 return xElemAccess
->hasElements();
600 //=========================================================================
602 // XNameAccess methods.
604 //=========================================================================
607 Any SAL_CALL
PropertySetRegistry::getByName( const OUString
& aName
)
608 throw( NoSuchElementException
, WrappedTargetException
, RuntimeException
)
610 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
612 Reference
< XNameAccess
> xNameAccess(
613 getRootConfigReadAccess(), UNO_QUERY
);
614 if ( xNameAccess
.is() )
619 return xNameAccess
->getByName( aName
);
621 catch (const NoSuchElementException
&)
625 catch (const WrappedTargetException
&)
634 //=========================================================================
636 Sequence
< OUString
> SAL_CALL
PropertySetRegistry::getElementNames()
637 throw( RuntimeException
)
639 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
641 Reference
< XNameAccess
> xNameAccess(
642 getRootConfigReadAccess(), UNO_QUERY
);
643 if ( xNameAccess
.is() )
645 return xNameAccess
->getElementNames();
647 return Sequence
< OUString
>( 0 );
650 //=========================================================================
652 sal_Bool SAL_CALL
PropertySetRegistry::hasByName( const OUString
& aName
)
653 throw( RuntimeException
)
655 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
657 Reference
< XNameAccess
> xNameAccess(
658 getRootConfigReadAccess(), UNO_QUERY
);
659 if ( xNameAccess
.is() )
661 return xNameAccess
->hasByName( aName
);
667 //=========================================================================
668 void PropertySetRegistry::add( PersistentPropertySet
* pSet
)
670 OUString
key( pSet
->getKey() );
672 if ( !key
.isEmpty() )
674 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
675 m_pImpl
->m_aPropSets
[ key
] = pSet
;
679 //=========================================================================
680 void PropertySetRegistry::remove( PersistentPropertySet
* pSet
)
682 OUString
key( pSet
->getKey() );
684 if ( !key
.isEmpty() )
686 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
688 PropertySetMap_Impl
& rSets
= m_pImpl
->m_aPropSets
;
690 PropertySetMap_Impl::iterator it
= rSets
.find( key
);
691 if ( it
!= rSets
.end() )
699 //=========================================================================
700 void PropertySetRegistry::renamePropertySet( const OUString
& rOldKey
,
701 const OUString
& rNewKey
)
703 if ( rOldKey
== rNewKey
)
706 Reference
< XNameAccess
> xRootNameAccess(
707 getConfigWriteAccess( OUString() ), UNO_QUERY
);
708 if ( xRootNameAccess
.is() )
711 if ( xRootNameAccess
->hasByName( rOldKey
) )
713 // New key not present?
714 if ( xRootNameAccess
->hasByName( rNewKey
) )
716 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
720 Reference
< XSingleServiceFactory
> xFac(
721 xRootNameAccess
, UNO_QUERY
);
722 Reference
< XChangesBatch
> xBatch( xFac
, UNO_QUERY
);
723 Reference
< XNameContainer
> xContainer( xFac
, UNO_QUERY
);
725 OSL_ENSURE( xFac
.is(),
726 "PropertySetRegistry::renamePropertySet - "
729 OSL_ENSURE( xBatch
.is(),
730 "PropertySetRegistry::renamePropertySet - "
733 OSL_ENSURE( xContainer
.is(),
734 "PropertySetRegistry::renamePropertySet - "
737 if ( xFac
.is() && xBatch
.is() && xContainer
.is() )
739 //////////////////////////////////////////////////////
740 // Create new "Properties" config item.
741 //////////////////////////////////////////////////////
745 Reference
< XNameReplace
> xNameReplace(
746 xFac
->createInstance(), UNO_QUERY
);
748 if ( xNameReplace
.is() )
751 xContainer
->insertByName(
752 rNewKey
, makeAny( xNameReplace
) );
754 xBatch
->commitChanges();
757 catch (const IllegalArgumentException
&)
761 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
762 "caught IllegalArgumentException!" );
765 catch (const ElementExistException
&)
769 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
770 "caught ElementExistException!" );
773 catch (const WrappedTargetException
&)
775 // insertByName, commitChanges
777 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
778 "caught WrappedTargetException!" );
781 catch (const RuntimeException
&)
783 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
784 "caught RuntimeException!" );
787 catch (const Exception
&)
791 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
792 "caught Exception!" );
796 //////////////////////////////////////////////////////
798 //////////////////////////////////////////////////////
800 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
801 xRootNameAccess
, UNO_QUERY
);
802 if ( !xRootHierNameAccess
.is() )
804 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
805 "No hierarchical name access!" );
811 OUString aOldValuesKey
812 = makeHierarchalNameSegment( rOldKey
);
813 aOldValuesKey
+= "/Values";
815 Reference
< XNameAccess
> xOldNameAccess
;
816 xRootHierNameAccess
->getByHierarchicalName(
819 if ( !xOldNameAccess
.is() )
821 OSL_FAIL( "PersistentPropertySet::renamePropertySet - "
822 "No old name access!" );
826 // Obtain property names.
827 Sequence
< OUString
> aElems
828 = xOldNameAccess
->getElementNames();
829 sal_Int32 nCount
= aElems
.getLength();
832 OUString aNewValuesKey
833 = makeHierarchalNameSegment( rNewKey
);
834 aNewValuesKey
+= "/Values";
836 Reference
< XSingleServiceFactory
> xNewFac
;
837 xRootHierNameAccess
->getByHierarchicalName(
842 OSL_FAIL( "PersistentPropertySet::renamePropertySet - "
847 Reference
< XNameContainer
> xNewContainer(
848 xNewFac
, UNO_QUERY
);
849 if ( !xNewContainer
.is() )
851 OSL_FAIL( "PersistentPropertySet::renamePropertySet - "
852 "No new container!" );
856 aOldValuesKey
+= "/";
858 OUString
aHandleKey("/Handle");
859 OUString
aValueKey("/Value");
860 OUString
aStateKey("/State");
861 OUString
aAttrKey("/Attributes");
863 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
865 const OUString
& rPropName
= aElems
[ n
];
868 Reference
< XNameReplace
> xNewPropNameReplace(
869 xNewFac
->createInstance(), UNO_QUERY
);
871 if ( !xNewPropNameReplace
.is() )
873 OSL_FAIL( "PersistentPropertySet::renamePropertySet - "
874 "No new prop name replace!" );
881 OUString aKey
= aOldValuesKey
;
882 aKey
+= makeHierarchalNameSegment( rPropName
);
885 OUString aNewKey1
= aKey
;
886 aNewKey1
+= aHandleKey
;
888 xRootHierNameAccess
->getByHierarchicalName(
890 xNewPropNameReplace
->replaceByName(
896 aNewKey1
+= aValueKey
;
898 xRootHierNameAccess
->getByHierarchicalName(
900 xNewPropNameReplace
->replaceByName(
906 aNewKey1
+= aStateKey
;
908 xRootHierNameAccess
->getByHierarchicalName(
910 xNewPropNameReplace
->replaceByName(
916 aNewKey1
+= aAttrKey
;
918 xRootHierNameAccess
->getByHierarchicalName(
920 xNewPropNameReplace
->replaceByName(
921 OUString("Attributes"),
925 xNewContainer
->insertByName(
926 rPropName
, makeAny( xNewPropNameReplace
) );
929 xBatch
->commitChanges();
933 catch (const IllegalArgumentException
&)
935 // insertByName, replaceByName
937 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
938 "caught IllegalArgumentException!" );
941 catch (const ElementExistException
&)
945 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
946 "caught ElementExistException!" );
949 catch (const WrappedTargetException
&)
951 // insertByName, replaceByName, commitChanges
953 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
954 "caught WrappedTargetException!" );
957 catch (const NoSuchElementException
&)
959 // getByHierarchicalName, replaceByName
961 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
962 "caught NoSuchElementException!" );
965 catch (const RuntimeException
&)
967 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
968 "caught RuntimeException!" );
971 catch (const Exception
&)
975 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
976 "caught Exception!" );
980 //////////////////////////////////////////////////////
981 // Remove old entry...
982 //////////////////////////////////////////////////////
987 xContainer
->removeByName( rOldKey
);
989 xBatch
->commitChanges();
994 catch (const NoSuchElementException
&)
998 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
999 "caught NoSuchElementException!" );
1002 catch (const WrappedTargetException
&)
1006 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
1007 "caught WrappedTargetException!" );
1014 OSL_FAIL( "PropertySetRegistry::renamePropertySet - Error!" );
1017 //=========================================================================
1018 Reference
< XMultiServiceFactory
> PropertySetRegistry::getConfigProvider()
1020 if ( !m_pImpl
->m_xConfigProvider
.is() )
1022 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
1023 if ( !m_pImpl
->m_xConfigProvider
.is() )
1025 const Sequence
< Any
>& rInitArgs
= m_pImpl
->m_aInitArgs
;
1027 if ( rInitArgs
.getLength() > 0 )
1029 // Extract config provider from service init args.
1030 rInitArgs
[ 0 ] >>= m_pImpl
->m_xConfigProvider
;
1032 OSL_ENSURE( m_pImpl
->m_xConfigProvider
.is(),
1033 "PropertySetRegistry::getConfigProvider - "
1034 "No config provider!" );
1040 m_pImpl
->m_xConfigProvider
= theDefaultProvider::get( m_xContext
);
1042 catch (const Exception
&)
1044 OSL_TRACE( "PropertySetRegistry::getConfigProvider - "
1045 "caught exception!" );
1051 return m_pImpl
->m_xConfigProvider
;
1054 //=========================================================================
1055 Reference
< XInterface
> PropertySetRegistry::getRootConfigReadAccess()
1059 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
1061 if ( !m_pImpl
->m_xRootReadAccess
.is() )
1063 if ( m_pImpl
->m_bTriedToGetRootReadAccess
) // #82494#
1065 OSL_FAIL( "PropertySetRegistry::getRootConfigReadAccess - "
1066 "Unable to read any config data! -> #82494#" );
1067 return Reference
< XInterface
>();
1070 getConfigProvider();
1072 if ( m_pImpl
->m_xConfigProvider
.is() )
1074 Sequence
< Any
> aArguments( 1 );
1075 PropertyValue aProperty
;
1077 = OUString( CFGPROPERTY_NODEPATH
);
1079 <<= OUString( STORE_CONTENTPROPERTIES_KEY
);
1080 aArguments
[ 0 ] <<= aProperty
;
1082 m_pImpl
->m_bTriedToGetRootReadAccess
= sal_True
;
1084 m_pImpl
->m_xRootReadAccess
=
1085 m_pImpl
->m_xConfigProvider
->createInstanceWithArguments(
1086 OUString( "com.sun.star.configuration.ConfigurationAccess" ),
1089 if ( m_pImpl
->m_xRootReadAccess
.is() )
1090 return m_pImpl
->m_xRootReadAccess
;
1094 return m_pImpl
->m_xRootReadAccess
;
1096 catch (const RuntimeException
&)
1100 catch (const Exception
&)
1102 // createInstance, createInstanceWithArguments
1104 OSL_FAIL( "PropertySetRegistry::getRootConfigReadAccess - caught Exception!" );
1105 return Reference
< XInterface
>();
1108 OSL_TRACE( "PropertySetRegistry::getRootConfigReadAccess - Error!" );
1109 return Reference
< XInterface
>();
1112 //=========================================================================
1113 Reference
< XInterface
> PropertySetRegistry::getConfigWriteAccess(
1114 const OUString
& rPath
)
1118 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
1120 if ( !m_pImpl
->m_xRootWriteAccess
.is() )
1122 if ( m_pImpl
->m_bTriedToGetRootWriteAccess
) // #82494#
1124 OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - "
1125 "Unable to write any config data! -> #82494#" );
1126 return Reference
< XInterface
>();
1129 getConfigProvider();
1131 if ( m_pImpl
->m_xConfigProvider
.is() )
1133 Sequence
< Any
> aArguments( 2 );
1134 PropertyValue aProperty
;
1136 aProperty
.Name
= OUString( CFGPROPERTY_NODEPATH
);
1137 aProperty
.Value
<<= OUString( STORE_CONTENTPROPERTIES_KEY
);
1138 aArguments
[ 0 ] <<= aProperty
;
1140 aProperty
.Name
= OUString( CFGPROPERTY_LAZYWRITE
);
1141 aProperty
.Value
<<= sal_True
;
1142 aArguments
[ 1 ] <<= aProperty
;
1144 m_pImpl
->m_bTriedToGetRootWriteAccess
= sal_True
;
1146 m_pImpl
->m_xRootWriteAccess
=
1147 m_pImpl
->m_xConfigProvider
->createInstanceWithArguments(
1148 OUString( "com.sun.star.configuration.ConfigurationUpdateAccess" ),
1151 OSL_ENSURE( m_pImpl
->m_xRootWriteAccess
.is(),
1152 "PropertySetRegistry::getConfigWriteAccess - "
1153 "No config update access!" );
1157 if ( m_pImpl
->m_xRootWriteAccess
.is() )
1159 if ( !rPath
.isEmpty() )
1161 Reference
< XHierarchicalNameAccess
> xNA(
1162 m_pImpl
->m_xRootWriteAccess
, UNO_QUERY
);
1165 Reference
< XInterface
> xInterface
;
1166 xNA
->getByHierarchicalName( rPath
) >>= xInterface
;
1168 if ( xInterface
.is() )
1173 return m_pImpl
->m_xRootWriteAccess
;
1176 catch (const RuntimeException
&)
1180 catch (const NoSuchElementException
&)
1182 // getByHierarchicalName
1184 OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - "
1185 "caught NoSuchElementException!" );
1186 return Reference
< XInterface
>();
1188 catch (const Exception
&)
1190 // createInstance, createInstanceWithArguments
1192 OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - "
1193 "caught Exception!" );
1194 return Reference
< XInterface
>();
1197 OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - Error!" );
1198 return Reference
< XInterface
>();
1201 //=========================================================================
1203 // PropertyListeners_Impl.
1205 //=========================================================================
1207 typedef OMultiTypeInterfaceContainerHelperVar
1212 > PropertyListeners_Impl
;
1214 //=========================================================================
1216 // PersistentPropertySet_Impl.
1218 //=========================================================================
1220 struct PersistentPropertySet_Impl
1222 PropertySetRegistry
* m_pCreator
;
1223 PropertySetInfo_Impl
* m_pInfo
;
1225 OUString m_aFullKey
;
1226 osl::Mutex m_aMutex
;
1227 OInterfaceContainerHelper
* m_pDisposeEventListeners
;
1228 OInterfaceContainerHelper
* m_pPropSetChangeListeners
;
1229 PropertyListeners_Impl
* m_pPropertyChangeListeners
;
1231 PersistentPropertySet_Impl( PropertySetRegistry
& rCreator
,
1232 const OUString
& rKey
)
1233 : m_pCreator( &rCreator
), m_pInfo( NULL
), m_aKey( rKey
),
1234 m_pDisposeEventListeners( NULL
), m_pPropSetChangeListeners( NULL
),
1235 m_pPropertyChangeListeners( NULL
)
1237 m_pCreator
->acquire();
1240 ~PersistentPropertySet_Impl()
1242 m_pCreator
->release();
1247 delete m_pDisposeEventListeners
;
1248 delete m_pPropSetChangeListeners
;
1249 delete m_pPropertyChangeListeners
;
1253 //=========================================================================
1254 //=========================================================================
1255 //=========================================================================
1257 // PersistentPropertySet Implementation.
1259 //=========================================================================
1260 //=========================================================================
1261 //=========================================================================
1263 PersistentPropertySet::PersistentPropertySet(
1264 const Reference
< XComponentContext
>& xContext
,
1265 PropertySetRegistry
& rCreator
,
1266 const OUString
& rKey
)
1267 : m_xContext( xContext
),
1268 m_pImpl( new PersistentPropertySet_Impl( rCreator
, rKey
) )
1270 // register at creator.
1271 rCreator
.add( this );
1274 //=========================================================================
1276 PersistentPropertySet::~PersistentPropertySet()
1278 // deregister at creator.
1279 m_pImpl
->m_pCreator
->remove( this );
1284 //=========================================================================
1286 // XInterface methods.
1288 //=========================================================================
1290 XINTERFACE_IMPL_9( PersistentPropertySet
,
1294 XPropertySet
, /* base of XPersistentPropertySet */
1296 XPersistentPropertySet
,
1298 XPropertySetInfoChangeNotifier
,
1301 //=========================================================================
1303 // XTypeProvider methods.
1305 //=========================================================================
1307 XTYPEPROVIDER_IMPL_8( PersistentPropertySet
,
1311 XPersistentPropertySet
,
1314 XPropertySetInfoChangeNotifier
,
1317 //=========================================================================
1319 // XServiceInfo methods.
1321 //=========================================================================
1323 XSERVICEINFO_NOFACTORY_IMPL_1( PersistentPropertySet
,
1324 OUString( "com.sun.star.comp.ucb.PersistentPropertySet" ),
1325 OUString( PERS_PROPSET_SERVICE_NAME
) );
1327 //=========================================================================
1329 // XComponent methods.
1331 //=========================================================================
1334 void SAL_CALL
PersistentPropertySet::dispose()
1335 throw( RuntimeException
)
1337 if ( m_pImpl
->m_pDisposeEventListeners
&&
1338 m_pImpl
->m_pDisposeEventListeners
->getLength() )
1341 aEvt
.Source
= static_cast< XComponent
* >( this );
1342 m_pImpl
->m_pDisposeEventListeners
->disposeAndClear( aEvt
);
1345 if ( m_pImpl
->m_pPropSetChangeListeners
&&
1346 m_pImpl
->m_pPropSetChangeListeners
->getLength() )
1349 aEvt
.Source
= static_cast< XPropertySetInfoChangeNotifier
* >( this );
1350 m_pImpl
->m_pPropSetChangeListeners
->disposeAndClear( aEvt
);
1353 if ( m_pImpl
->m_pPropertyChangeListeners
)
1356 aEvt
.Source
= static_cast< XPropertySet
* >( this );
1357 m_pImpl
->m_pPropertyChangeListeners
->disposeAndClear( aEvt
);
1361 //=========================================================================
1363 void SAL_CALL
PersistentPropertySet::addEventListener(
1364 const Reference
< XEventListener
>& Listener
)
1365 throw( RuntimeException
)
1367 if ( !m_pImpl
->m_pDisposeEventListeners
)
1368 m_pImpl
->m_pDisposeEventListeners
=
1369 new OInterfaceContainerHelper( m_pImpl
->m_aMutex
);
1371 m_pImpl
->m_pDisposeEventListeners
->addInterface( Listener
);
1374 //=========================================================================
1376 void SAL_CALL
PersistentPropertySet::removeEventListener(
1377 const Reference
< XEventListener
>& Listener
)
1378 throw( RuntimeException
)
1380 if ( m_pImpl
->m_pDisposeEventListeners
)
1381 m_pImpl
->m_pDisposeEventListeners
->removeInterface( Listener
);
1383 // Note: Don't want to delete empty container here -> performance.
1386 //=========================================================================
1388 // XPropertySet methods.
1390 //=========================================================================
1393 Reference
< XPropertySetInfo
> SAL_CALL
1394 PersistentPropertySet::getPropertySetInfo()
1395 throw( RuntimeException
)
1397 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
1399 PropertySetInfo_Impl
*& rpInfo
= m_pImpl
->m_pInfo
;
1402 rpInfo
= new PropertySetInfo_Impl( m_xContext
, this );
1405 return Reference
< XPropertySetInfo
>( rpInfo
);
1408 //=========================================================================
1410 void SAL_CALL
PersistentPropertySet::setPropertyValue(
1411 const OUString
& aPropertyName
, const Any
& aValue
)
1412 throw( UnknownPropertyException
,
1413 PropertyVetoException
,
1414 IllegalArgumentException
,
1415 WrappedTargetException
,
1418 if ( aPropertyName
.isEmpty() )
1419 throw UnknownPropertyException();
1421 osl::ClearableGuard
< osl::Mutex
> aCGuard( m_pImpl
->m_aMutex
);
1423 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
1424 m_pImpl
->m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1425 if ( xRootHierNameAccess
.is() )
1427 OUString
aFullPropName( getFullKey() );
1428 aFullPropName
+= "/";
1429 aFullPropName
+= makeHierarchalNameSegment( aPropertyName
);
1431 // Does property exist?
1432 if ( xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
) )
1434 Reference
< XNameReplace
> xNameReplace(
1435 m_pImpl
->m_pCreator
->getConfigWriteAccess(
1436 aFullPropName
), UNO_QUERY
);
1437 Reference
< XChangesBatch
> xBatch(
1438 m_pImpl
->m_pCreator
->getConfigWriteAccess(
1439 OUString() ), UNO_QUERY
);
1441 if ( xNameReplace
.is() && xBatch
.is() )
1446 OUString aValueName
= aFullPropName
;
1447 aValueName
+= "/Value";
1449 = xRootHierNameAccess
->getByHierarchicalName(
1451 // Check value type.
1452 if ( aOldValue
.getValueType() != aValue
.getValueType() )
1455 throw IllegalArgumentException();
1459 xNameReplace
->replaceByName(
1463 // Write state ( Now it is a directly set value )
1464 xNameReplace
->replaceByName(
1468 PropertyState_DIRECT_VALUE
) ) );
1471 xBatch
->commitChanges();
1473 PropertyChangeEvent aEvt
;
1474 if ( m_pImpl
->m_pPropertyChangeListeners
)
1477 aValueName
= aFullPropName
;
1478 aValueName
+= "/Handle";
1479 sal_Int32 nHandle
= -1;
1480 xRootHierNameAccess
->getByHierarchicalName( aValueName
)
1483 aEvt
.Source
= (OWeakObject
*)this;
1484 aEvt
.PropertyName
= aPropertyName
;
1485 aEvt
.PropertyHandle
= nHandle
;
1486 aEvt
.Further
= sal_False
;
1487 aEvt
.OldValue
= aOldValue
;
1488 aEvt
.NewValue
= aValue
;
1490 // Callback follows!
1493 notifyPropertyChangeEvent( aEvt
);
1497 catch (const IllegalArgumentException
&)
1501 catch (const NoSuchElementException
&)
1503 // getByHierarchicalName, replaceByName
1505 catch (const WrappedTargetException
&)
1507 // replaceByName, commitChanges
1513 throw UnknownPropertyException();
1516 //=========================================================================
1518 Any SAL_CALL
PersistentPropertySet::getPropertyValue(
1519 const OUString
& PropertyName
)
1520 throw( UnknownPropertyException
,
1521 WrappedTargetException
,
1524 if ( PropertyName
.isEmpty() )
1525 throw UnknownPropertyException();
1527 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
1529 Reference
< XHierarchicalNameAccess
> xNameAccess(
1530 m_pImpl
->m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1531 if ( xNameAccess
.is() )
1533 OUString
aFullPropName( getFullKey() );
1534 aFullPropName
+= "/";
1535 aFullPropName
+= makeHierarchalNameSegment( PropertyName
);
1536 aFullPropName
+= "/Value";
1539 return xNameAccess
->getByHierarchicalName( aFullPropName
);
1541 catch (const NoSuchElementException
&)
1543 throw UnknownPropertyException();
1547 throw UnknownPropertyException();
1550 //=========================================================================
1552 void SAL_CALL
PersistentPropertySet::addPropertyChangeListener(
1553 const OUString
& aPropertyName
,
1554 const Reference
< XPropertyChangeListener
>& xListener
)
1555 throw( UnknownPropertyException
,
1556 WrappedTargetException
,
1561 if ( !m_pImpl
->m_pPropertyChangeListeners
)
1562 m_pImpl
->m_pPropertyChangeListeners
=
1563 new PropertyListeners_Impl( m_pImpl
->m_aMutex
);
1565 m_pImpl
->m_pPropertyChangeListeners
->addInterface(
1566 aPropertyName
, xListener
);
1569 //=========================================================================
1571 void SAL_CALL
PersistentPropertySet::removePropertyChangeListener(
1572 const OUString
& aPropertyName
,
1573 const Reference
< XPropertyChangeListener
>& aListener
)
1574 throw( UnknownPropertyException
,
1575 WrappedTargetException
,
1580 if ( m_pImpl
->m_pPropertyChangeListeners
)
1581 m_pImpl
->m_pPropertyChangeListeners
->removeInterface(
1582 aPropertyName
, aListener
);
1584 // Note: Don't want to delete empty container here -> performance.
1587 //=========================================================================
1589 void SAL_CALL
PersistentPropertySet::addVetoableChangeListener(
1591 const Reference
< XVetoableChangeListener
>& )
1592 throw( UnknownPropertyException
,
1593 WrappedTargetException
,
1597 // OSL_FAIL( // "PersistentPropertySet::addVetoableChangeListener - N.Y.I." );
1600 //=========================================================================
1602 void SAL_CALL
PersistentPropertySet::removeVetoableChangeListener(
1604 const Reference
< XVetoableChangeListener
>& )
1605 throw( UnknownPropertyException
,
1606 WrappedTargetException
,
1610 // OSL_FAIL( // "PersistentPropertySet::removeVetoableChangeListener - N.Y.I." );
1613 //=========================================================================
1615 // XPersistentPropertySet methods.
1617 //=========================================================================
1620 Reference
< XPropertySetRegistry
> SAL_CALL
PersistentPropertySet::getRegistry()
1621 throw( RuntimeException
)
1623 return Reference
< XPropertySetRegistry
>( m_pImpl
->m_pCreator
);
1626 //=========================================================================
1628 OUString SAL_CALL
PersistentPropertySet::getKey()
1629 throw( RuntimeException
)
1631 return m_pImpl
->m_aKey
;
1634 //=========================================================================
1638 //=========================================================================
1641 OUString SAL_CALL
PersistentPropertySet::getName()
1642 throw( RuntimeException
)
1645 return m_pImpl
->m_aKey
;
1648 //=========================================================================
1650 void SAL_CALL
PersistentPropertySet::setName( const OUString
& aName
)
1651 throw( RuntimeException
)
1653 if ( aName
!= m_pImpl
->m_aKey
)
1654 m_pImpl
->m_pCreator
->renamePropertySet( m_pImpl
->m_aKey
, aName
);
1657 //=========================================================================
1659 // XPropertyContainer methods.
1661 //=========================================================================
1664 void SAL_CALL
PersistentPropertySet::addProperty(
1665 const OUString
& Name
, sal_Int16 Attributes
, const Any
& DefaultValue
)
1666 throw( PropertyExistException
,
1667 IllegalTypeException
,
1668 IllegalArgumentException
,
1671 if ( Name
.isEmpty() )
1672 throw IllegalArgumentException();
1674 // @@@ What other types can't be written to config server?
1676 // Check type class ( Not all types can be written to storage )
1677 TypeClass eTypeClass
= DefaultValue
.getValueTypeClass();
1678 if ( eTypeClass
== TypeClass_INTERFACE
)
1679 throw IllegalTypeException();
1681 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
1683 // Property already in set?
1685 OUString aFullValuesName
;
1687 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
1688 m_pImpl
->m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1689 if ( xRootHierNameAccess
.is() )
1691 aFullValuesName
= getFullKey();
1692 OUString aFullPropName
= aFullValuesName
;
1693 aFullPropName
+= "/";
1694 aFullPropName
+= makeHierarchalNameSegment( Name
);
1696 if ( xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
) )
1699 throw PropertyExistException();
1703 // Property is always removable.
1704 Attributes
|= PropertyAttribute::REMOVABLE
;
1708 Reference
< XSingleServiceFactory
> xFac(
1709 m_pImpl
->m_pCreator
->getConfigWriteAccess( aFullValuesName
),
1711 Reference
< XNameContainer
> xContainer( xFac
, UNO_QUERY
);
1712 Reference
< XChangesBatch
> xBatch(
1713 m_pImpl
->m_pCreator
->getConfigWriteAccess( OUString() ),
1716 OSL_ENSURE( xFac
.is(),
1717 "PersistentPropertySet::addProperty - No factory!" );
1719 OSL_ENSURE( xBatch
.is(),
1720 "PersistentPropertySet::addProperty - No batch!" );
1722 OSL_ENSURE( xContainer
.is(),
1723 "PersistentPropertySet::addProperty - No container!" );
1725 if ( xFac
.is() && xBatch
.is() && xContainer
.is() )
1729 // Create new "PropertyValue" config item.
1730 Reference
< XNameReplace
> xNameReplace(
1731 xFac
->createInstance(), UNO_QUERY
);
1733 if ( xNameReplace
.is() )
1738 xNameReplace
->replaceByName(
1740 makeAny( sal_Int32( -1 ) ) );
1742 // Set default value
1743 xNameReplace
->replaceByName(
1747 // Set state ( always "default" )
1748 xNameReplace
->replaceByName(
1752 PropertyState_DEFAULT_VALUE
) ) );
1755 xNameReplace
->replaceByName(
1756 OUString("Attributes"),
1757 makeAny( sal_Int32( Attributes
) ) );
1760 xContainer
->insertByName( Name
, makeAny( xNameReplace
) );
1763 xBatch
->commitChanges();
1765 // Property set info is invalid.
1766 if ( m_pImpl
->m_pInfo
)
1767 m_pImpl
->m_pInfo
->reset();
1769 // Notify propertyset info change listeners.
1770 if ( m_pImpl
->m_pPropSetChangeListeners
&&
1771 m_pImpl
->m_pPropSetChangeListeners
->getLength() )
1773 PropertySetInfoChangeEvent
evt(
1774 static_cast< OWeakObject
* >( this ),
1777 PropertySetInfoChange::PROPERTY_INSERTED
);
1778 notifyPropertySetInfoChange( evt
);
1785 catch (const IllegalArgumentException
&)
1789 OSL_FAIL( "PersistentPropertySet::addProperty - "
1790 "caught IllegalArgumentException!" );
1793 catch (const ElementExistException
&)
1797 OSL_FAIL( "PersistentPropertySet::addProperty - "
1798 "caught ElementExistException!" );
1801 catch (const WrappedTargetException
&)
1803 // replaceByName, insertByName, commitChanges
1805 OSL_FAIL( "PersistentPropertySet::addProperty - "
1806 "caught WrappedTargetException!" );
1809 catch (const RuntimeException
&)
1813 catch (const Exception
&)
1817 OSL_FAIL( "PersistentPropertySet::addProperty - "
1818 "caught Exception!" );
1823 OSL_FAIL( "PersistentPropertySet::addProperty - Error!" );
1826 //=========================================================================
1828 void SAL_CALL
PersistentPropertySet::removeProperty( const OUString
& Name
)
1829 throw( UnknownPropertyException
,
1830 NotRemoveableException
,
1833 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
1835 OUString aFullValuesName
;
1836 OUString aFullPropName
;
1838 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
1839 m_pImpl
->m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1840 if ( xRootHierNameAccess
.is() )
1842 aFullValuesName
= getFullKey();
1843 aFullPropName
= aFullValuesName
;
1844 aFullPropName
+= "/";
1845 aFullPropName
+= makeHierarchalNameSegment( Name
);
1848 if ( !xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
) )
1849 throw UnknownPropertyException();
1851 // Property removable?
1854 OUString aFullAttrName
= aFullPropName
;
1855 aFullAttrName
+= "/Attributes";
1857 sal_Int32 nAttribs
= 0;
1858 if ( xRootHierNameAccess
->getByHierarchicalName( aFullAttrName
)
1861 if ( !( nAttribs
& PropertyAttribute::REMOVABLE
) )
1864 throw NotRemoveableException();
1869 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1874 catch (const NoSuchElementException
&)
1876 // getByHierarchicalName
1878 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1879 "caught NoSuchElementException!" );
1882 // Remove property...
1884 Reference
< XNameContainer
> xContainer(
1885 m_pImpl
->m_pCreator
->getConfigWriteAccess( aFullValuesName
),
1887 Reference
< XChangesBatch
> xBatch(
1888 m_pImpl
->m_pCreator
->getConfigWriteAccess( OUString() ),
1891 OSL_ENSURE( xBatch
.is(),
1892 "PersistentPropertySet::removeProperty - No batch!" );
1894 OSL_ENSURE( xContainer
.is(),
1895 "PersistentPropertySet::removeProperty - No container!" );
1897 if ( xBatch
.is() && xContainer
.is() )
1901 sal_Int32 nHandle
= -1;
1903 if ( m_pImpl
->m_pPropSetChangeListeners
&&
1904 m_pImpl
->m_pPropSetChangeListeners
->getLength() )
1906 // Obtain property handle ( needed for propertysetinfo
1907 // change event )...
1911 OUString aFullHandleName
= aFullPropName
;
1915 if ( ! ( xRootHierNameAccess
->getByHierarchicalName(
1916 aFullHandleName
) >>= nHandle
) )
1920 catch (const NoSuchElementException
&)
1922 // getByHierarchicalName
1924 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1925 "caught NoSuchElementException!" );
1930 xContainer
->removeByName( Name
);
1931 xBatch
->commitChanges();
1933 // Property set info is invalid.
1934 if ( m_pImpl
->m_pInfo
)
1935 m_pImpl
->m_pInfo
->reset();
1937 // Notify propertyset info change listeners.
1938 if ( m_pImpl
->m_pPropSetChangeListeners
&&
1939 m_pImpl
->m_pPropSetChangeListeners
->getLength() )
1941 PropertySetInfoChangeEvent
evt(
1942 static_cast< OWeakObject
* >( this ),
1945 PropertySetInfoChange::PROPERTY_REMOVED
);
1946 notifyPropertySetInfoChange( evt
);
1952 catch (const NoSuchElementException
&)
1956 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1957 "caught NoSuchElementException!" );
1960 catch (const WrappedTargetException
&)
1964 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1965 "caught WrappedTargetException!" );
1971 OSL_FAIL( "PersistentPropertySet::removeProperty - Error!" );
1974 //=========================================================================
1976 // XPropertySetInfoChangeNotifier methods.
1978 //=========================================================================
1981 void SAL_CALL
PersistentPropertySet::addPropertySetInfoChangeListener(
1982 const Reference
< XPropertySetInfoChangeListener
>& Listener
)
1983 throw( RuntimeException
)
1985 if ( !m_pImpl
->m_pPropSetChangeListeners
)
1986 m_pImpl
->m_pPropSetChangeListeners
=
1987 new OInterfaceContainerHelper( m_pImpl
->m_aMutex
);
1989 m_pImpl
->m_pPropSetChangeListeners
->addInterface( Listener
);
1992 //=========================================================================
1994 void SAL_CALL
PersistentPropertySet::removePropertySetInfoChangeListener(
1995 const Reference
< XPropertySetInfoChangeListener
>& Listener
)
1996 throw( RuntimeException
)
1998 if ( m_pImpl
->m_pPropSetChangeListeners
)
1999 m_pImpl
->m_pPropSetChangeListeners
->removeInterface( Listener
);
2002 //=========================================================================
2004 // XPropertyAccess methods.
2006 //=========================================================================
2009 Sequence
< PropertyValue
> SAL_CALL
PersistentPropertySet::getPropertyValues()
2010 throw( RuntimeException
)
2012 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
2014 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
2015 m_pImpl
->m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
2016 if ( xRootHierNameAccess
.is() )
2020 Reference
< XNameAccess
> xNameAccess
;
2021 xRootHierNameAccess
->getByHierarchicalName(getFullKey())
2023 if ( xNameAccess
.is() )
2025 // Obtain property names.
2027 Sequence
< OUString
> aElems
= xNameAccess
->getElementNames();
2029 sal_Int32 nCount
= aElems
.getLength();
2032 Reference
< XHierarchicalNameAccess
> xHierNameAccess(
2033 xNameAccess
, UNO_QUERY
);
2035 OSL_ENSURE( xHierNameAccess
.is(),
2036 "PersistentPropertySet::getPropertyValues - "
2037 "No hierarchical name access!" );
2039 if ( xHierNameAccess
.is() )
2041 Sequence
< PropertyValue
> aValues( nCount
);
2043 const OUString
aHandleName("/Handle");
2044 const OUString
aValueName("/Value");
2045 const OUString
aStateName("/State");
2047 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
2049 PropertyValue
& rValue
= aValues
[ n
];
2050 OUString rName
= aElems
[ n
];
2052 = makeHierarchalNameSegment( rName
);
2054 // Set property name.
2056 rValue
.Name
= rName
;
2060 // Obtain and set property handle
2061 OUString aHierName
= aXMLName
;
2062 aHierName
+= aHandleName
;
2064 = xHierNameAccess
->getByHierarchicalName(
2067 if ( !( aKeyValue
>>= rValue
.Handle
) )
2068 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
2069 "Error getting property handle!" );
2071 catch (const NoSuchElementException
&)
2073 // getByHierarchicalName
2075 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
2076 "NoSuchElementException!" );
2081 // Obtain and set property value
2082 OUString aHierName
= aXMLName
;
2083 aHierName
+= aValueName
;
2085 = xHierNameAccess
->getByHierarchicalName(
2088 // Note: The value may be void if addProperty
2089 // was called with a default value
2092 catch (const NoSuchElementException
&)
2094 // getByHierarchicalName
2096 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
2097 "NoSuchElementException!" );
2102 // Obtain and set property state
2103 OUString aHierName
= aXMLName
;
2104 aHierName
+= aStateName
;
2106 = xHierNameAccess
->getByHierarchicalName(
2109 sal_Int32 nState
= 0;
2110 if ( !( aKeyValue
>>= nState
) )
2111 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
2112 "Error getting property state!" );
2114 rValue
.State
= PropertyState( nState
);
2116 catch (const NoSuchElementException
&)
2118 // getByHierarchicalName
2120 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
2121 "NoSuchElementException!" );
2130 catch (const NoSuchElementException
&)
2132 // getByHierarchicalName
2136 return Sequence
< PropertyValue
>( 0 );
2139 //=========================================================================
2141 void SAL_CALL
PersistentPropertySet::setPropertyValues(
2142 const Sequence
< PropertyValue
>& aProps
)
2143 throw( UnknownPropertyException
,
2144 PropertyVetoException
,
2145 IllegalArgumentException
,
2146 WrappedTargetException
,
2149 sal_Int32 nCount
= aProps
.getLength();
2153 osl::ClearableGuard
< osl::Mutex
> aCGuard( m_pImpl
->m_aMutex
);
2155 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
2156 m_pImpl
->m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
2157 if ( xRootHierNameAccess
.is() )
2159 const PropertyValue
* pNewValues
= aProps
.getConstArray();
2161 typedef std::list
< PropertyChangeEvent
> Events
;
2164 OUString
aFullPropNamePrefix( getFullKey() );
2165 aFullPropNamePrefix
+= "/";
2167 // Iterate over given property value sequence.
2168 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
2170 const PropertyValue
& rNewValue
= pNewValues
[ n
];
2171 const OUString
& rName
= rNewValue
.Name
;
2173 OUString aFullPropName
= aFullPropNamePrefix
;
2174 aFullPropName
+= makeHierarchalNameSegment( rName
);
2176 // Does property exist?
2177 if ( xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
) )
2179 Reference
< XNameReplace
> xNameReplace(
2180 m_pImpl
->m_pCreator
->getConfigWriteAccess(
2181 aFullPropName
), UNO_QUERY
);
2182 Reference
< XChangesBatch
> xBatch(
2183 m_pImpl
->m_pCreator
->getConfigWriteAccess(
2184 OUString() ), UNO_QUERY
);
2186 if ( xNameReplace
.is() && xBatch
.is() )
2191 xNameReplace
->replaceByName(
2193 makeAny( rNewValue
.Handle
) );
2196 OUString aValueName
= aFullPropName
;
2197 aValueName
+= "/Value";
2199 = xRootHierNameAccess
->getByHierarchicalName(
2202 xNameReplace
->replaceByName(
2206 // Write state ( Now it is a directly set value )
2207 xNameReplace
->replaceByName(
2211 PropertyState_DIRECT_VALUE
) ) );
2214 xBatch
->commitChanges();
2216 if ( m_pImpl
->m_pPropertyChangeListeners
)
2218 PropertyChangeEvent aEvt
;
2219 aEvt
.Source
= (OWeakObject
*)this;
2220 aEvt
.PropertyName
= rNewValue
.Name
;
2221 aEvt
.PropertyHandle
= rNewValue
.Handle
;
2222 aEvt
.Further
= sal_False
;
2223 aEvt
.OldValue
= aOldValue
;
2224 aEvt
.NewValue
= rNewValue
.Value
;
2226 aEvents
.push_back( aEvt
);
2229 catch (const IllegalArgumentException
&)
2233 catch (const NoSuchElementException
&)
2235 // getByHierarchicalName, replaceByName
2237 catch (const WrappedTargetException
&)
2239 // replaceByName, commitChanges
2245 // Callback follows!
2248 if ( m_pImpl
->m_pPropertyChangeListeners
)
2250 // Notify property changes.
2251 Events::const_iterator it
= aEvents
.begin();
2252 Events::const_iterator end
= aEvents
.end();
2256 notifyPropertyChangeEvent( (*it
) );
2264 OSL_FAIL( "PersistentPropertySet::setPropertyValues - Nothing set!" );
2267 //=========================================================================
2269 // Non-interface methods
2271 //=========================================================================
2273 void PersistentPropertySet::notifyPropertyChangeEvent(
2274 const PropertyChangeEvent
& rEvent
) const
2276 // Get "normal" listeners for the property.
2277 OInterfaceContainerHelper
* pContainer
=
2278 m_pImpl
->m_pPropertyChangeListeners
->getContainer(
2279 rEvent
.PropertyName
);
2280 if ( pContainer
&& pContainer
->getLength() )
2282 OInterfaceIteratorHelper
aIter( *pContainer
);
2283 while ( aIter
.hasMoreElements() )
2286 Reference
< XPropertyChangeListener
> xListener(
2287 aIter
.next(), UNO_QUERY
);
2288 if ( xListener
.is() )
2289 xListener
->propertyChange( rEvent
);
2293 // Get "normal" listeners for all properties.
2294 OInterfaceContainerHelper
* pNoNameContainer
=
2295 m_pImpl
->m_pPropertyChangeListeners
->getContainer( OUString() );
2296 if ( pNoNameContainer
&& pNoNameContainer
->getLength() )
2298 OInterfaceIteratorHelper
aIter( *pNoNameContainer
);
2299 while ( aIter
.hasMoreElements() )
2302 Reference
< XPropertyChangeListener
> xListener(
2303 aIter
.next(), UNO_QUERY
);
2304 if ( xListener
.is() )
2305 xListener
->propertyChange( rEvent
);
2310 //=========================================================================
2311 void PersistentPropertySet::notifyPropertySetInfoChange(
2312 const PropertySetInfoChangeEvent
& evt
) const
2314 if ( !m_pImpl
->m_pPropSetChangeListeners
)
2317 // Notify event listeners.
2318 OInterfaceIteratorHelper
aIter( *( m_pImpl
->m_pPropSetChangeListeners
) );
2319 while ( aIter
.hasMoreElements() )
2322 Reference
< XPropertySetInfoChangeListener
>
2323 xListener( aIter
.next(), UNO_QUERY
);
2324 if ( xListener
.is() )
2325 xListener
->propertySetInfoChange( evt
);
2329 //=========================================================================
2330 const OUString
& PersistentPropertySet::getFullKey()
2332 if ( m_pImpl
->m_aFullKey
.isEmpty() )
2334 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
2335 if ( m_pImpl
->m_aFullKey
.isEmpty() )
2338 = makeHierarchalNameSegment( m_pImpl
->m_aKey
);
2344 return m_pImpl
->m_aFullKey
;
2347 //=========================================================================
2348 PropertySetRegistry
& PersistentPropertySet::getPropertySetRegistry()
2350 return *m_pImpl
->m_pCreator
;
2353 //=========================================================================
2354 //=========================================================================
2356 // PropertySetInfo_Impl Implementation.
2358 //=========================================================================
2359 //=========================================================================
2361 PropertySetInfo_Impl::PropertySetInfo_Impl(
2362 const Reference
< XComponentContext
>& xContext
,
2363 PersistentPropertySet
* pOwner
)
2364 : m_xContext( xContext
),
2370 //=========================================================================
2372 PropertySetInfo_Impl::~PropertySetInfo_Impl()
2376 // !!! Do not delete m_pOwner !!!
2379 //=========================================================================
2381 // XInterface methods.
2383 //=========================================================================
2385 XINTERFACE_IMPL_2( PropertySetInfo_Impl
,
2389 //=========================================================================
2391 // XTypeProvider methods.
2393 //=========================================================================
2395 XTYPEPROVIDER_IMPL_2( PropertySetInfo_Impl
,
2399 //=========================================================================
2401 // XPropertySetInfo methods.
2403 //=========================================================================
2406 Sequence
< Property
> SAL_CALL
PropertySetInfo_Impl::getProperties()
2407 throw( RuntimeException
)
2411 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
2412 m_pOwner
->getPropertySetRegistry().getRootConfigReadAccess(),
2414 if ( xRootHierNameAccess
.is() )
2418 Reference
< XNameAccess
> xNameAccess
;
2419 xRootHierNameAccess
->getByHierarchicalName(
2420 m_pOwner
->getFullKey() )
2422 if ( xNameAccess
.is() )
2424 // Obtain property names.
2426 Sequence
< OUString
> aElems
2427 = xNameAccess
->getElementNames();
2429 sal_uInt32 nCount
= aElems
.getLength();
2430 Sequence
< Property
>* pPropSeq
2431 = new Sequence
< Property
>( nCount
);
2435 Reference
< XHierarchicalNameAccess
> xHierNameAccess(
2436 xNameAccess
, UNO_QUERY
);
2438 OSL_ENSURE( xHierNameAccess
.is(),
2439 "PropertySetInfo_Impl::getProperties - "
2440 "No hierarchical name access!" );
2442 if ( xHierNameAccess
.is() )
2444 const OUString
aHandleName("/Handle");
2445 const OUString
aValueName("/Value");
2446 const OUString
aAttrName("/Attributes");
2448 Property
* pProps
= pPropSeq
->getArray();
2450 for ( sal_uInt32 n
= 0; n
< nCount
; ++n
)
2452 Property
& rProp
= pProps
[ n
];
2453 OUString rName
= aElems
[ n
];
2455 = makeHierarchalNameSegment( rName
);
2457 // Set property name.
2463 // Obtain and set property handle
2464 OUString aHierName
= aXMLName
;
2465 aHierName
+= aHandleName
;
2467 = xHierNameAccess
->getByHierarchicalName(
2470 if ( !( aKeyValue
>>= rProp
.Handle
) )
2471 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2472 "Error getting property handle!" );
2474 catch (const NoSuchElementException
&)
2476 // getByHierarchicalName
2478 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2479 "NoSuchElementException!" );
2484 // Obtain and set property type
2485 OUString aHierName
= aXMLName
;
2486 aHierName
+= aValueName
;
2488 = xHierNameAccess
->getByHierarchicalName(
2491 // Note: The type may be void if addProperty
2492 // was called with a default value
2495 rProp
.Type
= aKeyValue
.getValueType();
2497 catch (const NoSuchElementException
&)
2499 // getByHierarchicalName
2501 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2502 "NoSuchElementException!" );
2507 // Obtain and set property attributes
2508 OUString aHierName
= aXMLName
;
2509 aHierName
+= aAttrName
;
2511 = xHierNameAccess
->getByHierarchicalName(
2514 sal_Int32 nAttribs
= 0;
2515 if ( aKeyValue
>>= nAttribs
)
2517 = sal_Int16( nAttribs
);
2519 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2520 "Error getting property attributes!" );
2522 catch (const NoSuchElementException
&)
2524 // getByHierarchicalName
2526 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2527 "NoSuchElementException!" );
2534 m_pProps
= pPropSeq
;
2538 catch (const NoSuchElementException
&)
2540 // getByHierarchicalName
2544 OSL_FAIL( "PropertySetInfo_Impl::getProperties - Error!" );
2545 m_pProps
= new Sequence
< Property
>( 0 );
2551 //=========================================================================
2553 Property SAL_CALL
PropertySetInfo_Impl::getPropertyByName(
2554 const OUString
& aName
)
2555 throw( UnknownPropertyException
, RuntimeException
)
2557 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
2558 m_pOwner
->getPropertySetRegistry().getRootConfigReadAccess(),
2560 if ( xRootHierNameAccess
.is() )
2562 OUString
aFullPropName( m_pOwner
->getFullKey() );
2563 aFullPropName
+= "/";
2564 aFullPropName
+= makeHierarchalNameSegment( aName
);
2566 // Does property exist?
2567 if ( !xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
) )
2568 throw UnknownPropertyException();
2575 OUString aKey
= aFullPropName
;
2578 if ( !( xRootHierNameAccess
->getByHierarchicalName( aKey
)
2579 >>= aProp
.Handle
) )
2581 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2586 // Obtain Value and extract type.
2587 aKey
= aFullPropName
;
2590 Any aValue
= xRootHierNameAccess
->getByHierarchicalName( aKey
);
2591 if ( !aValue
.hasValue() )
2593 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2598 aProp
.Type
= aValue
.getValueType();
2600 // Obtain Attributes.
2601 aKey
= aFullPropName
;
2602 aKey
+= "/Attributes";
2604 sal_Int32 nAttribs
= 0;
2605 if ( xRootHierNameAccess
->getByHierarchicalName( aKey
)
2607 aProp
.Attributes
= sal_Int16( nAttribs
);
2610 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2621 catch (const NoSuchElementException
&)
2623 // getByHierarchicalName
2625 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2626 "caught NoSuchElementException!" );
2631 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - Error!" );
2635 //=========================================================================
2637 sal_Bool SAL_CALL
PropertySetInfo_Impl::hasPropertyByName(
2638 const OUString
& Name
)
2639 throw( RuntimeException
)
2641 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
2642 m_pOwner
->getPropertySetRegistry().getRootConfigReadAccess(),
2644 if ( xRootHierNameAccess
.is() )
2646 OUString
aFullPropName( m_pOwner
->getFullKey() );
2647 aFullPropName
+= "/";
2648 aFullPropName
+= makeHierarchalNameSegment( Name
);
2650 return xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
);
2656 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */