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