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
.getStr()[ 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
< XMultiServiceFactory
> m_xSMgr
;
146 Sequence
< Property
>* m_pProps
;
147 PersistentPropertySet
* m_pOwner
;
150 PropertySetInfo_Impl( const Reference
< XMultiServiceFactory
>& rxSMgr
,
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
< XMultiServiceFactory
>& rXSMgr
)
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( 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_xSMgr
, 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
< XMultiServiceFactory
>& rXSMgr
,
331 const Sequence
< Any
> &rInitArgs
)
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_xSMgr
, *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_xSMgr
, *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
1041 = theDefaultProvider::get(
1042 comphelper::getComponentContext( m_xSMgr
) );
1044 catch (const Exception
&)
1046 OSL_TRACE( "PropertySetRegistry::getConfigProvider - "
1047 "caught exception!" );
1053 return m_pImpl
->m_xConfigProvider
;
1056 //=========================================================================
1057 Reference
< XInterface
> PropertySetRegistry::getRootConfigReadAccess()
1061 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
1063 if ( !m_pImpl
->m_xRootReadAccess
.is() )
1065 if ( m_pImpl
->m_bTriedToGetRootReadAccess
) // #82494#
1067 OSL_FAIL( "PropertySetRegistry::getRootConfigReadAccess - "
1068 "Unable to read any config data! -> #82494#" );
1069 return Reference
< XInterface
>();
1072 getConfigProvider();
1074 if ( m_pImpl
->m_xConfigProvider
.is() )
1076 Sequence
< Any
> aArguments( 1 );
1077 PropertyValue aProperty
;
1079 = OUString( CFGPROPERTY_NODEPATH
);
1081 <<= OUString( STORE_CONTENTPROPERTIES_KEY
);
1082 aArguments
[ 0 ] <<= aProperty
;
1084 m_pImpl
->m_bTriedToGetRootReadAccess
= sal_True
;
1086 m_pImpl
->m_xRootReadAccess
=
1087 m_pImpl
->m_xConfigProvider
->createInstanceWithArguments(
1088 OUString( "com.sun.star.configuration.ConfigurationAccess" ),
1091 if ( m_pImpl
->m_xRootReadAccess
.is() )
1092 return m_pImpl
->m_xRootReadAccess
;
1096 return m_pImpl
->m_xRootReadAccess
;
1098 catch (const RuntimeException
&)
1102 catch (const Exception
&)
1104 // createInstance, createInstanceWithArguments
1106 OSL_FAIL( "PropertySetRegistry::getRootConfigReadAccess - caught Exception!" );
1107 return Reference
< XInterface
>();
1110 OSL_TRACE( "PropertySetRegistry::getRootConfigReadAccess - Error!" );
1111 return Reference
< XInterface
>();
1114 //=========================================================================
1115 Reference
< XInterface
> PropertySetRegistry::getConfigWriteAccess(
1116 const OUString
& rPath
)
1120 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
1122 if ( !m_pImpl
->m_xRootWriteAccess
.is() )
1124 if ( m_pImpl
->m_bTriedToGetRootWriteAccess
) // #82494#
1126 OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - "
1127 "Unable to write any config data! -> #82494#" );
1128 return Reference
< XInterface
>();
1131 getConfigProvider();
1133 if ( m_pImpl
->m_xConfigProvider
.is() )
1135 Sequence
< Any
> aArguments( 2 );
1136 PropertyValue aProperty
;
1138 aProperty
.Name
= OUString( CFGPROPERTY_NODEPATH
);
1139 aProperty
.Value
<<= OUString( STORE_CONTENTPROPERTIES_KEY
);
1140 aArguments
[ 0 ] <<= aProperty
;
1142 aProperty
.Name
= OUString( CFGPROPERTY_LAZYWRITE
);
1143 aProperty
.Value
<<= sal_True
;
1144 aArguments
[ 1 ] <<= aProperty
;
1146 m_pImpl
->m_bTriedToGetRootWriteAccess
= sal_True
;
1148 m_pImpl
->m_xRootWriteAccess
=
1149 m_pImpl
->m_xConfigProvider
->createInstanceWithArguments(
1150 OUString( "com.sun.star.configuration.ConfigurationUpdateAccess" ),
1153 OSL_ENSURE( m_pImpl
->m_xRootWriteAccess
.is(),
1154 "PropertySetRegistry::getConfigWriteAccess - "
1155 "No config update access!" );
1159 if ( m_pImpl
->m_xRootWriteAccess
.is() )
1161 if ( !rPath
.isEmpty() )
1163 Reference
< XHierarchicalNameAccess
> xNA(
1164 m_pImpl
->m_xRootWriteAccess
, UNO_QUERY
);
1167 Reference
< XInterface
> xInterface
;
1168 xNA
->getByHierarchicalName( rPath
) >>= xInterface
;
1170 if ( xInterface
.is() )
1175 return m_pImpl
->m_xRootWriteAccess
;
1178 catch (const RuntimeException
&)
1182 catch (const NoSuchElementException
&)
1184 // getByHierarchicalName
1186 OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - "
1187 "caught NoSuchElementException!" );
1188 return Reference
< XInterface
>();
1190 catch (const Exception
&)
1192 // createInstance, createInstanceWithArguments
1194 OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - "
1195 "caught Exception!" );
1196 return Reference
< XInterface
>();
1199 OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - Error!" );
1200 return Reference
< XInterface
>();
1203 //=========================================================================
1205 // PropertyListeners_Impl.
1207 //=========================================================================
1209 typedef OMultiTypeInterfaceContainerHelperVar
1214 > PropertyListeners_Impl
;
1216 //=========================================================================
1218 // PersistentPropertySet_Impl.
1220 //=========================================================================
1222 struct PersistentPropertySet_Impl
1224 PropertySetRegistry
* m_pCreator
;
1225 PropertySetInfo_Impl
* m_pInfo
;
1227 OUString m_aFullKey
;
1228 osl::Mutex m_aMutex
;
1229 OInterfaceContainerHelper
* m_pDisposeEventListeners
;
1230 OInterfaceContainerHelper
* m_pPropSetChangeListeners
;
1231 PropertyListeners_Impl
* m_pPropertyChangeListeners
;
1233 PersistentPropertySet_Impl( PropertySetRegistry
& rCreator
,
1234 const OUString
& rKey
)
1235 : m_pCreator( &rCreator
), m_pInfo( NULL
), m_aKey( rKey
),
1236 m_pDisposeEventListeners( NULL
), m_pPropSetChangeListeners( NULL
),
1237 m_pPropertyChangeListeners( NULL
)
1239 m_pCreator
->acquire();
1242 ~PersistentPropertySet_Impl()
1244 m_pCreator
->release();
1249 delete m_pDisposeEventListeners
;
1250 delete m_pPropSetChangeListeners
;
1251 delete m_pPropertyChangeListeners
;
1255 //=========================================================================
1256 //=========================================================================
1257 //=========================================================================
1259 // PersistentPropertySet Implementation.
1261 //=========================================================================
1262 //=========================================================================
1263 //=========================================================================
1265 PersistentPropertySet::PersistentPropertySet(
1266 const Reference
< XMultiServiceFactory
>& rXSMgr
,
1267 PropertySetRegistry
& rCreator
,
1268 const OUString
& rKey
)
1269 : m_xSMgr( rXSMgr
),
1270 m_pImpl( new PersistentPropertySet_Impl( rCreator
, rKey
) )
1272 // register at creator.
1273 rCreator
.add( this );
1276 //=========================================================================
1278 PersistentPropertySet::~PersistentPropertySet()
1280 // deregister at creator.
1281 m_pImpl
->m_pCreator
->remove( this );
1286 //=========================================================================
1288 // XInterface methods.
1290 //=========================================================================
1292 XINTERFACE_IMPL_9( PersistentPropertySet
,
1296 XPropertySet
, /* base of XPersistentPropertySet */
1298 XPersistentPropertySet
,
1300 XPropertySetInfoChangeNotifier
,
1303 //=========================================================================
1305 // XTypeProvider methods.
1307 //=========================================================================
1309 XTYPEPROVIDER_IMPL_8( PersistentPropertySet
,
1313 XPersistentPropertySet
,
1316 XPropertySetInfoChangeNotifier
,
1319 //=========================================================================
1321 // XServiceInfo methods.
1323 //=========================================================================
1325 XSERVICEINFO_NOFACTORY_IMPL_1( PersistentPropertySet
,
1326 OUString( "com.sun.star.comp.ucb.PersistentPropertySet" ),
1327 OUString( PERS_PROPSET_SERVICE_NAME
) );
1329 //=========================================================================
1331 // XComponent methods.
1333 //=========================================================================
1336 void SAL_CALL
PersistentPropertySet::dispose()
1337 throw( RuntimeException
)
1339 if ( m_pImpl
->m_pDisposeEventListeners
&&
1340 m_pImpl
->m_pDisposeEventListeners
->getLength() )
1343 aEvt
.Source
= static_cast< XComponent
* >( this );
1344 m_pImpl
->m_pDisposeEventListeners
->disposeAndClear( aEvt
);
1347 if ( m_pImpl
->m_pPropSetChangeListeners
&&
1348 m_pImpl
->m_pPropSetChangeListeners
->getLength() )
1351 aEvt
.Source
= static_cast< XPropertySetInfoChangeNotifier
* >( this );
1352 m_pImpl
->m_pPropSetChangeListeners
->disposeAndClear( aEvt
);
1355 if ( m_pImpl
->m_pPropertyChangeListeners
)
1358 aEvt
.Source
= static_cast< XPropertySet
* >( this );
1359 m_pImpl
->m_pPropertyChangeListeners
->disposeAndClear( aEvt
);
1363 //=========================================================================
1365 void SAL_CALL
PersistentPropertySet::addEventListener(
1366 const Reference
< XEventListener
>& Listener
)
1367 throw( RuntimeException
)
1369 if ( !m_pImpl
->m_pDisposeEventListeners
)
1370 m_pImpl
->m_pDisposeEventListeners
=
1371 new OInterfaceContainerHelper( m_pImpl
->m_aMutex
);
1373 m_pImpl
->m_pDisposeEventListeners
->addInterface( Listener
);
1376 //=========================================================================
1378 void SAL_CALL
PersistentPropertySet::removeEventListener(
1379 const Reference
< XEventListener
>& Listener
)
1380 throw( RuntimeException
)
1382 if ( m_pImpl
->m_pDisposeEventListeners
)
1383 m_pImpl
->m_pDisposeEventListeners
->removeInterface( Listener
);
1385 // Note: Don't want to delete empty container here -> performance.
1388 //=========================================================================
1390 // XPropertySet methods.
1392 //=========================================================================
1395 Reference
< XPropertySetInfo
> SAL_CALL
1396 PersistentPropertySet::getPropertySetInfo()
1397 throw( RuntimeException
)
1399 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
1401 PropertySetInfo_Impl
*& rpInfo
= m_pImpl
->m_pInfo
;
1404 rpInfo
= new PropertySetInfo_Impl( m_xSMgr
, this );
1407 return Reference
< XPropertySetInfo
>( rpInfo
);
1410 //=========================================================================
1412 void SAL_CALL
PersistentPropertySet::setPropertyValue(
1413 const OUString
& aPropertyName
, const Any
& aValue
)
1414 throw( UnknownPropertyException
,
1415 PropertyVetoException
,
1416 IllegalArgumentException
,
1417 WrappedTargetException
,
1420 if ( aPropertyName
.isEmpty() )
1421 throw UnknownPropertyException();
1423 osl::ClearableGuard
< osl::Mutex
> aCGuard( m_pImpl
->m_aMutex
);
1425 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
1426 m_pImpl
->m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1427 if ( xRootHierNameAccess
.is() )
1429 OUString
aFullPropName( getFullKey() );
1430 aFullPropName
+= "/";
1431 aFullPropName
+= makeHierarchalNameSegment( aPropertyName
);
1433 // Does property exist?
1434 if ( xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
) )
1436 Reference
< XNameReplace
> xNameReplace(
1437 m_pImpl
->m_pCreator
->getConfigWriteAccess(
1438 aFullPropName
), UNO_QUERY
);
1439 Reference
< XChangesBatch
> xBatch(
1440 m_pImpl
->m_pCreator
->getConfigWriteAccess(
1441 OUString() ), UNO_QUERY
);
1443 if ( xNameReplace
.is() && xBatch
.is() )
1448 OUString aValueName
= aFullPropName
;
1449 aValueName
+= "/Value";
1451 = xRootHierNameAccess
->getByHierarchicalName(
1453 // Check value type.
1454 if ( aOldValue
.getValueType() != aValue
.getValueType() )
1457 throw IllegalArgumentException();
1461 xNameReplace
->replaceByName(
1465 // Write state ( Now it is a directly set value )
1466 xNameReplace
->replaceByName(
1470 PropertyState_DIRECT_VALUE
) ) );
1473 xBatch
->commitChanges();
1475 PropertyChangeEvent aEvt
;
1476 if ( m_pImpl
->m_pPropertyChangeListeners
)
1479 aValueName
= aFullPropName
;
1480 aValueName
+= "/Handle";
1481 sal_Int32 nHandle
= -1;
1482 xRootHierNameAccess
->getByHierarchicalName( aValueName
)
1485 aEvt
.Source
= (OWeakObject
*)this;
1486 aEvt
.PropertyName
= aPropertyName
;
1487 aEvt
.PropertyHandle
= nHandle
;
1488 aEvt
.Further
= sal_False
;
1489 aEvt
.OldValue
= aOldValue
;
1490 aEvt
.NewValue
= aValue
;
1492 // Callback follows!
1495 notifyPropertyChangeEvent( aEvt
);
1499 catch (const IllegalArgumentException
&)
1503 catch (const NoSuchElementException
&)
1505 // getByHierarchicalName, replaceByName
1507 catch (const WrappedTargetException
&)
1509 // replaceByName, commitChanges
1515 throw UnknownPropertyException();
1518 //=========================================================================
1520 Any SAL_CALL
PersistentPropertySet::getPropertyValue(
1521 const OUString
& PropertyName
)
1522 throw( UnknownPropertyException
,
1523 WrappedTargetException
,
1526 if ( PropertyName
.isEmpty() )
1527 throw UnknownPropertyException();
1529 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
1531 Reference
< XHierarchicalNameAccess
> xNameAccess(
1532 m_pImpl
->m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1533 if ( xNameAccess
.is() )
1535 OUString
aFullPropName( getFullKey() );
1536 aFullPropName
+= "/";
1537 aFullPropName
+= makeHierarchalNameSegment( PropertyName
);
1538 aFullPropName
+= "/Value";
1541 return xNameAccess
->getByHierarchicalName( aFullPropName
);
1543 catch (const NoSuchElementException
&)
1545 throw UnknownPropertyException();
1549 throw UnknownPropertyException();
1552 //=========================================================================
1554 void SAL_CALL
PersistentPropertySet::addPropertyChangeListener(
1555 const OUString
& aPropertyName
,
1556 const Reference
< XPropertyChangeListener
>& xListener
)
1557 throw( UnknownPropertyException
,
1558 WrappedTargetException
,
1563 if ( !m_pImpl
->m_pPropertyChangeListeners
)
1564 m_pImpl
->m_pPropertyChangeListeners
=
1565 new PropertyListeners_Impl( m_pImpl
->m_aMutex
);
1567 m_pImpl
->m_pPropertyChangeListeners
->addInterface(
1568 aPropertyName
, xListener
);
1571 //=========================================================================
1573 void SAL_CALL
PersistentPropertySet::removePropertyChangeListener(
1574 const OUString
& aPropertyName
,
1575 const Reference
< XPropertyChangeListener
>& aListener
)
1576 throw( UnknownPropertyException
,
1577 WrappedTargetException
,
1582 if ( m_pImpl
->m_pPropertyChangeListeners
)
1583 m_pImpl
->m_pPropertyChangeListeners
->removeInterface(
1584 aPropertyName
, aListener
);
1586 // Note: Don't want to delete empty container here -> performance.
1589 //=========================================================================
1591 void SAL_CALL
PersistentPropertySet::addVetoableChangeListener(
1593 const Reference
< XVetoableChangeListener
>& )
1594 throw( UnknownPropertyException
,
1595 WrappedTargetException
,
1599 // OSL_FAIL( // "PersistentPropertySet::addVetoableChangeListener - N.Y.I." );
1602 //=========================================================================
1604 void SAL_CALL
PersistentPropertySet::removeVetoableChangeListener(
1606 const Reference
< XVetoableChangeListener
>& )
1607 throw( UnknownPropertyException
,
1608 WrappedTargetException
,
1612 // OSL_FAIL( // "PersistentPropertySet::removeVetoableChangeListener - N.Y.I." );
1615 //=========================================================================
1617 // XPersistentPropertySet methods.
1619 //=========================================================================
1622 Reference
< XPropertySetRegistry
> SAL_CALL
PersistentPropertySet::getRegistry()
1623 throw( RuntimeException
)
1625 return Reference
< XPropertySetRegistry
>( m_pImpl
->m_pCreator
);
1628 //=========================================================================
1630 OUString SAL_CALL
PersistentPropertySet::getKey()
1631 throw( RuntimeException
)
1633 return m_pImpl
->m_aKey
;
1636 //=========================================================================
1640 //=========================================================================
1643 OUString SAL_CALL
PersistentPropertySet::getName()
1644 throw( RuntimeException
)
1647 return m_pImpl
->m_aKey
;
1650 //=========================================================================
1652 void SAL_CALL
PersistentPropertySet::setName( const OUString
& aName
)
1653 throw( RuntimeException
)
1655 if ( aName
!= m_pImpl
->m_aKey
)
1656 m_pImpl
->m_pCreator
->renamePropertySet( m_pImpl
->m_aKey
, aName
);
1659 //=========================================================================
1661 // XPropertyContainer methods.
1663 //=========================================================================
1666 void SAL_CALL
PersistentPropertySet::addProperty(
1667 const OUString
& Name
, sal_Int16 Attributes
, const Any
& DefaultValue
)
1668 throw( PropertyExistException
,
1669 IllegalTypeException
,
1670 IllegalArgumentException
,
1673 if ( Name
.isEmpty() )
1674 throw IllegalArgumentException();
1676 // @@@ What other types can't be written to config server?
1678 // Check type class ( Not all types can be written to storage )
1679 TypeClass eTypeClass
= DefaultValue
.getValueTypeClass();
1680 if ( eTypeClass
== TypeClass_INTERFACE
)
1681 throw IllegalTypeException();
1683 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
1685 // Property already in set?
1687 OUString aFullValuesName
;
1689 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
1690 m_pImpl
->m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1691 if ( xRootHierNameAccess
.is() )
1693 aFullValuesName
= getFullKey();
1694 OUString aFullPropName
= aFullValuesName
;
1695 aFullPropName
+= "/";
1696 aFullPropName
+= makeHierarchalNameSegment( Name
);
1698 if ( xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
) )
1701 throw PropertyExistException();
1705 // Property is always removable.
1706 Attributes
|= PropertyAttribute::REMOVABLE
;
1710 Reference
< XSingleServiceFactory
> xFac(
1711 m_pImpl
->m_pCreator
->getConfigWriteAccess( aFullValuesName
),
1713 Reference
< XNameContainer
> xContainer( xFac
, UNO_QUERY
);
1714 Reference
< XChangesBatch
> xBatch(
1715 m_pImpl
->m_pCreator
->getConfigWriteAccess( OUString() ),
1718 OSL_ENSURE( xFac
.is(),
1719 "PersistentPropertySet::addProperty - No factory!" );
1721 OSL_ENSURE( xBatch
.is(),
1722 "PersistentPropertySet::addProperty - No batch!" );
1724 OSL_ENSURE( xContainer
.is(),
1725 "PersistentPropertySet::addProperty - No container!" );
1727 if ( xFac
.is() && xBatch
.is() && xContainer
.is() )
1731 // Create new "PropertyValue" config item.
1732 Reference
< XNameReplace
> xNameReplace(
1733 xFac
->createInstance(), UNO_QUERY
);
1735 if ( xNameReplace
.is() )
1740 xNameReplace
->replaceByName(
1742 makeAny( sal_Int32( -1 ) ) );
1744 // Set default value
1745 xNameReplace
->replaceByName(
1749 // Set state ( always "default" )
1750 xNameReplace
->replaceByName(
1754 PropertyState_DEFAULT_VALUE
) ) );
1757 xNameReplace
->replaceByName(
1758 OUString("Attributes"),
1759 makeAny( sal_Int32( Attributes
) ) );
1762 xContainer
->insertByName( Name
, makeAny( xNameReplace
) );
1765 xBatch
->commitChanges();
1767 // Property set info is invalid.
1768 if ( m_pImpl
->m_pInfo
)
1769 m_pImpl
->m_pInfo
->reset();
1771 // Notify propertyset info change listeners.
1772 if ( m_pImpl
->m_pPropSetChangeListeners
&&
1773 m_pImpl
->m_pPropSetChangeListeners
->getLength() )
1775 PropertySetInfoChangeEvent
evt(
1776 static_cast< OWeakObject
* >( this ),
1779 PropertySetInfoChange::PROPERTY_INSERTED
);
1780 notifyPropertySetInfoChange( evt
);
1787 catch (const IllegalArgumentException
&)
1791 OSL_FAIL( "PersistentPropertySet::addProperty - "
1792 "caught IllegalArgumentException!" );
1795 catch (const ElementExistException
&)
1799 OSL_FAIL( "PersistentPropertySet::addProperty - "
1800 "caught ElementExistException!" );
1803 catch (const WrappedTargetException
&)
1805 // replaceByName, insertByName, commitChanges
1807 OSL_FAIL( "PersistentPropertySet::addProperty - "
1808 "caught WrappedTargetException!" );
1811 catch (const RuntimeException
&)
1815 catch (const Exception
&)
1819 OSL_FAIL( "PersistentPropertySet::addProperty - "
1820 "caught Exception!" );
1825 OSL_FAIL( "PersistentPropertySet::addProperty - Error!" );
1828 //=========================================================================
1830 void SAL_CALL
PersistentPropertySet::removeProperty( const OUString
& Name
)
1831 throw( UnknownPropertyException
,
1832 NotRemoveableException
,
1835 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
1837 OUString aFullValuesName
;
1838 OUString aFullPropName
;
1840 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
1841 m_pImpl
->m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1842 if ( xRootHierNameAccess
.is() )
1844 aFullValuesName
= getFullKey();
1845 aFullPropName
= aFullValuesName
;
1846 aFullPropName
+= "/";
1847 aFullPropName
+= makeHierarchalNameSegment( Name
);
1850 if ( !xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
) )
1851 throw UnknownPropertyException();
1853 // Property removable?
1856 OUString aFullAttrName
= aFullPropName
;
1857 aFullAttrName
+= "/Attributes";
1859 sal_Int32 nAttribs
= 0;
1860 if ( xRootHierNameAccess
->getByHierarchicalName( aFullAttrName
)
1863 if ( !( nAttribs
& PropertyAttribute::REMOVABLE
) )
1866 throw NotRemoveableException();
1871 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1876 catch (const NoSuchElementException
&)
1878 // getByHierarchicalName
1880 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1881 "caught NoSuchElementException!" );
1884 // Remove property...
1886 Reference
< XNameContainer
> xContainer(
1887 m_pImpl
->m_pCreator
->getConfigWriteAccess( aFullValuesName
),
1889 Reference
< XChangesBatch
> xBatch(
1890 m_pImpl
->m_pCreator
->getConfigWriteAccess( OUString() ),
1893 OSL_ENSURE( xBatch
.is(),
1894 "PersistentPropertySet::removeProperty - No batch!" );
1896 OSL_ENSURE( xContainer
.is(),
1897 "PersistentPropertySet::removeProperty - No container!" );
1899 if ( xBatch
.is() && xContainer
.is() )
1903 sal_Int32 nHandle
= -1;
1905 if ( m_pImpl
->m_pPropSetChangeListeners
&&
1906 m_pImpl
->m_pPropSetChangeListeners
->getLength() )
1908 // Obtain property handle ( needed for propertysetinfo
1909 // change event )...
1913 OUString aFullHandleName
= aFullPropName
;
1917 if ( ! ( xRootHierNameAccess
->getByHierarchicalName(
1918 aFullHandleName
) >>= nHandle
) )
1922 catch (const NoSuchElementException
&)
1924 // getByHierarchicalName
1926 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1927 "caught NoSuchElementException!" );
1932 xContainer
->removeByName( Name
);
1933 xBatch
->commitChanges();
1935 // Property set info is invalid.
1936 if ( m_pImpl
->m_pInfo
)
1937 m_pImpl
->m_pInfo
->reset();
1939 // Notify propertyset info change listeners.
1940 if ( m_pImpl
->m_pPropSetChangeListeners
&&
1941 m_pImpl
->m_pPropSetChangeListeners
->getLength() )
1943 PropertySetInfoChangeEvent
evt(
1944 static_cast< OWeakObject
* >( this ),
1947 PropertySetInfoChange::PROPERTY_REMOVED
);
1948 notifyPropertySetInfoChange( evt
);
1954 catch (const NoSuchElementException
&)
1958 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1959 "caught NoSuchElementException!" );
1962 catch (const WrappedTargetException
&)
1966 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1967 "caught WrappedTargetException!" );
1973 OSL_FAIL( "PersistentPropertySet::removeProperty - Error!" );
1976 //=========================================================================
1978 // XPropertySetInfoChangeNotifier methods.
1980 //=========================================================================
1983 void SAL_CALL
PersistentPropertySet::addPropertySetInfoChangeListener(
1984 const Reference
< XPropertySetInfoChangeListener
>& Listener
)
1985 throw( RuntimeException
)
1987 if ( !m_pImpl
->m_pPropSetChangeListeners
)
1988 m_pImpl
->m_pPropSetChangeListeners
=
1989 new OInterfaceContainerHelper( m_pImpl
->m_aMutex
);
1991 m_pImpl
->m_pPropSetChangeListeners
->addInterface( Listener
);
1994 //=========================================================================
1996 void SAL_CALL
PersistentPropertySet::removePropertySetInfoChangeListener(
1997 const Reference
< XPropertySetInfoChangeListener
>& Listener
)
1998 throw( RuntimeException
)
2000 if ( m_pImpl
->m_pPropSetChangeListeners
)
2001 m_pImpl
->m_pPropSetChangeListeners
->removeInterface( Listener
);
2004 //=========================================================================
2006 // XPropertyAccess methods.
2008 //=========================================================================
2011 Sequence
< PropertyValue
> SAL_CALL
PersistentPropertySet::getPropertyValues()
2012 throw( RuntimeException
)
2014 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
2016 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
2017 m_pImpl
->m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
2018 if ( xRootHierNameAccess
.is() )
2022 Reference
< XNameAccess
> xNameAccess
;
2023 xRootHierNameAccess
->getByHierarchicalName(getFullKey())
2025 if ( xNameAccess
.is() )
2027 // Obtain property names.
2029 Sequence
< OUString
> aElems
= xNameAccess
->getElementNames();
2031 sal_Int32 nCount
= aElems
.getLength();
2034 Reference
< XHierarchicalNameAccess
> xHierNameAccess(
2035 xNameAccess
, UNO_QUERY
);
2037 OSL_ENSURE( xHierNameAccess
.is(),
2038 "PersistentPropertySet::getPropertyValues - "
2039 "No hierarchical name access!" );
2041 if ( xHierNameAccess
.is() )
2043 Sequence
< PropertyValue
> aValues( nCount
);
2045 const OUString
aHandleName("/Handle");
2046 const OUString
aValueName("/Value");
2047 const OUString
aStateName("/State");
2049 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
2051 PropertyValue
& rValue
= aValues
[ n
];
2052 OUString rName
= aElems
[ n
];
2054 = makeHierarchalNameSegment( rName
);
2056 // Set property name.
2058 rValue
.Name
= rName
;
2062 // Obtain and set property handle
2063 OUString aHierName
= aXMLName
;
2064 aHierName
+= aHandleName
;
2066 = xHierNameAccess
->getByHierarchicalName(
2069 if ( !( aKeyValue
>>= rValue
.Handle
) )
2070 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
2071 "Error getting property handle!" );
2073 catch (const NoSuchElementException
&)
2075 // getByHierarchicalName
2077 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
2078 "NoSuchElementException!" );
2083 // Obtain and set property value
2084 OUString aHierName
= aXMLName
;
2085 aHierName
+= aValueName
;
2087 = xHierNameAccess
->getByHierarchicalName(
2090 // Note: The value may be void if addProperty
2091 // was called with a default value
2094 catch (const NoSuchElementException
&)
2096 // getByHierarchicalName
2098 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
2099 "NoSuchElementException!" );
2104 // Obtain and set property state
2105 OUString aHierName
= aXMLName
;
2106 aHierName
+= aStateName
;
2108 = xHierNameAccess
->getByHierarchicalName(
2111 sal_Int32 nState
= 0;
2112 if ( !( aKeyValue
>>= nState
) )
2113 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
2114 "Error getting property state!" );
2116 rValue
.State
= PropertyState( nState
);
2118 catch (const NoSuchElementException
&)
2120 // getByHierarchicalName
2122 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
2123 "NoSuchElementException!" );
2132 catch (const NoSuchElementException
&)
2134 // getByHierarchicalName
2138 return Sequence
< PropertyValue
>( 0 );
2141 //=========================================================================
2143 void SAL_CALL
PersistentPropertySet::setPropertyValues(
2144 const Sequence
< PropertyValue
>& aProps
)
2145 throw( UnknownPropertyException
,
2146 PropertyVetoException
,
2147 IllegalArgumentException
,
2148 WrappedTargetException
,
2151 sal_Int32 nCount
= aProps
.getLength();
2155 osl::ClearableGuard
< osl::Mutex
> aCGuard( m_pImpl
->m_aMutex
);
2157 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
2158 m_pImpl
->m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
2159 if ( xRootHierNameAccess
.is() )
2161 const PropertyValue
* pNewValues
= aProps
.getConstArray();
2163 typedef std::list
< PropertyChangeEvent
> Events
;
2166 OUString
aFullPropNamePrefix( getFullKey() );
2167 aFullPropNamePrefix
+= "/";
2169 // Iterate over given property value sequence.
2170 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
2172 const PropertyValue
& rNewValue
= pNewValues
[ n
];
2173 const OUString
& rName
= rNewValue
.Name
;
2175 OUString aFullPropName
= aFullPropNamePrefix
;
2176 aFullPropName
+= makeHierarchalNameSegment( rName
);
2178 // Does property exist?
2179 if ( xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
) )
2181 Reference
< XNameReplace
> xNameReplace(
2182 m_pImpl
->m_pCreator
->getConfigWriteAccess(
2183 aFullPropName
), UNO_QUERY
);
2184 Reference
< XChangesBatch
> xBatch(
2185 m_pImpl
->m_pCreator
->getConfigWriteAccess(
2186 OUString() ), UNO_QUERY
);
2188 if ( xNameReplace
.is() && xBatch
.is() )
2193 xNameReplace
->replaceByName(
2195 makeAny( rNewValue
.Handle
) );
2198 OUString aValueName
= aFullPropName
;
2199 aValueName
+= "/Value";
2201 = xRootHierNameAccess
->getByHierarchicalName(
2204 xNameReplace
->replaceByName(
2208 // Write state ( Now it is a directly set value )
2209 xNameReplace
->replaceByName(
2213 PropertyState_DIRECT_VALUE
) ) );
2216 xBatch
->commitChanges();
2218 if ( m_pImpl
->m_pPropertyChangeListeners
)
2220 PropertyChangeEvent aEvt
;
2221 aEvt
.Source
= (OWeakObject
*)this;
2222 aEvt
.PropertyName
= rNewValue
.Name
;
2223 aEvt
.PropertyHandle
= rNewValue
.Handle
;
2224 aEvt
.Further
= sal_False
;
2225 aEvt
.OldValue
= aOldValue
;
2226 aEvt
.NewValue
= rNewValue
.Value
;
2228 aEvents
.push_back( aEvt
);
2231 catch (const IllegalArgumentException
&)
2235 catch (const NoSuchElementException
&)
2237 // getByHierarchicalName, replaceByName
2239 catch (const WrappedTargetException
&)
2241 // replaceByName, commitChanges
2247 // Callback follows!
2250 if ( m_pImpl
->m_pPropertyChangeListeners
)
2252 // Notify property changes.
2253 Events::const_iterator it
= aEvents
.begin();
2254 Events::const_iterator end
= aEvents
.end();
2258 notifyPropertyChangeEvent( (*it
) );
2266 OSL_FAIL( "PersistentPropertySet::setPropertyValues - Nothing set!" );
2269 //=========================================================================
2271 // Non-interface methods
2273 //=========================================================================
2275 void PersistentPropertySet::notifyPropertyChangeEvent(
2276 const PropertyChangeEvent
& rEvent
) const
2278 // Get "normal" listeners for the property.
2279 OInterfaceContainerHelper
* pContainer
=
2280 m_pImpl
->m_pPropertyChangeListeners
->getContainer(
2281 rEvent
.PropertyName
);
2282 if ( pContainer
&& pContainer
->getLength() )
2284 OInterfaceIteratorHelper
aIter( *pContainer
);
2285 while ( aIter
.hasMoreElements() )
2288 Reference
< XPropertyChangeListener
> xListener(
2289 aIter
.next(), UNO_QUERY
);
2290 if ( xListener
.is() )
2291 xListener
->propertyChange( rEvent
);
2295 // Get "normal" listeners for all properties.
2296 OInterfaceContainerHelper
* pNoNameContainer
=
2297 m_pImpl
->m_pPropertyChangeListeners
->getContainer( OUString() );
2298 if ( pNoNameContainer
&& pNoNameContainer
->getLength() )
2300 OInterfaceIteratorHelper
aIter( *pNoNameContainer
);
2301 while ( aIter
.hasMoreElements() )
2304 Reference
< XPropertyChangeListener
> xListener(
2305 aIter
.next(), UNO_QUERY
);
2306 if ( xListener
.is() )
2307 xListener
->propertyChange( rEvent
);
2312 //=========================================================================
2313 void PersistentPropertySet::notifyPropertySetInfoChange(
2314 const PropertySetInfoChangeEvent
& evt
) const
2316 if ( !m_pImpl
->m_pPropSetChangeListeners
)
2319 // Notify event listeners.
2320 OInterfaceIteratorHelper
aIter( *( m_pImpl
->m_pPropSetChangeListeners
) );
2321 while ( aIter
.hasMoreElements() )
2324 Reference
< XPropertySetInfoChangeListener
>
2325 xListener( aIter
.next(), UNO_QUERY
);
2326 if ( xListener
.is() )
2327 xListener
->propertySetInfoChange( evt
);
2331 //=========================================================================
2332 const OUString
& PersistentPropertySet::getFullKey()
2334 if ( m_pImpl
->m_aFullKey
.isEmpty() )
2336 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
2337 if ( m_pImpl
->m_aFullKey
.isEmpty() )
2340 = makeHierarchalNameSegment( m_pImpl
->m_aKey
);
2346 return m_pImpl
->m_aFullKey
;
2349 //=========================================================================
2350 PropertySetRegistry
& PersistentPropertySet::getPropertySetRegistry()
2352 return *m_pImpl
->m_pCreator
;
2355 //=========================================================================
2356 //=========================================================================
2358 // PropertySetInfo_Impl Implementation.
2360 //=========================================================================
2361 //=========================================================================
2363 PropertySetInfo_Impl::PropertySetInfo_Impl(
2364 const Reference
< XMultiServiceFactory
>& rxSMgr
,
2365 PersistentPropertySet
* pOwner
)
2366 : m_xSMgr( rxSMgr
),
2372 //=========================================================================
2374 PropertySetInfo_Impl::~PropertySetInfo_Impl()
2378 // !!! Do not delete m_pOwner !!!
2381 //=========================================================================
2383 // XInterface methods.
2385 //=========================================================================
2387 XINTERFACE_IMPL_2( PropertySetInfo_Impl
,
2391 //=========================================================================
2393 // XTypeProvider methods.
2395 //=========================================================================
2397 XTYPEPROVIDER_IMPL_2( PropertySetInfo_Impl
,
2401 //=========================================================================
2403 // XPropertySetInfo methods.
2405 //=========================================================================
2408 Sequence
< Property
> SAL_CALL
PropertySetInfo_Impl::getProperties()
2409 throw( RuntimeException
)
2413 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
2414 m_pOwner
->getPropertySetRegistry().getRootConfigReadAccess(),
2416 if ( xRootHierNameAccess
.is() )
2420 Reference
< XNameAccess
> xNameAccess
;
2421 xRootHierNameAccess
->getByHierarchicalName(
2422 m_pOwner
->getFullKey() )
2424 if ( xNameAccess
.is() )
2426 // Obtain property names.
2428 Sequence
< OUString
> aElems
2429 = xNameAccess
->getElementNames();
2431 sal_uInt32 nCount
= aElems
.getLength();
2432 Sequence
< Property
>* pPropSeq
2433 = new Sequence
< Property
>( nCount
);
2437 Reference
< XHierarchicalNameAccess
> xHierNameAccess(
2438 xNameAccess
, UNO_QUERY
);
2440 OSL_ENSURE( xHierNameAccess
.is(),
2441 "PropertySetInfo_Impl::getProperties - "
2442 "No hierarchical name access!" );
2444 if ( xHierNameAccess
.is() )
2446 const OUString
aHandleName("/Handle");
2447 const OUString
aValueName("/Value");
2448 const OUString
aAttrName("/Attributes");
2450 Property
* pProps
= pPropSeq
->getArray();
2452 for ( sal_uInt32 n
= 0; n
< nCount
; ++n
)
2454 Property
& rProp
= pProps
[ n
];
2455 OUString rName
= aElems
[ n
];
2457 = makeHierarchalNameSegment( rName
);
2459 // Set property name.
2465 // Obtain and set property handle
2466 OUString aHierName
= aXMLName
;
2467 aHierName
+= aHandleName
;
2469 = xHierNameAccess
->getByHierarchicalName(
2472 if ( !( aKeyValue
>>= rProp
.Handle
) )
2473 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2474 "Error getting property handle!" );
2476 catch (const NoSuchElementException
&)
2478 // getByHierarchicalName
2480 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2481 "NoSuchElementException!" );
2486 // Obtain and set property type
2487 OUString aHierName
= aXMLName
;
2488 aHierName
+= aValueName
;
2490 = xHierNameAccess
->getByHierarchicalName(
2493 // Note: The type may be void if addProperty
2494 // was called with a default value
2497 rProp
.Type
= aKeyValue
.getValueType();
2499 catch (const NoSuchElementException
&)
2501 // getByHierarchicalName
2503 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2504 "NoSuchElementException!" );
2509 // Obtain and set property attributes
2510 OUString aHierName
= aXMLName
;
2511 aHierName
+= aAttrName
;
2513 = xHierNameAccess
->getByHierarchicalName(
2516 sal_Int32 nAttribs
= 0;
2517 if ( aKeyValue
>>= nAttribs
)
2519 = sal_Int16( nAttribs
);
2521 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2522 "Error getting property attributes!" );
2524 catch (const NoSuchElementException
&)
2526 // getByHierarchicalName
2528 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2529 "NoSuchElementException!" );
2536 m_pProps
= pPropSeq
;
2540 catch (const NoSuchElementException
&)
2542 // getByHierarchicalName
2546 OSL_FAIL( "PropertySetInfo_Impl::getProperties - Error!" );
2547 m_pProps
= new Sequence
< Property
>( 0 );
2553 //=========================================================================
2555 Property SAL_CALL
PropertySetInfo_Impl::getPropertyByName(
2556 const OUString
& aName
)
2557 throw( UnknownPropertyException
, RuntimeException
)
2559 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
2560 m_pOwner
->getPropertySetRegistry().getRootConfigReadAccess(),
2562 if ( xRootHierNameAccess
.is() )
2564 OUString
aFullPropName( m_pOwner
->getFullKey() );
2565 aFullPropName
+= "/";
2566 aFullPropName
+= makeHierarchalNameSegment( aName
);
2568 // Does property exist?
2569 if ( !xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
) )
2570 throw UnknownPropertyException();
2577 OUString aKey
= aFullPropName
;
2580 if ( !( xRootHierNameAccess
->getByHierarchicalName( aKey
)
2581 >>= aProp
.Handle
) )
2583 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2588 // Obtain Value and extract type.
2589 aKey
= aFullPropName
;
2592 Any aValue
= xRootHierNameAccess
->getByHierarchicalName( aKey
);
2593 if ( !aValue
.hasValue() )
2595 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2600 aProp
.Type
= aValue
.getValueType();
2602 // Obtain Attributes.
2603 aKey
= aFullPropName
;
2604 aKey
+= "/Attributes";
2606 sal_Int32 nAttribs
= 0;
2607 if ( xRootHierNameAccess
->getByHierarchicalName( aKey
)
2609 aProp
.Attributes
= sal_Int16( nAttribs
);
2612 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2623 catch (const NoSuchElementException
&)
2625 // getByHierarchicalName
2627 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2628 "caught NoSuchElementException!" );
2633 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - Error!" );
2637 //=========================================================================
2639 sal_Bool SAL_CALL
PropertySetInfo_Impl::hasPropertyByName(
2640 const OUString
& Name
)
2641 throw( RuntimeException
)
2643 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
2644 m_pOwner
->getPropertySetRegistry().getRootConfigReadAccess(),
2646 if ( xRootHierNameAccess
.is() )
2648 OUString
aFullPropName( m_pOwner
->getFullKey() );
2649 aFullPropName
+= "/";
2650 aFullPropName
+= makeHierarchalNameSegment( Name
);
2652 return xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
);
2658 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */