1*dde7d3faSAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3*dde7d3faSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4*dde7d3faSAndrew Rist * or more contributor license agreements. See the NOTICE file
5*dde7d3faSAndrew Rist * distributed with this work for additional information
6*dde7d3faSAndrew Rist * regarding copyright ownership. The ASF licenses this file
7*dde7d3faSAndrew Rist * to you under the Apache License, Version 2.0 (the
8*dde7d3faSAndrew Rist * "License"); you may not use this file except in compliance
9*dde7d3faSAndrew Rist * with the License. You may obtain a copy of the License at
10*dde7d3faSAndrew Rist *
11*dde7d3faSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12*dde7d3faSAndrew Rist *
13*dde7d3faSAndrew Rist * Unless required by applicable law or agreed to in writing,
14*dde7d3faSAndrew Rist * software distributed under the License is distributed on an
15*dde7d3faSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*dde7d3faSAndrew Rist * KIND, either express or implied. See the License for the
17*dde7d3faSAndrew Rist * specific language governing permissions and limitations
18*dde7d3faSAndrew Rist * under the License.
19*dde7d3faSAndrew Rist *
20*dde7d3faSAndrew Rist *************************************************************/
21*dde7d3faSAndrew Rist
22*dde7d3faSAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_comphelper.hxx"
26cdf0e10cSrcweir
27cdf0e10cSrcweir #include "opropertybag.hxx"
28cdf0e10cSrcweir #include "comphelper_module.hxx"
29cdf0e10cSrcweir
30cdf0e10cSrcweir #include <com/sun/star/beans/PropertyAttribute.hpp>
31cdf0e10cSrcweir #include <com/sun/star/beans/NamedValue.hpp>
32cdf0e10cSrcweir #include <com/sun/star/beans/Property.hpp>
33cdf0e10cSrcweir
34cdf0e10cSrcweir #include <comphelper/namedvaluecollection.hxx>
35cdf0e10cSrcweir
36cdf0e10cSrcweir #include <cppuhelper/exc_hlp.hxx>
37cdf0e10cSrcweir #include <osl/thread.h>
38cdf0e10cSrcweir
39cdf0e10cSrcweir #include <algorithm>
40cdf0e10cSrcweir #include <functional>
41cdf0e10cSrcweir
42cdf0e10cSrcweir
43cdf0e10cSrcweir //--------------------------------------------------------------------------
44cdf0e10cSrcweir using namespace ::com::sun::star;
45cdf0e10cSrcweir
createRegistryInfo_OPropertyBag()46cdf0e10cSrcweir void createRegistryInfo_OPropertyBag()
47cdf0e10cSrcweir {
48cdf0e10cSrcweir static ::comphelper::module::OAutoRegistration< ::comphelper::OPropertyBag > aAutoRegistration;
49cdf0e10cSrcweir }
50cdf0e10cSrcweir
51cdf0e10cSrcweir //........................................................................
52cdf0e10cSrcweir namespace comphelper
53cdf0e10cSrcweir {
54cdf0e10cSrcweir //........................................................................
55cdf0e10cSrcweir
56cdf0e10cSrcweir using namespace ::com::sun::star::uno;
57cdf0e10cSrcweir using namespace ::com::sun::star::lang;
58cdf0e10cSrcweir using namespace ::com::sun::star::beans;
59cdf0e10cSrcweir using namespace ::com::sun::star::util;
60cdf0e10cSrcweir using namespace ::com::sun::star::container;
61cdf0e10cSrcweir
62cdf0e10cSrcweir //====================================================================
63cdf0e10cSrcweir //= OPropertyBag
64cdf0e10cSrcweir //====================================================================
65cdf0e10cSrcweir //--------------------------------------------------------------------
OPropertyBag(const Reference<XComponentContext> & _rxContext)66cdf0e10cSrcweir OPropertyBag::OPropertyBag( const Reference< XComponentContext >& _rxContext )
67cdf0e10cSrcweir :OPropertyBag_PBase( GetBroadcastHelper(), this )
68cdf0e10cSrcweir ,::cppu::IEventNotificationHook()
69cdf0e10cSrcweir ,m_aContext( _rxContext )
70cdf0e10cSrcweir ,m_bAutoAddProperties( false )
71cdf0e10cSrcweir ,m_NotifyListeners(m_aMutex)
72cdf0e10cSrcweir ,m_isModified(false)
73cdf0e10cSrcweir
74cdf0e10cSrcweir {
75cdf0e10cSrcweir }
76cdf0e10cSrcweir
77cdf0e10cSrcweir //--------------------------------------------------------------------
~OPropertyBag()78cdf0e10cSrcweir OPropertyBag::~OPropertyBag()
79cdf0e10cSrcweir {
80cdf0e10cSrcweir }
81cdf0e10cSrcweir
82cdf0e10cSrcweir //--------------------------------------------------------------------
IMPLEMENT_FORWARD_XINTERFACE2(OPropertyBag,OPropertyBag_Base,OPropertyBag_PBase)83cdf0e10cSrcweir IMPLEMENT_FORWARD_XINTERFACE2( OPropertyBag, OPropertyBag_Base, OPropertyBag_PBase )
84cdf0e10cSrcweir IMPLEMENT_FORWARD_XTYPEPROVIDER2( OPropertyBag, OPropertyBag_Base, OPropertyBag_PBase )
85cdf0e10cSrcweir
86cdf0e10cSrcweir //--------------------------------------------------------------------
87cdf0e10cSrcweir Sequence< ::rtl::OUString > OPropertyBag::getSupportedServiceNames_static() throw( RuntimeException )
88cdf0e10cSrcweir {
89cdf0e10cSrcweir Sequence< ::rtl::OUString > aServices(1);
90cdf0e10cSrcweir aServices[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.beans.PropertyBag" ) );
91cdf0e10cSrcweir return aServices;
92cdf0e10cSrcweir }
93cdf0e10cSrcweir
94cdf0e10cSrcweir //--------------------------------------------------------------------
initialize(const Sequence<Any> & _rArguments)95cdf0e10cSrcweir void SAL_CALL OPropertyBag::initialize( const Sequence< Any >& _rArguments ) throw (Exception, RuntimeException)
96cdf0e10cSrcweir {
97cdf0e10cSrcweir ::comphelper::NamedValueCollection aArguments( _rArguments );
98cdf0e10cSrcweir
99cdf0e10cSrcweir Sequence< Type > aTypes;
100cdf0e10cSrcweir if ( aArguments.get_ensureType( "AllowedTypes", aTypes ) )
101cdf0e10cSrcweir ::std::copy(
102cdf0e10cSrcweir aTypes.getConstArray(),
103cdf0e10cSrcweir aTypes.getConstArray() + aTypes.getLength(),
104cdf0e10cSrcweir ::std::insert_iterator< TypeBag >( m_aAllowedTypes, m_aAllowedTypes.begin() )
105cdf0e10cSrcweir );
106cdf0e10cSrcweir
107cdf0e10cSrcweir aArguments.get_ensureType( "AutomaticAddition", m_bAutoAddProperties );
108cdf0e10cSrcweir bool AllowEmptyPropertyName(false);
109cdf0e10cSrcweir aArguments.get_ensureType( "AllowEmptyPropertyName",
110cdf0e10cSrcweir AllowEmptyPropertyName );
111cdf0e10cSrcweir if (AllowEmptyPropertyName) {
112cdf0e10cSrcweir m_aDynamicProperties.setAllowEmptyPropertyName(
113cdf0e10cSrcweir AllowEmptyPropertyName);
114cdf0e10cSrcweir }
115cdf0e10cSrcweir }
116cdf0e10cSrcweir
117cdf0e10cSrcweir //--------------------------------------------------------------------
getImplementationName_static()118cdf0e10cSrcweir ::rtl::OUString OPropertyBag::getImplementationName_static() throw( RuntimeException )
119cdf0e10cSrcweir {
120cdf0e10cSrcweir return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.comphelper.OPropertyBag" ) );
121cdf0e10cSrcweir }
122cdf0e10cSrcweir
123cdf0e10cSrcweir //--------------------------------------------------------------------
Create(const Reference<XComponentContext> & _rxContext)124cdf0e10cSrcweir Reference< XInterface > SAL_CALL OPropertyBag::Create( const Reference< XComponentContext >& _rxContext )
125cdf0e10cSrcweir {
126cdf0e10cSrcweir return *new OPropertyBag( _rxContext );
127cdf0e10cSrcweir }
128cdf0e10cSrcweir
129cdf0e10cSrcweir //--------------------------------------------------------------------
getImplementationName()130cdf0e10cSrcweir ::rtl::OUString SAL_CALL OPropertyBag::getImplementationName() throw (RuntimeException)
131cdf0e10cSrcweir {
132cdf0e10cSrcweir return getImplementationName_static();
133cdf0e10cSrcweir }
134cdf0e10cSrcweir
135cdf0e10cSrcweir //--------------------------------------------------------------------
supportsService(const::rtl::OUString & rServiceName)136cdf0e10cSrcweir ::sal_Bool SAL_CALL OPropertyBag::supportsService( const ::rtl::OUString& rServiceName ) throw (RuntimeException)
137cdf0e10cSrcweir {
138cdf0e10cSrcweir Sequence< ::rtl::OUString > aServices( getSupportedServiceNames_static() );
139cdf0e10cSrcweir const ::rtl::OUString* pStart = aServices.getConstArray();
140cdf0e10cSrcweir const ::rtl::OUString* pEnd = aServices.getConstArray() + aServices.getLength();
141cdf0e10cSrcweir return ::std::find( pStart, pEnd, rServiceName ) != pEnd;
142cdf0e10cSrcweir }
143cdf0e10cSrcweir
144cdf0e10cSrcweir //--------------------------------------------------------------------
getSupportedServiceNames()145cdf0e10cSrcweir Sequence< ::rtl::OUString > SAL_CALL OPropertyBag::getSupportedServiceNames( ) throw (RuntimeException)
146cdf0e10cSrcweir {
147cdf0e10cSrcweir return getSupportedServiceNames_static();
148cdf0e10cSrcweir }
149cdf0e10cSrcweir
150cdf0e10cSrcweir //--------------------------------------------------------------------
fireEvents(sal_Int32 *,sal_Int32 nCount,sal_Bool bVetoable,bool bIgnoreRuntimeExceptionsWhileFiring)151cdf0e10cSrcweir void OPropertyBag::fireEvents(
152cdf0e10cSrcweir sal_Int32 * /*pnHandles*/,
153cdf0e10cSrcweir sal_Int32 nCount,
154cdf0e10cSrcweir sal_Bool bVetoable,
155cdf0e10cSrcweir bool bIgnoreRuntimeExceptionsWhileFiring)
156cdf0e10cSrcweir {
157cdf0e10cSrcweir if (nCount && !bVetoable) {
158cdf0e10cSrcweir setModifiedImpl(sal_True, bIgnoreRuntimeExceptionsWhileFiring);
159cdf0e10cSrcweir }
160cdf0e10cSrcweir }
161cdf0e10cSrcweir
setModifiedImpl(::sal_Bool bModified,bool bIgnoreRuntimeExceptionsWhileFiring)162cdf0e10cSrcweir void OPropertyBag::setModifiedImpl(::sal_Bool bModified,
163cdf0e10cSrcweir bool bIgnoreRuntimeExceptionsWhileFiring)
164cdf0e10cSrcweir {
165cdf0e10cSrcweir { // do not lock mutex while notifying (#i93514#) to prevent deadlock
166cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
167cdf0e10cSrcweir m_isModified = bModified;
168cdf0e10cSrcweir }
169cdf0e10cSrcweir if (bModified) {
170cdf0e10cSrcweir try {
171cdf0e10cSrcweir Reference<XInterface> xThis(*this);
172cdf0e10cSrcweir EventObject event(xThis);
173cdf0e10cSrcweir m_NotifyListeners.notifyEach(
174cdf0e10cSrcweir &XModifyListener::modified, event);
175cdf0e10cSrcweir } catch (RuntimeException &) {
176cdf0e10cSrcweir if (!bIgnoreRuntimeExceptionsWhileFiring) {
177cdf0e10cSrcweir throw;
178cdf0e10cSrcweir }
179cdf0e10cSrcweir } catch (Exception &) {
180cdf0e10cSrcweir // ignore
181cdf0e10cSrcweir }
182cdf0e10cSrcweir }
183cdf0e10cSrcweir }
184cdf0e10cSrcweir
185cdf0e10cSrcweir //--------------------------------------------------------------------
isModified()186cdf0e10cSrcweir ::sal_Bool SAL_CALL OPropertyBag::isModified()
187cdf0e10cSrcweir throw (RuntimeException)
188cdf0e10cSrcweir {
189cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
190cdf0e10cSrcweir return m_isModified;
191cdf0e10cSrcweir }
192cdf0e10cSrcweir
setModified(::sal_Bool bModified)193cdf0e10cSrcweir void SAL_CALL OPropertyBag::setModified( ::sal_Bool bModified )
194cdf0e10cSrcweir throw (PropertyVetoException, RuntimeException)
195cdf0e10cSrcweir {
196cdf0e10cSrcweir setModifiedImpl(bModified, false);
197cdf0e10cSrcweir }
198cdf0e10cSrcweir
addModifyListener(const Reference<XModifyListener> & xListener)199cdf0e10cSrcweir void SAL_CALL OPropertyBag::addModifyListener(
200cdf0e10cSrcweir const Reference< XModifyListener > & xListener)
201cdf0e10cSrcweir throw (RuntimeException)
202cdf0e10cSrcweir {
203cdf0e10cSrcweir m_NotifyListeners.addInterface(xListener);
204cdf0e10cSrcweir }
205cdf0e10cSrcweir
removeModifyListener(const Reference<XModifyListener> & xListener)206cdf0e10cSrcweir void SAL_CALL OPropertyBag::removeModifyListener(
207cdf0e10cSrcweir const Reference< XModifyListener > & xListener)
208cdf0e10cSrcweir throw (RuntimeException)
209cdf0e10cSrcweir {
210cdf0e10cSrcweir m_NotifyListeners.removeInterface(xListener);
211cdf0e10cSrcweir }
212cdf0e10cSrcweir
213cdf0e10cSrcweir //--------------------------------------------------------------------
getPropertySetInfo()214cdf0e10cSrcweir Reference< XPropertySetInfo > SAL_CALL OPropertyBag::getPropertySetInfo( ) throw(RuntimeException)
215cdf0e10cSrcweir {
216cdf0e10cSrcweir return createPropertySetInfo( getInfoHelper() );
217cdf0e10cSrcweir }
218cdf0e10cSrcweir
219cdf0e10cSrcweir //--------------------------------------------------------------------
has(const Any &)220cdf0e10cSrcweir ::sal_Bool SAL_CALL OPropertyBag::has( const Any& /*aElement*/ ) throw (RuntimeException)
221cdf0e10cSrcweir {
222cdf0e10cSrcweir // XSet is only a workaround for addProperty not being able to add default-void properties.
223cdf0e10cSrcweir // So, everything of XSet except insert is implemented empty
224cdf0e10cSrcweir return sal_False;
225cdf0e10cSrcweir }
226cdf0e10cSrcweir
227cdf0e10cSrcweir //--------------------------------------------------------------------
insert(const Any & _element)228cdf0e10cSrcweir void SAL_CALL OPropertyBag::insert( const Any& _element ) throw (IllegalArgumentException, ElementExistException, RuntimeException)
229cdf0e10cSrcweir {
230cdf0e10cSrcweir // This is a workaround for addProperty not being able to add default-void properties.
231cdf0e10cSrcweir // If we ever have a smarter XPropertyContainer::addProperty interface, we can remove this, ehm, well, hack.
232cdf0e10cSrcweir Property aProperty;
233cdf0e10cSrcweir if ( !( _element >>= aProperty ) )
234cdf0e10cSrcweir throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
235cdf0e10cSrcweir
236cdf0e10cSrcweir ::osl::ClearableMutexGuard g( m_aMutex );
237cdf0e10cSrcweir
238cdf0e10cSrcweir // check whether the type is allowed, everything else will be checked
239cdf0e10cSrcweir // by m_aDynamicProperties
240cdf0e10cSrcweir if ( !m_aAllowedTypes.empty()
241cdf0e10cSrcweir && m_aAllowedTypes.find( aProperty.Type ) == m_aAllowedTypes.end()
242cdf0e10cSrcweir )
243cdf0e10cSrcweir throw IllegalTypeException( ::rtl::OUString(), *this );
244cdf0e10cSrcweir
245cdf0e10cSrcweir m_aDynamicProperties.addVoidProperty( aProperty.Name, aProperty.Type, findFreeHandle(), aProperty.Attributes );
246cdf0e10cSrcweir
247cdf0e10cSrcweir // our property info is dirty
248cdf0e10cSrcweir m_pArrayHelper.reset();
249cdf0e10cSrcweir
250cdf0e10cSrcweir g.clear();
251cdf0e10cSrcweir setModified(sal_True);
252cdf0e10cSrcweir }
253cdf0e10cSrcweir
254cdf0e10cSrcweir //--------------------------------------------------------------------
remove(const Any &)255cdf0e10cSrcweir void SAL_CALL OPropertyBag::remove( const Any& /*aElement*/ ) throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
256cdf0e10cSrcweir {
257cdf0e10cSrcweir // XSet is only a workaround for addProperty not being able to add default-void properties.
258cdf0e10cSrcweir // So, everything of XSet except insert is implemented empty
259cdf0e10cSrcweir throw NoSuchElementException( ::rtl::OUString(), *this );
260cdf0e10cSrcweir }
261cdf0e10cSrcweir
262cdf0e10cSrcweir
263cdf0e10cSrcweir //--------------------------------------------------------------------
createEnumeration()264cdf0e10cSrcweir Reference< XEnumeration > SAL_CALL OPropertyBag::createEnumeration( ) throw (RuntimeException)
265cdf0e10cSrcweir {
266cdf0e10cSrcweir // XSet is only a workaround for addProperty not being able to add default-void properties.
267cdf0e10cSrcweir // So, everything of XSet except insert is implemented empty
268cdf0e10cSrcweir return NULL;
269cdf0e10cSrcweir }
270cdf0e10cSrcweir
271cdf0e10cSrcweir //--------------------------------------------------------------------
getElementType()272cdf0e10cSrcweir Type SAL_CALL OPropertyBag::getElementType( ) throw (RuntimeException)
273cdf0e10cSrcweir {
274cdf0e10cSrcweir // XSet is only a workaround for addProperty not being able to add default-void properties.
275cdf0e10cSrcweir // So, everything of XSet except insert is implemented empty
276cdf0e10cSrcweir return Type();
277cdf0e10cSrcweir }
278cdf0e10cSrcweir
279cdf0e10cSrcweir //--------------------------------------------------------------------
hasElements()280cdf0e10cSrcweir ::sal_Bool SAL_CALL OPropertyBag::hasElements( ) throw (RuntimeException)
281cdf0e10cSrcweir {
282cdf0e10cSrcweir // XSet is only a workaround for addProperty not being able to add default-void properties.
283cdf0e10cSrcweir // So, everything of XSet except insert is implemented empty
284cdf0e10cSrcweir return sal_False;
285cdf0e10cSrcweir }
286cdf0e10cSrcweir
287cdf0e10cSrcweir //--------------------------------------------------------------------
getFastPropertyValue(Any & _rValue,sal_Int32 _nHandle) const288cdf0e10cSrcweir void SAL_CALL OPropertyBag::getFastPropertyValue( Any& _rValue, sal_Int32 _nHandle ) const
289cdf0e10cSrcweir {
290cdf0e10cSrcweir m_aDynamicProperties.getFastPropertyValue( _nHandle, _rValue );
291cdf0e10cSrcweir }
292cdf0e10cSrcweir
293cdf0e10cSrcweir //--------------------------------------------------------------------
convertFastPropertyValue(Any & _rConvertedValue,Any & _rOldValue,sal_Int32 _nHandle,const Any & _rValue)294cdf0e10cSrcweir sal_Bool SAL_CALL OPropertyBag::convertFastPropertyValue( Any& _rConvertedValue, Any& _rOldValue, sal_Int32 _nHandle, const Any& _rValue ) throw (IllegalArgumentException)
295cdf0e10cSrcweir {
296cdf0e10cSrcweir return m_aDynamicProperties.convertFastPropertyValue( _nHandle, _rValue, _rConvertedValue, _rOldValue );
297cdf0e10cSrcweir }
298cdf0e10cSrcweir
299cdf0e10cSrcweir //--------------------------------------------------------------------
setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any & rValue)300cdf0e10cSrcweir void SAL_CALL OPropertyBag::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw (Exception)
301cdf0e10cSrcweir {
302cdf0e10cSrcweir m_aDynamicProperties.setFastPropertyValue( nHandle, rValue );
303cdf0e10cSrcweir }
304cdf0e10cSrcweir
305cdf0e10cSrcweir //--------------------------------------------------------------------
getInfoHelper()306cdf0e10cSrcweir ::cppu::IPropertyArrayHelper& SAL_CALL OPropertyBag::getInfoHelper()
307cdf0e10cSrcweir {
308cdf0e10cSrcweir if ( !m_pArrayHelper.get() )
309cdf0e10cSrcweir {
310cdf0e10cSrcweir Sequence< Property > aProperties;
311cdf0e10cSrcweir m_aDynamicProperties.describeProperties( aProperties );
312cdf0e10cSrcweir m_pArrayHelper.reset( new ::cppu::OPropertyArrayHelper( aProperties ) );
313cdf0e10cSrcweir }
314cdf0e10cSrcweir return *m_pArrayHelper;
315cdf0e10cSrcweir
316cdf0e10cSrcweir }
317cdf0e10cSrcweir
318cdf0e10cSrcweir //--------------------------------------------------------------------
findFreeHandle() const319cdf0e10cSrcweir sal_Int32 OPropertyBag::findFreeHandle() const
320cdf0e10cSrcweir {
321cdf0e10cSrcweir const sal_Int32 nPrime = 1009;
322cdf0e10cSrcweir const sal_Int32 nSeed = 11;
323cdf0e10cSrcweir
324cdf0e10cSrcweir sal_Int32 nCheck = nSeed;
325cdf0e10cSrcweir while ( m_aDynamicProperties.hasPropertyByHandle( nCheck ) && ( nCheck != 1 ) )
326cdf0e10cSrcweir {
327cdf0e10cSrcweir nCheck = ( nCheck * nSeed ) % nPrime;
328cdf0e10cSrcweir }
329cdf0e10cSrcweir
330cdf0e10cSrcweir if ( nCheck == 1 )
331cdf0e10cSrcweir { // uh ... we already have 1008 handles used up
332cdf0e10cSrcweir // -> simply count upwards
333cdf0e10cSrcweir while ( m_aDynamicProperties.hasPropertyByHandle( nCheck ) )
334cdf0e10cSrcweir ++nCheck;
335cdf0e10cSrcweir }
336cdf0e10cSrcweir
337cdf0e10cSrcweir return nCheck;
338cdf0e10cSrcweir }
339cdf0e10cSrcweir
340cdf0e10cSrcweir //--------------------------------------------------------------------
addProperty(const::rtl::OUString & _rName,::sal_Int16 _nAttributes,const Any & _rInitialValue)341cdf0e10cSrcweir void SAL_CALL OPropertyBag::addProperty( const ::rtl::OUString& _rName, ::sal_Int16 _nAttributes, const Any& _rInitialValue ) throw (PropertyExistException, IllegalTypeException, IllegalArgumentException, RuntimeException)
342cdf0e10cSrcweir {
343cdf0e10cSrcweir ::osl::ClearableMutexGuard g( m_aMutex );
344cdf0e10cSrcweir
345cdf0e10cSrcweir // check whether the type is allowed, everything else will be checked
346cdf0e10cSrcweir // by m_aDynamicProperties
347cdf0e10cSrcweir Type aPropertyType = _rInitialValue.getValueType();
348cdf0e10cSrcweir if ( _rInitialValue.hasValue()
349cdf0e10cSrcweir && !m_aAllowedTypes.empty()
350cdf0e10cSrcweir && m_aAllowedTypes.find( aPropertyType ) == m_aAllowedTypes.end()
351cdf0e10cSrcweir )
352cdf0e10cSrcweir throw IllegalTypeException( ::rtl::OUString(), *this );
353cdf0e10cSrcweir
354cdf0e10cSrcweir m_aDynamicProperties.addProperty( _rName, findFreeHandle(), _nAttributes, _rInitialValue );
355cdf0e10cSrcweir
356cdf0e10cSrcweir // our property info is dirty
357cdf0e10cSrcweir m_pArrayHelper.reset();
358cdf0e10cSrcweir
359cdf0e10cSrcweir g.clear();
360cdf0e10cSrcweir setModified(sal_True);
361cdf0e10cSrcweir }
362cdf0e10cSrcweir
363cdf0e10cSrcweir //--------------------------------------------------------------------
removeProperty(const::rtl::OUString & _rName)364cdf0e10cSrcweir void SAL_CALL OPropertyBag::removeProperty( const ::rtl::OUString& _rName ) throw (UnknownPropertyException, NotRemoveableException, RuntimeException)
365cdf0e10cSrcweir {
366cdf0e10cSrcweir ::osl::ClearableMutexGuard g( m_aMutex );
367cdf0e10cSrcweir
368cdf0e10cSrcweir m_aDynamicProperties.removeProperty( _rName );
369cdf0e10cSrcweir
370cdf0e10cSrcweir // our property info is dirty
371cdf0e10cSrcweir m_pArrayHelper.reset();
372cdf0e10cSrcweir
373cdf0e10cSrcweir g.clear();
374cdf0e10cSrcweir setModified(sal_True);
375cdf0e10cSrcweir }
376cdf0e10cSrcweir
377cdf0e10cSrcweir //--------------------------------------------------------------------
378cdf0e10cSrcweir namespace
379cdf0e10cSrcweir {
380cdf0e10cSrcweir struct ComparePropertyValueByName : public ::std::binary_function< PropertyValue, PropertyValue, bool >
381cdf0e10cSrcweir {
operator ()comphelper::__anondd1279a70111::ComparePropertyValueByName382cdf0e10cSrcweir bool operator()( const PropertyValue& _rLHS, const PropertyValue& _rRHS )
383cdf0e10cSrcweir {
384cdf0e10cSrcweir return _rLHS.Name < _rRHS.Name;
385cdf0e10cSrcweir }
386cdf0e10cSrcweir };
387cdf0e10cSrcweir
388cdf0e10cSrcweir template< typename CLASS >
389cdf0e10cSrcweir struct TransformPropertyToName : public ::std::unary_function< CLASS, ::rtl::OUString >
390cdf0e10cSrcweir {
operator ()comphelper::__anondd1279a70111::TransformPropertyToName391cdf0e10cSrcweir const ::rtl::OUString& operator()( const CLASS& _rProp )
392cdf0e10cSrcweir {
393cdf0e10cSrcweir return _rProp.Name;
394cdf0e10cSrcweir }
395cdf0e10cSrcweir };
396cdf0e10cSrcweir
397cdf0e10cSrcweir struct ExtractPropertyValue : public ::std::unary_function< PropertyValue, Any >
398cdf0e10cSrcweir {
operator ()comphelper::__anondd1279a70111::ExtractPropertyValue399cdf0e10cSrcweir const Any& operator()( const PropertyValue& _rProp )
400cdf0e10cSrcweir {
401cdf0e10cSrcweir return _rProp.Value;
402cdf0e10cSrcweir }
403cdf0e10cSrcweir };
404cdf0e10cSrcweir }
405cdf0e10cSrcweir
406cdf0e10cSrcweir //--------------------------------------------------------------------
getPropertyValues()407cdf0e10cSrcweir Sequence< PropertyValue > SAL_CALL OPropertyBag::getPropertyValues( ) throw (RuntimeException)
408cdf0e10cSrcweir {
409cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
410cdf0e10cSrcweir
411cdf0e10cSrcweir // all registered properties
412cdf0e10cSrcweir Sequence< Property > aProperties;
413cdf0e10cSrcweir m_aDynamicProperties.describeProperties( aProperties );
414cdf0e10cSrcweir
415cdf0e10cSrcweir // their names
416cdf0e10cSrcweir Sequence< ::rtl::OUString > aNames( aProperties.getLength() );
417cdf0e10cSrcweir ::std::transform(
418cdf0e10cSrcweir aProperties.getConstArray(),
419cdf0e10cSrcweir aProperties.getConstArray() + aProperties.getLength(),
420cdf0e10cSrcweir aNames.getArray(),
421cdf0e10cSrcweir TransformPropertyToName< Property >()
422cdf0e10cSrcweir );
423cdf0e10cSrcweir
424cdf0e10cSrcweir // their values
425cdf0e10cSrcweir Sequence< Any > aValues;
426cdf0e10cSrcweir try
427cdf0e10cSrcweir {
428cdf0e10cSrcweir aValues = OPropertyBag_PBase::getPropertyValues( aNames );
429cdf0e10cSrcweir if ( aValues.getLength() != aNames.getLength() )
430cdf0e10cSrcweir throw RuntimeException();
431cdf0e10cSrcweir }
432cdf0e10cSrcweir catch( const RuntimeException& )
433cdf0e10cSrcweir {
434cdf0e10cSrcweir throw;
435cdf0e10cSrcweir }
436cdf0e10cSrcweir catch( const Exception& )
437cdf0e10cSrcweir {
438cdf0e10cSrcweir // ignore
439cdf0e10cSrcweir }
440cdf0e10cSrcweir
441cdf0e10cSrcweir // merge names and values, and retrieve the state/handle
442cdf0e10cSrcweir ::cppu::IPropertyArrayHelper& rPropInfo = getInfoHelper();
443cdf0e10cSrcweir
444cdf0e10cSrcweir Sequence< PropertyValue > aPropertyValues( aNames.getLength() );
445cdf0e10cSrcweir const ::rtl::OUString* pName = aNames.getConstArray();
446cdf0e10cSrcweir const ::rtl::OUString* pNamesEnd = aNames.getConstArray() + aNames.getLength();
447cdf0e10cSrcweir const Any* pValue = aValues.getArray();
448cdf0e10cSrcweir PropertyValue* pPropertyValue = aPropertyValues.getArray();
449cdf0e10cSrcweir
450cdf0e10cSrcweir for ( ; pName != pNamesEnd; ++pName, ++pValue, ++pPropertyValue )
451cdf0e10cSrcweir {
452cdf0e10cSrcweir pPropertyValue->Name = *pName;
453cdf0e10cSrcweir pPropertyValue->Handle = rPropInfo.getHandleByName( *pName );
454cdf0e10cSrcweir pPropertyValue->Value = *pValue;
455cdf0e10cSrcweir pPropertyValue->State = getPropertyStateByHandle( pPropertyValue->Handle );
456cdf0e10cSrcweir }
457cdf0e10cSrcweir
458cdf0e10cSrcweir return aPropertyValues;
459cdf0e10cSrcweir }
460cdf0e10cSrcweir
461cdf0e10cSrcweir //--------------------------------------------------------------------
impl_setPropertyValues_throw(const Sequence<PropertyValue> & _rProps)462cdf0e10cSrcweir void OPropertyBag::impl_setPropertyValues_throw( const Sequence< PropertyValue >& _rProps )
463cdf0e10cSrcweir {
464cdf0e10cSrcweir // sort (the XMultiPropertySet interface requires this)
465cdf0e10cSrcweir Sequence< PropertyValue > aProperties( _rProps );
466cdf0e10cSrcweir ::std::sort(
467cdf0e10cSrcweir aProperties.getArray(),
468cdf0e10cSrcweir aProperties.getArray() + aProperties.getLength(),
469cdf0e10cSrcweir ComparePropertyValueByName()
470cdf0e10cSrcweir );
471cdf0e10cSrcweir
472cdf0e10cSrcweir // a sequence of names
473cdf0e10cSrcweir Sequence< ::rtl::OUString > aNames( aProperties.getLength() );
474cdf0e10cSrcweir ::std::transform(
475cdf0e10cSrcweir aProperties.getConstArray(),
476cdf0e10cSrcweir aProperties.getConstArray() + aProperties.getLength(),
477cdf0e10cSrcweir aNames.getArray(),
478cdf0e10cSrcweir TransformPropertyToName< PropertyValue >()
479cdf0e10cSrcweir );
480cdf0e10cSrcweir
481cdf0e10cSrcweir try
482cdf0e10cSrcweir {
483cdf0e10cSrcweir ::cppu::IPropertyArrayHelper& rPropInfo = getInfoHelper();
484cdf0e10cSrcweir
485cdf0e10cSrcweir // check for unknown properties
486cdf0e10cSrcweir // we cannot simply rely on the XMultiPropertySet::setPropertyValues
487cdf0e10cSrcweir // implementation of our base class, since it does not throw
488cdf0e10cSrcweir // an UnknownPropertyException. More precise, XMultiPropertySet::setPropertyValues
489cdf0e10cSrcweir // does not allow to throw this exception, while XPropertyAccess::setPropertyValues
490cdf0e10cSrcweir // requires it
491cdf0e10cSrcweir sal_Int32 nCount = aNames.getLength();
492cdf0e10cSrcweir
493cdf0e10cSrcweir Sequence< sal_Int32 > aHandles( nCount );
494cdf0e10cSrcweir sal_Int32* pHandle = aHandles.getArray();
495cdf0e10cSrcweir const PropertyValue* pProperty = aProperties.getConstArray();
496cdf0e10cSrcweir for ( const ::rtl::OUString* pName = aNames.getConstArray();
497cdf0e10cSrcweir pName != aNames.getConstArray() + aNames.getLength();
498cdf0e10cSrcweir ++pName, ++pHandle, ++pProperty
499cdf0e10cSrcweir )
500cdf0e10cSrcweir {
501cdf0e10cSrcweir *pHandle = rPropInfo.getHandleByName( *pName );
502cdf0e10cSrcweir if ( *pHandle != -1 )
503cdf0e10cSrcweir continue;
504cdf0e10cSrcweir
505cdf0e10cSrcweir // there's a property requested which we do not know
506cdf0e10cSrcweir if ( m_bAutoAddProperties )
507cdf0e10cSrcweir {
508cdf0e10cSrcweir // add the property
509cdf0e10cSrcweir sal_Int16 nAttributes = PropertyAttribute::BOUND | PropertyAttribute::REMOVEABLE | PropertyAttribute::MAYBEDEFAULT;
510cdf0e10cSrcweir addProperty( *pName, nAttributes, pProperty->Value );
511cdf0e10cSrcweir // rPropInfo is invalid, refetch
512cdf0e10cSrcweir rPropInfo = getInfoHelper();
513cdf0e10cSrcweir *pHandle = rPropInfo.getHandleByName( *pName );
514cdf0e10cSrcweir continue;
515cdf0e10cSrcweir }
516cdf0e10cSrcweir
517cdf0e10cSrcweir // no way out
518cdf0e10cSrcweir throw UnknownPropertyException( *pName, *this );
519cdf0e10cSrcweir }
520cdf0e10cSrcweir
521cdf0e10cSrcweir // a sequence of values
522cdf0e10cSrcweir Sequence< Any > aValues( aProperties.getLength() );
523cdf0e10cSrcweir ::std::transform(
524cdf0e10cSrcweir aProperties.getConstArray(),
525cdf0e10cSrcweir aProperties.getConstArray() + aProperties.getLength(),
526cdf0e10cSrcweir aValues.getArray(),
527cdf0e10cSrcweir ExtractPropertyValue()
528cdf0e10cSrcweir );
529cdf0e10cSrcweir
530cdf0e10cSrcweir setFastPropertyValues( nCount, aHandles.getArray(), aValues.getConstArray(), nCount );
531cdf0e10cSrcweir }
532cdf0e10cSrcweir catch( const PropertyVetoException& ) { throw; }
533cdf0e10cSrcweir catch( const IllegalArgumentException& ) { throw; }
534cdf0e10cSrcweir catch( const WrappedTargetException& ) { throw; }
535cdf0e10cSrcweir catch( const RuntimeException& ) { throw; }
536cdf0e10cSrcweir catch( const UnknownPropertyException& ) { throw; }
537cdf0e10cSrcweir catch( const Exception& )
538cdf0e10cSrcweir {
539cdf0e10cSrcweir throw WrappedTargetException( ::rtl::OUString(), *this, ::cppu::getCaughtException() );
540cdf0e10cSrcweir }
541cdf0e10cSrcweir }
542cdf0e10cSrcweir
543cdf0e10cSrcweir //--------------------------------------------------------------------
setPropertyValues(const Sequence<PropertyValue> & _rProps)544cdf0e10cSrcweir void SAL_CALL OPropertyBag::setPropertyValues( const Sequence< PropertyValue >& _rProps ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
545cdf0e10cSrcweir {
546cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
547cdf0e10cSrcweir impl_setPropertyValues_throw( _rProps );
548cdf0e10cSrcweir }
549cdf0e10cSrcweir
550cdf0e10cSrcweir //--------------------------------------------------------------------
getPropertyStateByHandle(sal_Int32 _nHandle)551cdf0e10cSrcweir PropertyState OPropertyBag::getPropertyStateByHandle( sal_Int32 _nHandle )
552cdf0e10cSrcweir {
553cdf0e10cSrcweir // for properties which do not support the MAYBEDEFAULT attribute, don't rely on the base class, but
554cdf0e10cSrcweir // assume they're always in DIRECT state.
555cdf0e10cSrcweir // (Note that this probably would belong into the base class. However, this would mean we would need
556cdf0e10cSrcweir // to check all existent usages of the base class, where MAYBEDEFAULT is *not* set, but
557cdf0e10cSrcweir // a default is nonetheless supplied/used. This is hard to accomplish reliably, in the
558cdf0e10cSrcweir // current phase.
559cdf0e10cSrcweir // #i78593# / 2007-07-07 / frank.schoenheit@sun.com
560cdf0e10cSrcweir
561cdf0e10cSrcweir ::cppu::IPropertyArrayHelper& rPropInfo = getInfoHelper();
562cdf0e10cSrcweir sal_Int16 nAttributes(0);
563cdf0e10cSrcweir OSL_VERIFY( rPropInfo.fillPropertyMembersByHandle( NULL, &nAttributes, _nHandle ) );
564cdf0e10cSrcweir if ( ( nAttributes & PropertyAttribute::MAYBEDEFAULT ) == 0 )
565cdf0e10cSrcweir return PropertyState_DIRECT_VALUE;
566cdf0e10cSrcweir
567cdf0e10cSrcweir return OPropertyBag_PBase::getPropertyStateByHandle( _nHandle );
568cdf0e10cSrcweir }
569cdf0e10cSrcweir
570cdf0e10cSrcweir //--------------------------------------------------------------------
getPropertyDefaultByHandle(sal_Int32 _nHandle) const571cdf0e10cSrcweir Any OPropertyBag::getPropertyDefaultByHandle( sal_Int32 _nHandle ) const
572cdf0e10cSrcweir {
573cdf0e10cSrcweir Any aDefault;
574cdf0e10cSrcweir m_aDynamicProperties.getPropertyDefaultByHandle( _nHandle, aDefault );
575cdf0e10cSrcweir return aDefault;
576cdf0e10cSrcweir }
577cdf0e10cSrcweir
578cdf0e10cSrcweir //........................................................................
579cdf0e10cSrcweir } // namespace comphelper
580cdf0e10cSrcweir //........................................................................
581cdf0e10cSrcweir
582