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 #include "propertysetbase.hxx"
23 #include <cppuhelper/typeprovider.hxx> // for getImplementationId()
25 #include <com/sun/star/beans/XPropertySet.hpp>
26 #include <com/sun/star/beans/XMultiPropertySet.hpp>
27 #include <com/sun/star/beans/XPropertyState.hpp>
28 #include <com/sun/star/uno/Reference.hxx>
29 #include <tools/solar.h>
33 using com::sun::star::uno::Any
;
34 using com::sun::star::uno::Type
;
35 using com::sun::star::uno::Sequence
;
36 using com::sun::star::uno::Reference
;
37 using com::sun::star::uno::Exception
;
38 using com::sun::star::uno::RuntimeException
;
39 using com::sun::star::lang::IllegalArgumentException
;
40 using com::sun::star::beans::Property
;
41 using com::sun::star::beans::XPropertySetInfo
;
43 PropertyAccessorBase::~PropertyAccessorBase()
47 oslInterlockedCount SAL_CALL
PropertyAccessorBase::acquire()
52 oslInterlockedCount SAL_CALL
PropertyAccessorBase::release()
54 if ( --m_refCount
== 0 )
62 PropertySetBase::PropertySetBase( )
63 :m_pProperties( NULL
)
67 PropertySetBase::~PropertySetBase( )
69 DELETEZ( m_pProperties
);
72 cppu::IPropertyArrayHelper
& SAL_CALL
PropertySetBase::getInfoHelper()
76 OSL_ENSURE( !m_aProperties
.empty(), "PropertySetBase::getInfoHelper: no registered properties!" );
77 m_pProperties
= new cppu::OPropertyArrayHelper( &m_aProperties
[0], m_aProperties
.size(), sal_False
);
79 return *m_pProperties
;
82 Reference
< XPropertySetInfo
> SAL_CALL
PropertySetBase::getPropertySetInfo( ) throw(RuntimeException
)
84 return cppu::OPropertySetHelper::createPropertySetInfo( getInfoHelper() );
87 void PropertySetBase::registerProperty( const Property
& rProperty
,
88 const ::rtl::Reference
< PropertyAccessorBase
>& rAccessor
)
90 OSL_ENSURE( rAccessor
.get(), "PropertySetBase::registerProperty: invalid property accessor, this will crash!" );
91 m_aAccessors
.insert( PropertyAccessors::value_type( rProperty
.Handle
, rAccessor
) );
93 OSL_ENSURE( ( rAccessor
->isWriteable() == true )
94 == ( ( rProperty
.Attributes
& com::sun::star::beans::PropertyAttribute::READONLY
) == 0 ),
95 "PropertySetBase::registerProperty: inconsistence!" );
97 m_aProperties
.push_back( rProperty
);
100 void PropertySetBase::notifyAndCachePropertyValue( sal_Int32 nHandle
)
102 ::osl::ClearableMutexGuard
aGuard( GetMutex() );
104 PropertyValueCache::iterator aPos
= m_aCache
.find( nHandle
);
105 if ( aPos
== m_aCache
.end() )
106 { // method has never before been invoked for this property
109 // determine the type of this property
110 ::cppu::IPropertyArrayHelper
& rPropertyMetaData
= getInfoHelper();
112 OSL_VERIFY( rPropertyMetaData
.fillPropertyMembersByHandle( &sPropName
, NULL
, nHandle
) );
113 Property aProperty
= rPropertyMetaData
.getPropertyByName( sPropName
);
114 // default construct a value of this type
115 Any
aEmptyValue( NULL
, aProperty
.Type
);
116 // insert into the cache
117 aPos
= m_aCache
.insert( PropertyValueCache::value_type( nHandle
, aEmptyValue
) ).first
;
119 catch( const Exception
& )
121 OSL_FAIL( "PropertySetBase::notifyAndCachePropertyValue: this is not expected to fail!" );
124 Any aOldValue
= aPos
->second
;
125 // determine the current value
127 getFastPropertyValue( aNewValue
, nHandle
);
128 // remember the old value
129 aPos
->second
= aNewValue
;
132 if ( aNewValue
!= aOldValue
)
133 firePropertyChange( nHandle
, aNewValue
, aOldValue
);
136 void PropertySetBase::initializePropertyValueCache( sal_Int32 nHandle
)
139 getFastPropertyValue( aCurrentValue
, nHandle
);
141 #if OSL_DEBUG_LEVEL > 0
142 ::std::pair
< PropertyValueCache::iterator
, bool > aInsertResult
=
144 m_aCache
.insert( PropertyValueCache::value_type( nHandle
, aCurrentValue
) );
145 OSL_ENSURE( aInsertResult
.second
, "PropertySetBase::initializePropertyValueCache: already cached a value for this property!" );
148 PropertyAccessorBase
& PropertySetBase::locatePropertyHandler( sal_Int32 nHandle
) const
150 PropertyAccessors::const_iterator aPropertyPos
= m_aAccessors
.find( nHandle
);
151 OSL_ENSURE( aPropertyPos
!= m_aAccessors
.end() && aPropertyPos
->second
.get(),
152 "PropertySetBase::locatePropertyHandler: accessor map is corrupted!" );
153 // neither should this be called for handles where there is no accessor, nor should a
154 // NULL accssor be in the map
155 return *aPropertyPos
->second
;
158 sal_Bool SAL_CALL
PropertySetBase::convertFastPropertyValue( Any
& rConvertedValue
, Any
& rOldValue
, sal_Int32 nHandle
,
160 throw (IllegalArgumentException
)
162 PropertyAccessorBase
& rAccessor
= locatePropertyHandler( nHandle
);
163 if ( !rAccessor
.approveValue( rValue
) )
164 throw IllegalArgumentException( OUString(), *this, 0 );
166 rAccessor
.getValue( rOldValue
);
167 if ( rOldValue
!= rValue
)
169 rConvertedValue
= rValue
; // no conversion at all
175 void SAL_CALL
PropertySetBase::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle
, const Any
& rValue
)
178 PropertyAccessorBase
& rAccessor
= locatePropertyHandler( nHandle
);
179 rAccessor
.setValue( rValue
);
182 void SAL_CALL
PropertySetBase::getFastPropertyValue( Any
& rValue
, sal_Int32 nHandle
) const
184 PropertyAccessorBase
& rAccessor
= locatePropertyHandler( nHandle
);
185 rAccessor
.getValue( rValue
);
188 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */