update dev300-m57
[ooovba.git] / cppuhelper / source / propertysetmixin.cxx
blob0d33f65a67102cd3b4a2a65e8b1a8d7c150ec749
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: propertysetmixin.cxx,v $
10 * $Revision: 1.7 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_cppuhelper.hxx"
34 #include "sal/config.h"
36 #include "cppuhelper/propertysetmixin.hxx"
38 #include "com/sun/star/beans/Property.hpp"
39 #include "com/sun/star/beans/PropertyChangeEvent.hpp"
40 #include "com/sun/star/beans/PropertyAttribute.hpp"
41 #include "com/sun/star/beans/PropertyValue.hpp"
42 #include "com/sun/star/beans/PropertyVetoException.hpp"
43 #include "com/sun/star/beans/UnknownPropertyException.hpp"
44 #include "com/sun/star/beans/XFastPropertySet.hpp"
45 #include "com/sun/star/beans/XPropertyAccess.hpp"
46 #include "com/sun/star/beans/XPropertyChangeListener.hpp"
47 #include "com/sun/star/beans/XPropertySet.hpp"
48 #include "com/sun/star/beans/XPropertySetInfo.hpp"
49 #include "com/sun/star/beans/XVetoableChangeListener.hpp"
50 #include "com/sun/star/container/NoSuchElementException.hpp"
51 #include "com/sun/star/container/XHierarchicalNameAccess.hpp"
52 #include "com/sun/star/lang/DisposedException.hpp"
53 #include "com/sun/star/lang/EventObject.hpp"
54 #include "com/sun/star/lang/IllegalAccessException.hpp"
55 #include "com/sun/star/lang/IllegalArgumentException.hpp"
56 #include "com/sun/star/lang/WrappedTargetException.hpp"
57 #include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
58 #include "com/sun/star/lang/XComponent.hpp"
59 #include "com/sun/star/lang/XMultiComponentFactory.hpp"
60 #include "com/sun/star/reflection/XCompoundTypeDescription.hpp"
61 #include "com/sun/star/reflection/XIdlClass.hpp"
62 #include "com/sun/star/reflection/XIdlField2.hpp"
63 #include "com/sun/star/reflection/XIdlReflection.hpp"
64 #include "com/sun/star/reflection/XIndirectTypeDescription.hpp"
65 #include "com/sun/star/reflection/XInterfaceAttributeTypeDescription2.hpp"
66 #include "com/sun/star/reflection/XInterfaceMemberTypeDescription.hpp"
67 #include "com/sun/star/reflection/XInterfaceTypeDescription2.hpp"
68 #include "com/sun/star/reflection/XStructTypeDescription.hpp"
69 #include "com/sun/star/reflection/XTypeDescription.hpp"
70 #include "com/sun/star/uno/Any.hxx"
71 #include "com/sun/star/uno/DeploymentException.hpp"
72 #include "com/sun/star/uno/Exception.hpp"
73 #include "com/sun/star/uno/Reference.hxx"
74 #include "com/sun/star/uno/RuntimeException.hpp"
75 #include "com/sun/star/uno/Sequence.hxx"
76 #include "com/sun/star/uno/Type.hxx"
77 #include "com/sun/star/uno/TypeClass.hpp"
78 #include "com/sun/star/uno/XComponentContext.hpp"
79 #include "com/sun/star/uno/XInterface.hpp"
80 #include "cppuhelper/implbase1.hxx"
81 #include "cppuhelper/weak.hxx"
82 #include "osl/diagnose.h"
83 #include "osl/mutex.hxx"
84 #include "rtl/ref.hxx"
85 #include "rtl/string.h"
86 #include "rtl/ustring.h"
87 #include "rtl/ustring.hxx"
88 #include "sal/types.h"
89 #include "salhelper/simplereferenceobject.hxx"
91 #include <algorithm>
92 #include <map>
93 #include <new>
94 #include <set>
95 #include <vector>
97 using cppu::PropertySetMixinImpl;
99 namespace css = com::sun::star;
101 namespace {
103 template< typename T > struct AutoDispose {
104 AutoDispose() {}
106 ~AutoDispose() {
107 try {
108 dispose();
109 } catch (...) {}
112 void dispose() {
113 css::uno::Reference< css::lang::XComponent > comp(
114 ifc, css::uno::UNO_QUERY);
115 if (comp.is()) {
116 comp->dispose();
118 ifc.clear();
121 css::uno::Reference< T > ifc;
123 private:
124 AutoDispose(AutoDispose &); // not defined
125 void operator =(AutoDispose); // not defined
128 struct PropertyData {
129 explicit PropertyData(
130 css::beans::Property const & theProperty, bool thePresent):
131 property(theProperty), present(thePresent) {}
133 css::beans::Property property;
134 bool present;
137 struct Data: public salhelper::SimpleReferenceObject {
138 typedef std::map< rtl::OUString, PropertyData > PropertyMap;
140 PropertyMap properties;
142 PropertyMap::const_iterator get(
143 css::uno::Reference< css::uno::XInterface > const & object,
144 rtl::OUString const & name) const;
146 protected:
147 void initProperties(
148 css::uno::Reference< css::reflection::XTypeDescription > const & type,
149 css::uno::Sequence< rtl::OUString > const & absentOptional,
150 std::vector< rtl::OUString > * handleNames)
152 TypeSet seen;
153 initProperties(type, absentOptional, handleNames, &seen);
156 private:
157 typedef std::set< rtl::OUString > TypeSet;
159 void initProperties(
160 css::uno::Reference< css::reflection::XTypeDescription > const & type,
161 css::uno::Sequence< rtl::OUString > const & absentOptional,
162 std::vector< rtl::OUString > * handleNames, TypeSet * seen);
164 static css::uno::Reference< css::reflection::XTypeDescription >
165 resolveTypedefs(
166 css::uno::Reference< css::reflection::XTypeDescription > const & type);
169 Data::PropertyMap::const_iterator Data::get(
170 css::uno::Reference< css::uno::XInterface > const & object,
171 rtl::OUString const & name) const
173 PropertyMap::const_iterator i(properties.find(name));
174 if (i == properties.end() || !i->second.present) {
175 throw css::beans::UnknownPropertyException(name, object);
177 return i;
180 void Data::initProperties(
181 css::uno::Reference< css::reflection::XTypeDescription > const & type,
182 css::uno::Sequence< rtl::OUString > const & absentOptional,
183 std::vector< rtl::OUString > * handleNames, TypeSet * seen)
185 css::uno::Reference< css::reflection::XInterfaceTypeDescription2 > ifc(
186 resolveTypedefs(type), css::uno::UNO_QUERY_THROW);
187 if (seen->insert(ifc->getName()).second) {
188 css::uno::Sequence<
189 css::uno::Reference< css::reflection::XTypeDescription > > bases(
190 ifc->getBaseTypes());
191 for (sal_Int32 i = 0; i < bases.getLength(); ++i) {
192 initProperties(bases[i], absentOptional, handleNames, seen);
194 css::uno::Sequence<
195 css::uno::Reference<
196 css::reflection::XInterfaceMemberTypeDescription > > members(
197 ifc->getMembers());
198 rtl::OUString const * absentBegin = absentOptional.getConstArray();
199 rtl::OUString const * absentEnd =
200 absentBegin + absentOptional.getLength();
201 for (sal_Int32 i = 0; i < members.getLength(); ++i) {
202 if (members[i]->getTypeClass()
203 == css::uno::TypeClass_INTERFACE_ATTRIBUTE)
205 css::uno::Reference<
206 css::reflection::XInterfaceAttributeTypeDescription2 > attr(
207 members[i], css::uno::UNO_QUERY_THROW);
208 sal_Int16 attrAttribs = 0;
209 if (attr->isBound()) {
210 attrAttribs |= css::beans::PropertyAttribute::BOUND;
212 bool setUnknown = false;
213 if (attr->isReadOnly()) {
214 attrAttribs |= css::beans::PropertyAttribute::READONLY;
215 setUnknown = true;
217 css::uno::Sequence<
218 css::uno::Reference<
219 css::reflection::XCompoundTypeDescription > > excs(
220 attr->getGetExceptions());
221 bool getUnknown = false;
222 //XXX Special interpretation of getter/setter exceptions only
223 // works if the specified exceptions are of the exact type, not
224 // of a supertype:
225 for (sal_Int32 j = 0; j < excs.getLength(); ++j) {
226 if (excs[j]->getName().equalsAsciiL(
227 RTL_CONSTASCII_STRINGPARAM(
228 "com.sun.star.beans.UnknownPropertyException")))
230 getUnknown = true;
231 break;
234 excs = attr->getSetExceptions();
235 for (sal_Int32 j = 0; j < excs.getLength(); ++j) {
236 if (excs[j]->getName().equalsAsciiL(
237 RTL_CONSTASCII_STRINGPARAM(
238 "com.sun.star.beans.UnknownPropertyException")))
240 setUnknown = true;
241 } else if (excs[j]->getName().equalsAsciiL(
242 RTL_CONSTASCII_STRINGPARAM(
243 "com.sun.star.beans."
244 "PropertyVetoException")))
246 attrAttribs
247 |= css::beans::PropertyAttribute::CONSTRAINED;
250 if (getUnknown && setUnknown) {
251 attrAttribs |= css::beans::PropertyAttribute::OPTIONAL;
253 css::uno::Reference< css::reflection::XTypeDescription > t(
254 attr->getType());
255 for (;;)
257 t = resolveTypedefs(t);
258 sal_Int16 n;
259 if (t->getName().matchAsciiL(
260 RTL_CONSTASCII_STRINGPARAM(
261 "com.sun.star.beans.Ambiguous<")))
263 n = css::beans::PropertyAttribute::MAYBEAMBIGUOUS;
264 } else if (t->getName().matchAsciiL(
265 RTL_CONSTASCII_STRINGPARAM(
266 "com.sun.star.beans.Defaulted<")))
268 n = css::beans::PropertyAttribute::MAYBEDEFAULT;
269 } else if (t->getName().matchAsciiL(
270 RTL_CONSTASCII_STRINGPARAM(
271 "com.sun.star.beans.Optional<")))
273 n = css::beans::PropertyAttribute::MAYBEVOID;
274 } else {
275 break;
277 if ((attrAttribs & n) != 0) {
278 break;
280 attrAttribs |= n;
281 css::uno::Sequence<
282 css::uno::Reference< css::reflection::XTypeDescription > >
283 args(
284 css::uno::Reference<
285 css::reflection::XStructTypeDescription >(
287 css::uno::UNO_QUERY_THROW)->getTypeArguments());
288 if (args.getLength() != 1) {
289 throw css::uno::RuntimeException(
290 rtl::OUString(
291 RTL_CONSTASCII_USTRINGPARAM(
292 "inconsistent UNO type registry")),
293 css::uno::Reference< css::uno::XInterface >());
295 t = args[0];
297 std::vector< rtl::OUString >::size_type handles
298 = handleNames->size();
299 if (handles > SAL_MAX_INT32) {
300 throw css::uno::RuntimeException(
301 rtl::OUString(
302 RTL_CONSTASCII_USTRINGPARAM(
303 "interface type has too many attributes")),
304 css::uno::Reference< css::uno::XInterface >());
306 rtl::OUString name(members[i]->getMemberName());
307 if (!properties.insert(
308 PropertyMap::value_type(
309 name,
310 PropertyData(
311 css::beans::Property(
312 name, static_cast< sal_Int32 >(handles),
313 css::uno::Type(
314 t->getTypeClass(), t->getName()),
315 attrAttribs),
316 (std::find(absentBegin, absentEnd, name)
317 == absentEnd)))).
318 second)
320 throw css::uno::RuntimeException(
321 rtl::OUString(
322 RTL_CONSTASCII_USTRINGPARAM(
323 "inconsistent UNO type registry")),
324 css::uno::Reference< css::uno::XInterface >());
326 handleNames->push_back(name);
332 css::uno::Reference< css::reflection::XTypeDescription > Data::resolveTypedefs(
333 css::uno::Reference< css::reflection::XTypeDescription > const & type)
335 css::uno::Reference< css::reflection::XTypeDescription > t(type);
336 while (t->getTypeClass() == css::uno::TypeClass_TYPEDEF) {
337 t = css::uno::Reference< css::reflection::XIndirectTypeDescription >(
338 t, css::uno::UNO_QUERY_THROW)->getReferencedType();
340 return t;
343 class Info: public cppu::WeakImplHelper1< css::beans::XPropertySetInfo > {
344 public:
345 explicit Info(Data * data): m_data(data) {}
347 virtual css::uno::Sequence< css::beans::Property > SAL_CALL getProperties()
348 throw (css::uno::RuntimeException);
350 virtual css::beans::Property SAL_CALL getPropertyByName(
351 rtl::OUString const & name)
352 throw (
353 css::beans::UnknownPropertyException, css::uno::RuntimeException);
355 virtual sal_Bool SAL_CALL hasPropertyByName(rtl::OUString const & name)
356 throw (css::uno::RuntimeException);
358 private:
359 rtl::Reference< Data > m_data;
362 css::uno::Sequence< css::beans::Property > Info::getProperties()
363 throw (css::uno::RuntimeException)
365 try {
366 OSL_ASSERT(m_data->properties.size() <= SAL_MAX_INT32);
367 css::uno::Sequence< css::beans::Property > s(
368 static_cast< sal_Int32 >(m_data->properties.size()));
369 sal_Int32 n = 0;
370 for (Data::PropertyMap::iterator i(m_data->properties.begin());
371 i != m_data->properties.end(); ++i)
373 if (i->second.present) {
374 s[n++] = i->second.property;
377 s.realloc(n);
378 return s;
379 } catch (std::bad_alloc &) {
380 //TODO OutOfMemoryException:
381 throw css::uno::RuntimeException(
382 rtl::OUString(), static_cast< cppu::OWeakObject * >(this));
386 css::beans::Property Info::getPropertyByName(rtl::OUString const & name)
387 throw (css::beans::UnknownPropertyException, css::uno::RuntimeException)
389 return m_data->get(static_cast< cppu::OWeakObject * >(this), name)->
390 second.property;
393 sal_Bool Info::hasPropertyByName(rtl::OUString const & name)
394 throw (css::uno::RuntimeException)
396 Data::PropertyMap::iterator i(m_data->properties.find(name));
397 return i != m_data->properties.end() && i->second.present;
400 typedef
401 std::multiset< css::uno::Reference< css::beans::XPropertyChangeListener > >
402 BoundListenerBag;
406 class PropertySetMixinImpl::BoundListeners::Impl {
407 public:
408 BoundListenerBag specificListeners;
409 BoundListenerBag unspecificListeners;
410 css::beans::PropertyChangeEvent event;
413 PropertySetMixinImpl::BoundListeners::BoundListeners(): m_impl(new Impl) {}
415 PropertySetMixinImpl::BoundListeners::~BoundListeners() {
416 delete m_impl;
419 void PropertySetMixinImpl::BoundListeners::notify() const {
420 for (BoundListenerBag::const_iterator i(m_impl->specificListeners.begin());
421 i != m_impl->specificListeners.end(); ++i)
423 try {
424 (*i)->propertyChange(m_impl->event);
425 } catch (css::lang::DisposedException &) {}
427 for (BoundListenerBag::const_iterator i(
428 m_impl->unspecificListeners.begin());
429 i != m_impl->unspecificListeners.end(); ++i)
431 try {
432 (*i)->propertyChange(m_impl->event);
433 } catch (css::lang::DisposedException &) {}
437 class PropertySetMixinImpl::Impl: public Data {
438 public:
439 Impl(
440 css::uno::Reference< css::uno::XComponentContext > const & context,
441 Implements theImplements,
442 css::uno::Sequence< rtl::OUString > const & absentOptional,
443 css::uno::Type const & type);
445 rtl::OUString translateHandle(
446 css::uno::Reference< css::uno::XInterface > const & object,
447 sal_Int32 handle) const;
449 void setProperty(
450 css::uno::Reference< css::uno::XInterface > const & object,
451 rtl::OUString const & name, css::uno::Any const & value,
452 bool isAmbiguous, bool isDefaulted, sal_Int16 illegalArgumentPosition)
453 const;
455 css::uno::Any getProperty(
456 css::uno::Reference< css::uno::XInterface > const & object,
457 rtl::OUString const & name, css::beans::PropertyState * state) const;
459 PropertySetMixinImpl::Implements implements;
460 css::uno::Sequence< rtl::OUString > handleMap;
462 typedef std::map< rtl::OUString, BoundListenerBag > BoundListenerMap;
464 typedef
465 std::multiset< css::uno::Reference< css::beans::XVetoableChangeListener > >
466 VetoListenerBag;
468 typedef std::map< rtl::OUString, VetoListenerBag > VetoListenerMap;
470 mutable osl::Mutex mutex;
471 BoundListenerMap boundListeners;
472 VetoListenerMap vetoListeners;
473 bool disposed;
475 private:
476 css::uno::Reference< css::reflection::XIdlClass > getReflection(
477 rtl::OUString const & typeName) const;
479 static css::uno::Any wrapValue(
480 css::uno::Reference< css::uno::XInterface > const & object,
481 css::uno::Any const & value,
482 css::uno::Reference< css::reflection::XIdlClass > const & type,
483 bool wrapAmbiguous, bool isAmbiguous, bool wrapDefaulted,
484 bool isDefaulted, bool wrapOptional);
486 css::uno::Reference< css::uno::XComponentContext > const & m_context;
487 css::uno::Sequence< rtl::OUString > m_absentOptional;
488 css::uno::Type m_type;
489 css::uno::Reference< css::reflection::XIdlClass > m_idlClass;
492 PropertySetMixinImpl::Impl::Impl(
493 css::uno::Reference< css::uno::XComponentContext > const & context,
494 Implements theImplements,
495 css::uno::Sequence< rtl::OUString > const & absentOptional,
496 css::uno::Type const & type):
497 implements(theImplements), disposed(false), m_context(context),
498 m_absentOptional(absentOptional), m_type(type)
500 OSL_ASSERT(
501 context.is()
502 && ((implements
503 & ~(IMPLEMENTS_PROPERTY_SET | IMPLEMENTS_FAST_PROPERTY_SET
504 | IMPLEMENTS_PROPERTY_ACCESS))
505 == 0));
506 m_idlClass = getReflection(m_type.getTypeName());
507 css::uno::Reference< css::reflection::XTypeDescription > ifc;
508 try {
509 ifc = css::uno::Reference< css::reflection::XTypeDescription >(
510 css::uno::Reference< css::container::XHierarchicalNameAccess >(
511 m_context->getValueByName(
512 rtl::OUString(
513 RTL_CONSTASCII_USTRINGPARAM(
514 "/singletons/com.sun.star.reflection."
515 "theTypeDescriptionManager"))),
516 css::uno::UNO_QUERY_THROW)->getByHierarchicalName(
517 m_type.getTypeName()),
518 css::uno::UNO_QUERY_THROW);
519 } catch (css::container::NoSuchElementException & e) {
520 throw css::uno::RuntimeException(
521 (rtl::OUString(
522 RTL_CONSTASCII_USTRINGPARAM(
523 "unexpected"
524 " com.sun.star.container.NoSuchElementException: "))
525 + e.Message),
526 css::uno::Reference< css::uno::XInterface >());
528 std::vector< rtl::OUString > handleNames;
529 initProperties(ifc, m_absentOptional, &handleNames);
530 std::vector< rtl::OUString >::size_type size = handleNames.size();
531 OSL_ASSERT(size <= SAL_MAX_INT32);
532 handleMap.realloc(static_cast< sal_Int32 >(size));
533 std::copy(handleNames.begin(), handleNames.end(), handleMap.getArray());
536 rtl::OUString PropertySetMixinImpl::Impl::translateHandle(
537 css::uno::Reference< css::uno::XInterface > const & object,
538 sal_Int32 handle) const
540 if (handle < 0 || handle >= handleMap.getLength()) {
541 throw css::beans::UnknownPropertyException(
542 (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("bad handle "))
543 + rtl::OUString::valueOf(handle)),
544 object);
546 return handleMap[handle];
549 void PropertySetMixinImpl::Impl::setProperty(
550 css::uno::Reference< css::uno::XInterface > const & object,
551 rtl::OUString const & name, css::uno::Any const & value, bool isAmbiguous,
552 bool isDefaulted, sal_Int16 illegalArgumentPosition) const
554 PropertyMap::const_iterator i(properties.find(name));
555 if (i == properties.end()) {
556 throw css::beans::UnknownPropertyException(name, object);
558 if ((isAmbiguous
559 && ((i->second.property.Attributes
560 & css::beans::PropertyAttribute::MAYBEAMBIGUOUS)
561 == 0))
562 || (isDefaulted
563 && ((i->second.property.Attributes
564 & css::beans::PropertyAttribute::MAYBEDEFAULT)
565 == 0)))
567 throw css::lang::IllegalArgumentException(
568 (rtl::OUString(
569 RTL_CONSTASCII_USTRINGPARAM(
570 "flagging as ambiguous/defaulted non-ambiguous/defaulted"
571 " property "))
572 + name),
573 object, illegalArgumentPosition);
575 css::uno::Reference< css::reflection::XIdlField2 > f(
576 m_idlClass->getField(name), css::uno::UNO_QUERY_THROW);
577 css::uno::Any o(object->queryInterface(m_type));
578 css::uno::Any v(
579 wrapValue(
580 object, value,
581 (css::uno::Reference< css::reflection::XIdlField2 >(
582 m_idlClass->getField(name), css::uno::UNO_QUERY_THROW)->
583 getType()),
584 ((i->second.property.Attributes
585 & css::beans::PropertyAttribute::MAYBEAMBIGUOUS)
586 != 0),
587 isAmbiguous,
588 ((i->second.property.Attributes
589 & css::beans::PropertyAttribute::MAYBEDEFAULT)
590 != 0),
591 isDefaulted,
592 ((i->second.property.Attributes
593 & css::beans::PropertyAttribute::MAYBEVOID)
594 != 0)));
595 try {
596 f->set(o, v);
597 } catch (css::lang::IllegalArgumentException & e) {
598 if (e.ArgumentPosition == 1) {
599 throw css::lang::IllegalArgumentException(
600 e.Message, object, illegalArgumentPosition);
601 } else {
602 throw css::uno::RuntimeException(
603 (rtl::OUString(
604 RTL_CONSTASCII_USTRINGPARAM(
605 "unexpected"
606 " com.sun.star.lang.IllegalArgumentException: "))
607 + e.Message),
608 object);
610 } catch (css::lang::IllegalAccessException &) {
611 //TODO Clarify whether PropertyVetoException is the correct exception
612 // to throw when trying to set a read-only property:
613 throw css::beans::PropertyVetoException(
614 (rtl::OUString(
615 RTL_CONSTASCII_USTRINGPARAM("cannot set read-only property "))
616 + name),
617 object);
618 } catch (css::lang::WrappedTargetRuntimeException & e) {
619 //FIXME A WrappedTargetRuntimeException from XIdlField2.get is not
620 // guaranteed to originate directly within XIdlField2.get (and thus have
621 // the expected semantics); it might also be passed through from lower
622 // layers.
623 if (e.TargetException.isExtractableTo(
624 getCppuType(
625 static_cast< css::beans::UnknownPropertyException * >(0)))
626 && ((i->second.property.Attributes
627 & css::beans::PropertyAttribute::OPTIONAL)
628 != 0))
630 throw css::beans::UnknownPropertyException(name, object);
631 } else if (e.TargetException.isExtractableTo(
632 getCppuType(
633 static_cast< css::beans::PropertyVetoException * >(
634 0)))
635 && ((i->second.property.Attributes
636 & css::beans::PropertyAttribute::CONSTRAINED)
637 != 0))
639 throw css::beans::PropertyVetoException(name, object);
640 } else {
641 throw css::lang::WrappedTargetException(
642 e.Message, object, e.TargetException);
647 css::uno::Any PropertySetMixinImpl::Impl::getProperty(
648 css::uno::Reference< css::uno::XInterface > const & object,
649 rtl::OUString const & name, css::beans::PropertyState * state) const
651 PropertyMap::const_iterator i(properties.find(name));
652 if (i == properties.end()) {
653 throw css::beans::UnknownPropertyException(name, object);
655 css::uno::Reference< css::reflection::XIdlField2 > field(
656 m_idlClass->getField(name), css::uno::UNO_QUERY_THROW);
657 css::uno::Any value;
658 try {
659 value = field->get(object->queryInterface(m_type));
660 } catch (css::lang::IllegalArgumentException & e) {
661 throw css::uno::RuntimeException(
662 (rtl::OUString(
663 RTL_CONSTASCII_USTRINGPARAM(
664 "unexpected com.sun.star.lang.IllegalArgumentException: "))
665 + e.Message),
666 object);
667 } catch (css::lang::WrappedTargetRuntimeException & e) {
668 //FIXME A WrappedTargetRuntimeException from XIdlField2.get is not
669 // guaranteed to originate directly within XIdlField2.get (and thus have
670 // the expected semantics); it might also be passed through from lower
671 // layers.
672 if (e.TargetException.isExtractableTo(
673 getCppuType(
674 static_cast< css::beans::UnknownPropertyException * >(0)))
675 && ((i->second.property.Attributes
676 & css::beans::PropertyAttribute::OPTIONAL)
677 != 0))
679 throw css::beans::UnknownPropertyException(name, object);
680 } else {
681 throw css::lang::WrappedTargetException(
682 e.Message, object, e.TargetException);
685 bool undoAmbiguous
686 = ((i->second.property.Attributes
687 & css::beans::PropertyAttribute::MAYBEAMBIGUOUS)
688 != 0);
689 bool undoDefaulted
690 = ((i->second.property.Attributes
691 & css::beans::PropertyAttribute::MAYBEDEFAULT)
692 != 0);
693 bool undoOptional
694 = ((i->second.property.Attributes
695 & css::beans::PropertyAttribute::MAYBEVOID)
696 != 0);
697 bool isAmbiguous = false;
698 bool isDefaulted = false;
699 while (undoAmbiguous || undoDefaulted || undoOptional) {
700 if (undoAmbiguous
701 && value.getValueTypeName().matchAsciiL(
702 RTL_CONSTASCII_STRINGPARAM("com.sun.star.beans.Ambiguous<")))
704 css::uno::Reference< css::reflection::XIdlClass > ambiguous(
705 getReflection(value.getValueTypeName()));
706 try {
707 if (!(css::uno::Reference< css::reflection::XIdlField2 >(
708 ambiguous->getField(
709 rtl::OUString(
710 RTL_CONSTASCII_USTRINGPARAM("IsAmbiguous"))),
711 css::uno::UNO_QUERY_THROW)->get(value)
712 >>= isAmbiguous))
714 throw css::uno::RuntimeException(
715 rtl::OUString(
716 RTL_CONSTASCII_USTRINGPARAM(
717 "unexpected type of"
718 " com.sun.star.beans.Ambiguous IsAmbiguous"
719 " member")),
720 object);
722 value = css::uno::Reference< css::reflection::XIdlField2 >(
723 ambiguous->getField(
724 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Value"))),
725 css::uno::UNO_QUERY_THROW)->get(value);
726 } catch (css::lang::IllegalArgumentException & e) {
727 throw css::uno::RuntimeException(
728 (rtl::OUString(
729 RTL_CONSTASCII_USTRINGPARAM(
730 "unexpected com.sun.star.lang."
731 "IllegalArgumentException: "))
732 + e.Message),
733 object);
735 undoAmbiguous = false;
736 } else if (undoDefaulted
737 && value.getValueTypeName().matchAsciiL(
738 RTL_CONSTASCII_STRINGPARAM(
739 "com.sun.star.beans.Defaulted<")))
741 css::uno::Reference< css::reflection::XIdlClass > defaulted(
742 getReflection(value.getValueTypeName()));
743 try {
745 if (!(css::uno::Reference< css::reflection::XIdlField2 >(
746 defaulted->getField(
747 rtl::OUString(
748 RTL_CONSTASCII_USTRINGPARAM("IsDefaulted"))),
749 css::uno::UNO_QUERY_THROW)->get(value)
750 >>= isDefaulted))
752 throw css::uno::RuntimeException(
753 rtl::OUString(
754 RTL_CONSTASCII_USTRINGPARAM(
755 "unexpected type of"
756 " com.sun.star.beans.Defaulted IsDefaulted"
757 " member")),
758 object);
760 value = css::uno::Reference< css::reflection::XIdlField2 >(
761 defaulted->getField(
762 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Value"))),
763 css::uno::UNO_QUERY_THROW)->get(value);
764 } catch (css::lang::IllegalArgumentException & e) {
765 throw css::uno::RuntimeException(
766 (rtl::OUString(
767 RTL_CONSTASCII_USTRINGPARAM(
768 "unexpected com.sun.star.lang."
769 "IllegalArgumentException: "))
770 + e.Message),
771 object);
773 undoDefaulted = false;
774 } else if (undoOptional
775 && value.getValueTypeName().matchAsciiL(
776 RTL_CONSTASCII_STRINGPARAM(
777 "com.sun.star.beans.Optional<")))
779 css::uno::Reference< css::reflection::XIdlClass > optional(
780 getReflection(value.getValueTypeName()));
781 try {
782 bool present = false;
783 if (!(css::uno::Reference< css::reflection::XIdlField2 >(
784 optional->getField(
785 rtl::OUString(
786 RTL_CONSTASCII_USTRINGPARAM("IsPresent"))),
787 css::uno::UNO_QUERY_THROW)->get(value)
788 >>= present))
790 throw css::uno::RuntimeException(
791 rtl::OUString(
792 RTL_CONSTASCII_USTRINGPARAM(
793 "unexpected type of com.sun.star.beans.Optional"
794 " IsPresent member")),
795 object);
797 if (!present) {
798 value.clear();
799 break;
801 value = css::uno::Reference< css::reflection::XIdlField2 >(
802 optional->getField(
803 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Value"))),
804 css::uno::UNO_QUERY_THROW)->get(value);
805 } catch (css::lang::IllegalArgumentException & e) {
806 throw css::uno::RuntimeException(
807 (rtl::OUString(
808 RTL_CONSTASCII_USTRINGPARAM(
809 "unexpected com.sun.star.lang."
810 "IllegalArgumentException: "))
811 + e.Message),
812 object);
814 undoOptional = false;
815 } else {
816 throw css::uno::RuntimeException(
817 (rtl::OUString(
818 RTL_CONSTASCII_USTRINGPARAM(
819 "unexpected type of attribute "))
820 + name),
821 object);
824 if (state != 0) {
825 //XXX If isAmbiguous && isDefaulted, arbitrarily choose AMBIGUOUS_VALUE
826 // over DEFAULT_VALUE:
827 *state = isAmbiguous
828 ? css::beans::PropertyState_AMBIGUOUS_VALUE
829 : isDefaulted
830 ? css::beans::PropertyState_DEFAULT_VALUE
831 : css::beans::PropertyState_DIRECT_VALUE;
833 return value;
836 css::uno::Reference< css::reflection::XIdlClass >
837 PropertySetMixinImpl::Impl::getReflection(rtl::OUString const & typeName) const
839 css::uno::Reference< css::lang::XMultiComponentFactory > factory(
840 m_context->getServiceManager(), css::uno::UNO_QUERY_THROW);
841 AutoDispose< css::reflection::XIdlReflection > refl;
842 try {
843 refl.ifc = css::uno::Reference< css::reflection::XIdlReflection >(
844 factory->createInstanceWithContext(
845 rtl::OUString(
846 RTL_CONSTASCII_USTRINGPARAM(
847 "com.sun.star.reflection.CoreReflection")),
848 m_context),
849 css::uno::UNO_QUERY_THROW);
850 } catch (css::uno::RuntimeException &) {
851 throw;
852 } catch (css::uno::Exception & e) {
853 throw css::uno::DeploymentException(
854 (rtl::OUString(
855 RTL_CONSTASCII_USTRINGPARAM(
856 "component context fails to supply service"
857 " com.sun.star.reflection.CoreReflection: "))
858 + e.Message),
859 m_context);
861 css::uno::Reference< css::reflection::XIdlClass > idlClass(
862 refl.ifc->forName(typeName), css::uno::UNO_QUERY_THROW);
863 refl.dispose();
864 return idlClass;
867 css::uno::Any PropertySetMixinImpl::Impl::wrapValue(
868 css::uno::Reference< css::uno::XInterface > const & object,
869 css::uno::Any const & value,
870 css::uno::Reference< css::reflection::XIdlClass > const & type,
871 bool wrapAmbiguous, bool isAmbiguous, bool wrapDefaulted, bool isDefaulted,
872 bool wrapOptional)
874 OSL_ASSERT(
875 (wrapAmbiguous || !isAmbiguous) && (wrapDefaulted || !isDefaulted));
876 if (wrapAmbiguous
877 && type->getName().matchAsciiL(
878 RTL_CONSTASCII_STRINGPARAM("com.sun.star.beans.Ambiguous<")))
880 css::uno::Any strct;
881 type->createObject(strct);
882 try {
883 css::uno::Reference< css::reflection::XIdlField2 > field(
884 type->getField(
885 rtl::OUString(
886 RTL_CONSTASCII_USTRINGPARAM("Value"))),
887 css::uno::UNO_QUERY_THROW);
888 field->set(
889 strct,
890 wrapValue(
891 object, value, field->getType(), false, false,
892 wrapDefaulted, isDefaulted, wrapOptional));
893 css::uno::Reference< css::reflection::XIdlField2 >(
894 type->getField(
895 rtl::OUString(
896 RTL_CONSTASCII_USTRINGPARAM("IsAmbiguous"))),
897 css::uno::UNO_QUERY_THROW)->set(
898 strct, css::uno::makeAny(isAmbiguous));
899 } catch (css::lang::IllegalArgumentException & e) {
900 throw css::uno::RuntimeException(
901 (rtl::OUString(
902 RTL_CONSTASCII_USTRINGPARAM(
903 "unexpected"
904 " com.sun.star.lang.IllegalArgumentException: "))
905 + e.Message),
906 object);
907 } catch (css::lang::IllegalAccessException & e) {
908 throw css::uno::RuntimeException(
909 (rtl::OUString(
910 RTL_CONSTASCII_USTRINGPARAM(
911 "unexpected"
912 " com.sun.star.lang.IllegalAccessException: "))
913 + e.Message),
914 object);
916 return strct;
917 } else if (wrapDefaulted
918 && type->getName().matchAsciiL(
919 RTL_CONSTASCII_STRINGPARAM("com.sun.star.beans.Defaulted<")))
921 css::uno::Any strct;
922 type->createObject(strct);
923 try {
924 css::uno::Reference< css::reflection::XIdlField2 > field(
925 type->getField(
926 rtl::OUString(
927 RTL_CONSTASCII_USTRINGPARAM("Value"))),
928 css::uno::UNO_QUERY_THROW);
929 field->set(
930 strct,
931 wrapValue(
932 object, value, field->getType(), wrapAmbiguous, isAmbiguous,
933 false, false, wrapOptional));
934 css::uno::Reference< css::reflection::XIdlField2 >(
935 type->getField(
936 rtl::OUString(
937 RTL_CONSTASCII_USTRINGPARAM("IsDefaulted"))),
938 css::uno::UNO_QUERY_THROW)->set(
939 strct, css::uno::makeAny(isDefaulted));
940 } catch (css::lang::IllegalArgumentException & e) {
941 throw css::uno::RuntimeException(
942 (rtl::OUString(
943 RTL_CONSTASCII_USTRINGPARAM(
944 "unexpected"
945 " com.sun.star.lang.IllegalArgumentException: "))
946 + e.Message),
947 object);
948 } catch (css::lang::IllegalAccessException & e) {
949 throw css::uno::RuntimeException(
950 (rtl::OUString(
951 RTL_CONSTASCII_USTRINGPARAM(
952 "unexpected"
953 " com.sun.star.lang.IllegalAccessException: "))
954 + e.Message),
955 object);
957 return strct;
958 } else if (wrapOptional
959 && type->getName().matchAsciiL(
960 RTL_CONSTASCII_STRINGPARAM("com.sun.star.beans.Optional<")))
962 css::uno::Any strct;
963 type->createObject(strct);
964 bool present = value.hasValue();
965 try {
966 css::uno::Reference< css::reflection::XIdlField2 >(
967 type->getField(
968 rtl::OUString(
969 RTL_CONSTASCII_USTRINGPARAM("IsPresent"))),
970 css::uno::UNO_QUERY_THROW)->set(
971 strct, css::uno::makeAny(present));
972 if (present) {
973 css::uno::Reference< css::reflection::XIdlField2 > field(
974 type->getField(
975 rtl::OUString(
976 RTL_CONSTASCII_USTRINGPARAM("Value"))),
977 css::uno::UNO_QUERY_THROW);
978 field->set(
979 strct,
980 wrapValue(
981 object, value, field->getType(), wrapAmbiguous,
982 isAmbiguous, wrapDefaulted, isDefaulted, false));
984 } catch (css::lang::IllegalArgumentException & e) {
985 throw css::uno::RuntimeException(
986 (rtl::OUString(
987 RTL_CONSTASCII_USTRINGPARAM(
988 "unexpected"
989 " com.sun.star.lang.IllegalArgumentException: "))
990 + e.Message),
991 object);
992 } catch (css::lang::IllegalAccessException & e) {
993 throw css::uno::RuntimeException(
994 (rtl::OUString(
995 RTL_CONSTASCII_USTRINGPARAM(
996 "unexpected"
997 " com.sun.star.lang.IllegalAccessException: "))
998 + e.Message),
999 object);
1001 return strct;
1002 } else {
1003 if (wrapAmbiguous || wrapDefaulted || wrapOptional) {
1004 throw css::uno::RuntimeException(
1005 rtl::OUString(
1006 RTL_CONSTASCII_USTRINGPARAM(
1007 "unexpected type of attribute")),
1008 object);
1010 return value;
1014 PropertySetMixinImpl::PropertySetMixinImpl(
1015 css::uno::Reference< css::uno::XComponentContext > const & context,
1016 Implements implements,
1017 css::uno::Sequence< rtl::OUString > const & absentOptional,
1018 css::uno::Type const & type)
1020 m_impl = new Impl(context, implements, absentOptional, type);
1021 m_impl->acquire();
1024 PropertySetMixinImpl::~PropertySetMixinImpl() {
1025 m_impl->release();
1028 void PropertySetMixinImpl::checkUnknown(rtl::OUString const & propertyName) {
1029 if (propertyName.getLength() != 0) {
1030 m_impl->get(
1031 static_cast< css::beans::XPropertySet * >(this), propertyName);
1035 void PropertySetMixinImpl::prepareSet(
1036 rtl::OUString const & propertyName, css::uno::Any const & oldValue,
1037 css::uno::Any const & newValue, BoundListeners * boundListeners)
1039 Impl::PropertyMap::const_iterator it(m_impl->properties.find(propertyName));
1040 OSL_ASSERT(it != m_impl->properties.end());
1041 Impl::VetoListenerBag specificVeto;
1042 Impl::VetoListenerBag unspecificVeto;
1044 osl::MutexGuard g(m_impl->mutex);
1045 if (m_impl->disposed) {
1046 throw css::lang::DisposedException(
1047 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("disposed")),
1048 static_cast< css::beans::XPropertySet * >(this));
1050 if ((it->second.property.Attributes
1051 & css::beans::PropertyAttribute::CONSTRAINED)
1052 != 0)
1054 Impl::VetoListenerMap::const_iterator i(
1055 m_impl->vetoListeners.find(propertyName));
1056 if (i != m_impl->vetoListeners.end()) {
1057 specificVeto = i->second;
1059 i = m_impl->vetoListeners.find(rtl::OUString());
1060 if (i != m_impl->vetoListeners.end()) {
1061 unspecificVeto = i->second;
1064 if ((it->second.property.Attributes
1065 & css::beans::PropertyAttribute::BOUND)
1066 != 0)
1068 OSL_ASSERT(boundListeners != 0);
1069 Impl::BoundListenerMap::const_iterator i(
1070 m_impl->boundListeners.find(propertyName));
1071 if (i != m_impl->boundListeners.end()) {
1072 boundListeners->m_impl->specificListeners = i->second;
1074 i = m_impl->boundListeners.find(rtl::OUString());
1075 if (i != m_impl->boundListeners.end()) {
1076 boundListeners->m_impl->unspecificListeners = i->second;
1080 if ((it->second.property.Attributes
1081 & css::beans::PropertyAttribute::CONSTRAINED)
1082 != 0)
1084 css::beans::PropertyChangeEvent event(
1085 static_cast< css::beans::XPropertySet * >(this), propertyName,
1086 false, it->second.property.Handle, oldValue, newValue);
1087 for (Impl::VetoListenerBag::iterator i(specificVeto.begin());
1088 i != specificVeto.end(); ++i)
1090 try {
1091 (*i)->vetoableChange(event);
1092 } catch (css::lang::DisposedException &) {}
1094 for (Impl::VetoListenerBag::iterator i(unspecificVeto.begin());
1095 i != unspecificVeto.end(); ++i)
1097 try {
1098 (*i)->vetoableChange(event);
1099 } catch (css::lang::DisposedException &) {}
1102 if ((it->second.property.Attributes & css::beans::PropertyAttribute::BOUND)
1103 != 0)
1105 OSL_ASSERT(boundListeners != 0);
1106 boundListeners->m_impl->event = css::beans::PropertyChangeEvent(
1107 static_cast< css::beans::XPropertySet * >(this), propertyName,
1108 false, it->second.property.Handle, oldValue, newValue);
1112 void PropertySetMixinImpl::dispose() {
1113 Impl::BoundListenerMap boundListeners;
1114 Impl::VetoListenerMap vetoListeners;
1116 osl::MutexGuard g(m_impl->mutex);
1117 boundListeners.swap(m_impl->boundListeners);
1118 vetoListeners.swap(m_impl->vetoListeners);
1119 m_impl->disposed = true;
1121 css::lang::EventObject event(
1122 static_cast< css::beans::XPropertySet * >(this));
1123 for (Impl::BoundListenerMap::iterator i(boundListeners.begin());
1124 i != boundListeners.end(); ++i)
1126 for (BoundListenerBag::iterator j(i->second.begin());
1127 j != i->second.end(); ++j)
1129 (*j)->disposing(event);
1132 for (Impl::VetoListenerMap::iterator i(vetoListeners.begin());
1133 i != vetoListeners.end(); ++i)
1135 for (Impl::VetoListenerBag::iterator j(i->second.begin());
1136 j != i->second.end(); ++j)
1138 (*j)->disposing(event);
1143 css::uno::Any PropertySetMixinImpl::queryInterface(css::uno::Type const & type)
1144 throw (css::uno::RuntimeException)
1146 if (((m_impl->implements & IMPLEMENTS_PROPERTY_SET) != 0
1147 && type == css::beans::XPropertySet::static_type()))
1149 css::uno::Reference< css::uno::XInterface > ifc(
1150 static_cast< css::beans::XPropertySet * >(this));
1151 return css::uno::Any(&ifc, type);
1152 } else if ((m_impl->implements & IMPLEMENTS_FAST_PROPERTY_SET) != 0
1153 && type == css::beans::XFastPropertySet::static_type())
1155 css::uno::Reference< css::uno::XInterface > ifc(
1156 static_cast< css::beans::XFastPropertySet * >(this));
1157 return css::uno::Any(&ifc, type);
1158 } else if ((m_impl->implements & IMPLEMENTS_PROPERTY_ACCESS) != 0
1159 && type == css::beans::XPropertyAccess::static_type())
1161 css::uno::Reference< css::uno::XInterface > ifc(
1162 static_cast< css::beans::XPropertyAccess * >(this));
1163 return css::uno::Any(&ifc, type);
1164 } else {
1165 return css::uno::Any();
1169 css::uno::Reference< css::beans::XPropertySetInfo >
1170 PropertySetMixinImpl::getPropertySetInfo() throw (css::uno::RuntimeException) {
1171 try {
1172 return new Info(m_impl);
1173 } catch (std::bad_alloc &) {
1174 //TODO OutOfMemoryException:
1175 throw css::uno::RuntimeException(
1176 rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1180 void PropertySetMixinImpl::setPropertyValue(
1181 rtl::OUString const & propertyName, css::uno::Any const & value)
1182 throw (
1183 css::beans::UnknownPropertyException, css::beans::PropertyVetoException,
1184 css::lang::IllegalArgumentException, css::lang::WrappedTargetException,
1185 css::uno::RuntimeException)
1187 try {
1188 m_impl->setProperty(
1189 static_cast< css::beans::XPropertySet * >(this), propertyName,
1190 value, false, false, 1);
1191 } catch (std::bad_alloc &) {
1192 //TODO OutOfMemoryException:
1193 throw css::uno::RuntimeException(
1194 rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1198 css::uno::Any PropertySetMixinImpl::getPropertyValue(
1199 rtl::OUString const & propertyName)
1200 throw (
1201 css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
1202 css::uno::RuntimeException)
1204 try {
1205 return m_impl->getProperty(
1206 static_cast< css::beans::XPropertySet * >(this), propertyName, 0);
1207 } catch (std::bad_alloc &) {
1208 //TODO OutOfMemoryException:
1209 throw css::uno::RuntimeException(
1210 rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1214 void PropertySetMixinImpl::addPropertyChangeListener(
1215 rtl::OUString const & propertyName,
1216 css::uno::Reference< css::beans::XPropertyChangeListener > const & listener)
1217 throw (
1218 css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
1219 css::uno::RuntimeException)
1221 css::uno::Reference< css::beans::XPropertyChangeListener >(
1222 listener, css::uno::UNO_QUERY_THROW); // reject NULL listener
1223 checkUnknown(propertyName);
1224 try {
1225 bool disposed;
1227 osl::MutexGuard g(m_impl->mutex);
1228 disposed = m_impl->disposed;
1229 if (!disposed) {
1230 m_impl->boundListeners[propertyName].insert(listener);
1233 if (disposed) {
1234 listener->disposing(
1235 css::lang::EventObject(
1236 static_cast< css::beans::XPropertySet * >(this)));
1238 } catch (std::bad_alloc &) {
1239 //TODO OutOfMemoryException:
1240 throw css::uno::RuntimeException(
1241 rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1245 void PropertySetMixinImpl::removePropertyChangeListener(
1246 rtl::OUString const & propertyName,
1247 css::uno::Reference< css::beans::XPropertyChangeListener > const & listener)
1248 throw (
1249 css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
1250 css::uno::RuntimeException)
1252 OSL_ASSERT(listener.is());
1253 checkUnknown(propertyName);
1254 try {
1255 osl::MutexGuard g(m_impl->mutex);
1256 Impl::BoundListenerMap::iterator i(
1257 m_impl->boundListeners.find(propertyName));
1258 if (i != m_impl->boundListeners.end()) {
1259 BoundListenerBag::iterator j(i->second.find(listener));
1260 if (j != i->second.end()) {
1261 i->second.erase(j);
1264 } catch (std::bad_alloc &) {
1265 //TODO OutOfMemoryException:
1266 throw css::uno::RuntimeException(
1267 rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1271 void PropertySetMixinImpl::addVetoableChangeListener(
1272 rtl::OUString const & propertyName,
1273 css::uno::Reference< css::beans::XVetoableChangeListener > const & listener)
1274 throw (
1275 css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
1276 css::uno::RuntimeException)
1278 css::uno::Reference< css::beans::XVetoableChangeListener >(
1279 listener, css::uno::UNO_QUERY_THROW); // reject NULL listener
1280 checkUnknown(propertyName);
1281 try {
1282 bool disposed;
1284 osl::MutexGuard g(m_impl->mutex);
1285 disposed = m_impl->disposed;
1286 if (!disposed) {
1287 m_impl->vetoListeners[propertyName].insert(listener);
1290 if (disposed) {
1291 listener->disposing(
1292 css::lang::EventObject(
1293 static_cast< css::beans::XPropertySet * >(this)));
1295 } catch (std::bad_alloc &) {
1296 //TODO OutOfMemoryException:
1297 throw css::uno::RuntimeException(
1298 rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1302 void PropertySetMixinImpl::removeVetoableChangeListener(
1303 rtl::OUString const & propertyName,
1304 css::uno::Reference< css::beans::XVetoableChangeListener > const & listener)
1305 throw (
1306 css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
1307 css::uno::RuntimeException)
1309 OSL_ASSERT(listener.is());
1310 checkUnknown(propertyName);
1311 try {
1312 osl::MutexGuard g(m_impl->mutex);
1313 Impl::VetoListenerMap::iterator i(
1314 m_impl->vetoListeners.find(propertyName));
1315 if (i != m_impl->vetoListeners.end()) {
1316 Impl::VetoListenerBag::iterator j(i->second.find(listener));
1317 if (j != i->second.end()) {
1318 i->second.erase(j);
1321 } catch (std::bad_alloc &) {
1322 //TODO OutOfMemoryException:
1323 throw css::uno::RuntimeException(
1324 rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1328 void PropertySetMixinImpl::setFastPropertyValue(
1329 sal_Int32 handle, css::uno::Any const & value)
1330 throw (
1331 css::beans::UnknownPropertyException, css::beans::PropertyVetoException,
1332 css::lang::IllegalArgumentException, css::lang::WrappedTargetException,
1333 css::uno::RuntimeException)
1335 try {
1336 m_impl->setProperty(
1337 static_cast< css::beans::XPropertySet * >(this),
1338 m_impl->translateHandle(
1339 static_cast< css::beans::XPropertySet * >(this), handle),
1340 value, false, false, 1);
1341 } catch (std::bad_alloc &) {
1342 //TODO OutOfMemoryException:
1343 throw css::uno::RuntimeException(
1344 rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1348 css::uno::Any PropertySetMixinImpl::getFastPropertyValue(sal_Int32 handle)
1349 throw (
1350 css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
1351 css::uno::RuntimeException)
1353 try {
1354 return m_impl->getProperty(
1355 static_cast< css::beans::XPropertySet * >(this),
1356 m_impl->translateHandle(
1357 static_cast< css::beans::XPropertySet * >(this), handle),
1359 } catch (std::bad_alloc &) {
1360 //TODO OutOfMemoryException:
1361 throw css::uno::RuntimeException(
1362 rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1366 css::uno::Sequence< css::beans::PropertyValue >
1367 PropertySetMixinImpl::getPropertyValues() throw (css::uno::RuntimeException) {
1368 try {
1369 css::uno::Sequence< css::beans::PropertyValue > s(
1370 m_impl->handleMap.getLength());
1371 sal_Int32 n = 0;
1372 for (sal_Int32 i = 0; i < m_impl->handleMap.getLength(); ++i) {
1373 try {
1374 s[n].Value = m_impl->getProperty(
1375 static_cast< css::beans::XPropertySet * >(this),
1376 m_impl->handleMap[i], &s[n].State);
1377 } catch (css::beans::UnknownPropertyException &) {
1378 continue;
1379 } catch (css::lang::WrappedTargetException & e) {
1380 throw css::lang::WrappedTargetRuntimeException(
1381 e.Message, static_cast< css::beans::XPropertySet * >(this),
1382 e.TargetException);
1384 s[n].Name = m_impl->handleMap[i];
1385 s[n].Handle = i;
1386 ++n;
1388 s.realloc(n);
1389 return s;
1390 } catch (std::bad_alloc &) {
1391 //TODO OutOfMemoryException:
1392 throw css::uno::RuntimeException(
1393 rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1397 void PropertySetMixinImpl::setPropertyValues(
1398 css::uno::Sequence< css::beans::PropertyValue > const & props)
1399 throw (
1400 css::beans::UnknownPropertyException, css::beans::PropertyVetoException,
1401 css::lang::IllegalArgumentException, css::lang::WrappedTargetException,
1402 css::uno::RuntimeException)
1404 try {
1405 for (sal_Int32 i = 0; i < props.getLength(); ++i) {
1406 if (props[i].Handle != -1
1407 && (props[i].Name
1408 != m_impl->translateHandle(
1409 static_cast< css::beans::XPropertySet * >(this),
1410 props[i].Handle)))
1412 throw css::beans::UnknownPropertyException(
1413 (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("name "))
1414 + props[i].Name
1415 + rtl::OUString(
1416 RTL_CONSTASCII_USTRINGPARAM(" does not match handle "))
1417 + rtl::OUString::valueOf(props[i].Handle)),
1418 static_cast< css::beans::XPropertySet * >(this));
1420 m_impl->setProperty(
1421 static_cast< css::beans::XPropertySet * >(this), props[i].Name,
1422 props[i].Value,
1423 props[i].State == css::beans::PropertyState_AMBIGUOUS_VALUE,
1424 props[i].State == css::beans::PropertyState_DEFAULT_VALUE, 0);
1426 } catch (std::bad_alloc &) {
1427 //TODO OutOfMemoryException:
1428 throw css::uno::RuntimeException(
1429 rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));