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

Generated by: LCOV version 1.10