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

Generated by: LCOV version 1.10