1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 /**************************************************************************
23 **************************************************************************
25 *************************************************************************/
28 #include <unordered_map>
29 #include <sal/log.hxx>
30 #include <osl/diagnose.h>
31 #include <rtl/ustrbuf.hxx>
32 #include <rtl/ref.hxx>
33 #include <cppuhelper/interfacecontainer.hxx>
34 #include <comphelper/interfacecontainer2.hxx>
35 #include <comphelper/propertysequence.hxx>
36 #include <com/sun/star/beans/IllegalTypeException.hpp>
37 #include <com/sun/star/beans/NotRemoveableException.hpp>
38 #include <com/sun/star/beans/PropertyAttribute.hpp>
39 #include <com/sun/star/beans/PropertyExistException.hpp>
40 #include <com/sun/star/beans/PropertySetInfoChange.hpp>
41 #include <com/sun/star/configuration/theDefaultProvider.hpp>
42 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
43 #include <com/sun/star/container/XNameContainer.hpp>
44 #include <com/sun/star/container/XNameReplace.hpp>
45 #include <com/sun/star/util/XChangesBatch.hpp>
46 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
47 #include <cppuhelper/implbase.hxx>
48 #include <ucbhelper/getcomponentcontext.hxx>
49 #include <ucbhelper/macros.hxx>
50 #include <tools/diagnose_ex.h>
51 #include "ucbstore.hxx"
53 using namespace com::sun::star::beans
;
54 using namespace com::sun::star::configuration
;
55 using namespace com::sun::star::container
;
56 using namespace com::sun::star::lang
;
57 using namespace com::sun::star::ucb
;
58 using namespace com::sun::star::uno
;
59 using namespace com::sun::star::util
;
60 using namespace comphelper
;
64 static OUString
makeHierarchalNameSegment( const OUString
& rIn
)
66 OUStringBuffer aBuffer
;
67 aBuffer
.append( "['" );
69 sal_Int32 nCount
= rIn
.getLength();
70 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
72 const sal_Unicode c
= rIn
[ n
];
76 aBuffer
.append( "&" );
80 aBuffer
.append( """ );
84 aBuffer
.append( "'" );
88 aBuffer
.append( "<" );
92 aBuffer
.append( ">" );
101 aBuffer
.append( "']" );
102 return aBuffer
.makeStringAndClear();
105 #define STORE_CONTENTPROPERTIES_KEY "/org.openoffice.ucb.Store/ContentProperties"
107 // describe path of cfg entry
108 #define CFGPROPERTY_NODEPATH "nodepath"
110 // PropertySetMap_Impl.
111 typedef std::unordered_map
< OUString
, PersistentPropertySet
*> PropertySetMap_Impl
;
113 // class PropertySetInfo_Impl
114 class PropertySetInfo_Impl
: public cppu::WeakImplHelper
< XPropertySetInfo
>
116 std::unique_ptr
<Sequence
< Property
>>
118 PersistentPropertySet
* m_pOwner
;
121 explicit PropertySetInfo_Impl(PersistentPropertySet
* pOwner
);
124 virtual Sequence
< Property
> SAL_CALL
getProperties() override
;
125 virtual Property SAL_CALL
getPropertyByName( const OUString
& aName
) override
;
126 virtual sal_Bool SAL_CALL
hasPropertyByName( const OUString
& Name
) override
;
128 // Non-interface methods.
129 void reset() { m_pProps
.reset(); }
139 Sequence
< Any
> m_aInitArgs
;
140 Reference
< XPropertySetRegistry
> m_xTheRegistry
;
144 // UcbStore Implementation.
147 UcbStore::UcbStore( const Reference
< XComponentContext
>& xContext
)
148 : m_xContext( xContext
),
149 m_pImpl( new UcbStore_Impl
)
155 UcbStore::~UcbStore()
159 XSERVICEINFO_COMMOM_IMPL( UcbStore
,
160 "com.sun.star.comp.ucb.UcbStore" )
161 /// @throws css::uno::Exception
162 static css::uno::Reference
< css::uno::XInterface
>
163 UcbStore_CreateInstance( const css::uno::Reference
< css::lang::XMultiServiceFactory
> & rSMgr
)
165 return static_cast<css::lang::XServiceInfo
*>(
166 new UcbStore(ucbhelper::getComponentContext(rSMgr
)));
169 css::uno::Sequence
< OUString
>
170 UcbStore::getSupportedServiceNames_Static()
172 css::uno::Sequence
< OUString
> aSNS
{ STORE_SERVICE_NAME
};
176 // Service factory implementation.
179 ONE_INSTANCE_SERVICE_FACTORY_IMPL( UcbStore
);
182 // XPropertySetRegistryFactory methods.
186 Reference
< XPropertySetRegistry
> SAL_CALL
187 UcbStore::createPropertySetRegistry( const OUString
& )
189 // The URL parameter is ignored by this interface implementation. It always
190 // uses the configuration server as storage medium.
192 if ( !m_pImpl
->m_xTheRegistry
.is() )
194 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
195 if ( !m_pImpl
->m_xTheRegistry
.is() )
196 m_pImpl
->m_xTheRegistry
= new PropertySetRegistry( m_xContext
, m_pImpl
->m_aInitArgs
);
199 return m_pImpl
->m_xTheRegistry
;
203 // XInitialization methods.
207 void SAL_CALL
UcbStore::initialize( const Sequence
< Any
>& aArguments
)
209 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
210 m_pImpl
->m_aInitArgs
= aArguments
;
215 // PropertySetRegistry_Impl.
218 struct PropertySetRegistry_Impl
220 const Sequence
< Any
> m_aInitArgs
;
221 PropertySetMap_Impl m_aPropSets
;
222 Reference
< XMultiServiceFactory
> m_xConfigProvider
;
223 Reference
< XInterface
> m_xRootReadAccess
;
224 Reference
< XInterface
> m_xRootWriteAccess
;
226 bool m_bTriedToGetRootReadAccess
;
227 bool m_bTriedToGetRootWriteAccess
;
229 explicit PropertySetRegistry_Impl(const Sequence
<Any
> &rInitArgs
)
230 : m_aInitArgs(rInitArgs
)
231 , m_bTriedToGetRootReadAccess(false)
232 , m_bTriedToGetRootWriteAccess(false)
237 // PropertySetRegistry Implementation.
240 PropertySetRegistry::PropertySetRegistry(
241 const Reference
< XComponentContext
>& xContext
,
242 const Sequence
< Any
> &rInitArgs
)
243 : m_xContext( xContext
),
244 m_pImpl( new PropertySetRegistry_Impl( rInitArgs
) )
250 PropertySetRegistry::~PropertySetRegistry()
255 // XServiceInfo methods.
258 OUString SAL_CALL
PropertySetRegistry::getImplementationName()
260 return "com.sun.star.comp.ucb.PropertySetRegistry";
263 sal_Bool SAL_CALL
PropertySetRegistry::supportsService( const OUString
& ServiceName
)
265 return cppu::supportsService( this, ServiceName
);
268 css::uno::Sequence
< OUString
> SAL_CALL
PropertySetRegistry::getSupportedServiceNames()
270 return { PROPSET_REG_SERVICE_NAME
};
274 // XPropertySetRegistry methods.
278 Reference
< XPersistentPropertySet
> SAL_CALL
279 PropertySetRegistry::openPropertySet( const OUString
& key
, sal_Bool create
)
281 if ( !key
.isEmpty() )
283 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
285 PropertySetMap_Impl
& rSets
= m_pImpl
->m_aPropSets
;
287 PropertySetMap_Impl::const_iterator it
= rSets
.find( key
);
288 if ( it
!= rSets
.end() )
290 // Already instantiated.
291 return Reference
< XPersistentPropertySet
>( (*it
).second
);
295 // Create new instance.
296 Reference
< XNameAccess
> xRootNameAccess(
297 getRootConfigReadAccess(), UNO_QUERY
);
298 if ( xRootNameAccess
.is() )
300 // Propertyset in registry?
301 if ( xRootNameAccess
->hasByName( key
) )
304 return Reference
< XPersistentPropertySet
>(
305 new PersistentPropertySet(
310 // No. Create entry for propertyset.
312 Reference
< XSingleServiceFactory
> xFac(
313 getConfigWriteAccess( OUString() ), UNO_QUERY
);
314 Reference
< XChangesBatch
> xBatch( xFac
, UNO_QUERY
);
315 Reference
< XNameContainer
> xContainer( xFac
, UNO_QUERY
);
317 OSL_ENSURE( xFac
.is(),
318 "PropertySetRegistry::openPropertySet - "
321 OSL_ENSURE( xBatch
.is(),
322 "PropertySetRegistry::openPropertySet - "
325 OSL_ENSURE( xContainer
.is(),
326 "PropertySetRegistry::openPropertySet - "
329 if ( xFac
.is() && xBatch
.is() && xContainer
.is() )
333 // Create new "Properties" config item.
334 Reference
< XNameReplace
> xNameReplace(
335 xFac
->createInstance(), UNO_QUERY
);
337 if ( xNameReplace
.is() )
342 xContainer
->insertByName(
343 key
, makeAny( xNameReplace
) );
345 xBatch
->commitChanges();
347 return Reference
< XPersistentPropertySet
>(
348 new PersistentPropertySet(
352 catch (const IllegalArgumentException
&)
356 OSL_FAIL( "PropertySetRegistry::openPropertySet - "
357 "caught IllegalArgumentException!" );
359 catch (const ElementExistException
&)
363 OSL_FAIL( "PropertySetRegistry::openPropertySet - "
364 "caught ElementExistException!" );
366 catch (const WrappedTargetException
&)
368 // insertByName, commitChanges
370 OSL_FAIL( "PropertySetRegistry::openPropertySet - "
371 "caught WrappedTargetException!" );
373 catch (const RuntimeException
&)
375 OSL_FAIL( "PropertySetRegistry::openPropertySet - "
376 "caught RuntimeException!" );
378 catch (const Exception
&)
382 OSL_FAIL( "PropertySetRegistry::openPropertySet - "
383 "caught Exception!" );
389 // No entry. Fail, but no error.
390 return Reference
< XPersistentPropertySet
>();
394 SAL_WARN( "ucb", "no root access" );
398 return Reference
< XPersistentPropertySet
>();
403 void SAL_CALL
PropertySetRegistry::removePropertySet( const OUString
& key
)
408 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
410 Reference
< XNameAccess
> xRootNameAccess(
411 getRootConfigReadAccess(), UNO_QUERY
);
412 if ( xRootNameAccess
.is() )
414 // Propertyset in registry?
415 if ( !xRootNameAccess
->hasByName( key
) )
417 Reference
< XChangesBatch
> xBatch(
418 getConfigWriteAccess( OUString() ), UNO_QUERY
);
419 Reference
< XNameContainer
> xContainer( xBatch
, UNO_QUERY
);
421 if ( xBatch
.is() && xContainer
.is() )
426 xContainer
->removeByName( key
);
428 xBatch
->commitChanges();
433 catch (const NoSuchElementException
&)
437 OSL_FAIL( "PropertySetRegistry::removePropertySet - "
438 "caught NoSuchElementException!" );
441 catch (const WrappedTargetException
&)
445 OSL_FAIL( "PropertySetRegistry::removePropertySet - "
446 "caught WrappedTargetException!" );
454 SAL_WARN( "ucb", "no root access" );
458 // XElementAccess methods.
462 css::uno::Type SAL_CALL
PropertySetRegistry::getElementType()
464 return cppu::UnoType
<XPersistentPropertySet
>::get();
469 sal_Bool SAL_CALL
PropertySetRegistry::hasElements()
471 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
473 Reference
< XElementAccess
> xElemAccess(
474 getRootConfigReadAccess(), UNO_QUERY
);
475 if ( xElemAccess
.is() )
476 return xElemAccess
->hasElements();
482 // XNameAccess methods.
486 Any SAL_CALL
PropertySetRegistry::getByName( const OUString
& aName
)
488 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
490 Reference
< XNameAccess
> xNameAccess(
491 getRootConfigReadAccess(), UNO_QUERY
);
492 if ( xNameAccess
.is() )
497 return xNameAccess
->getByName( aName
);
499 catch (const NoSuchElementException
&)
503 catch (const WrappedTargetException
&)
514 Sequence
< OUString
> SAL_CALL
PropertySetRegistry::getElementNames()
516 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
518 Reference
< XNameAccess
> xNameAccess(
519 getRootConfigReadAccess(), UNO_QUERY
);
520 if ( xNameAccess
.is() )
522 return xNameAccess
->getElementNames();
524 return Sequence
< OUString
>( 0 );
529 sal_Bool SAL_CALL
PropertySetRegistry::hasByName( const OUString
& aName
)
531 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
533 Reference
< XNameAccess
> xNameAccess(
534 getRootConfigReadAccess(), UNO_QUERY
);
535 if ( xNameAccess
.is() )
537 return xNameAccess
->hasByName( aName
);
544 void PropertySetRegistry::add( PersistentPropertySet
* pSet
)
546 OUString
key( pSet
->getKey() );
548 if ( !key
.isEmpty() )
550 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
551 m_pImpl
->m_aPropSets
[ key
] = pSet
;
556 void PropertySetRegistry::remove( PersistentPropertySet
* pSet
)
558 OUString
key( pSet
->getKey() );
560 if ( !key
.isEmpty() )
562 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
564 PropertySetMap_Impl
& rSets
= m_pImpl
->m_aPropSets
;
566 PropertySetMap_Impl::iterator it
= rSets
.find( key
);
567 if ( it
!= rSets
.end() )
576 void PropertySetRegistry::renamePropertySet( const OUString
& rOldKey
,
577 const OUString
& rNewKey
)
579 if ( rOldKey
== rNewKey
)
582 Reference
< XNameAccess
> xRootNameAccess(
583 getConfigWriteAccess( OUString() ), UNO_QUERY
);
584 if ( xRootNameAccess
.is() )
587 if ( xRootNameAccess
->hasByName( rOldKey
) )
589 // New key not present?
590 if ( xRootNameAccess
->hasByName( rNewKey
) )
592 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
596 Reference
< XSingleServiceFactory
> xFac(
597 xRootNameAccess
, UNO_QUERY
);
598 Reference
< XChangesBatch
> xBatch( xFac
, UNO_QUERY
);
599 Reference
< XNameContainer
> xContainer( xFac
, UNO_QUERY
);
601 OSL_ENSURE( xFac
.is(),
602 "PropertySetRegistry::renamePropertySet - "
605 OSL_ENSURE( xBatch
.is(),
606 "PropertySetRegistry::renamePropertySet - "
609 OSL_ENSURE( xContainer
.is(),
610 "PropertySetRegistry::renamePropertySet - "
613 if ( xFac
.is() && xBatch
.is() && xContainer
.is() )
616 // Create new "Properties" config item.
621 Reference
< XNameReplace
> xNameReplace(
622 xFac
->createInstance(), UNO_QUERY
);
624 if ( xNameReplace
.is() )
627 xContainer
->insertByName(
628 rNewKey
, makeAny( xNameReplace
) );
630 xBatch
->commitChanges();
633 catch (const IllegalArgumentException
&)
637 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
638 "caught IllegalArgumentException!" );
641 catch (const ElementExistException
&)
645 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
646 "caught ElementExistException!" );
649 catch (const WrappedTargetException
&)
651 // insertByName, commitChanges
653 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
654 "caught WrappedTargetException!" );
657 catch (const RuntimeException
&)
659 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
660 "caught RuntimeException!" );
663 catch (const Exception
&)
667 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
668 "caught Exception!" );
676 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
677 xRootNameAccess
, UNO_QUERY
);
678 if ( !xRootHierNameAccess
.is() )
680 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
681 "No hierarchical name access!" );
687 OUString aOldValuesKey
688 = makeHierarchalNameSegment( rOldKey
) + "/Values";
690 Reference
< XNameAccess
> xOldNameAccess
;
691 xRootHierNameAccess
->getByHierarchicalName(
694 if ( !xOldNameAccess
.is() )
696 OSL_FAIL( "PersistentPropertySet::renamePropertySet - "
697 "No old name access!" );
701 // Obtain property names.
702 const Sequence
< OUString
> aElems
703 = xOldNameAccess
->getElementNames();
704 if ( aElems
.hasElements() )
706 OUString aNewValuesKey
707 = makeHierarchalNameSegment( rNewKey
) + "/Values";
709 Reference
< XSingleServiceFactory
> xNewFac
;
710 xRootHierNameAccess
->getByHierarchicalName(
715 OSL_FAIL( "PersistentPropertySet::renamePropertySet - "
720 Reference
< XNameContainer
> xNewContainer(
721 xNewFac
, UNO_QUERY
);
722 if ( !xNewContainer
.is() )
724 OSL_FAIL( "PersistentPropertySet::renamePropertySet - "
725 "No new container!" );
729 aOldValuesKey
+= "/";
731 OUString
const aHandleKey("/Handle");
732 OUString
const aValueKey("/Value");
733 OUString
const aStateKey("/State");
734 OUString
const aAttrKey("/Attributes");
736 for ( const OUString
& rPropName
: aElems
)
739 Reference
< XNameReplace
> xNewPropNameReplace(
740 xNewFac
->createInstance(), UNO_QUERY
);
742 if ( !xNewPropNameReplace
.is() )
744 OSL_FAIL( "PersistentPropertySet::renamePropertySet - "
745 "No new prop name replace!" );
752 OUString aKey
= aOldValuesKey
;
753 aKey
+= makeHierarchalNameSegment( rPropName
);
756 OUString aNewKey1
= aKey
+ aHandleKey
;
758 xRootHierNameAccess
->getByHierarchicalName(
760 xNewPropNameReplace
->replaceByName( "Handle", aAny
);
763 aNewKey1
= aKey
+ aValueKey
;
765 xRootHierNameAccess
->getByHierarchicalName(
767 xNewPropNameReplace
->replaceByName( "Value", aAny
);
770 aNewKey1
= aKey
+ aStateKey
;
772 xRootHierNameAccess
->getByHierarchicalName(
774 xNewPropNameReplace
->replaceByName( "State", aAny
);
777 aNewKey1
= aKey
+ aAttrKey
;
779 xRootHierNameAccess
->getByHierarchicalName(
781 xNewPropNameReplace
->replaceByName( "Attributes", aAny
);
784 xNewContainer
->insertByName(
785 rPropName
, makeAny( xNewPropNameReplace
) );
788 xBatch
->commitChanges();
792 catch (const IllegalArgumentException
&)
794 // insertByName, replaceByName
796 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
797 "caught IllegalArgumentException!" );
800 catch (const ElementExistException
&)
804 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
805 "caught ElementExistException!" );
808 catch (const WrappedTargetException
&)
810 // insertByName, replaceByName, commitChanges
812 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
813 "caught WrappedTargetException!" );
816 catch (const NoSuchElementException
&)
818 // getByHierarchicalName, replaceByName
820 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
821 "caught NoSuchElementException!" );
824 catch (const RuntimeException
&)
826 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
827 "caught RuntimeException!" );
830 catch (const Exception
&)
834 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
835 "caught Exception!" );
840 // Remove old entry...
846 xContainer
->removeByName( rOldKey
);
848 xBatch
->commitChanges();
853 catch (const NoSuchElementException
&)
857 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
858 "caught NoSuchElementException!" );
861 catch (const WrappedTargetException
&)
865 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
866 "caught WrappedTargetException!" );
873 OSL_FAIL( "PropertySetRegistry::renamePropertySet - Error!" );
877 Reference
< XMultiServiceFactory
> PropertySetRegistry::getConfigProvider()
879 if ( !m_pImpl
->m_xConfigProvider
.is() )
881 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
882 if ( !m_pImpl
->m_xConfigProvider
.is() )
884 const Sequence
< Any
>& rInitArgs
= m_pImpl
->m_aInitArgs
;
886 if ( rInitArgs
.hasElements() )
888 // Extract config provider from service init args.
889 rInitArgs
[ 0 ] >>= m_pImpl
->m_xConfigProvider
;
891 OSL_ENSURE( m_pImpl
->m_xConfigProvider
.is(),
892 "PropertySetRegistry::getConfigProvider - "
893 "No config provider!" );
899 m_pImpl
->m_xConfigProvider
= theDefaultProvider::get( m_xContext
);
901 catch (const Exception
&)
903 TOOLS_WARN_EXCEPTION( "ucb", "");
909 return m_pImpl
->m_xConfigProvider
;
913 Reference
< XInterface
> PropertySetRegistry::getRootConfigReadAccess()
917 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
919 if ( !m_pImpl
->m_xRootReadAccess
.is() )
921 if ( m_pImpl
->m_bTriedToGetRootReadAccess
)
923 OSL_FAIL( "PropertySetRegistry::getRootConfigReadAccess - "
924 "Unable to read any config data! -> #82494#" );
925 return Reference
< XInterface
>();
930 if ( m_pImpl
->m_xConfigProvider
.is() )
932 Sequence
<Any
> aArguments(comphelper::InitAnyPropertySequence(
934 {CFGPROPERTY_NODEPATH
, Any(OUString( STORE_CONTENTPROPERTIES_KEY
))}
937 m_pImpl
->m_bTriedToGetRootReadAccess
= true;
939 m_pImpl
->m_xRootReadAccess
=
940 m_pImpl
->m_xConfigProvider
->createInstanceWithArguments(
941 "com.sun.star.configuration.ConfigurationAccess",
944 if ( m_pImpl
->m_xRootReadAccess
.is() )
945 return m_pImpl
->m_xRootReadAccess
;
949 return m_pImpl
->m_xRootReadAccess
;
951 catch (const RuntimeException
&)
955 catch (const Exception
&)
957 // createInstance, createInstanceWithArguments
959 OSL_FAIL( "PropertySetRegistry::getRootConfigReadAccess - caught Exception!" );
960 return Reference
< XInterface
>();
963 SAL_WARN( "ucb", "Error!" );
964 return Reference
< XInterface
>();
968 Reference
< XInterface
> PropertySetRegistry::getConfigWriteAccess(
969 const OUString
& rPath
)
973 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
975 if ( !m_pImpl
->m_xRootWriteAccess
.is() )
977 if ( m_pImpl
->m_bTriedToGetRootWriteAccess
)
979 OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - "
980 "Unable to write any config data! -> #82494#" );
981 return Reference
< XInterface
>();
986 if ( m_pImpl
->m_xConfigProvider
.is() )
988 Sequence
<Any
> aArguments(comphelper::InitAnyPropertySequence(
990 {CFGPROPERTY_NODEPATH
, Any(OUString( STORE_CONTENTPROPERTIES_KEY
))}
993 m_pImpl
->m_bTriedToGetRootWriteAccess
= true;
995 m_pImpl
->m_xRootWriteAccess
=
996 m_pImpl
->m_xConfigProvider
->createInstanceWithArguments(
997 "com.sun.star.configuration.ConfigurationUpdateAccess",
1000 OSL_ENSURE( m_pImpl
->m_xRootWriteAccess
.is(),
1001 "PropertySetRegistry::getConfigWriteAccess - "
1002 "No config update access!" );
1006 if ( m_pImpl
->m_xRootWriteAccess
.is() )
1008 if ( !rPath
.isEmpty() )
1010 Reference
< XHierarchicalNameAccess
> xNA(
1011 m_pImpl
->m_xRootWriteAccess
, UNO_QUERY
);
1014 Reference
< XInterface
> xInterface
;
1015 xNA
->getByHierarchicalName( rPath
) >>= xInterface
;
1017 if ( xInterface
.is() )
1022 return m_pImpl
->m_xRootWriteAccess
;
1025 catch (const RuntimeException
&)
1029 catch (const NoSuchElementException
&)
1031 // getByHierarchicalName
1033 OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - "
1034 "caught NoSuchElementException!" );
1035 return Reference
< XInterface
>();
1037 catch (const Exception
&)
1039 // createInstance, createInstanceWithArguments
1041 OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - "
1042 "caught Exception!" );
1043 return Reference
< XInterface
>();
1046 OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - Error!" );
1047 return Reference
< XInterface
>();
1050 typedef OMultiTypeInterfaceContainerHelperVar
<OUString
> PropertyListeners_Impl
;
1052 struct PersistentPropertySet_Impl
1054 rtl::Reference
<PropertySetRegistry
> m_pCreator
;
1055 rtl::Reference
<PropertySetInfo_Impl
> m_pInfo
;
1056 OUString
const m_aKey
;
1057 OUString m_aFullKey
;
1058 osl::Mutex m_aMutex
;
1059 std::unique_ptr
<OInterfaceContainerHelper2
> m_pDisposeEventListeners
;
1060 std::unique_ptr
<OInterfaceContainerHelper2
> m_pPropSetChangeListeners
;
1061 std::unique_ptr
<PropertyListeners_Impl
> m_pPropertyChangeListeners
;
1063 PersistentPropertySet_Impl( PropertySetRegistry
& rCreator
,
1064 const OUString
& rKey
)
1065 : m_pCreator( &rCreator
), m_aKey( rKey
)
1071 // PersistentPropertySet Implementation.
1074 PersistentPropertySet::PersistentPropertySet(
1075 PropertySetRegistry
& rCreator
,
1076 const OUString
& rKey
)
1077 : m_pImpl( new PersistentPropertySet_Impl( rCreator
, rKey
) )
1079 // register at creator.
1080 rCreator
.add( this );
1085 PersistentPropertySet::~PersistentPropertySet()
1087 // deregister at creator.
1088 m_pImpl
->m_pCreator
->remove( this );
1091 // XServiceInfo methods.
1093 OUString SAL_CALL
PersistentPropertySet::getImplementationName()
1095 return "com.sun.star.comp.ucb.PersistentPropertySet";
1098 sal_Bool SAL_CALL
PersistentPropertySet::supportsService( const OUString
& ServiceName
)
1100 return cppu::supportsService( this, ServiceName
);
1103 css::uno::Sequence
< OUString
> SAL_CALL
1104 PersistentPropertySet::getSupportedServiceNames()
1106 return { PERS_PROPSET_SERVICE_NAME
};
1110 // XComponent methods.
1114 void SAL_CALL
PersistentPropertySet::dispose()
1116 if ( m_pImpl
->m_pDisposeEventListeners
&&
1117 m_pImpl
->m_pDisposeEventListeners
->getLength() )
1120 aEvt
.Source
= static_cast< XComponent
* >( this );
1121 m_pImpl
->m_pDisposeEventListeners
->disposeAndClear( aEvt
);
1124 if ( m_pImpl
->m_pPropSetChangeListeners
&&
1125 m_pImpl
->m_pPropSetChangeListeners
->getLength() )
1128 aEvt
.Source
= static_cast< XPropertySetInfoChangeNotifier
* >( this );
1129 m_pImpl
->m_pPropSetChangeListeners
->disposeAndClear( aEvt
);
1132 if ( m_pImpl
->m_pPropertyChangeListeners
)
1135 aEvt
.Source
= static_cast< XPropertySet
* >( this );
1136 m_pImpl
->m_pPropertyChangeListeners
->disposeAndClear( aEvt
);
1142 void SAL_CALL
PersistentPropertySet::addEventListener(
1143 const Reference
< XEventListener
>& Listener
)
1145 if ( !m_pImpl
->m_pDisposeEventListeners
)
1146 m_pImpl
->m_pDisposeEventListeners
.reset(
1147 new OInterfaceContainerHelper2( m_pImpl
->m_aMutex
) );
1149 m_pImpl
->m_pDisposeEventListeners
->addInterface( Listener
);
1154 void SAL_CALL
PersistentPropertySet::removeEventListener(
1155 const Reference
< XEventListener
>& Listener
)
1157 if ( m_pImpl
->m_pDisposeEventListeners
)
1158 m_pImpl
->m_pDisposeEventListeners
->removeInterface( Listener
);
1160 // Note: Don't want to delete empty container here -> performance.
1164 // XPropertySet methods.
1168 Reference
< XPropertySetInfo
> SAL_CALL
PersistentPropertySet::getPropertySetInfo()
1170 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
1172 if ( !m_pImpl
->m_pInfo
.is() )
1174 m_pImpl
->m_pInfo
= new PropertySetInfo_Impl( this );
1176 return Reference
< XPropertySetInfo
>( m_pImpl
->m_pInfo
.get() );
1181 void SAL_CALL
PersistentPropertySet::setPropertyValue( const OUString
& aPropertyName
,
1184 osl::ClearableGuard
< osl::Mutex
> aCGuard( m_pImpl
->m_aMutex
);
1186 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
1187 m_pImpl
->m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1188 if ( xRootHierNameAccess
.is() )
1190 OUString
aFullPropName( getFullKey() + "/" );
1191 aFullPropName
+= makeHierarchalNameSegment( aPropertyName
);
1193 // Does property exist?
1194 if ( xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
) )
1196 Reference
< XNameReplace
> xNameReplace(
1197 m_pImpl
->m_pCreator
->getConfigWriteAccess(
1198 aFullPropName
), UNO_QUERY
);
1199 Reference
< XChangesBatch
> xBatch(
1200 m_pImpl
->m_pCreator
->getConfigWriteAccess(
1201 OUString() ), UNO_QUERY
);
1203 if ( xNameReplace
.is() && xBatch
.is() )
1208 OUString aValueName
= aFullPropName
+ "/Value";
1210 = xRootHierNameAccess
->getByHierarchicalName(
1212 // Check value type.
1213 if ( aOldValue
.getValueType() != aValue
.getValueType() )
1216 throw IllegalArgumentException();
1220 xNameReplace
->replaceByName( "Value", aValue
);
1222 // Write state ( Now it is a directly set value )
1223 xNameReplace
->replaceByName(
1227 PropertyState_DIRECT_VALUE
) ) );
1230 xBatch
->commitChanges();
1232 PropertyChangeEvent aEvt
;
1233 if ( m_pImpl
->m_pPropertyChangeListeners
)
1236 aValueName
= aFullPropName
+ "/Handle";
1237 sal_Int32 nHandle
= -1;
1238 xRootHierNameAccess
->getByHierarchicalName( aValueName
)
1241 aEvt
.Source
= static_cast<OWeakObject
*>(this);
1242 aEvt
.PropertyName
= aPropertyName
;
1243 aEvt
.PropertyHandle
= nHandle
;
1244 aEvt
.Further
= false;
1245 aEvt
.OldValue
= aOldValue
;
1246 aEvt
.NewValue
= aValue
;
1248 // Callback follows!
1251 notifyPropertyChangeEvent( aEvt
);
1255 catch (const IllegalArgumentException
&)
1259 catch (const NoSuchElementException
&)
1261 // getByHierarchicalName, replaceByName
1263 catch (const WrappedTargetException
&)
1265 // replaceByName, commitChanges
1271 throw UnknownPropertyException(aPropertyName
);
1276 Any SAL_CALL
PersistentPropertySet::getPropertyValue(
1277 const OUString
& PropertyName
)
1279 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
1281 Reference
< XHierarchicalNameAccess
> xNameAccess(
1282 m_pImpl
->m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1283 if ( xNameAccess
.is() )
1285 OUString
aFullPropName( getFullKey() + "/" );
1286 aFullPropName
+= makeHierarchalNameSegment( PropertyName
) + "/Value";
1289 return xNameAccess
->getByHierarchicalName( aFullPropName
);
1291 catch (const NoSuchElementException
&)
1293 throw UnknownPropertyException(aFullPropName
);
1297 throw UnknownPropertyException(PropertyName
);
1302 void SAL_CALL
PersistentPropertySet::addPropertyChangeListener(
1303 const OUString
& aPropertyName
,
1304 const Reference
< XPropertyChangeListener
>& xListener
)
1308 if ( !m_pImpl
->m_pPropertyChangeListeners
)
1309 m_pImpl
->m_pPropertyChangeListeners
.reset(
1310 new PropertyListeners_Impl( m_pImpl
->m_aMutex
) );
1312 m_pImpl
->m_pPropertyChangeListeners
->addInterface(
1313 aPropertyName
, xListener
);
1318 void SAL_CALL
PersistentPropertySet::removePropertyChangeListener(
1319 const OUString
& aPropertyName
,
1320 const Reference
< XPropertyChangeListener
>& aListener
)
1324 if ( m_pImpl
->m_pPropertyChangeListeners
)
1325 m_pImpl
->m_pPropertyChangeListeners
->removeInterface(
1326 aPropertyName
, aListener
);
1328 // Note: Don't want to delete empty container here -> performance.
1333 void SAL_CALL
PersistentPropertySet::addVetoableChangeListener(
1335 const Reference
< XVetoableChangeListener
>& )
1338 // OSL_FAIL( // "PersistentPropertySet::addVetoableChangeListener - N.Y.I." );
1343 void SAL_CALL
PersistentPropertySet::removeVetoableChangeListener(
1345 const Reference
< XVetoableChangeListener
>& )
1348 // OSL_FAIL( // "PersistentPropertySet::removeVetoableChangeListener - N.Y.I." );
1352 // XPersistentPropertySet methods.
1356 Reference
< XPropertySetRegistry
> SAL_CALL
PersistentPropertySet::getRegistry()
1358 return Reference
< XPropertySetRegistry
>( m_pImpl
->m_pCreator
.get() );
1363 OUString SAL_CALL
PersistentPropertySet::getKey()
1365 return m_pImpl
->m_aKey
;
1373 OUString SAL_CALL
PersistentPropertySet::getName()
1376 return m_pImpl
->m_aKey
;
1381 void SAL_CALL
PersistentPropertySet::setName( const OUString
& aName
)
1383 if ( aName
!= m_pImpl
->m_aKey
)
1384 m_pImpl
->m_pCreator
->renamePropertySet( m_pImpl
->m_aKey
, aName
);
1388 // XPropertyContainer methods.
1392 void SAL_CALL
PersistentPropertySet::addProperty(
1393 const OUString
& Name
, sal_Int16 Attributes
, const Any
& DefaultValue
)
1395 if ( Name
.isEmpty() )
1396 throw IllegalArgumentException();
1398 // @@@ What other types can't be written to config server?
1400 // Check type class ( Not all types can be written to storage )
1401 TypeClass eTypeClass
= DefaultValue
.getValueTypeClass();
1402 if ( eTypeClass
== TypeClass_INTERFACE
)
1403 throw IllegalTypeException();
1405 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
1407 // Property already in set?
1409 OUString aFullValuesName
;
1411 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
1412 m_pImpl
->m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1413 if ( xRootHierNameAccess
.is() )
1415 aFullValuesName
= getFullKey();
1416 OUString aFullPropName
= aFullValuesName
+ "/";
1417 aFullPropName
+= makeHierarchalNameSegment( Name
);
1419 if ( xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
) )
1422 throw PropertyExistException();
1426 // Property is always removable.
1427 Attributes
|= PropertyAttribute::REMOVABLE
;
1431 Reference
< XSingleServiceFactory
> xFac(
1432 m_pImpl
->m_pCreator
->getConfigWriteAccess( aFullValuesName
),
1434 Reference
< XNameContainer
> xContainer( xFac
, UNO_QUERY
);
1435 Reference
< XChangesBatch
> xBatch(
1436 m_pImpl
->m_pCreator
->getConfigWriteAccess( OUString() ),
1439 OSL_ENSURE( xFac
.is(),
1440 "PersistentPropertySet::addProperty - No factory!" );
1442 OSL_ENSURE( xBatch
.is(),
1443 "PersistentPropertySet::addProperty - No batch!" );
1445 OSL_ENSURE( xContainer
.is(),
1446 "PersistentPropertySet::addProperty - No container!" );
1448 if ( xFac
.is() && xBatch
.is() && xContainer
.is() )
1452 // Create new "PropertyValue" config item.
1453 Reference
< XNameReplace
> xNameReplace(
1454 xFac
->createInstance(), UNO_QUERY
);
1456 if ( xNameReplace
.is() )
1461 xNameReplace
->replaceByName(
1463 makeAny( sal_Int32( -1 ) ) );
1465 // Set default value
1466 xNameReplace
->replaceByName(
1470 // Set state ( always "default" )
1471 xNameReplace
->replaceByName(
1475 PropertyState_DEFAULT_VALUE
) ) );
1478 xNameReplace
->replaceByName(
1480 makeAny( sal_Int32( Attributes
) ) );
1483 xContainer
->insertByName( Name
, makeAny( xNameReplace
) );
1486 xBatch
->commitChanges();
1488 // Property set info is invalid.
1489 if ( m_pImpl
->m_pInfo
.is() )
1490 m_pImpl
->m_pInfo
->reset();
1492 // Notify propertyset info change listeners.
1493 if ( m_pImpl
->m_pPropSetChangeListeners
&&
1494 m_pImpl
->m_pPropSetChangeListeners
->getLength() )
1496 PropertySetInfoChangeEvent
evt(
1497 static_cast< OWeakObject
* >( this ),
1500 PropertySetInfoChange::PROPERTY_INSERTED
);
1501 notifyPropertySetInfoChange( evt
);
1508 catch (const IllegalArgumentException
&)
1512 OSL_FAIL( "PersistentPropertySet::addProperty - "
1513 "caught IllegalArgumentException!" );
1516 catch (const ElementExistException
&)
1520 OSL_FAIL( "PersistentPropertySet::addProperty - "
1521 "caught ElementExistException!" );
1524 catch (const WrappedTargetException
&)
1526 // replaceByName, insertByName, commitChanges
1528 OSL_FAIL( "PersistentPropertySet::addProperty - "
1529 "caught WrappedTargetException!" );
1532 catch (const RuntimeException
&)
1536 catch (const Exception
&)
1540 OSL_FAIL( "PersistentPropertySet::addProperty - "
1541 "caught Exception!" );
1546 OSL_FAIL( "PersistentPropertySet::addProperty - Error!" );
1551 void SAL_CALL
PersistentPropertySet::removeProperty( const OUString
& Name
)
1553 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
1555 OUString aFullValuesName
;
1556 OUString aFullPropName
;
1558 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
1559 m_pImpl
->m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1560 if ( xRootHierNameAccess
.is() )
1562 aFullValuesName
= getFullKey();
1563 aFullPropName
= aFullValuesName
+ "/";
1564 aFullPropName
+= makeHierarchalNameSegment( Name
);
1567 if ( !xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
) )
1568 throw UnknownPropertyException(aFullPropName
);
1570 // Property removable?
1573 OUString aFullAttrName
= aFullPropName
+ "/Attributes";
1575 sal_Int32 nAttribs
= 0;
1576 if ( xRootHierNameAccess
->getByHierarchicalName( aFullAttrName
)
1579 if ( !( nAttribs
& PropertyAttribute::REMOVABLE
) )
1582 throw NotRemoveableException();
1587 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1592 catch (const NoSuchElementException
&)
1594 // getByHierarchicalName
1596 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1597 "caught NoSuchElementException!" );
1600 // Remove property...
1602 Reference
< XNameContainer
> xContainer(
1603 m_pImpl
->m_pCreator
->getConfigWriteAccess( aFullValuesName
),
1605 Reference
< XChangesBatch
> xBatch(
1606 m_pImpl
->m_pCreator
->getConfigWriteAccess( OUString() ),
1609 OSL_ENSURE( xBatch
.is(),
1610 "PersistentPropertySet::removeProperty - No batch!" );
1612 OSL_ENSURE( xContainer
.is(),
1613 "PersistentPropertySet::removeProperty - No container!" );
1615 if ( xBatch
.is() && xContainer
.is() )
1619 sal_Int32 nHandle
= -1;
1621 if ( m_pImpl
->m_pPropSetChangeListeners
&&
1622 m_pImpl
->m_pPropSetChangeListeners
->getLength() )
1624 // Obtain property handle ( needed for propertysetinfo
1625 // change event )...
1629 OUString aFullHandleName
= aFullPropName
+ "/Handle";
1631 if ( ! ( xRootHierNameAccess
->getByHierarchicalName(
1632 aFullHandleName
) >>= nHandle
) )
1636 catch (const NoSuchElementException
&)
1638 // getByHierarchicalName
1640 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1641 "caught NoSuchElementException!" );
1646 xContainer
->removeByName( Name
);
1647 xBatch
->commitChanges();
1649 // Property set info is invalid.
1650 if ( m_pImpl
->m_pInfo
.is() )
1651 m_pImpl
->m_pInfo
->reset();
1653 // Notify propertyset info change listeners.
1654 if ( m_pImpl
->m_pPropSetChangeListeners
&&
1655 m_pImpl
->m_pPropSetChangeListeners
->getLength() )
1657 PropertySetInfoChangeEvent
evt(
1658 static_cast< OWeakObject
* >( this ),
1661 PropertySetInfoChange::PROPERTY_REMOVED
);
1662 notifyPropertySetInfoChange( evt
);
1668 catch (const NoSuchElementException
&)
1672 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1673 "caught NoSuchElementException!" );
1676 catch (const WrappedTargetException
&)
1680 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1681 "caught WrappedTargetException!" );
1687 OSL_FAIL( "PersistentPropertySet::removeProperty - Error!" );
1691 // XPropertySetInfoChangeNotifier methods.
1695 void SAL_CALL
PersistentPropertySet::addPropertySetInfoChangeListener(
1696 const Reference
< XPropertySetInfoChangeListener
>& Listener
)
1698 if ( !m_pImpl
->m_pPropSetChangeListeners
)
1699 m_pImpl
->m_pPropSetChangeListeners
.reset(
1700 new OInterfaceContainerHelper2( m_pImpl
->m_aMutex
) );
1702 m_pImpl
->m_pPropSetChangeListeners
->addInterface( Listener
);
1707 void SAL_CALL
PersistentPropertySet::removePropertySetInfoChangeListener(
1708 const Reference
< XPropertySetInfoChangeListener
>& Listener
)
1710 if ( m_pImpl
->m_pPropSetChangeListeners
)
1711 m_pImpl
->m_pPropSetChangeListeners
->removeInterface( Listener
);
1715 // XPropertyAccess methods.
1719 Sequence
< PropertyValue
> SAL_CALL
PersistentPropertySet::getPropertyValues()
1721 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
1723 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
1724 m_pImpl
->m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1725 if ( xRootHierNameAccess
.is() )
1729 Reference
< XNameAccess
> xNameAccess
;
1730 xRootHierNameAccess
->getByHierarchicalName(getFullKey())
1732 if ( xNameAccess
.is() )
1734 // Obtain property names.
1736 Sequence
< OUString
> aElems
= xNameAccess
->getElementNames();
1738 sal_Int32 nCount
= aElems
.getLength();
1741 Reference
< XHierarchicalNameAccess
> xHierNameAccess(
1742 xNameAccess
, UNO_QUERY
);
1744 OSL_ENSURE( xHierNameAccess
.is(),
1745 "PersistentPropertySet::getPropertyValues - "
1746 "No hierarchical name access!" );
1748 if ( xHierNameAccess
.is() )
1750 Sequence
< PropertyValue
> aValues( nCount
);
1752 const OUString
aHandleName("/Handle");
1753 const OUString
aValueName("/Value");
1754 const OUString
aStateName("/State");
1756 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
1758 PropertyValue
& rValue
= aValues
[ n
];
1759 OUString rName
= aElems
[ n
];
1761 = makeHierarchalNameSegment( rName
);
1763 // Set property name.
1765 rValue
.Name
= rName
;
1769 // Obtain and set property handle
1770 OUString aHierName
= aXMLName
+ aHandleName
;
1772 = xHierNameAccess
->getByHierarchicalName(
1775 if ( !( aKeyValue
>>= rValue
.Handle
) )
1776 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1777 "Error getting property handle!" );
1779 catch (const NoSuchElementException
&)
1781 // getByHierarchicalName
1783 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1784 "NoSuchElementException!" );
1789 // Obtain and set property value
1790 OUString aHierName
= aXMLName
+ aValueName
;
1792 = xHierNameAccess
->getByHierarchicalName(
1795 // Note: The value may be void if addProperty
1796 // was called with a default value
1799 catch (const NoSuchElementException
&)
1801 // getByHierarchicalName
1803 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1804 "NoSuchElementException!" );
1809 // Obtain and set property state
1810 OUString aHierName
= aXMLName
+aStateName
;
1812 = xHierNameAccess
->getByHierarchicalName(
1815 sal_Int32 nState
= 0;
1816 if ( !( aKeyValue
>>= nState
) )
1817 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1818 "Error getting property state!" );
1820 rValue
.State
= PropertyState( nState
);
1822 catch (const NoSuchElementException
&)
1824 // getByHierarchicalName
1826 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1827 "NoSuchElementException!" );
1836 catch (const NoSuchElementException
&)
1838 // getByHierarchicalName
1842 return Sequence
< PropertyValue
>( 0 );
1847 void SAL_CALL
PersistentPropertySet::setPropertyValues(
1848 const Sequence
< PropertyValue
>& aProps
)
1850 if ( !aProps
.hasElements() )
1853 osl::ClearableGuard
< osl::Mutex
> aCGuard( m_pImpl
->m_aMutex
);
1855 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
1856 m_pImpl
->m_pCreator
->getRootConfigReadAccess(), UNO_QUERY
);
1857 if ( xRootHierNameAccess
.is() )
1859 std::vector
< PropertyChangeEvent
> aEvents
;
1861 OUString
aFullPropNamePrefix( getFullKey() + "/" );
1863 // Iterate over given property value sequence.
1864 for ( const PropertyValue
& rNewValue
: aProps
)
1866 const OUString
& rName
= rNewValue
.Name
;
1868 OUString aFullPropName
= aFullPropNamePrefix
;
1869 aFullPropName
+= makeHierarchalNameSegment( rName
);
1871 // Does property exist?
1872 if ( xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
) )
1874 Reference
< XNameReplace
> xNameReplace(
1875 m_pImpl
->m_pCreator
->getConfigWriteAccess(
1876 aFullPropName
), UNO_QUERY
);
1877 Reference
< XChangesBatch
> xBatch(
1878 m_pImpl
->m_pCreator
->getConfigWriteAccess(
1879 OUString() ), UNO_QUERY
);
1881 if ( xNameReplace
.is() && xBatch
.is() )
1886 xNameReplace
->replaceByName(
1888 makeAny( rNewValue
.Handle
) );
1891 OUString aValueName
= aFullPropName
+"/Value";
1893 = xRootHierNameAccess
->getByHierarchicalName(
1896 xNameReplace
->replaceByName(
1900 // Write state ( Now it is a directly set value )
1901 xNameReplace
->replaceByName(
1905 PropertyState_DIRECT_VALUE
) ) );
1908 xBatch
->commitChanges();
1910 if ( m_pImpl
->m_pPropertyChangeListeners
)
1912 PropertyChangeEvent aEvt
;
1913 aEvt
.Source
= static_cast<OWeakObject
*>(this);
1914 aEvt
.PropertyName
= rNewValue
.Name
;
1915 aEvt
.PropertyHandle
= rNewValue
.Handle
;
1916 aEvt
.Further
= false;
1917 aEvt
.OldValue
= aOldValue
;
1918 aEvt
.NewValue
= rNewValue
.Value
;
1920 aEvents
.push_back( aEvt
);
1923 catch (const IllegalArgumentException
&)
1927 catch (const NoSuchElementException
&)
1929 // getByHierarchicalName, replaceByName
1931 catch (const WrappedTargetException
&)
1933 // replaceByName, commitChanges
1939 // Callback follows!
1942 if ( m_pImpl
->m_pPropertyChangeListeners
)
1944 // Notify property changes.
1945 for (auto const& event
: aEvents
)
1947 notifyPropertyChangeEvent( event
);
1954 OSL_FAIL( "PersistentPropertySet::setPropertyValues - Nothing set!" );
1958 // Non-interface methods
1961 void PersistentPropertySet::notifyPropertyChangeEvent(
1962 const PropertyChangeEvent
& rEvent
) const
1964 // Get "normal" listeners for the property.
1965 OInterfaceContainerHelper
* pContainer
=
1966 m_pImpl
->m_pPropertyChangeListeners
->getContainer(
1967 rEvent
.PropertyName
);
1968 if ( pContainer
&& pContainer
->getLength() )
1970 OInterfaceIteratorHelper
aIter( *pContainer
);
1971 while ( aIter
.hasMoreElements() )
1974 Reference
< XPropertyChangeListener
> xListener(
1975 aIter
.next(), UNO_QUERY
);
1976 if ( xListener
.is() )
1977 xListener
->propertyChange( rEvent
);
1981 // Get "normal" listeners for all properties.
1982 OInterfaceContainerHelper
* pNoNameContainer
=
1983 m_pImpl
->m_pPropertyChangeListeners
->getContainer( OUString() );
1984 if ( pNoNameContainer
&& pNoNameContainer
->getLength() )
1986 OInterfaceIteratorHelper
aIter( *pNoNameContainer
);
1987 while ( aIter
.hasMoreElements() )
1990 Reference
< XPropertyChangeListener
> xListener(
1991 aIter
.next(), UNO_QUERY
);
1992 if ( xListener
.is() )
1993 xListener
->propertyChange( rEvent
);
1999 void PersistentPropertySet::notifyPropertySetInfoChange(
2000 const PropertySetInfoChangeEvent
& evt
) const
2002 if ( !m_pImpl
->m_pPropSetChangeListeners
)
2005 // Notify event listeners.
2006 OInterfaceIteratorHelper2
aIter( *( m_pImpl
->m_pPropSetChangeListeners
) );
2007 while ( aIter
.hasMoreElements() )
2010 Reference
< XPropertySetInfoChangeListener
>
2011 xListener( aIter
.next(), UNO_QUERY
);
2012 if ( xListener
.is() )
2013 xListener
->propertySetInfoChange( evt
);
2018 const OUString
& PersistentPropertySet::getFullKey()
2020 if ( m_pImpl
->m_aFullKey
.isEmpty() )
2022 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
2023 if ( m_pImpl
->m_aFullKey
.isEmpty() )
2026 = makeHierarchalNameSegment( m_pImpl
->m_aKey
);
2032 return m_pImpl
->m_aFullKey
;
2036 PropertySetRegistry
& PersistentPropertySet::getPropertySetRegistry()
2038 return *m_pImpl
->m_pCreator
;
2042 // PropertySetInfo_Impl Implementation.
2045 PropertySetInfo_Impl::PropertySetInfo_Impl(
2046 PersistentPropertySet
* pOwner
)
2047 : m_pOwner( pOwner
)
2052 // XPropertySetInfo methods.
2056 Sequence
< Property
> SAL_CALL
PropertySetInfo_Impl::getProperties()
2060 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
2061 m_pOwner
->getPropertySetRegistry().getRootConfigReadAccess(),
2063 if ( xRootHierNameAccess
.is() )
2067 Reference
< XNameAccess
> xNameAccess
;
2068 xRootHierNameAccess
->getByHierarchicalName(
2069 m_pOwner
->getFullKey() )
2071 if ( xNameAccess
.is() )
2073 // Obtain property names.
2075 Sequence
< OUString
> aElems
2076 = xNameAccess
->getElementNames();
2078 sal_uInt32 nCount
= aElems
.getLength();
2079 Sequence
< Property
>* pPropSeq
2080 = new Sequence
< Property
>( nCount
);
2084 Reference
< XHierarchicalNameAccess
> xHierNameAccess(
2085 xNameAccess
, UNO_QUERY
);
2087 OSL_ENSURE( xHierNameAccess
.is(),
2088 "PropertySetInfo_Impl::getProperties - "
2089 "No hierarchical name access!" );
2091 if ( xHierNameAccess
.is() )
2093 const OUString
aHandleName("/Handle");
2094 const OUString
aValueName("/Value");
2095 const OUString
aAttrName("/Attributes");
2097 Property
* pProps
= pPropSeq
->getArray();
2099 for ( sal_uInt32 n
= 0; n
< nCount
; ++n
)
2101 Property
& rProp
= pProps
[ n
];
2102 OUString rName
= aElems
[ n
];
2104 = makeHierarchalNameSegment( rName
);
2106 // Set property name.
2112 // Obtain and set property handle
2113 OUString aHierName
= aXMLName
+ aHandleName
;
2115 = xHierNameAccess
->getByHierarchicalName(
2118 if ( !( aKeyValue
>>= rProp
.Handle
) )
2119 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2120 "Error getting property handle!" );
2122 catch (const NoSuchElementException
&)
2124 // getByHierarchicalName
2126 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2127 "NoSuchElementException!" );
2132 // Obtain and set property type
2133 OUString aHierName
= aXMLName
+ aValueName
;
2135 = xHierNameAccess
->getByHierarchicalName(
2138 // Note: The type may be void if addProperty
2139 // was called with a default value
2142 rProp
.Type
= aKeyValue
.getValueType();
2144 catch (const NoSuchElementException
&)
2146 // getByHierarchicalName
2148 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2149 "NoSuchElementException!" );
2154 // Obtain and set property attributes
2155 OUString aHierName
= aXMLName
+ aAttrName
;
2157 = xHierNameAccess
->getByHierarchicalName(
2160 sal_Int32 nAttribs
= 0;
2161 if ( aKeyValue
>>= nAttribs
)
2163 = sal_Int16( nAttribs
);
2165 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2166 "Error getting property attributes!" );
2168 catch (const NoSuchElementException
&)
2170 // getByHierarchicalName
2172 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2173 "NoSuchElementException!" );
2180 m_pProps
.reset( pPropSeq
);
2184 catch (const NoSuchElementException
&)
2186 // getByHierarchicalName
2190 OSL_FAIL( "PropertySetInfo_Impl::getProperties - Error!" );
2191 m_pProps
.reset( new Sequence
< Property
>( 0 ) );
2199 Property SAL_CALL
PropertySetInfo_Impl::getPropertyByName(
2200 const OUString
& aName
)
2202 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
2203 m_pOwner
->getPropertySetRegistry().getRootConfigReadAccess(),
2205 if ( xRootHierNameAccess
.is() )
2207 OUString
aFullPropName( m_pOwner
->getFullKey() + "/" );
2208 aFullPropName
+= makeHierarchalNameSegment( aName
);
2210 // Does property exist?
2211 if ( !xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
) )
2212 throw UnknownPropertyException(aFullPropName
);
2219 OUString aKey
= aFullPropName
+ "/Handle";
2221 if ( !( xRootHierNameAccess
->getByHierarchicalName( aKey
)
2222 >>= aProp
.Handle
) )
2224 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2229 // Obtain Value and extract type.
2230 aKey
= aFullPropName
+ "/Value";
2232 Any aValue
= xRootHierNameAccess
->getByHierarchicalName( aKey
);
2233 if ( !aValue
.hasValue() )
2235 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2240 aProp
.Type
= aValue
.getValueType();
2242 // Obtain Attributes.
2243 aKey
= aFullPropName
+ "/Attributes";
2245 sal_Int32 nAttribs
= 0;
2246 if ( xRootHierNameAccess
->getByHierarchicalName( aKey
)
2248 aProp
.Attributes
= sal_Int16( nAttribs
);
2251 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2262 catch (const NoSuchElementException
&)
2264 // getByHierarchicalName
2266 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2267 "caught NoSuchElementException!" );
2272 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - Error!" );
2278 sal_Bool SAL_CALL
PropertySetInfo_Impl::hasPropertyByName(
2279 const OUString
& Name
)
2281 Reference
< XHierarchicalNameAccess
> xRootHierNameAccess(
2282 m_pOwner
->getPropertySetRegistry().getRootConfigReadAccess(),
2284 if ( xRootHierNameAccess
.is() )
2286 OUString
aFullPropName( m_pOwner
->getFullKey() + "/" );
2287 aFullPropName
+= makeHierarchalNameSegment( Name
);
2289 return xRootHierNameAccess
->hasByHierarchicalName( aFullPropName
);
2295 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */