LCOV - code coverage report
Current view: top level - cppuhelper/source - propertysetmixin.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 181 509 35.6 %
Date: 2015-06-13 12:38:46 Functions: 21 46 45.7 %
Legend: Lines: hit not hit

          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             : #include <sal/config.h>
      21             : 
      22             : #include <algorithm>
      23             : #include <cassert>
      24             : #include <exception>
      25             : #include <map>
      26             : #include <set>
      27             : #include <vector>
      28             : 
      29             : #include <com/sun/star/beans/Property.hpp>
      30             : #include <com/sun/star/beans/PropertyChangeEvent.hpp>
      31             : #include <com/sun/star/beans/PropertyAttribute.hpp>
      32             : #include <com/sun/star/beans/PropertyValue.hpp>
      33             : #include <com/sun/star/beans/PropertyVetoException.hpp>
      34             : #include <com/sun/star/beans/UnknownPropertyException.hpp>
      35             : #include <com/sun/star/beans/XFastPropertySet.hpp>
      36             : #include <com/sun/star/beans/XPropertyAccess.hpp>
      37             : #include <com/sun/star/beans/XPropertyChangeListener.hpp>
      38             : #include <com/sun/star/beans/XPropertySet.hpp>
      39             : #include <com/sun/star/beans/XPropertySetInfo.hpp>
      40             : #include <com/sun/star/beans/XVetoableChangeListener.hpp>
      41             : #include <com/sun/star/container/NoSuchElementException.hpp>
      42             : #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
      43             : #include <com/sun/star/lang/DisposedException.hpp>
      44             : #include <com/sun/star/lang/EventObject.hpp>
      45             : #include <com/sun/star/lang/IllegalAccessException.hpp>
      46             : #include <com/sun/star/lang/IllegalArgumentException.hpp>
      47             : #include <com/sun/star/lang/WrappedTargetException.hpp>
      48             : #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
      49             : #include <com/sun/star/reflection/XCompoundTypeDescription.hpp>
      50             : #include <com/sun/star/reflection/XIdlClass.hpp>
      51             : #include <com/sun/star/reflection/XIdlField2.hpp>
      52             : #include <com/sun/star/reflection/XIndirectTypeDescription.hpp>
      53             : #include <com/sun/star/reflection/XInterfaceAttributeTypeDescription2.hpp>
      54             : #include <com/sun/star/reflection/XInterfaceMemberTypeDescription.hpp>
      55             : #include <com/sun/star/reflection/XInterfaceTypeDescription2.hpp>
      56             : #include <com/sun/star/reflection/XStructTypeDescription.hpp>
      57             : #include <com/sun/star/reflection/XTypeDescription.hpp>
      58             : #include <com/sun/star/reflection/theCoreReflection.hpp>
      59             : #include <com/sun/star/uno/Any.hxx>
      60             : #include <com/sun/star/uno/DeploymentException.hpp>
      61             : #include <com/sun/star/uno/Exception.hpp>
      62             : #include <com/sun/star/uno/Reference.hxx>
      63             : #include <com/sun/star/uno/RuntimeException.hpp>
      64             : #include <com/sun/star/uno/Sequence.hxx>
      65             : #include <com/sun/star/uno/Type.hxx>
      66             : #include <com/sun/star/uno/TypeClass.hpp>
      67             : #include <com/sun/star/uno/XComponentContext.hpp>
      68             : #include <com/sun/star/uno/XInterface.hpp>
      69             : #include <cppuhelper/implbase1.hxx>
      70             : #include <cppuhelper/propertysetmixin.hxx>
      71             : #include <cppuhelper/weak.hxx>
      72             : #include <osl/mutex.hxx>
      73             : #include <rtl/ref.hxx>
      74             : #include <rtl/ustring.hxx>
      75             : #include <sal/types.h>
      76             : #include <salhelper/simplereferenceobject.hxx>
      77             : 
      78             : using cppu::PropertySetMixinImpl;
      79             : 
      80             : namespace {
      81             : 
      82      151974 : struct PropertyData {
      83       30402 :     explicit PropertyData(
      84             :         css::beans::Property const & theProperty, bool thePresent):
      85       30402 :         property(theProperty), present(thePresent) {}
      86             : 
      87             :     css::beans::Property property;
      88             :     bool present;
      89             : };
      90             : 
      91       19962 : struct Data: public salhelper::SimpleReferenceObject {
      92             :     typedef std::map< rtl::OUString, PropertyData > PropertyMap;
      93             : 
      94             :     PropertyMap properties;
      95             : 
      96             :     PropertyMap::const_iterator get(
      97             :         css::uno::Reference< css::uno::XInterface > const & object,
      98             :         rtl::OUString const & name) const;
      99             : 
     100             : protected:
     101        9987 :     void initProperties(
     102             :         css::uno::Reference< css::reflection::XTypeDescription > const & type,
     103             :         css::uno::Sequence< rtl::OUString > const & absentOptional,
     104             :         std::vector< rtl::OUString > * handleNames)
     105             :     {
     106        9987 :         TypeSet seen;
     107        9987 :         initProperties(type, absentOptional, handleNames, &seen);
     108        9987 :     }
     109             : 
     110             : private:
     111             :     typedef std::set< rtl::OUString > TypeSet;
     112             : 
     113             :     void initProperties(
     114             :         css::uno::Reference< css::reflection::XTypeDescription > const & type,
     115             :         css::uno::Sequence< rtl::OUString > const & absentOptional,
     116             :         std::vector< rtl::OUString > * handleNames, TypeSet * seen);
     117             : 
     118             :     static css::uno::Reference< css::reflection::XTypeDescription >
     119             :     resolveTypedefs(
     120             :         css::uno::Reference< css::reflection::XTypeDescription > const & type);
     121             : };
     122             : 
     123           0 : Data::PropertyMap::const_iterator Data::get(
     124             :     css::uno::Reference< css::uno::XInterface > const & object,
     125             :     rtl::OUString const & name) const
     126             : {
     127           0 :     PropertyMap::const_iterator i(properties.find(name));
     128           0 :     if (i == properties.end() || !i->second.present) {
     129           0 :         throw css::beans::UnknownPropertyException(name, object);
     130             :     }
     131           0 :     return i;
     132             : }
     133             : 
     134       50029 : void Data::initProperties(
     135             :     css::uno::Reference< css::reflection::XTypeDescription > const & type,
     136             :     css::uno::Sequence< rtl::OUString > const & absentOptional,
     137             :     std::vector< rtl::OUString > * handleNames, TypeSet * seen)
     138             : {
     139             :     css::uno::Reference< css::reflection::XInterfaceTypeDescription2 > ifc(
     140       50029 :         resolveTypedefs(type), css::uno::UNO_QUERY_THROW);
     141       50029 :     if (seen->insert(ifc->getName()).second) {
     142             :         css::uno::Sequence<
     143             :         css::uno::Reference< css::reflection::XTypeDescription > > bases(
     144       40010 :             ifc->getBaseTypes());
     145       80052 :         for (sal_Int32 i = 0; i < bases.getLength(); ++i) {
     146       40042 :             initProperties(bases[i], absentOptional, handleNames, seen);
     147             :         }
     148             :         css::uno::Sequence<
     149             :         css::uno::Reference<
     150             :         css::reflection::XInterfaceMemberTypeDescription > > members(
     151       80020 :             ifc->getMembers());
     152       40010 :         rtl::OUString const * absentBegin = absentOptional.getConstArray();
     153             :         rtl::OUString const * absentEnd =
     154       40010 :             absentBegin + absentOptional.getLength();
     155      150442 :         for (sal_Int32 i = 0; i < members.getLength(); ++i) {
     156      110432 :             if (members[i]->getTypeClass()
     157             :                 == css::uno::TypeClass_INTERFACE_ATTRIBUTE)
     158             :             {
     159             :                 css::uno::Reference<
     160             :                 css::reflection::XInterfaceAttributeTypeDescription2 > attr(
     161       30402 :                     members[i], css::uno::UNO_QUERY_THROW);
     162       30402 :                 sal_Int16 attrAttribs = 0;
     163       30402 :                 if (attr->isBound()) {
     164         457 :                     attrAttribs |= css::beans::PropertyAttribute::BOUND;
     165             :                 }
     166       30402 :                 bool setUnknown = false;
     167       30402 :                 if (attr->isReadOnly()) {
     168       19963 :                     attrAttribs |= css::beans::PropertyAttribute::READONLY;
     169       19963 :                     setUnknown = true;
     170             :                 }
     171             :                 css::uno::Sequence<
     172             :                 css::uno::Reference<
     173             :                 css::reflection::XCompoundTypeDescription > > excs(
     174       60804 :                     attr->getGetExceptions());
     175       30402 :                 bool getUnknown = false;
     176             :                 //XXX  Special interpretation of getter/setter exceptions only
     177             :                 // works if the specified exceptions are of the exact type, not
     178             :                 // of a supertype:
     179       30402 :                 for (sal_Int32 j = 0; j < excs.getLength(); ++j) {
     180         407 :                     if ( excs[j]->getName() == "com.sun.star.beans.UnknownPropertyException" )
     181             :                     {
     182         407 :                         getUnknown = true;
     183         407 :                         break;
     184             :                     }
     185             :                 }
     186       30402 :                 excs = attr->getSetExceptions();
     187       30848 :                 for (sal_Int32 j = 0; j < excs.getLength(); ++j) {
     188         446 :                     if ( excs[j]->getName() == "com.sun.star.beans.UnknownPropertyException" )
     189             :                     {
     190         407 :                         setUnknown = true;
     191          39 :                     } else if ( excs[j]->getName() == "com.sun.star.beans.PropertyVetoException" )
     192             :                     {
     193             :                         attrAttribs
     194          15 :                             |= css::beans::PropertyAttribute::CONSTRAINED;
     195             :                     }
     196             :                 }
     197       30402 :                 if (getUnknown && setUnknown) {
     198         407 :                     attrAttribs |= css::beans::PropertyAttribute::OPTIONAL;
     199             :                 }
     200             :                 css::uno::Reference< css::reflection::XTypeDescription > t(
     201       60804 :                     attr->getType());
     202             :                 for (;;)
     203             :                 {
     204       30403 :                     t = resolveTypedefs(t);
     205             :                     sal_Int16 n;
     206       91209 :                     if (t->getName().startsWith(
     207       60806 :                             "com.sun.star.beans.Ambiguous<"))
     208             :                     {
     209           0 :                         n = css::beans::PropertyAttribute::MAYBEAMBIGUOUS;
     210       91209 :                     } else if (t->getName().startsWith(
     211       60806 :                                    "com.sun.star.beans.Defaulted<"))
     212             :                     {
     213           0 :                         n = css::beans::PropertyAttribute::MAYBEDEFAULT;
     214       91209 :                     } else if (t->getName().startsWith(
     215       60806 :                                    "com.sun.star.beans.Optional<"))
     216             :                     {
     217           1 :                         n = css::beans::PropertyAttribute::MAYBEVOID;
     218             :                     } else {
     219       60804 :                         break;
     220             :                     }
     221           1 :                     if ((attrAttribs & n) != 0) {
     222           0 :                         break;
     223             :                     }
     224           1 :                     attrAttribs |= n;
     225             :                     css::uno::Sequence<
     226             :                     css::uno::Reference< css::reflection::XTypeDescription > >
     227             :                         args(
     228             :                             css::uno::Reference<
     229             :                             css::reflection::XStructTypeDescription >(
     230           2 :                                 t, css::uno::UNO_QUERY_THROW)->
     231           1 :                             getTypeArguments());
     232           1 :                     if (args.getLength() != 1) {
     233             :                         throw css::uno::RuntimeException(
     234           0 :                             "inconsistent UNO type registry");
     235             :                     }
     236           1 :                     t = args[0];
     237           1 :                 }
     238             :                 std::vector< rtl::OUString >::size_type handles
     239       30402 :                     = handleNames->size();
     240       30402 :                 if (handles > SAL_MAX_INT32) {
     241             :                     throw css::uno::RuntimeException(
     242           0 :                         "interface type has too many attributes");
     243             :                 }
     244       60804 :                 rtl::OUString name(members[i]->getMemberName());
     245       60804 :                 if (!properties.insert(
     246             :                         PropertyMap::value_type(
     247             :                             name,
     248             :                             PropertyData(
     249             :                                 css::beans::Property(
     250             :                                     name, static_cast< sal_Int32 >(handles),
     251             :                                     css::uno::Type(
     252       60804 :                                         t->getTypeClass(), t->getName()),
     253             :                                     attrAttribs),
     254       30402 :                                 (std::find(absentBegin, absentEnd, name)
     255      121608 :                                  == absentEnd)))).
     256       30402 :                     second)
     257             :                 {
     258             :                     throw css::uno::RuntimeException(
     259           0 :                         "inconsistent UNO type registry");
     260             :                 }
     261       60804 :                 handleNames->push_back(name);
     262             :             }
     263       40010 :         }
     264       50029 :     }
     265       50029 : }
     266             : 
     267       80432 : css::uno::Reference< css::reflection::XTypeDescription > Data::resolveTypedefs(
     268             :     css::uno::Reference< css::reflection::XTypeDescription > const & type)
     269             : {
     270       80432 :     css::uno::Reference< css::reflection::XTypeDescription > t(type);
     271      160883 :     while (t->getTypeClass() == css::uno::TypeClass_TYPEDEF) {
     272          38 :         t = css::uno::Reference< css::reflection::XIndirectTypeDescription >(
     273          57 :             t, css::uno::UNO_QUERY_THROW)->getReferencedType();
     274             :     }
     275       80432 :     return t;
     276             : }
     277             : 
     278           0 : class Info: public cppu::WeakImplHelper1< css::beans::XPropertySetInfo > {
     279             : public:
     280           0 :     explicit Info(Data * data): m_data(data) {}
     281             : 
     282             :     virtual css::uno::Sequence< css::beans::Property > SAL_CALL getProperties()
     283             :         throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     284             : 
     285             :     virtual css::beans::Property SAL_CALL getPropertyByName(
     286             :         rtl::OUString const & name)
     287             :         throw (
     288             :             css::beans::UnknownPropertyException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     289             : 
     290             :     virtual sal_Bool SAL_CALL hasPropertyByName(rtl::OUString const & name)
     291             :         throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     292             : 
     293             : private:
     294             :     rtl::Reference< Data > m_data;
     295             : };
     296             : 
     297           0 : css::uno::Sequence< css::beans::Property > Info::getProperties()
     298             :     throw (css::uno::RuntimeException, std::exception)
     299             : {
     300             :     assert(m_data->properties.size() <= SAL_MAX_INT32);
     301             :     css::uno::Sequence< css::beans::Property > s(
     302           0 :         static_cast< sal_Int32 >(m_data->properties.size()));
     303           0 :     sal_Int32 n = 0;
     304           0 :     for (Data::PropertyMap::iterator i(m_data->properties.begin());
     305           0 :          i != m_data->properties.end(); ++i)
     306             :     {
     307           0 :         if (i->second.present) {
     308           0 :             s[n++] = i->second.property;
     309             :         }
     310             :     }
     311           0 :     s.realloc(n);
     312           0 :     return s;
     313             : }
     314             : 
     315           0 : css::beans::Property Info::getPropertyByName(rtl::OUString const & name)
     316             :     throw (css::beans::UnknownPropertyException, css::uno::RuntimeException, std::exception)
     317             : {
     318           0 :     return m_data->get(static_cast< cppu::OWeakObject * >(this), name)->
     319           0 :         second.property;
     320             : }
     321             : 
     322           0 : sal_Bool Info::hasPropertyByName(rtl::OUString const & name)
     323             :     throw (css::uno::RuntimeException, std::exception)
     324             : {
     325           0 :     Data::PropertyMap::iterator i(m_data->properties.find(name));
     326           0 :     return i != m_data->properties.end() && i->second.present;
     327             : }
     328             : 
     329             : typedef
     330             : std::multiset< css::uno::Reference< css::beans::XPropertyChangeListener > >
     331             : BoundListenerBag;
     332             : 
     333             : }
     334             : 
     335           0 : class PropertySetMixinImpl::BoundListeners::Impl {
     336             : public:
     337             :     BoundListenerBag specificListeners;
     338             :     BoundListenerBag unspecificListeners;
     339             :     css::beans::PropertyChangeEvent event;
     340             : };
     341             : 
     342           0 : PropertySetMixinImpl::BoundListeners::BoundListeners(): m_impl(new Impl) {}
     343             : 
     344           0 : PropertySetMixinImpl::BoundListeners::~BoundListeners() {
     345           0 :     delete m_impl;
     346           0 : }
     347             : 
     348           0 : void PropertySetMixinImpl::BoundListeners::notify() const {
     349           0 :     for (BoundListenerBag::const_iterator i(m_impl->specificListeners.begin());
     350           0 :          i != m_impl->specificListeners.end(); ++i)
     351             :     {
     352             :         try {
     353           0 :             (*i)->propertyChange(m_impl->event);
     354           0 :         } catch (css::lang::DisposedException &) {}
     355             :     }
     356           0 :     for (BoundListenerBag::const_iterator i(
     357           0 :              m_impl->unspecificListeners.begin());
     358           0 :          i != m_impl->unspecificListeners.end(); ++i)
     359             :     {
     360             :         try {
     361           0 :             (*i)->propertyChange(m_impl->event);
     362           0 :         } catch (css::lang::DisposedException &) {}
     363             :     }
     364           0 : }
     365             : 
     366       19950 : class PropertySetMixinImpl::Impl: public Data {
     367             : public:
     368             :     Impl(
     369             :         css::uno::Reference< css::uno::XComponentContext > const & context,
     370             :         Implements theImplements,
     371             :         css::uno::Sequence< rtl::OUString > const & absentOptional,
     372             :         css::uno::Type const & type);
     373             : 
     374             :     rtl::OUString translateHandle(
     375             :         css::uno::Reference< css::uno::XInterface > const & object,
     376             :         sal_Int32 handle) const;
     377             : 
     378             :     void setProperty(
     379             :         css::uno::Reference< css::uno::XInterface > const & object,
     380             :         rtl::OUString const & name, css::uno::Any const & value,
     381             :         bool isAmbiguous, bool isDefaulted, sal_Int16 illegalArgumentPosition)
     382             :         const;
     383             : 
     384             :     css::uno::Any getProperty(
     385             :         css::uno::Reference< css::uno::XInterface > const & object,
     386             :         rtl::OUString const & name, css::beans::PropertyState * state) const;
     387             : 
     388             :     PropertySetMixinImpl::Implements implements;
     389             :     css::uno::Sequence< rtl::OUString > handleMap;
     390             : 
     391             :     typedef std::map< rtl::OUString, BoundListenerBag > BoundListenerMap;
     392             : 
     393             :     typedef
     394             :     std::multiset< css::uno::Reference< css::beans::XVetoableChangeListener > >
     395             :     VetoListenerBag;
     396             : 
     397             :     typedef std::map< rtl::OUString, VetoListenerBag > VetoListenerMap;
     398             : 
     399             :     mutable osl::Mutex mutex;
     400             :     BoundListenerMap boundListeners;
     401             :     VetoListenerMap vetoListeners;
     402             :     bool disposed;
     403             : 
     404             : private:
     405             :     css::uno::Reference< css::reflection::XIdlClass > getReflection(
     406             :         rtl::OUString const & typeName) const;
     407             : 
     408             :     static css::uno::Any wrapValue(
     409             :         css::uno::Reference< css::uno::XInterface > const & object,
     410             :         css::uno::Any const & value,
     411             :         css::uno::Reference< css::reflection::XIdlClass > const & type,
     412             :         bool wrapAmbiguous, bool isAmbiguous, bool wrapDefaulted,
     413             :         bool isDefaulted, bool wrapOptional);
     414             : 
     415             :     css::uno::Reference< css::uno::XComponentContext > const & m_context;
     416             :     css::uno::Sequence< rtl::OUString > m_absentOptional;
     417             :     css::uno::Type m_type;
     418             :     css::uno::Reference< css::reflection::XIdlClass > m_idlClass;
     419             : };
     420             : 
     421        9987 : PropertySetMixinImpl::Impl::Impl(
     422             :     css::uno::Reference< css::uno::XComponentContext > const & context,
     423             :     Implements theImplements,
     424             :     css::uno::Sequence< rtl::OUString > const & absentOptional,
     425             :     css::uno::Type const & type):
     426             :     implements(theImplements), disposed(false), m_context(context),
     427        9987 :     m_absentOptional(absentOptional), m_type(type)
     428             : {
     429             :     assert(context.is());
     430             :     assert(
     431             :         (implements
     432             :          & ~(IMPLEMENTS_PROPERTY_SET | IMPLEMENTS_FAST_PROPERTY_SET
     433             :              | IMPLEMENTS_PROPERTY_ACCESS))
     434             :         == 0);
     435        9987 :     m_idlClass = getReflection(m_type.getTypeName());
     436        9987 :     css::uno::Reference< css::reflection::XTypeDescription > ifc;
     437             :     try {
     438       19974 :         ifc = css::uno::Reference< css::reflection::XTypeDescription >(
     439             :             css::uno::Reference< css::container::XHierarchicalNameAccess >(
     440        9987 :                 m_context->getValueByName(
     441             :                     "/singletons/com.sun.star.reflection."
     442        9987 :                     "theTypeDescriptionManager"),
     443       19974 :                 css::uno::UNO_QUERY_THROW)->getByHierarchicalName(
     444        9987 :                     m_type.getTypeName()),
     445        9987 :             css::uno::UNO_QUERY_THROW);
     446           0 :     } catch (css::container::NoSuchElementException & e) {
     447             :         throw css::uno::RuntimeException(
     448             :             "unexpected com.sun.star.container.NoSuchElementException: "
     449           0 :              + e.Message);
     450             :     }
     451       19974 :     std::vector< rtl::OUString > handleNames;
     452        9987 :     initProperties(ifc, m_absentOptional, &handleNames);
     453        9987 :     std::vector< rtl::OUString >::size_type size = handleNames.size();
     454             :     assert(size <= SAL_MAX_INT32);
     455        9987 :     handleMap.realloc(static_cast< sal_Int32 >(size));
     456       19974 :     std::copy(handleNames.begin(), handleNames.end(), handleMap.getArray());
     457        9987 : }
     458             : 
     459           0 : rtl::OUString PropertySetMixinImpl::Impl::translateHandle(
     460             :     css::uno::Reference< css::uno::XInterface > const & object,
     461             :     sal_Int32 handle) const
     462             : {
     463           0 :     if (handle < 0 || handle >= handleMap.getLength()) {
     464             :         throw css::beans::UnknownPropertyException(
     465           0 :             "bad handle " + rtl::OUString::number(handle), object);
     466             :     }
     467           0 :     return handleMap[handle];
     468             : }
     469             : 
     470         851 : void PropertySetMixinImpl::Impl::setProperty(
     471             :     css::uno::Reference< css::uno::XInterface > const & object,
     472             :     rtl::OUString const & name, css::uno::Any const & value, bool isAmbiguous,
     473             :     bool isDefaulted, sal_Int16 illegalArgumentPosition) const
     474             : {
     475         851 :     PropertyMap::const_iterator i(properties.find(name));
     476         851 :     if (i == properties.end()) {
     477           0 :         throw css::beans::UnknownPropertyException(name, object);
     478             :     }
     479         851 :     if ((isAmbiguous
     480           0 :          && ((i->second.property.Attributes
     481           0 :               & css::beans::PropertyAttribute::MAYBEAMBIGUOUS)
     482             :              == 0))
     483        1702 :         || (isDefaulted
     484           0 :             && ((i->second.property.Attributes
     485           0 :                  & css::beans::PropertyAttribute::MAYBEDEFAULT)
     486             :                 == 0)))
     487             :     {
     488             :         throw css::lang::IllegalArgumentException(
     489             :             ("flagging as ambiguous/defaulted non-ambiguous/defaulted property "
     490           0 :              + name),
     491           0 :             object, illegalArgumentPosition);
     492             :     }
     493             :     css::uno::Reference< css::reflection::XIdlField2 > f(
     494         851 :         m_idlClass->getField(name), css::uno::UNO_QUERY_THROW);
     495        1702 :     css::uno::Any o(object->queryInterface(m_type));
     496             :     css::uno::Any v(
     497             :         wrapValue(
     498             :             object, value,
     499             :             (css::uno::Reference< css::reflection::XIdlField2 >(
     500        2553 :                 m_idlClass->getField(name), css::uno::UNO_QUERY_THROW)->
     501         851 :              getType()),
     502         851 :             ((i->second.property.Attributes
     503         851 :               & css::beans::PropertyAttribute::MAYBEAMBIGUOUS)
     504             :              != 0),
     505             :             isAmbiguous,
     506         851 :             ((i->second.property.Attributes
     507         851 :               & css::beans::PropertyAttribute::MAYBEDEFAULT)
     508             :              != 0),
     509             :             isDefaulted,
     510         851 :             ((i->second.property.Attributes
     511         851 :               & css::beans::PropertyAttribute::MAYBEVOID)
     512        5106 :              != 0)));
     513             :     try {
     514         851 :         f->set(o, v);
     515           0 :     } catch (css::lang::IllegalArgumentException & e) {
     516           0 :         if (e.ArgumentPosition == 1) {
     517             :             throw css::lang::IllegalArgumentException(
     518           0 :                 e.Message, object, illegalArgumentPosition);
     519             :         } else {
     520             :             throw css::uno::RuntimeException(
     521             :                 ("unexpected com.sun.star.lang.IllegalArgumentException: "
     522           0 :                  + e.Message),
     523           0 :                 object);
     524             :         }
     525           0 :     } catch (css::lang::IllegalAccessException &) {
     526             :         //TODO  Clarify whether PropertyVetoException is the correct exception
     527             :         // to throw when trying to set a read-only property:
     528             :         throw css::beans::PropertyVetoException(
     529           0 :             "cannot set read-only property " + name, object);
     530           0 :     } catch (css::lang::WrappedTargetRuntimeException & e) {
     531             :         //FIXME  A WrappedTargetRuntimeException from XIdlField2.get is not
     532             :         // guaranteed to originate directly within XIdlField2.get (and thus have
     533             :         // the expected semantics); it might also be passed through from lower
     534             :         // layers.
     535           0 :         if (e.TargetException.isExtractableTo(
     536           0 :                 cppu::UnoType<css::beans::UnknownPropertyException>::get())
     537           0 :             && ((i->second.property.Attributes
     538           0 :                  & css::beans::PropertyAttribute::OPTIONAL)
     539             :                 != 0))
     540             :         {
     541           0 :             throw css::beans::UnknownPropertyException(name, object);
     542           0 :         } else if (e.TargetException.isExtractableTo(
     543           0 :                        cppu::UnoType<css::beans::PropertyVetoException>::get())
     544           0 :                    && ((i->second.property.Attributes
     545           0 :                         & css::beans::PropertyAttribute::CONSTRAINED)
     546             :                        != 0))
     547             :         {
     548           0 :             css::beans::PropertyVetoException exc;
     549           0 :             e.TargetException >>= exc;
     550           0 :             if (exc.Message.isEmpty() )
     551           0 :                 throw css::beans::PropertyVetoException("Invalid " + name, object);
     552             :             else
     553           0 :                 throw exc;
     554             :         } else {
     555             :             throw css::lang::WrappedTargetException(
     556           0 :                 e.Message, object, e.TargetException);
     557             :         }
     558         851 :     }
     559         851 : }
     560             : 
     561         851 : css::uno::Any PropertySetMixinImpl::Impl::getProperty(
     562             :     css::uno::Reference< css::uno::XInterface > const & object,
     563             :     rtl::OUString const & name, css::beans::PropertyState * state) const
     564             : {
     565         851 :     PropertyMap::const_iterator i(properties.find(name));
     566         851 :     if (i == properties.end()) {
     567           0 :         throw css::beans::UnknownPropertyException(name, object);
     568             :     }
     569             :     css::uno::Reference< css::reflection::XIdlField2 > field(
     570         851 :         m_idlClass->getField(name), css::uno::UNO_QUERY_THROW);
     571         851 :     css::uno::Any value;
     572             :     try {
     573         851 :         value = field->get(object->queryInterface(m_type));
     574           0 :     } catch (css::lang::IllegalArgumentException & e) {
     575             :         throw css::uno::RuntimeException(
     576             :             ("unexpected com.sun.star.lang.IllegalArgumentException: "
     577           0 :              + e.Message),
     578           0 :             object);
     579           0 :     } catch (css::lang::WrappedTargetRuntimeException & e) {
     580             :         //FIXME  A WrappedTargetRuntimeException from XIdlField2.get is not
     581             :         // guaranteed to originate directly within XIdlField2.get (and thus have
     582             :         // the expected semantics); it might also be passed through from lower
     583             :         // layers.
     584           0 :         if (e.TargetException.isExtractableTo(
     585           0 :                 cppu::UnoType<css::beans::UnknownPropertyException>::get())
     586           0 :             && ((i->second.property.Attributes
     587           0 :                  & css::beans::PropertyAttribute::OPTIONAL)
     588             :                 != 0))
     589             :         {
     590           0 :             throw css::beans::UnknownPropertyException(name, object);
     591             :         } else {
     592             :             throw css::lang::WrappedTargetException(
     593           0 :                 e.Message, object, e.TargetException);
     594             :         }
     595             :     }
     596             :     bool undoAmbiguous
     597         851 :         = ((i->second.property.Attributes
     598         851 :             & css::beans::PropertyAttribute::MAYBEAMBIGUOUS)
     599         851 :            != 0);
     600             :     bool undoDefaulted
     601         851 :         = ((i->second.property.Attributes
     602         851 :             & css::beans::PropertyAttribute::MAYBEDEFAULT)
     603         851 :            != 0);
     604             :     bool undoOptional
     605         851 :         = ((i->second.property.Attributes
     606         851 :             & css::beans::PropertyAttribute::MAYBEVOID)
     607         851 :            != 0);
     608         851 :     bool isAmbiguous = false;
     609         851 :     bool isDefaulted = false;
     610        1702 :     while (undoAmbiguous || undoDefaulted || undoOptional) {
     611           0 :         if (undoAmbiguous
     612           0 :             && value.getValueTypeName().startsWith(
     613           0 :                 "com.sun.star.beans.Ambiguous<"))
     614             :         {
     615             :             css::uno::Reference< css::reflection::XIdlClass > ambiguous(
     616           0 :                 getReflection(value.getValueTypeName()));
     617             :             try {
     618           0 :                 if (!(css::uno::Reference< css::reflection::XIdlField2 >(
     619           0 :                           ambiguous->getField("IsAmbiguous"),
     620           0 :                           css::uno::UNO_QUERY_THROW)->get(value)
     621           0 :                       >>= isAmbiguous))
     622             :                 {
     623             :                     throw css::uno::RuntimeException(
     624             :                         ("unexpected type of com.sun.star.beans.Ambiguous"
     625             :                          " IsAmbiguous member"),
     626           0 :                         object);
     627             :                 }
     628           0 :                 value = css::uno::Reference< css::reflection::XIdlField2 >(
     629           0 :                     ambiguous->getField("Value"), css::uno::UNO_QUERY_THROW)->
     630           0 :                     get(value);
     631           0 :             } catch (css::lang::IllegalArgumentException & e) {
     632             :                 throw css::uno::RuntimeException(
     633             :                     ("unexpected com.sun.star.lang.IllegalArgumentException: "
     634           0 :                      + e.Message),
     635           0 :                     object);
     636             :             }
     637           0 :             undoAmbiguous = false;
     638           0 :         } else if (undoDefaulted
     639           0 :                    && value.getValueTypeName().startsWith(
     640           0 :                        "com.sun.star.beans.Defaulted<"))
     641             :         {
     642             :             css::uno::Reference< css::reflection::XIdlClass > defaulted(
     643           0 :                 getReflection(value.getValueTypeName()));
     644             :             try {
     645             : 
     646           0 :                 if (!(css::uno::Reference< css::reflection::XIdlField2 >(
     647           0 :                           defaulted->getField("IsDefaulted"),
     648           0 :                           css::uno::UNO_QUERY_THROW)->get(value)
     649           0 :                       >>= isDefaulted))
     650             :                 {
     651             :                     throw css::uno::RuntimeException(
     652             :                         ("unexpected type of com.sun.star.beans.Defaulted"
     653             :                          " IsDefaulted member"),
     654           0 :                         object);
     655             :                 }
     656           0 :                 value = css::uno::Reference< css::reflection::XIdlField2 >(
     657           0 :                     defaulted->getField("Value"), css::uno::UNO_QUERY_THROW)->
     658           0 :                     get(value);
     659           0 :             } catch (css::lang::IllegalArgumentException & e) {
     660             :                 throw css::uno::RuntimeException(
     661             :                     ("unexpected com.sun.star.lang.IllegalArgumentException: "
     662           0 :                      + e.Message),
     663           0 :                     object);
     664             :             }
     665           0 :             undoDefaulted = false;
     666           0 :         } else if (undoOptional
     667           0 :                    && value.getValueTypeName().startsWith(
     668           0 :                        "com.sun.star.beans.Optional<"))
     669             :         {
     670             :             css::uno::Reference< css::reflection::XIdlClass > optional(
     671           0 :                 getReflection(value.getValueTypeName()));
     672             :             try {
     673           0 :                 bool present = false;
     674           0 :                 if (!(css::uno::Reference< css::reflection::XIdlField2 >(
     675           0 :                           optional->getField("IsPresent"),
     676           0 :                           css::uno::UNO_QUERY_THROW)->get(value)
     677           0 :                       >>= present))
     678             :                 {
     679             :                     throw css::uno::RuntimeException(
     680             :                         ("unexpected type of com.sun.star.beans.Optional"
     681             :                          " IsPresent member"),
     682           0 :                         object);
     683             :                 }
     684           0 :                 if (!present) {
     685           0 :                     value.clear();
     686           0 :                     break;
     687             :                 }
     688           0 :                 value = css::uno::Reference< css::reflection::XIdlField2 >(
     689           0 :                     optional->getField("Value"), css::uno::UNO_QUERY_THROW)->
     690           0 :                     get(value);
     691           0 :             } catch (css::lang::IllegalArgumentException & e) {
     692             :                 throw css::uno::RuntimeException(
     693             :                     ("unexpected com.sun.star.lang.IllegalArgumentException: "
     694           0 :                      + e.Message),
     695           0 :                     object);
     696             :             }
     697           0 :             undoOptional = false;
     698             :         } else {
     699             :             throw css::uno::RuntimeException(
     700           0 :                 "unexpected type of attribute " + name, object);
     701             :         }
     702             :     }
     703         851 :     if (state != 0) {
     704             :         //XXX  If isAmbiguous && isDefaulted, arbitrarily choose AMBIGUOUS_VALUE
     705             :         // over DEFAULT_VALUE:
     706             :         *state = isAmbiguous
     707             :             ? css::beans::PropertyState_AMBIGUOUS_VALUE
     708             :             : isDefaulted
     709             :             ? css::beans::PropertyState_DEFAULT_VALUE
     710           0 :             : css::beans::PropertyState_DIRECT_VALUE;
     711             :     }
     712         851 :     return value;
     713             : }
     714             : 
     715             : css::uno::Reference< css::reflection::XIdlClass >
     716        9987 : PropertySetMixinImpl::Impl::getReflection(rtl::OUString const & typeName) const
     717             : {
     718             :     return css::uno::Reference< css::reflection::XIdlClass >(
     719       19974 :         css::reflection::theCoreReflection::get(m_context)->forName(typeName),
     720       19974 :         css::uno::UNO_SET_THROW);
     721             : }
     722             : 
     723         851 : css::uno::Any PropertySetMixinImpl::Impl::wrapValue(
     724             :     css::uno::Reference< css::uno::XInterface > const & object,
     725             :     css::uno::Any const & value,
     726             :     css::uno::Reference< css::reflection::XIdlClass > const & type,
     727             :     bool wrapAmbiguous, bool isAmbiguous, bool wrapDefaulted, bool isDefaulted,
     728             :     bool wrapOptional)
     729             : {
     730             :     assert(wrapAmbiguous || !isAmbiguous);
     731             :     assert(wrapDefaulted || !isDefaulted);
     732        2553 :     if (wrapAmbiguous
     733        1702 :         && type->getName().startsWith("com.sun.star.beans.Ambiguous<"))
     734             :     {
     735           0 :         css::uno::Any strct;
     736           0 :         type->createObject(strct);
     737             :         try {
     738             :             css::uno::Reference< css::reflection::XIdlField2 > field(
     739           0 :                 type->getField("Value"), css::uno::UNO_QUERY_THROW);
     740           0 :             field->set(
     741             :                 strct,
     742             :                 wrapValue(
     743           0 :                     object, value, field->getType(), false, false,
     744           0 :                     wrapDefaulted, isDefaulted, wrapOptional));
     745             :             css::uno::Reference< css::reflection::XIdlField2 >(
     746           0 :                 type->getField("IsAmbiguous"), css::uno::UNO_QUERY_THROW)->set(
     747           0 :                     strct, css::uno::makeAny(isAmbiguous));
     748           0 :         } catch (css::lang::IllegalArgumentException & e) {
     749             :             throw css::uno::RuntimeException(
     750             :                 ("unexpected com.sun.star.lang.IllegalArgumentException: "
     751           0 :                  + e.Message),
     752           0 :                 object);
     753           0 :         } catch (css::lang::IllegalAccessException & e) {
     754             :             throw css::uno::RuntimeException(
     755             :                 ("unexpected com.sun.star.lang.IllegalAccessException: "
     756           0 :                  + e.Message),
     757           0 :                 object);
     758             :         }
     759           0 :         return strct;
     760        2553 :     } else if (wrapDefaulted
     761        1702 :                && type->getName().startsWith("com.sun.star.beans.Defaulted<"))
     762             :     {
     763           0 :         css::uno::Any strct;
     764           0 :         type->createObject(strct);
     765             :         try {
     766             :             css::uno::Reference< css::reflection::XIdlField2 > field(
     767           0 :                 type->getField("Value"), css::uno::UNO_QUERY_THROW);
     768           0 :             field->set(
     769             :                 strct,
     770             :                 wrapValue(
     771           0 :                     object, value, field->getType(), wrapAmbiguous, isAmbiguous,
     772           0 :                     false, false, wrapOptional));
     773             :             css::uno::Reference< css::reflection::XIdlField2 >(
     774           0 :                 type->getField("IsDefaulted"), css::uno::UNO_QUERY_THROW)->set(
     775           0 :                     strct, css::uno::makeAny(isDefaulted));
     776           0 :         } catch (css::lang::IllegalArgumentException & e) {
     777             :             throw css::uno::RuntimeException(
     778             :                 ("unexpected com.sun.star.lang.IllegalArgumentException: "
     779           0 :                  + e.Message),
     780           0 :                 object);
     781           0 :         } catch (css::lang::IllegalAccessException & e) {
     782             :             throw css::uno::RuntimeException(
     783             :                 ("unexpected com.sun.star.lang.IllegalAccessException: "
     784           0 :                  + e.Message),
     785           0 :                 object);
     786             :         }
     787           0 :         return strct;
     788        2553 :     } else if (wrapOptional
     789        1702 :                && type->getName().startsWith("com.sun.star.beans.Optional<"))
     790             :     {
     791           0 :         css::uno::Any strct;
     792           0 :         type->createObject(strct);
     793           0 :         bool present = value.hasValue();
     794             :         try {
     795             :             css::uno::Reference< css::reflection::XIdlField2 >(
     796           0 :                 type->getField("IsPresent"), css::uno::UNO_QUERY_THROW)->set(
     797           0 :                     strct, css::uno::makeAny(present));
     798           0 :             if (present) {
     799             :                 css::uno::Reference< css::reflection::XIdlField2 > field(
     800           0 :                     type->getField("Value"), css::uno::UNO_QUERY_THROW);
     801           0 :                 field->set(
     802             :                     strct,
     803             :                     wrapValue(
     804           0 :                         object, value, field->getType(), wrapAmbiguous,
     805           0 :                         isAmbiguous, wrapDefaulted, isDefaulted, false));
     806             :             }
     807           0 :         } catch (css::lang::IllegalArgumentException & e) {
     808             :             throw css::uno::RuntimeException(
     809             :                 ("unexpected com.sun.star.lang.IllegalArgumentException: "
     810           0 :                  + e.Message),
     811           0 :                 object);
     812           0 :         } catch (css::lang::IllegalAccessException & e) {
     813             :             throw css::uno::RuntimeException(
     814             :                 ("unexpected com.sun.star.lang.IllegalAccessException: "
     815           0 :                  + e.Message),
     816           0 :                 object);
     817             :         }
     818           0 :         return strct;
     819             :     } else {
     820         851 :         if (wrapAmbiguous || wrapDefaulted || wrapOptional) {
     821             :             throw css::uno::RuntimeException(
     822           0 :                 "unexpected type of attribute", object);
     823             :         }
     824         851 :         return value;
     825             :     }
     826             : }
     827             : 
     828        9987 : PropertySetMixinImpl::PropertySetMixinImpl(
     829             :     css::uno::Reference< css::uno::XComponentContext > const & context,
     830             :     Implements implements,
     831             :     css::uno::Sequence< rtl::OUString > const & absentOptional,
     832        9987 :     css::uno::Type const & type)
     833             : {
     834        9987 :     m_impl = new Impl(context, implements, absentOptional, type);
     835        9987 :     m_impl->acquire();
     836        9987 : }
     837             : 
     838       19950 : PropertySetMixinImpl::~PropertySetMixinImpl() {
     839        9975 :     m_impl->release();
     840        9975 : }
     841             : 
     842           0 : void PropertySetMixinImpl::checkUnknown(rtl::OUString const & propertyName) {
     843           0 :     if (!propertyName.isEmpty()) {
     844             :         m_impl->get(
     845           0 :             static_cast< css::beans::XPropertySet * >(this), propertyName);
     846             :     }
     847           0 : }
     848             : 
     849           0 : void PropertySetMixinImpl::prepareSet(
     850             :     rtl::OUString const & propertyName, css::uno::Any const & oldValue,
     851             :     css::uno::Any const & newValue, BoundListeners * boundListeners)
     852             : {
     853           0 :     Impl::PropertyMap::const_iterator it(m_impl->properties.find(propertyName));
     854             :     assert(it != m_impl->properties.end());
     855           0 :     Impl::VetoListenerBag specificVeto;
     856           0 :     Impl::VetoListenerBag unspecificVeto;
     857             :     {
     858           0 :         osl::MutexGuard g(m_impl->mutex);
     859           0 :         if (m_impl->disposed) {
     860             :             throw css::lang::DisposedException(
     861           0 :                 "disposed", static_cast< css::beans::XPropertySet * >(this));
     862             :         }
     863           0 :         if ((it->second.property.Attributes
     864           0 :              & css::beans::PropertyAttribute::CONSTRAINED)
     865             :             != 0)
     866             :         {
     867             :             Impl::VetoListenerMap::const_iterator i(
     868           0 :                 m_impl->vetoListeners.find(propertyName));
     869           0 :             if (i != m_impl->vetoListeners.end()) {
     870           0 :                 specificVeto = i->second;
     871             :             }
     872           0 :             i = m_impl->vetoListeners.find("");
     873           0 :             if (i != m_impl->vetoListeners.end()) {
     874           0 :                 unspecificVeto = i->second;
     875             :             }
     876             :         }
     877           0 :         if ((it->second.property.Attributes
     878           0 :              & css::beans::PropertyAttribute::BOUND)
     879             :             != 0)
     880             :         {
     881             :             assert(boundListeners != 0);
     882             :             Impl::BoundListenerMap::const_iterator i(
     883           0 :                 m_impl->boundListeners.find(propertyName));
     884           0 :             if (i != m_impl->boundListeners.end()) {
     885           0 :                 boundListeners->m_impl->specificListeners = i->second;
     886             :             }
     887           0 :             i = m_impl->boundListeners.find("");
     888           0 :             if (i != m_impl->boundListeners.end()) {
     889           0 :                 boundListeners->m_impl->unspecificListeners = i->second;
     890             :             }
     891           0 :         }
     892             :     }
     893           0 :     if ((it->second.property.Attributes
     894           0 :          & css::beans::PropertyAttribute::CONSTRAINED)
     895             :         != 0)
     896             :     {
     897             :         css::beans::PropertyChangeEvent event(
     898             :             static_cast< css::beans::XPropertySet * >(this), propertyName,
     899           0 :             false, it->second.property.Handle, oldValue, newValue);
     900           0 :         for (Impl::VetoListenerBag::iterator i(specificVeto.begin());
     901           0 :              i != specificVeto.end(); ++i)
     902             :         {
     903             :             try {
     904           0 :                 (*i)->vetoableChange(event);
     905           0 :             } catch (css::lang::DisposedException &) {}
     906             :         }
     907           0 :         for (Impl::VetoListenerBag::iterator i(unspecificVeto.begin());
     908           0 :              i != unspecificVeto.end(); ++i)
     909             :         {
     910             :             try {
     911           0 :                 (*i)->vetoableChange(event);
     912           0 :             } catch (css::lang::DisposedException &) {}
     913           0 :         }
     914             :     }
     915           0 :     if ((it->second.property.Attributes & css::beans::PropertyAttribute::BOUND)
     916             :         != 0)
     917             :     {
     918             :         assert(boundListeners != 0);
     919           0 :         boundListeners->m_impl->event = css::beans::PropertyChangeEvent(
     920             :             static_cast< css::beans::XPropertySet * >(this), propertyName,
     921           0 :             false, it->second.property.Handle, oldValue, newValue);
     922           0 :     }
     923           0 : }
     924             : 
     925           8 : void PropertySetMixinImpl::dispose() {
     926           8 :     Impl::BoundListenerMap boundListeners;
     927          16 :     Impl::VetoListenerMap vetoListeners;
     928             :     {
     929           8 :         osl::MutexGuard g(m_impl->mutex);
     930           8 :         boundListeners.swap(m_impl->boundListeners);
     931           8 :         vetoListeners.swap(m_impl->vetoListeners);
     932           8 :         m_impl->disposed = true;
     933             :     }
     934             :     css::lang::EventObject event(
     935          16 :         static_cast< css::beans::XPropertySet * >(this));
     936          24 :     for (Impl::BoundListenerMap::iterator i(boundListeners.begin());
     937          16 :          i != boundListeners.end(); ++i)
     938             :     {
     939           0 :         for (BoundListenerBag::iterator j(i->second.begin());
     940           0 :              j != i->second.end(); ++j)
     941             :         {
     942           0 :             (*j)->disposing(event);
     943             :         }
     944             :     }
     945          24 :     for (Impl::VetoListenerMap::iterator i(vetoListeners.begin());
     946          16 :          i != vetoListeners.end(); ++i)
     947             :     {
     948           0 :         for (Impl::VetoListenerBag::iterator j(i->second.begin());
     949           0 :              j != i->second.end(); ++j)
     950             :         {
     951           0 :             (*j)->disposing(event);
     952             :         }
     953           8 :     }
     954           8 : }
     955             : 
     956        1427 : css::uno::Any PropertySetMixinImpl::queryInterface(css::uno::Type const & type)
     957             :     throw (css::uno::RuntimeException, std::exception)
     958             : {
     959        2854 :     if (((m_impl->implements & IMPLEMENTS_PROPERTY_SET) != 0
     960        1427 :          && type == css::beans::XPropertySet::static_type()))
     961             :     {
     962             :         css::uno::Reference< css::uno::XInterface > ifc(
     963         851 :             static_cast< css::beans::XPropertySet * >(this));
     964         851 :         return css::uno::Any(&ifc, type);
     965        1152 :     } else if ((m_impl->implements & IMPLEMENTS_FAST_PROPERTY_SET) != 0
     966         576 :                && type == css::beans::XFastPropertySet::static_type())
     967             :     {
     968             :         css::uno::Reference< css::uno::XInterface > ifc(
     969           0 :             static_cast< css::beans::XFastPropertySet * >(this));
     970           0 :         return css::uno::Any(&ifc, type);
     971        1152 :     } else if ((m_impl->implements & IMPLEMENTS_PROPERTY_ACCESS) != 0
     972         576 :                && type == css::beans::XPropertyAccess::static_type())
     973             :     {
     974             :         css::uno::Reference< css::uno::XInterface > ifc(
     975           0 :             static_cast< css::beans::XPropertyAccess * >(this));
     976           0 :         return css::uno::Any(&ifc, type);
     977             :     } else {
     978         576 :         return css::uno::Any();
     979             :     }
     980             : }
     981             : 
     982             : css::uno::Reference< css::beans::XPropertySetInfo >
     983           0 : PropertySetMixinImpl::getPropertySetInfo()
     984             :     throw (css::uno::RuntimeException, std::exception)
     985             : {
     986           0 :     return new Info(m_impl);
     987             : }
     988             : 
     989         851 : void PropertySetMixinImpl::setPropertyValue(
     990             :     rtl::OUString const & propertyName, css::uno::Any const & value)
     991             :     throw (
     992             :         css::beans::UnknownPropertyException, css::beans::PropertyVetoException,
     993             :         css::lang::IllegalArgumentException, css::lang::WrappedTargetException,
     994             :         css::uno::RuntimeException, std::exception)
     995             : {
     996             :     m_impl->setProperty(
     997             :         static_cast< css::beans::XPropertySet * >(this), propertyName, value,
     998         851 :         false, false, 1);
     999         851 : }
    1000             : 
    1001         851 : css::uno::Any PropertySetMixinImpl::getPropertyValue(
    1002             :     rtl::OUString const & propertyName)
    1003             :     throw (
    1004             :         css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
    1005             :         css::uno::RuntimeException, std::exception)
    1006             : {
    1007             :     return m_impl->getProperty(
    1008         851 :         static_cast< css::beans::XPropertySet * >(this), propertyName, 0);
    1009             : }
    1010             : 
    1011           0 : void PropertySetMixinImpl::addPropertyChangeListener(
    1012             :     rtl::OUString const & propertyName,
    1013             :     css::uno::Reference< css::beans::XPropertyChangeListener > const & listener)
    1014             :     throw (
    1015             :         css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
    1016             :         css::uno::RuntimeException, std::exception)
    1017             : {
    1018             :     css::uno::Reference< css::beans::XPropertyChangeListener >(
    1019           0 :         listener, css::uno::UNO_SET_THROW); // reject NULL listener
    1020           0 :     checkUnknown(propertyName);
    1021             :     bool disposed;
    1022             :     {
    1023           0 :         osl::MutexGuard g(m_impl->mutex);
    1024           0 :         disposed = m_impl->disposed;
    1025           0 :         if (!disposed) {
    1026           0 :             m_impl->boundListeners[propertyName].insert(listener);
    1027           0 :         }
    1028             :     }
    1029           0 :     if (disposed) {
    1030           0 :         listener->disposing(
    1031             :             css::lang::EventObject(
    1032           0 :                 static_cast< css::beans::XPropertySet * >(this)));
    1033             :     }
    1034           0 : }
    1035             : 
    1036           0 : void PropertySetMixinImpl::removePropertyChangeListener(
    1037             :     rtl::OUString const & propertyName,
    1038             :     css::uno::Reference< css::beans::XPropertyChangeListener > const & listener)
    1039             :     throw (
    1040             :         css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
    1041             :         css::uno::RuntimeException, std::exception)
    1042             : {
    1043             :     assert(listener.is());
    1044           0 :     checkUnknown(propertyName);
    1045           0 :     osl::MutexGuard g(m_impl->mutex);
    1046             :     Impl::BoundListenerMap::iterator i(
    1047           0 :         m_impl->boundListeners.find(propertyName));
    1048           0 :     if (i != m_impl->boundListeners.end()) {
    1049           0 :         BoundListenerBag::iterator j(i->second.find(listener));
    1050           0 :         if (j != i->second.end()) {
    1051           0 :             i->second.erase(j);
    1052             :         }
    1053           0 :     }
    1054           0 : }
    1055             : 
    1056           0 : void PropertySetMixinImpl::addVetoableChangeListener(
    1057             :     rtl::OUString const & propertyName,
    1058             :     css::uno::Reference< css::beans::XVetoableChangeListener > const & listener)
    1059             :     throw (
    1060             :         css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
    1061             :         css::uno::RuntimeException, std::exception)
    1062             : {
    1063             :     css::uno::Reference< css::beans::XVetoableChangeListener >(
    1064           0 :         listener, css::uno::UNO_SET_THROW); // reject NULL listener
    1065           0 :     checkUnknown(propertyName);
    1066             :     bool disposed;
    1067             :     {
    1068           0 :         osl::MutexGuard g(m_impl->mutex);
    1069           0 :         disposed = m_impl->disposed;
    1070           0 :         if (!disposed) {
    1071           0 :             m_impl->vetoListeners[propertyName].insert(listener);
    1072           0 :         }
    1073             :     }
    1074           0 :     if (disposed) {
    1075           0 :         listener->disposing(
    1076             :             css::lang::EventObject(
    1077           0 :                 static_cast< css::beans::XPropertySet * >(this)));
    1078             :     }
    1079           0 : }
    1080             : 
    1081           0 : void PropertySetMixinImpl::removeVetoableChangeListener(
    1082             :     rtl::OUString const & propertyName,
    1083             :     css::uno::Reference< css::beans::XVetoableChangeListener > const & listener)
    1084             :     throw (
    1085             :         css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
    1086             :         css::uno::RuntimeException, std::exception)
    1087             : {
    1088             :     assert(listener.is());
    1089           0 :     checkUnknown(propertyName);
    1090           0 :     osl::MutexGuard g(m_impl->mutex);
    1091           0 :     Impl::VetoListenerMap::iterator i(m_impl->vetoListeners.find(propertyName));
    1092           0 :     if (i != m_impl->vetoListeners.end()) {
    1093           0 :         Impl::VetoListenerBag::iterator j(i->second.find(listener));
    1094           0 :         if (j != i->second.end()) {
    1095           0 :             i->second.erase(j);
    1096             :         }
    1097           0 :     }
    1098           0 : }
    1099             : 
    1100           0 : void PropertySetMixinImpl::setFastPropertyValue(
    1101             :     sal_Int32 handle, css::uno::Any const & value)
    1102             :     throw (
    1103             :         css::beans::UnknownPropertyException, css::beans::PropertyVetoException,
    1104             :         css::lang::IllegalArgumentException, css::lang::WrappedTargetException,
    1105             :         css::uno::RuntimeException, std::exception)
    1106             : {
    1107             :     m_impl->setProperty(
    1108             :         static_cast< css::beans::XPropertySet * >(this),
    1109             :         m_impl->translateHandle(
    1110             :             static_cast< css::beans::XPropertySet * >(this), handle),
    1111           0 :         value, false, false, 1);
    1112           0 : }
    1113             : 
    1114           0 : css::uno::Any PropertySetMixinImpl::getFastPropertyValue(sal_Int32 handle)
    1115             :     throw (
    1116             :         css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
    1117             :         css::uno::RuntimeException, std::exception)
    1118             : {
    1119             :     return m_impl->getProperty(
    1120             :         static_cast< css::beans::XPropertySet * >(this),
    1121             :         m_impl->translateHandle(
    1122             :             static_cast< css::beans::XPropertySet * >(this), handle),
    1123           0 :         0);
    1124             : }
    1125             : 
    1126             : css::uno::Sequence< css::beans::PropertyValue >
    1127           0 : PropertySetMixinImpl::getPropertyValues()
    1128             :     throw (css::uno::RuntimeException, std::exception)
    1129             : {
    1130             :     css::uno::Sequence< css::beans::PropertyValue > s(
    1131           0 :         m_impl->handleMap.getLength());
    1132           0 :     sal_Int32 n = 0;
    1133           0 :     for (sal_Int32 i = 0; i < m_impl->handleMap.getLength(); ++i) {
    1134             :         try {
    1135           0 :             s[n].Value = m_impl->getProperty(
    1136             :                 static_cast< css::beans::XPropertySet * >(this),
    1137           0 :                 m_impl->handleMap[i], &s[n].State);
    1138           0 :         } catch (css::beans::UnknownPropertyException &) {
    1139           0 :             continue;
    1140           0 :         } catch (css::lang::WrappedTargetException & e) {
    1141             :             throw css::lang::WrappedTargetRuntimeException(
    1142             :                 e.Message, static_cast< css::beans::XPropertySet * >(this),
    1143           0 :                 e.TargetException);
    1144             :         }
    1145           0 :         s[n].Name = m_impl->handleMap[i];
    1146           0 :         s[n].Handle = i;
    1147           0 :         ++n;
    1148             :     }
    1149           0 :     s.realloc(n);
    1150           0 :     return s;
    1151             : }
    1152             : 
    1153           0 : void PropertySetMixinImpl::setPropertyValues(
    1154             :     css::uno::Sequence< css::beans::PropertyValue > const & props)
    1155             :     throw (
    1156             :         css::beans::UnknownPropertyException, css::beans::PropertyVetoException,
    1157             :         css::lang::IllegalArgumentException, css::lang::WrappedTargetException,
    1158             :         css::uno::RuntimeException, std::exception)
    1159             : {
    1160           0 :     for (sal_Int32 i = 0; i < props.getLength(); ++i) {
    1161           0 :         if (props[i].Handle != -1
    1162           0 :             && (props[i].Name
    1163           0 :                 != m_impl->translateHandle(
    1164             :                     static_cast< css::beans::XPropertySet * >(this),
    1165           0 :                     props[i].Handle)))
    1166             :         {
    1167             :             throw css::beans::UnknownPropertyException(
    1168           0 :                 ("name " + props[i].Name + " does not match handle "
    1169           0 :                  + rtl::OUString::number(props[i].Handle)),
    1170           0 :                 static_cast< css::beans::XPropertySet * >(this));
    1171             :         }
    1172             :         m_impl->setProperty(
    1173           0 :             static_cast< css::beans::XPropertySet * >(this), props[i].Name,
    1174           0 :             props[i].Value,
    1175           0 :             props[i].State == css::beans::PropertyState_AMBIGUOUS_VALUE,
    1176           0 :             props[i].State == css::beans::PropertyState_DEFAULT_VALUE, 0);
    1177             :     }
    1178           0 : }
    1179             : 
    1180             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11