Version 3.6.0.2, tag libreoffice-3.6.0.2
[LibreOffice.git] / cppuhelper / source / propertysetmixin.cxx
blob85a4d80a1d35adeacaf92005dc0f43a5d37886ef
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include "sal/config.h"
32 #include "cppuhelper/propertysetmixin.hxx"
34 #include "com/sun/star/beans/Property.hpp"
35 #include "com/sun/star/beans/PropertyChangeEvent.hpp"
36 #include "com/sun/star/beans/PropertyAttribute.hpp"
37 #include "com/sun/star/beans/PropertyValue.hpp"
38 #include "com/sun/star/beans/PropertyVetoException.hpp"
39 #include "com/sun/star/beans/UnknownPropertyException.hpp"
40 #include "com/sun/star/beans/XFastPropertySet.hpp"
41 #include "com/sun/star/beans/XPropertyAccess.hpp"
42 #include "com/sun/star/beans/XPropertyChangeListener.hpp"
43 #include "com/sun/star/beans/XPropertySet.hpp"
44 #include "com/sun/star/beans/XPropertySetInfo.hpp"
45 #include "com/sun/star/beans/XVetoableChangeListener.hpp"
46 #include "com/sun/star/container/NoSuchElementException.hpp"
47 #include "com/sun/star/container/XHierarchicalNameAccess.hpp"
48 #include "com/sun/star/lang/DisposedException.hpp"
49 #include "com/sun/star/lang/EventObject.hpp"
50 #include "com/sun/star/lang/IllegalAccessException.hpp"
51 #include "com/sun/star/lang/IllegalArgumentException.hpp"
52 #include "com/sun/star/lang/WrappedTargetException.hpp"
53 #include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
54 #include "com/sun/star/lang/XComponent.hpp"
55 #include "com/sun/star/lang/XMultiComponentFactory.hpp"
56 #include "com/sun/star/reflection/XCompoundTypeDescription.hpp"
57 #include "com/sun/star/reflection/XIdlClass.hpp"
58 #include "com/sun/star/reflection/XIdlField2.hpp"
59 #include "com/sun/star/reflection/XIdlReflection.hpp"
60 #include "com/sun/star/reflection/XIndirectTypeDescription.hpp"
61 #include "com/sun/star/reflection/XInterfaceAttributeTypeDescription2.hpp"
62 #include "com/sun/star/reflection/XInterfaceMemberTypeDescription.hpp"
63 #include "com/sun/star/reflection/XInterfaceTypeDescription2.hpp"
64 #include "com/sun/star/reflection/XStructTypeDescription.hpp"
65 #include "com/sun/star/reflection/XTypeDescription.hpp"
66 #include "com/sun/star/uno/Any.hxx"
67 #include "com/sun/star/uno/DeploymentException.hpp"
68 #include "com/sun/star/uno/Exception.hpp"
69 #include "com/sun/star/uno/Reference.hxx"
70 #include "com/sun/star/uno/RuntimeException.hpp"
71 #include "com/sun/star/uno/Sequence.hxx"
72 #include "com/sun/star/uno/Type.hxx"
73 #include "com/sun/star/uno/TypeClass.hpp"
74 #include "com/sun/star/uno/XComponentContext.hpp"
75 #include "com/sun/star/uno/XInterface.hpp"
76 #include "cppuhelper/implbase1.hxx"
77 #include "cppuhelper/weak.hxx"
78 #include "osl/diagnose.h"
79 #include "osl/mutex.hxx"
80 #include "rtl/ref.hxx"
81 #include "rtl/string.h"
82 #include "rtl/ustring.h"
83 #include "rtl/ustring.hxx"
84 #include "sal/types.h"
85 #include "salhelper/simplereferenceobject.hxx"
87 #include <algorithm>
88 #include <map>
89 #include <new>
90 #include <set>
91 #include <vector>
93 using cppu::PropertySetMixinImpl;
95 namespace css = com::sun::star;
97 namespace {
99 template< typename T > struct AutoDispose {
100 AutoDispose() {}
102 ~AutoDispose() {
103 try {
104 dispose();
105 } catch (...) {}
108 void dispose() {
109 css::uno::Reference< css::lang::XComponent > comp(
110 ifc, css::uno::UNO_QUERY);
111 if (comp.is()) {
112 comp->dispose();
114 ifc.clear();
117 css::uno::Reference< T > ifc;
119 private:
120 AutoDispose(AutoDispose &); // not defined
121 void operator =(AutoDispose); // not defined
124 struct PropertyData {
125 explicit PropertyData(
126 css::beans::Property const & theProperty, bool thePresent):
127 property(theProperty), present(thePresent) {}
129 css::beans::Property property;
130 bool present;
133 struct Data: public salhelper::SimpleReferenceObject {
134 typedef std::map< rtl::OUString, PropertyData > PropertyMap;
136 PropertyMap properties;
138 PropertyMap::const_iterator get(
139 css::uno::Reference< css::uno::XInterface > const & object,
140 rtl::OUString const & name) const;
142 protected:
143 void initProperties(
144 css::uno::Reference< css::reflection::XTypeDescription > const & type,
145 css::uno::Sequence< rtl::OUString > const & absentOptional,
146 std::vector< rtl::OUString > * handleNames)
148 TypeSet seen;
149 initProperties(type, absentOptional, handleNames, &seen);
152 private:
153 typedef std::set< rtl::OUString > TypeSet;
155 void initProperties(
156 css::uno::Reference< css::reflection::XTypeDescription > const & type,
157 css::uno::Sequence< rtl::OUString > const & absentOptional,
158 std::vector< rtl::OUString > * handleNames, TypeSet * seen);
160 static css::uno::Reference< css::reflection::XTypeDescription >
161 resolveTypedefs(
162 css::uno::Reference< css::reflection::XTypeDescription > const & type);
165 Data::PropertyMap::const_iterator Data::get(
166 css::uno::Reference< css::uno::XInterface > const & object,
167 rtl::OUString const & name) const
169 PropertyMap::const_iterator i(properties.find(name));
170 if (i == properties.end() || !i->second.present) {
171 throw css::beans::UnknownPropertyException(name, object);
173 return i;
176 void Data::initProperties(
177 css::uno::Reference< css::reflection::XTypeDescription > const & type,
178 css::uno::Sequence< rtl::OUString > const & absentOptional,
179 std::vector< rtl::OUString > * handleNames, TypeSet * seen)
181 css::uno::Reference< css::reflection::XInterfaceTypeDescription2 > ifc(
182 resolveTypedefs(type), css::uno::UNO_QUERY_THROW);
183 if (seen->insert(ifc->getName()).second) {
184 css::uno::Sequence<
185 css::uno::Reference< css::reflection::XTypeDescription > > bases(
186 ifc->getBaseTypes());
187 for (sal_Int32 i = 0; i < bases.getLength(); ++i) {
188 initProperties(bases[i], absentOptional, handleNames, seen);
190 css::uno::Sequence<
191 css::uno::Reference<
192 css::reflection::XInterfaceMemberTypeDescription > > members(
193 ifc->getMembers());
194 rtl::OUString const * absentBegin = absentOptional.getConstArray();
195 rtl::OUString const * absentEnd =
196 absentBegin + absentOptional.getLength();
197 for (sal_Int32 i = 0; i < members.getLength(); ++i) {
198 if (members[i]->getTypeClass()
199 == css::uno::TypeClass_INTERFACE_ATTRIBUTE)
201 css::uno::Reference<
202 css::reflection::XInterfaceAttributeTypeDescription2 > attr(
203 members[i], css::uno::UNO_QUERY_THROW);
204 sal_Int16 attrAttribs = 0;
205 if (attr->isBound()) {
206 attrAttribs |= css::beans::PropertyAttribute::BOUND;
208 bool setUnknown = false;
209 if (attr->isReadOnly()) {
210 attrAttribs |= css::beans::PropertyAttribute::READONLY;
211 setUnknown = true;
213 css::uno::Sequence<
214 css::uno::Reference<
215 css::reflection::XCompoundTypeDescription > > excs(
216 attr->getGetExceptions());
217 bool getUnknown = false;
218 //XXX Special interpretation of getter/setter exceptions only
219 // works if the specified exceptions are of the exact type, not
220 // of a supertype:
221 for (sal_Int32 j = 0; j < excs.getLength(); ++j) {
222 if ( excs[j]->getName() == "com.sun.star.beans.UnknownPropertyException" )
224 getUnknown = true;
225 break;
228 excs = attr->getSetExceptions();
229 for (sal_Int32 j = 0; j < excs.getLength(); ++j) {
230 if ( excs[j]->getName() == "com.sun.star.beans.UnknownPropertyException" )
232 setUnknown = true;
233 } else if ( excs[j]->getName() == "com.sun.star.beans.PropertyVetoException" )
235 attrAttribs
236 |= css::beans::PropertyAttribute::CONSTRAINED;
239 if (getUnknown && setUnknown) {
240 attrAttribs |= css::beans::PropertyAttribute::OPTIONAL;
242 css::uno::Reference< css::reflection::XTypeDescription > t(
243 attr->getType());
244 for (;;)
246 t = resolveTypedefs(t);
247 sal_Int16 n;
248 if (t->getName().matchAsciiL(
249 RTL_CONSTASCII_STRINGPARAM(
250 "com.sun.star.beans.Ambiguous<")))
252 n = css::beans::PropertyAttribute::MAYBEAMBIGUOUS;
253 } else if (t->getName().matchAsciiL(
254 RTL_CONSTASCII_STRINGPARAM(
255 "com.sun.star.beans.Defaulted<")))
257 n = css::beans::PropertyAttribute::MAYBEDEFAULT;
258 } else if (t->getName().matchAsciiL(
259 RTL_CONSTASCII_STRINGPARAM(
260 "com.sun.star.beans.Optional<")))
262 n = css::beans::PropertyAttribute::MAYBEVOID;
263 } else {
264 break;
266 if ((attrAttribs & n) != 0) {
267 break;
269 attrAttribs |= n;
270 css::uno::Sequence<
271 css::uno::Reference< css::reflection::XTypeDescription > >
272 args(
273 css::uno::Reference<
274 css::reflection::XStructTypeDescription >(
276 css::uno::UNO_QUERY_THROW)->getTypeArguments());
277 if (args.getLength() != 1) {
278 throw css::uno::RuntimeException(
279 rtl::OUString(
280 RTL_CONSTASCII_USTRINGPARAM(
281 "inconsistent UNO type registry")),
282 css::uno::Reference< css::uno::XInterface >());
284 t = args[0];
286 std::vector< rtl::OUString >::size_type handles
287 = handleNames->size();
288 if (handles > SAL_MAX_INT32) {
289 throw css::uno::RuntimeException(
290 rtl::OUString(
291 RTL_CONSTASCII_USTRINGPARAM(
292 "interface type has too many attributes")),
293 css::uno::Reference< css::uno::XInterface >());
295 rtl::OUString name(members[i]->getMemberName());
296 if (!properties.insert(
297 PropertyMap::value_type(
298 name,
299 PropertyData(
300 css::beans::Property(
301 name, static_cast< sal_Int32 >(handles),
302 css::uno::Type(
303 t->getTypeClass(), t->getName()),
304 attrAttribs),
305 (std::find(absentBegin, absentEnd, name)
306 == absentEnd)))).
307 second)
309 throw css::uno::RuntimeException(
310 rtl::OUString(
311 RTL_CONSTASCII_USTRINGPARAM(
312 "inconsistent UNO type registry")),
313 css::uno::Reference< css::uno::XInterface >());
315 handleNames->push_back(name);
321 css::uno::Reference< css::reflection::XTypeDescription > Data::resolveTypedefs(
322 css::uno::Reference< css::reflection::XTypeDescription > const & type)
324 css::uno::Reference< css::reflection::XTypeDescription > t(type);
325 while (t->getTypeClass() == css::uno::TypeClass_TYPEDEF) {
326 t = css::uno::Reference< css::reflection::XIndirectTypeDescription >(
327 t, css::uno::UNO_QUERY_THROW)->getReferencedType();
329 return t;
332 class Info: public cppu::WeakImplHelper1< css::beans::XPropertySetInfo > {
333 public:
334 explicit Info(Data * data): m_data(data) {}
336 virtual css::uno::Sequence< css::beans::Property > SAL_CALL getProperties()
337 throw (css::uno::RuntimeException);
339 virtual css::beans::Property SAL_CALL getPropertyByName(
340 rtl::OUString const & name)
341 throw (
342 css::beans::UnknownPropertyException, css::uno::RuntimeException);
344 virtual sal_Bool SAL_CALL hasPropertyByName(rtl::OUString const & name)
345 throw (css::uno::RuntimeException);
347 private:
348 rtl::Reference< Data > m_data;
351 css::uno::Sequence< css::beans::Property > Info::getProperties()
352 throw (css::uno::RuntimeException)
354 try {
355 OSL_ASSERT(m_data->properties.size() <= SAL_MAX_INT32);
356 css::uno::Sequence< css::beans::Property > s(
357 static_cast< sal_Int32 >(m_data->properties.size()));
358 sal_Int32 n = 0;
359 for (Data::PropertyMap::iterator i(m_data->properties.begin());
360 i != m_data->properties.end(); ++i)
362 if (i->second.present) {
363 s[n++] = i->second.property;
366 s.realloc(n);
367 return s;
368 } catch (std::bad_alloc &) {
369 //TODO OutOfMemoryException:
370 throw css::uno::RuntimeException(
371 rtl::OUString(), static_cast< cppu::OWeakObject * >(this));
375 css::beans::Property Info::getPropertyByName(rtl::OUString const & name)
376 throw (css::beans::UnknownPropertyException, css::uno::RuntimeException)
378 return m_data->get(static_cast< cppu::OWeakObject * >(this), name)->
379 second.property;
382 sal_Bool Info::hasPropertyByName(rtl::OUString const & name)
383 throw (css::uno::RuntimeException)
385 Data::PropertyMap::iterator i(m_data->properties.find(name));
386 return i != m_data->properties.end() && i->second.present;
389 typedef
390 std::multiset< css::uno::Reference< css::beans::XPropertyChangeListener > >
391 BoundListenerBag;
395 class PropertySetMixinImpl::BoundListeners::Impl {
396 public:
397 BoundListenerBag specificListeners;
398 BoundListenerBag unspecificListeners;
399 css::beans::PropertyChangeEvent event;
402 PropertySetMixinImpl::BoundListeners::BoundListeners(): m_impl(new Impl) {}
404 PropertySetMixinImpl::BoundListeners::~BoundListeners() {
405 delete m_impl;
408 void PropertySetMixinImpl::BoundListeners::notify() const {
409 for (BoundListenerBag::const_iterator i(m_impl->specificListeners.begin());
410 i != m_impl->specificListeners.end(); ++i)
412 try {
413 (*i)->propertyChange(m_impl->event);
414 } catch (css::lang::DisposedException &) {}
416 for (BoundListenerBag::const_iterator i(
417 m_impl->unspecificListeners.begin());
418 i != m_impl->unspecificListeners.end(); ++i)
420 try {
421 (*i)->propertyChange(m_impl->event);
422 } catch (css::lang::DisposedException &) {}
426 class PropertySetMixinImpl::Impl: public Data {
427 public:
428 Impl(
429 css::uno::Reference< css::uno::XComponentContext > const & context,
430 Implements theImplements,
431 css::uno::Sequence< rtl::OUString > const & absentOptional,
432 css::uno::Type const & type);
434 rtl::OUString translateHandle(
435 css::uno::Reference< css::uno::XInterface > const & object,
436 sal_Int32 handle) const;
438 void setProperty(
439 css::uno::Reference< css::uno::XInterface > const & object,
440 rtl::OUString const & name, css::uno::Any const & value,
441 bool isAmbiguous, bool isDefaulted, sal_Int16 illegalArgumentPosition)
442 const;
444 css::uno::Any getProperty(
445 css::uno::Reference< css::uno::XInterface > const & object,
446 rtl::OUString const & name, css::beans::PropertyState * state) const;
448 PropertySetMixinImpl::Implements implements;
449 css::uno::Sequence< rtl::OUString > handleMap;
451 typedef std::map< rtl::OUString, BoundListenerBag > BoundListenerMap;
453 typedef
454 std::multiset< css::uno::Reference< css::beans::XVetoableChangeListener > >
455 VetoListenerBag;
457 typedef std::map< rtl::OUString, VetoListenerBag > VetoListenerMap;
459 mutable osl::Mutex mutex;
460 BoundListenerMap boundListeners;
461 VetoListenerMap vetoListeners;
462 bool disposed;
464 private:
465 css::uno::Reference< css::reflection::XIdlClass > getReflection(
466 rtl::OUString const & typeName) const;
468 static css::uno::Any wrapValue(
469 css::uno::Reference< css::uno::XInterface > const & object,
470 css::uno::Any const & value,
471 css::uno::Reference< css::reflection::XIdlClass > const & type,
472 bool wrapAmbiguous, bool isAmbiguous, bool wrapDefaulted,
473 bool isDefaulted, bool wrapOptional);
475 css::uno::Reference< css::uno::XComponentContext > const & m_context;
476 css::uno::Sequence< rtl::OUString > m_absentOptional;
477 css::uno::Type m_type;
478 css::uno::Reference< css::reflection::XIdlClass > m_idlClass;
481 PropertySetMixinImpl::Impl::Impl(
482 css::uno::Reference< css::uno::XComponentContext > const & context,
483 Implements theImplements,
484 css::uno::Sequence< rtl::OUString > const & absentOptional,
485 css::uno::Type const & type):
486 implements(theImplements), disposed(false), m_context(context),
487 m_absentOptional(absentOptional), m_type(type)
489 OSL_ASSERT(
490 context.is()
491 && ((implements
492 & ~(IMPLEMENTS_PROPERTY_SET | IMPLEMENTS_FAST_PROPERTY_SET
493 | IMPLEMENTS_PROPERTY_ACCESS))
494 == 0));
495 m_idlClass = getReflection(m_type.getTypeName());
496 css::uno::Reference< css::reflection::XTypeDescription > ifc;
497 try {
498 ifc = css::uno::Reference< css::reflection::XTypeDescription >(
499 css::uno::Reference< css::container::XHierarchicalNameAccess >(
500 m_context->getValueByName(
501 rtl::OUString(
502 RTL_CONSTASCII_USTRINGPARAM(
503 "/singletons/com.sun.star.reflection."
504 "theTypeDescriptionManager"))),
505 css::uno::UNO_QUERY_THROW)->getByHierarchicalName(
506 m_type.getTypeName()),
507 css::uno::UNO_QUERY_THROW);
508 } catch (css::container::NoSuchElementException & e) {
509 throw css::uno::RuntimeException(
510 (rtl::OUString(
511 RTL_CONSTASCII_USTRINGPARAM(
512 "unexpected"
513 " com.sun.star.container.NoSuchElementException: "))
514 + e.Message),
515 css::uno::Reference< css::uno::XInterface >());
517 std::vector< rtl::OUString > handleNames;
518 initProperties(ifc, m_absentOptional, &handleNames);
519 std::vector< rtl::OUString >::size_type size = handleNames.size();
520 OSL_ASSERT(size <= SAL_MAX_INT32);
521 handleMap.realloc(static_cast< sal_Int32 >(size));
522 std::copy(handleNames.begin(), handleNames.end(), handleMap.getArray());
525 rtl::OUString PropertySetMixinImpl::Impl::translateHandle(
526 css::uno::Reference< css::uno::XInterface > const & object,
527 sal_Int32 handle) const
529 if (handle < 0 || handle >= handleMap.getLength()) {
530 throw css::beans::UnknownPropertyException(
531 (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("bad handle "))
532 + rtl::OUString::valueOf(handle)),
533 object);
535 return handleMap[handle];
538 void PropertySetMixinImpl::Impl::setProperty(
539 css::uno::Reference< css::uno::XInterface > const & object,
540 rtl::OUString const & name, css::uno::Any const & value, bool isAmbiguous,
541 bool isDefaulted, sal_Int16 illegalArgumentPosition) const
543 PropertyMap::const_iterator i(properties.find(name));
544 if (i == properties.end()) {
545 throw css::beans::UnknownPropertyException(name, object);
547 if ((isAmbiguous
548 && ((i->second.property.Attributes
549 & css::beans::PropertyAttribute::MAYBEAMBIGUOUS)
550 == 0))
551 || (isDefaulted
552 && ((i->second.property.Attributes
553 & css::beans::PropertyAttribute::MAYBEDEFAULT)
554 == 0)))
556 throw css::lang::IllegalArgumentException(
557 (rtl::OUString(
558 RTL_CONSTASCII_USTRINGPARAM(
559 "flagging as ambiguous/defaulted non-ambiguous/defaulted"
560 " property "))
561 + name),
562 object, illegalArgumentPosition);
564 css::uno::Reference< css::reflection::XIdlField2 > f(
565 m_idlClass->getField(name), css::uno::UNO_QUERY_THROW);
566 css::uno::Any o(object->queryInterface(m_type));
567 css::uno::Any v(
568 wrapValue(
569 object, value,
570 (css::uno::Reference< css::reflection::XIdlField2 >(
571 m_idlClass->getField(name), css::uno::UNO_QUERY_THROW)->
572 getType()),
573 ((i->second.property.Attributes
574 & css::beans::PropertyAttribute::MAYBEAMBIGUOUS)
575 != 0),
576 isAmbiguous,
577 ((i->second.property.Attributes
578 & css::beans::PropertyAttribute::MAYBEDEFAULT)
579 != 0),
580 isDefaulted,
581 ((i->second.property.Attributes
582 & css::beans::PropertyAttribute::MAYBEVOID)
583 != 0)));
584 try {
585 f->set(o, v);
586 } catch (css::lang::IllegalArgumentException & e) {
587 if (e.ArgumentPosition == 1) {
588 throw css::lang::IllegalArgumentException(
589 e.Message, object, illegalArgumentPosition);
590 } else {
591 throw css::uno::RuntimeException(
592 (rtl::OUString(
593 RTL_CONSTASCII_USTRINGPARAM(
594 "unexpected"
595 " com.sun.star.lang.IllegalArgumentException: "))
596 + e.Message),
597 object);
599 } catch (css::lang::IllegalAccessException &) {
600 //TODO Clarify whether PropertyVetoException is the correct exception
601 // to throw when trying to set a read-only property:
602 throw css::beans::PropertyVetoException(
603 (rtl::OUString(
604 RTL_CONSTASCII_USTRINGPARAM("cannot set read-only property "))
605 + name),
606 object);
607 } catch (css::lang::WrappedTargetRuntimeException & e) {
608 //FIXME A WrappedTargetRuntimeException from XIdlField2.get is not
609 // guaranteed to originate directly within XIdlField2.get (and thus have
610 // the expected semantics); it might also be passed through from lower
611 // layers.
612 if (e.TargetException.isExtractableTo(
613 getCppuType(
614 static_cast< css::beans::UnknownPropertyException * >(0)))
615 && ((i->second.property.Attributes
616 & css::beans::PropertyAttribute::OPTIONAL)
617 != 0))
619 throw css::beans::UnknownPropertyException(name, object);
620 } else if (e.TargetException.isExtractableTo(
621 getCppuType(
622 static_cast< css::beans::PropertyVetoException * >(
623 0)))
624 && ((i->second.property.Attributes
625 & css::beans::PropertyAttribute::CONSTRAINED)
626 != 0))
628 throw css::beans::PropertyVetoException(name, object);
629 } else {
630 throw css::lang::WrappedTargetException(
631 e.Message, object, e.TargetException);
636 css::uno::Any PropertySetMixinImpl::Impl::getProperty(
637 css::uno::Reference< css::uno::XInterface > const & object,
638 rtl::OUString const & name, css::beans::PropertyState * state) const
640 PropertyMap::const_iterator i(properties.find(name));
641 if (i == properties.end()) {
642 throw css::beans::UnknownPropertyException(name, object);
644 css::uno::Reference< css::reflection::XIdlField2 > field(
645 m_idlClass->getField(name), css::uno::UNO_QUERY_THROW);
646 css::uno::Any value;
647 try {
648 value = field->get(object->queryInterface(m_type));
649 } catch (css::lang::IllegalArgumentException & e) {
650 throw css::uno::RuntimeException(
651 (rtl::OUString(
652 RTL_CONSTASCII_USTRINGPARAM(
653 "unexpected com.sun.star.lang.IllegalArgumentException: "))
654 + e.Message),
655 object);
656 } catch (css::lang::WrappedTargetRuntimeException & e) {
657 //FIXME A WrappedTargetRuntimeException from XIdlField2.get is not
658 // guaranteed to originate directly within XIdlField2.get (and thus have
659 // the expected semantics); it might also be passed through from lower
660 // layers.
661 if (e.TargetException.isExtractableTo(
662 getCppuType(
663 static_cast< css::beans::UnknownPropertyException * >(0)))
664 && ((i->second.property.Attributes
665 & css::beans::PropertyAttribute::OPTIONAL)
666 != 0))
668 throw css::beans::UnknownPropertyException(name, object);
669 } else {
670 throw css::lang::WrappedTargetException(
671 e.Message, object, e.TargetException);
674 bool undoAmbiguous
675 = ((i->second.property.Attributes
676 & css::beans::PropertyAttribute::MAYBEAMBIGUOUS)
677 != 0);
678 bool undoDefaulted
679 = ((i->second.property.Attributes
680 & css::beans::PropertyAttribute::MAYBEDEFAULT)
681 != 0);
682 bool undoOptional
683 = ((i->second.property.Attributes
684 & css::beans::PropertyAttribute::MAYBEVOID)
685 != 0);
686 bool isAmbiguous = false;
687 bool isDefaulted = false;
688 while (undoAmbiguous || undoDefaulted || undoOptional) {
689 if (undoAmbiguous
690 && value.getValueTypeName().matchAsciiL(
691 RTL_CONSTASCII_STRINGPARAM("com.sun.star.beans.Ambiguous<")))
693 css::uno::Reference< css::reflection::XIdlClass > ambiguous(
694 getReflection(value.getValueTypeName()));
695 try {
696 if (!(css::uno::Reference< css::reflection::XIdlField2 >(
697 ambiguous->getField(
698 rtl::OUString(
699 RTL_CONSTASCII_USTRINGPARAM("IsAmbiguous"))),
700 css::uno::UNO_QUERY_THROW)->get(value)
701 >>= isAmbiguous))
703 throw css::uno::RuntimeException(
704 rtl::OUString(
705 RTL_CONSTASCII_USTRINGPARAM(
706 "unexpected type of"
707 " com.sun.star.beans.Ambiguous IsAmbiguous"
708 " member")),
709 object);
711 value = css::uno::Reference< css::reflection::XIdlField2 >(
712 ambiguous->getField(
713 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Value"))),
714 css::uno::UNO_QUERY_THROW)->get(value);
715 } catch (css::lang::IllegalArgumentException & e) {
716 throw css::uno::RuntimeException(
717 (rtl::OUString(
718 RTL_CONSTASCII_USTRINGPARAM(
719 "unexpected com.sun.star.lang."
720 "IllegalArgumentException: "))
721 + e.Message),
722 object);
724 undoAmbiguous = false;
725 } else if (undoDefaulted
726 && value.getValueTypeName().matchAsciiL(
727 RTL_CONSTASCII_STRINGPARAM(
728 "com.sun.star.beans.Defaulted<")))
730 css::uno::Reference< css::reflection::XIdlClass > defaulted(
731 getReflection(value.getValueTypeName()));
732 try {
734 if (!(css::uno::Reference< css::reflection::XIdlField2 >(
735 defaulted->getField(
736 rtl::OUString(
737 RTL_CONSTASCII_USTRINGPARAM("IsDefaulted"))),
738 css::uno::UNO_QUERY_THROW)->get(value)
739 >>= isDefaulted))
741 throw css::uno::RuntimeException(
742 rtl::OUString(
743 RTL_CONSTASCII_USTRINGPARAM(
744 "unexpected type of"
745 " com.sun.star.beans.Defaulted IsDefaulted"
746 " member")),
747 object);
749 value = css::uno::Reference< css::reflection::XIdlField2 >(
750 defaulted->getField(
751 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Value"))),
752 css::uno::UNO_QUERY_THROW)->get(value);
753 } catch (css::lang::IllegalArgumentException & e) {
754 throw css::uno::RuntimeException(
755 (rtl::OUString(
756 RTL_CONSTASCII_USTRINGPARAM(
757 "unexpected com.sun.star.lang."
758 "IllegalArgumentException: "))
759 + e.Message),
760 object);
762 undoDefaulted = false;
763 } else if (undoOptional
764 && value.getValueTypeName().matchAsciiL(
765 RTL_CONSTASCII_STRINGPARAM(
766 "com.sun.star.beans.Optional<")))
768 css::uno::Reference< css::reflection::XIdlClass > optional(
769 getReflection(value.getValueTypeName()));
770 try {
771 bool present = false;
772 if (!(css::uno::Reference< css::reflection::XIdlField2 >(
773 optional->getField(
774 rtl::OUString(
775 RTL_CONSTASCII_USTRINGPARAM("IsPresent"))),
776 css::uno::UNO_QUERY_THROW)->get(value)
777 >>= present))
779 throw css::uno::RuntimeException(
780 rtl::OUString(
781 RTL_CONSTASCII_USTRINGPARAM(
782 "unexpected type of com.sun.star.beans.Optional"
783 " IsPresent member")),
784 object);
786 if (!present) {
787 value.clear();
788 break;
790 value = css::uno::Reference< css::reflection::XIdlField2 >(
791 optional->getField(
792 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Value"))),
793 css::uno::UNO_QUERY_THROW)->get(value);
794 } catch (css::lang::IllegalArgumentException & e) {
795 throw css::uno::RuntimeException(
796 (rtl::OUString(
797 RTL_CONSTASCII_USTRINGPARAM(
798 "unexpected com.sun.star.lang."
799 "IllegalArgumentException: "))
800 + e.Message),
801 object);
803 undoOptional = false;
804 } else {
805 throw css::uno::RuntimeException(
806 (rtl::OUString(
807 RTL_CONSTASCII_USTRINGPARAM(
808 "unexpected type of attribute "))
809 + name),
810 object);
813 if (state != 0) {
814 //XXX If isAmbiguous && isDefaulted, arbitrarily choose AMBIGUOUS_VALUE
815 // over DEFAULT_VALUE:
816 *state = isAmbiguous
817 ? css::beans::PropertyState_AMBIGUOUS_VALUE
818 : isDefaulted
819 ? css::beans::PropertyState_DEFAULT_VALUE
820 : css::beans::PropertyState_DIRECT_VALUE;
822 return value;
825 css::uno::Reference< css::reflection::XIdlClass >
826 PropertySetMixinImpl::Impl::getReflection(rtl::OUString const & typeName) const
828 css::uno::Reference< css::lang::XMultiComponentFactory > factory(
829 m_context->getServiceManager(), css::uno::UNO_QUERY_THROW);
830 AutoDispose< css::reflection::XIdlReflection > refl;
831 try {
832 refl.ifc = css::uno::Reference< css::reflection::XIdlReflection >(
833 factory->createInstanceWithContext(
834 rtl::OUString(
835 RTL_CONSTASCII_USTRINGPARAM(
836 "com.sun.star.reflection.CoreReflection")),
837 m_context),
838 css::uno::UNO_QUERY_THROW);
839 } catch (css::uno::RuntimeException &) {
840 throw;
841 } catch (css::uno::Exception & e) {
842 throw css::uno::DeploymentException(
843 (rtl::OUString(
844 RTL_CONSTASCII_USTRINGPARAM(
845 "component context fails to supply service"
846 " com.sun.star.reflection.CoreReflection: "))
847 + e.Message),
848 m_context);
850 css::uno::Reference< css::reflection::XIdlClass > idlClass(
851 refl.ifc->forName(typeName), css::uno::UNO_QUERY_THROW);
852 refl.dispose();
853 return idlClass;
856 css::uno::Any PropertySetMixinImpl::Impl::wrapValue(
857 css::uno::Reference< css::uno::XInterface > const & object,
858 css::uno::Any const & value,
859 css::uno::Reference< css::reflection::XIdlClass > const & type,
860 bool wrapAmbiguous, bool isAmbiguous, bool wrapDefaulted, bool isDefaulted,
861 bool wrapOptional)
863 OSL_ASSERT(
864 (wrapAmbiguous || !isAmbiguous) && (wrapDefaulted || !isDefaulted));
865 if (wrapAmbiguous
866 && type->getName().matchAsciiL(
867 RTL_CONSTASCII_STRINGPARAM("com.sun.star.beans.Ambiguous<")))
869 css::uno::Any strct;
870 type->createObject(strct);
871 try {
872 css::uno::Reference< css::reflection::XIdlField2 > field(
873 type->getField(
874 rtl::OUString(
875 RTL_CONSTASCII_USTRINGPARAM("Value"))),
876 css::uno::UNO_QUERY_THROW);
877 field->set(
878 strct,
879 wrapValue(
880 object, value, field->getType(), false, false,
881 wrapDefaulted, isDefaulted, wrapOptional));
882 css::uno::Reference< css::reflection::XIdlField2 >(
883 type->getField(
884 rtl::OUString(
885 RTL_CONSTASCII_USTRINGPARAM("IsAmbiguous"))),
886 css::uno::UNO_QUERY_THROW)->set(
887 strct, css::uno::makeAny(isAmbiguous));
888 } catch (css::lang::IllegalArgumentException & e) {
889 throw css::uno::RuntimeException(
890 (rtl::OUString(
891 RTL_CONSTASCII_USTRINGPARAM(
892 "unexpected"
893 " com.sun.star.lang.IllegalArgumentException: "))
894 + e.Message),
895 object);
896 } catch (css::lang::IllegalAccessException & e) {
897 throw css::uno::RuntimeException(
898 (rtl::OUString(
899 RTL_CONSTASCII_USTRINGPARAM(
900 "unexpected"
901 " com.sun.star.lang.IllegalAccessException: "))
902 + e.Message),
903 object);
905 return strct;
906 } else if (wrapDefaulted
907 && type->getName().matchAsciiL(
908 RTL_CONSTASCII_STRINGPARAM("com.sun.star.beans.Defaulted<")))
910 css::uno::Any strct;
911 type->createObject(strct);
912 try {
913 css::uno::Reference< css::reflection::XIdlField2 > field(
914 type->getField(
915 rtl::OUString(
916 RTL_CONSTASCII_USTRINGPARAM("Value"))),
917 css::uno::UNO_QUERY_THROW);
918 field->set(
919 strct,
920 wrapValue(
921 object, value, field->getType(), wrapAmbiguous, isAmbiguous,
922 false, false, wrapOptional));
923 css::uno::Reference< css::reflection::XIdlField2 >(
924 type->getField(
925 rtl::OUString(
926 RTL_CONSTASCII_USTRINGPARAM("IsDefaulted"))),
927 css::uno::UNO_QUERY_THROW)->set(
928 strct, css::uno::makeAny(isDefaulted));
929 } catch (css::lang::IllegalArgumentException & e) {
930 throw css::uno::RuntimeException(
931 (rtl::OUString(
932 RTL_CONSTASCII_USTRINGPARAM(
933 "unexpected"
934 " com.sun.star.lang.IllegalArgumentException: "))
935 + e.Message),
936 object);
937 } catch (css::lang::IllegalAccessException & e) {
938 throw css::uno::RuntimeException(
939 (rtl::OUString(
940 RTL_CONSTASCII_USTRINGPARAM(
941 "unexpected"
942 " com.sun.star.lang.IllegalAccessException: "))
943 + e.Message),
944 object);
946 return strct;
947 } else if (wrapOptional
948 && type->getName().matchAsciiL(
949 RTL_CONSTASCII_STRINGPARAM("com.sun.star.beans.Optional<")))
951 css::uno::Any strct;
952 type->createObject(strct);
953 bool present = value.hasValue();
954 try {
955 css::uno::Reference< css::reflection::XIdlField2 >(
956 type->getField(
957 rtl::OUString(
958 RTL_CONSTASCII_USTRINGPARAM("IsPresent"))),
959 css::uno::UNO_QUERY_THROW)->set(
960 strct, css::uno::makeAny(present));
961 if (present) {
962 css::uno::Reference< css::reflection::XIdlField2 > field(
963 type->getField(
964 rtl::OUString(
965 RTL_CONSTASCII_USTRINGPARAM("Value"))),
966 css::uno::UNO_QUERY_THROW);
967 field->set(
968 strct,
969 wrapValue(
970 object, value, field->getType(), wrapAmbiguous,
971 isAmbiguous, wrapDefaulted, isDefaulted, false));
973 } catch (css::lang::IllegalArgumentException & e) {
974 throw css::uno::RuntimeException(
975 (rtl::OUString(
976 RTL_CONSTASCII_USTRINGPARAM(
977 "unexpected"
978 " com.sun.star.lang.IllegalArgumentException: "))
979 + e.Message),
980 object);
981 } catch (css::lang::IllegalAccessException & e) {
982 throw css::uno::RuntimeException(
983 (rtl::OUString(
984 RTL_CONSTASCII_USTRINGPARAM(
985 "unexpected"
986 " com.sun.star.lang.IllegalAccessException: "))
987 + e.Message),
988 object);
990 return strct;
991 } else {
992 if (wrapAmbiguous || wrapDefaulted || wrapOptional) {
993 throw css::uno::RuntimeException(
994 rtl::OUString(
995 RTL_CONSTASCII_USTRINGPARAM(
996 "unexpected type of attribute")),
997 object);
999 return value;
1003 PropertySetMixinImpl::PropertySetMixinImpl(
1004 css::uno::Reference< css::uno::XComponentContext > const & context,
1005 Implements implements,
1006 css::uno::Sequence< rtl::OUString > const & absentOptional,
1007 css::uno::Type const & type)
1009 m_impl = new Impl(context, implements, absentOptional, type);
1010 m_impl->acquire();
1013 PropertySetMixinImpl::~PropertySetMixinImpl() {
1014 m_impl->release();
1017 void PropertySetMixinImpl::checkUnknown(rtl::OUString const & propertyName) {
1018 if (!propertyName.isEmpty()) {
1019 m_impl->get(
1020 static_cast< css::beans::XPropertySet * >(this), propertyName);
1024 void PropertySetMixinImpl::prepareSet(
1025 rtl::OUString const & propertyName, css::uno::Any const & oldValue,
1026 css::uno::Any const & newValue, BoundListeners * boundListeners)
1028 Impl::PropertyMap::const_iterator it(m_impl->properties.find(propertyName));
1029 OSL_ASSERT(it != m_impl->properties.end());
1030 Impl::VetoListenerBag specificVeto;
1031 Impl::VetoListenerBag unspecificVeto;
1033 osl::MutexGuard g(m_impl->mutex);
1034 if (m_impl->disposed) {
1035 throw css::lang::DisposedException(
1036 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("disposed")),
1037 static_cast< css::beans::XPropertySet * >(this));
1039 if ((it->second.property.Attributes
1040 & css::beans::PropertyAttribute::CONSTRAINED)
1041 != 0)
1043 Impl::VetoListenerMap::const_iterator i(
1044 m_impl->vetoListeners.find(propertyName));
1045 if (i != m_impl->vetoListeners.end()) {
1046 specificVeto = i->second;
1048 i = m_impl->vetoListeners.find(rtl::OUString());
1049 if (i != m_impl->vetoListeners.end()) {
1050 unspecificVeto = i->second;
1053 if ((it->second.property.Attributes
1054 & css::beans::PropertyAttribute::BOUND)
1055 != 0)
1057 OSL_ASSERT(boundListeners != 0);
1058 Impl::BoundListenerMap::const_iterator i(
1059 m_impl->boundListeners.find(propertyName));
1060 if (i != m_impl->boundListeners.end()) {
1061 boundListeners->m_impl->specificListeners = i->second;
1063 i = m_impl->boundListeners.find(rtl::OUString());
1064 if (i != m_impl->boundListeners.end()) {
1065 boundListeners->m_impl->unspecificListeners = i->second;
1069 if ((it->second.property.Attributes
1070 & css::beans::PropertyAttribute::CONSTRAINED)
1071 != 0)
1073 css::beans::PropertyChangeEvent event(
1074 static_cast< css::beans::XPropertySet * >(this), propertyName,
1075 false, it->second.property.Handle, oldValue, newValue);
1076 for (Impl::VetoListenerBag::iterator i(specificVeto.begin());
1077 i != specificVeto.end(); ++i)
1079 try {
1080 (*i)->vetoableChange(event);
1081 } catch (css::lang::DisposedException &) {}
1083 for (Impl::VetoListenerBag::iterator i(unspecificVeto.begin());
1084 i != unspecificVeto.end(); ++i)
1086 try {
1087 (*i)->vetoableChange(event);
1088 } catch (css::lang::DisposedException &) {}
1091 if ((it->second.property.Attributes & css::beans::PropertyAttribute::BOUND)
1092 != 0)
1094 OSL_ASSERT(boundListeners != 0);
1095 boundListeners->m_impl->event = css::beans::PropertyChangeEvent(
1096 static_cast< css::beans::XPropertySet * >(this), propertyName,
1097 false, it->second.property.Handle, oldValue, newValue);
1101 void PropertySetMixinImpl::dispose() {
1102 Impl::BoundListenerMap boundListeners;
1103 Impl::VetoListenerMap vetoListeners;
1105 osl::MutexGuard g(m_impl->mutex);
1106 boundListeners.swap(m_impl->boundListeners);
1107 vetoListeners.swap(m_impl->vetoListeners);
1108 m_impl->disposed = true;
1110 css::lang::EventObject event(
1111 static_cast< css::beans::XPropertySet * >(this));
1112 for (Impl::BoundListenerMap::iterator i(boundListeners.begin());
1113 i != boundListeners.end(); ++i)
1115 for (BoundListenerBag::iterator j(i->second.begin());
1116 j != i->second.end(); ++j)
1118 (*j)->disposing(event);
1121 for (Impl::VetoListenerMap::iterator i(vetoListeners.begin());
1122 i != vetoListeners.end(); ++i)
1124 for (Impl::VetoListenerBag::iterator j(i->second.begin());
1125 j != i->second.end(); ++j)
1127 (*j)->disposing(event);
1132 css::uno::Any PropertySetMixinImpl::queryInterface(css::uno::Type const & type)
1133 throw (css::uno::RuntimeException)
1135 if (((m_impl->implements & IMPLEMENTS_PROPERTY_SET) != 0
1136 && type == css::beans::XPropertySet::static_type()))
1138 css::uno::Reference< css::uno::XInterface > ifc(
1139 static_cast< css::beans::XPropertySet * >(this));
1140 return css::uno::Any(&ifc, type);
1141 } else if ((m_impl->implements & IMPLEMENTS_FAST_PROPERTY_SET) != 0
1142 && type == css::beans::XFastPropertySet::static_type())
1144 css::uno::Reference< css::uno::XInterface > ifc(
1145 static_cast< css::beans::XFastPropertySet * >(this));
1146 return css::uno::Any(&ifc, type);
1147 } else if ((m_impl->implements & IMPLEMENTS_PROPERTY_ACCESS) != 0
1148 && type == css::beans::XPropertyAccess::static_type())
1150 css::uno::Reference< css::uno::XInterface > ifc(
1151 static_cast< css::beans::XPropertyAccess * >(this));
1152 return css::uno::Any(&ifc, type);
1153 } else {
1154 return css::uno::Any();
1158 css::uno::Reference< css::beans::XPropertySetInfo >
1159 PropertySetMixinImpl::getPropertySetInfo() throw (css::uno::RuntimeException) {
1160 try {
1161 return new Info(m_impl);
1162 } catch (std::bad_alloc &) {
1163 //TODO OutOfMemoryException:
1164 throw css::uno::RuntimeException(
1165 rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1169 void PropertySetMixinImpl::setPropertyValue(
1170 rtl::OUString const & propertyName, css::uno::Any const & value)
1171 throw (
1172 css::beans::UnknownPropertyException, css::beans::PropertyVetoException,
1173 css::lang::IllegalArgumentException, css::lang::WrappedTargetException,
1174 css::uno::RuntimeException)
1176 try {
1177 m_impl->setProperty(
1178 static_cast< css::beans::XPropertySet * >(this), propertyName,
1179 value, false, false, 1);
1180 } catch (std::bad_alloc &) {
1181 //TODO OutOfMemoryException:
1182 throw css::uno::RuntimeException(
1183 rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1187 css::uno::Any PropertySetMixinImpl::getPropertyValue(
1188 rtl::OUString const & propertyName)
1189 throw (
1190 css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
1191 css::uno::RuntimeException)
1193 try {
1194 return m_impl->getProperty(
1195 static_cast< css::beans::XPropertySet * >(this), propertyName, 0);
1196 } catch (std::bad_alloc &) {
1197 //TODO OutOfMemoryException:
1198 throw css::uno::RuntimeException(
1199 rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1203 void PropertySetMixinImpl::addPropertyChangeListener(
1204 rtl::OUString const & propertyName,
1205 css::uno::Reference< css::beans::XPropertyChangeListener > const & listener)
1206 throw (
1207 css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
1208 css::uno::RuntimeException)
1210 css::uno::Reference< css::beans::XPropertyChangeListener >(
1211 listener, css::uno::UNO_QUERY_THROW); // reject NULL listener
1212 checkUnknown(propertyName);
1213 try {
1214 bool disposed;
1216 osl::MutexGuard g(m_impl->mutex);
1217 disposed = m_impl->disposed;
1218 if (!disposed) {
1219 m_impl->boundListeners[propertyName].insert(listener);
1222 if (disposed) {
1223 listener->disposing(
1224 css::lang::EventObject(
1225 static_cast< css::beans::XPropertySet * >(this)));
1227 } catch (std::bad_alloc &) {
1228 //TODO OutOfMemoryException:
1229 throw css::uno::RuntimeException(
1230 rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1234 void PropertySetMixinImpl::removePropertyChangeListener(
1235 rtl::OUString const & propertyName,
1236 css::uno::Reference< css::beans::XPropertyChangeListener > const & listener)
1237 throw (
1238 css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
1239 css::uno::RuntimeException)
1241 OSL_ASSERT(listener.is());
1242 checkUnknown(propertyName);
1243 try {
1244 osl::MutexGuard g(m_impl->mutex);
1245 Impl::BoundListenerMap::iterator i(
1246 m_impl->boundListeners.find(propertyName));
1247 if (i != m_impl->boundListeners.end()) {
1248 BoundListenerBag::iterator j(i->second.find(listener));
1249 if (j != i->second.end()) {
1250 i->second.erase(j);
1253 } catch (std::bad_alloc &) {
1254 //TODO OutOfMemoryException:
1255 throw css::uno::RuntimeException(
1256 rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1260 void PropertySetMixinImpl::addVetoableChangeListener(
1261 rtl::OUString const & propertyName,
1262 css::uno::Reference< css::beans::XVetoableChangeListener > const & listener)
1263 throw (
1264 css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
1265 css::uno::RuntimeException)
1267 css::uno::Reference< css::beans::XVetoableChangeListener >(
1268 listener, css::uno::UNO_QUERY_THROW); // reject NULL listener
1269 checkUnknown(propertyName);
1270 try {
1271 bool disposed;
1273 osl::MutexGuard g(m_impl->mutex);
1274 disposed = m_impl->disposed;
1275 if (!disposed) {
1276 m_impl->vetoListeners[propertyName].insert(listener);
1279 if (disposed) {
1280 listener->disposing(
1281 css::lang::EventObject(
1282 static_cast< css::beans::XPropertySet * >(this)));
1284 } catch (std::bad_alloc &) {
1285 //TODO OutOfMemoryException:
1286 throw css::uno::RuntimeException(
1287 rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1291 void PropertySetMixinImpl::removeVetoableChangeListener(
1292 rtl::OUString const & propertyName,
1293 css::uno::Reference< css::beans::XVetoableChangeListener > const & listener)
1294 throw (
1295 css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
1296 css::uno::RuntimeException)
1298 OSL_ASSERT(listener.is());
1299 checkUnknown(propertyName);
1300 try {
1301 osl::MutexGuard g(m_impl->mutex);
1302 Impl::VetoListenerMap::iterator i(
1303 m_impl->vetoListeners.find(propertyName));
1304 if (i != m_impl->vetoListeners.end()) {
1305 Impl::VetoListenerBag::iterator j(i->second.find(listener));
1306 if (j != i->second.end()) {
1307 i->second.erase(j);
1310 } catch (std::bad_alloc &) {
1311 //TODO OutOfMemoryException:
1312 throw css::uno::RuntimeException(
1313 rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1317 void PropertySetMixinImpl::setFastPropertyValue(
1318 sal_Int32 handle, css::uno::Any const & value)
1319 throw (
1320 css::beans::UnknownPropertyException, css::beans::PropertyVetoException,
1321 css::lang::IllegalArgumentException, css::lang::WrappedTargetException,
1322 css::uno::RuntimeException)
1324 try {
1325 m_impl->setProperty(
1326 static_cast< css::beans::XPropertySet * >(this),
1327 m_impl->translateHandle(
1328 static_cast< css::beans::XPropertySet * >(this), handle),
1329 value, false, false, 1);
1330 } catch (std::bad_alloc &) {
1331 //TODO OutOfMemoryException:
1332 throw css::uno::RuntimeException(
1333 rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1337 css::uno::Any PropertySetMixinImpl::getFastPropertyValue(sal_Int32 handle)
1338 throw (
1339 css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
1340 css::uno::RuntimeException)
1342 try {
1343 return m_impl->getProperty(
1344 static_cast< css::beans::XPropertySet * >(this),
1345 m_impl->translateHandle(
1346 static_cast< css::beans::XPropertySet * >(this), handle),
1348 } catch (std::bad_alloc &) {
1349 //TODO OutOfMemoryException:
1350 throw css::uno::RuntimeException(
1351 rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1355 css::uno::Sequence< css::beans::PropertyValue >
1356 PropertySetMixinImpl::getPropertyValues() throw (css::uno::RuntimeException) {
1357 try {
1358 css::uno::Sequence< css::beans::PropertyValue > s(
1359 m_impl->handleMap.getLength());
1360 sal_Int32 n = 0;
1361 for (sal_Int32 i = 0; i < m_impl->handleMap.getLength(); ++i) {
1362 try {
1363 s[n].Value = m_impl->getProperty(
1364 static_cast< css::beans::XPropertySet * >(this),
1365 m_impl->handleMap[i], &s[n].State);
1366 } catch (css::beans::UnknownPropertyException &) {
1367 continue;
1368 } catch (css::lang::WrappedTargetException & e) {
1369 throw css::lang::WrappedTargetRuntimeException(
1370 e.Message, static_cast< css::beans::XPropertySet * >(this),
1371 e.TargetException);
1373 s[n].Name = m_impl->handleMap[i];
1374 s[n].Handle = i;
1375 ++n;
1377 s.realloc(n);
1378 return s;
1379 } catch (std::bad_alloc &) {
1380 //TODO OutOfMemoryException:
1381 throw css::uno::RuntimeException(
1382 rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1386 void PropertySetMixinImpl::setPropertyValues(
1387 css::uno::Sequence< css::beans::PropertyValue > const & props)
1388 throw (
1389 css::beans::UnknownPropertyException, css::beans::PropertyVetoException,
1390 css::lang::IllegalArgumentException, css::lang::WrappedTargetException,
1391 css::uno::RuntimeException)
1393 try {
1394 for (sal_Int32 i = 0; i < props.getLength(); ++i) {
1395 if (props[i].Handle != -1
1396 && (props[i].Name
1397 != m_impl->translateHandle(
1398 static_cast< css::beans::XPropertySet * >(this),
1399 props[i].Handle)))
1401 throw css::beans::UnknownPropertyException(
1402 (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("name "))
1403 + props[i].Name
1404 + rtl::OUString(
1405 RTL_CONSTASCII_USTRINGPARAM(" does not match handle "))
1406 + rtl::OUString::valueOf(props[i].Handle)),
1407 static_cast< css::beans::XPropertySet * >(this));
1409 m_impl->setProperty(
1410 static_cast< css::beans::XPropertySet * >(this), props[i].Name,
1411 props[i].Value,
1412 props[i].State == css::beans::PropertyState_AMBIGUOUS_VALUE,
1413 props[i].State == css::beans::PropertyState_DEFAULT_VALUE, 0);
1415 } catch (std::bad_alloc &) {
1416 //TODO OutOfMemoryException:
1417 throw css::uno::RuntimeException(
1418 rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1422 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */