bump product version to 4.1.6.2
[LibreOffice.git] / cppuhelper / source / propertysetmixin.cxx
blobf1d7c52610461809c92c96a1d051b4d2e8c4985d
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "sal/config.h"
23 #include "cppuhelper/propertysetmixin.hxx"
25 #include "com/sun/star/beans/Property.hpp"
26 #include "com/sun/star/beans/PropertyChangeEvent.hpp"
27 #include "com/sun/star/beans/PropertyAttribute.hpp"
28 #include "com/sun/star/beans/PropertyValue.hpp"
29 #include "com/sun/star/beans/PropertyVetoException.hpp"
30 #include "com/sun/star/beans/UnknownPropertyException.hpp"
31 #include "com/sun/star/beans/XFastPropertySet.hpp"
32 #include "com/sun/star/beans/XPropertyAccess.hpp"
33 #include "com/sun/star/beans/XPropertyChangeListener.hpp"
34 #include "com/sun/star/beans/XPropertySet.hpp"
35 #include "com/sun/star/beans/XPropertySetInfo.hpp"
36 #include "com/sun/star/beans/XVetoableChangeListener.hpp"
37 #include "com/sun/star/container/NoSuchElementException.hpp"
38 #include "com/sun/star/container/XHierarchicalNameAccess.hpp"
39 #include "com/sun/star/lang/DisposedException.hpp"
40 #include "com/sun/star/lang/EventObject.hpp"
41 #include "com/sun/star/lang/IllegalAccessException.hpp"
42 #include "com/sun/star/lang/IllegalArgumentException.hpp"
43 #include "com/sun/star/lang/WrappedTargetException.hpp"
44 #include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
45 #include "com/sun/star/lang/XComponent.hpp"
46 #include "com/sun/star/lang/XMultiComponentFactory.hpp"
47 #include "com/sun/star/reflection/XCompoundTypeDescription.hpp"
48 #include "com/sun/star/reflection/XIdlClass.hpp"
49 #include "com/sun/star/reflection/XIdlField2.hpp"
50 #include "com/sun/star/reflection/XIdlReflection.hpp"
51 #include "com/sun/star/reflection/XIndirectTypeDescription.hpp"
52 #include "com/sun/star/reflection/XInterfaceAttributeTypeDescription2.hpp"
53 #include "com/sun/star/reflection/XInterfaceMemberTypeDescription.hpp"
54 #include "com/sun/star/reflection/XInterfaceTypeDescription2.hpp"
55 #include "com/sun/star/reflection/XStructTypeDescription.hpp"
56 #include "com/sun/star/reflection/XTypeDescription.hpp"
57 #include "com/sun/star/uno/Any.hxx"
58 #include "com/sun/star/uno/DeploymentException.hpp"
59 #include "com/sun/star/uno/Exception.hpp"
60 #include "com/sun/star/uno/Reference.hxx"
61 #include "com/sun/star/uno/RuntimeException.hpp"
62 #include "com/sun/star/uno/Sequence.hxx"
63 #include "com/sun/star/uno/Type.hxx"
64 #include "com/sun/star/uno/TypeClass.hpp"
65 #include "com/sun/star/uno/XComponentContext.hpp"
66 #include "com/sun/star/uno/XInterface.hpp"
67 #include "cppuhelper/implbase1.hxx"
68 #include "cppuhelper/weak.hxx"
69 #include "osl/diagnose.h"
70 #include "osl/mutex.hxx"
71 #include "rtl/ref.hxx"
72 #include "rtl/string.h"
73 #include "rtl/ustring.h"
74 #include "rtl/ustring.hxx"
75 #include "sal/types.h"
76 #include "salhelper/simplereferenceobject.hxx"
78 #include <algorithm>
79 #include <map>
80 #include <new>
81 #include <set>
82 #include <vector>
84 using cppu::PropertySetMixinImpl;
86 namespace {
88 template< typename T > struct AutoDispose {
89 AutoDispose() {}
91 ~AutoDispose() {
92 try {
93 dispose();
94 } catch (...) {}
97 void dispose() {
98 css::uno::Reference< css::lang::XComponent > comp(
99 ifc, css::uno::UNO_QUERY);
100 if (comp.is()) {
101 comp->dispose();
103 ifc.clear();
106 css::uno::Reference< T > ifc;
108 private:
109 AutoDispose(AutoDispose &); // not defined
110 void operator =(AutoDispose); // not defined
113 struct PropertyData {
114 explicit PropertyData(
115 css::beans::Property const & theProperty, bool thePresent):
116 property(theProperty), present(thePresent) {}
118 css::beans::Property property;
119 bool present;
122 struct Data: public salhelper::SimpleReferenceObject {
123 typedef std::map< rtl::OUString, PropertyData > PropertyMap;
125 PropertyMap properties;
127 PropertyMap::const_iterator get(
128 css::uno::Reference< css::uno::XInterface > const & object,
129 rtl::OUString const & name) const;
131 protected:
132 void initProperties(
133 css::uno::Reference< css::reflection::XTypeDescription > const & type,
134 css::uno::Sequence< rtl::OUString > const & absentOptional,
135 std::vector< rtl::OUString > * handleNames)
137 TypeSet seen;
138 initProperties(type, absentOptional, handleNames, &seen);
141 private:
142 typedef std::set< rtl::OUString > TypeSet;
144 void initProperties(
145 css::uno::Reference< css::reflection::XTypeDescription > const & type,
146 css::uno::Sequence< rtl::OUString > const & absentOptional,
147 std::vector< rtl::OUString > * handleNames, TypeSet * seen);
149 static css::uno::Reference< css::reflection::XTypeDescription >
150 resolveTypedefs(
151 css::uno::Reference< css::reflection::XTypeDescription > const & type);
154 Data::PropertyMap::const_iterator Data::get(
155 css::uno::Reference< css::uno::XInterface > const & object,
156 rtl::OUString const & name) const
158 PropertyMap::const_iterator i(properties.find(name));
159 if (i == properties.end() || !i->second.present) {
160 throw css::beans::UnknownPropertyException(name, object);
162 return i;
165 void Data::initProperties(
166 css::uno::Reference< css::reflection::XTypeDescription > const & type,
167 css::uno::Sequence< rtl::OUString > const & absentOptional,
168 std::vector< rtl::OUString > * handleNames, TypeSet * seen)
170 css::uno::Reference< css::reflection::XInterfaceTypeDescription2 > ifc(
171 resolveTypedefs(type), css::uno::UNO_QUERY_THROW);
172 if (seen->insert(ifc->getName()).second) {
173 css::uno::Sequence<
174 css::uno::Reference< css::reflection::XTypeDescription > > bases(
175 ifc->getBaseTypes());
176 for (sal_Int32 i = 0; i < bases.getLength(); ++i) {
177 initProperties(bases[i], absentOptional, handleNames, seen);
179 css::uno::Sequence<
180 css::uno::Reference<
181 css::reflection::XInterfaceMemberTypeDescription > > members(
182 ifc->getMembers());
183 rtl::OUString const * absentBegin = absentOptional.getConstArray();
184 rtl::OUString const * absentEnd =
185 absentBegin + absentOptional.getLength();
186 for (sal_Int32 i = 0; i < members.getLength(); ++i) {
187 if (members[i]->getTypeClass()
188 == css::uno::TypeClass_INTERFACE_ATTRIBUTE)
190 css::uno::Reference<
191 css::reflection::XInterfaceAttributeTypeDescription2 > attr(
192 members[i], css::uno::UNO_QUERY_THROW);
193 sal_Int16 attrAttribs = 0;
194 if (attr->isBound()) {
195 attrAttribs |= css::beans::PropertyAttribute::BOUND;
197 bool setUnknown = false;
198 if (attr->isReadOnly()) {
199 attrAttribs |= css::beans::PropertyAttribute::READONLY;
200 setUnknown = true;
202 css::uno::Sequence<
203 css::uno::Reference<
204 css::reflection::XCompoundTypeDescription > > excs(
205 attr->getGetExceptions());
206 bool getUnknown = false;
207 //XXX Special interpretation of getter/setter exceptions only
208 // works if the specified exceptions are of the exact type, not
209 // of a supertype:
210 for (sal_Int32 j = 0; j < excs.getLength(); ++j) {
211 if ( excs[j]->getName() == "com.sun.star.beans.UnknownPropertyException" )
213 getUnknown = true;
214 break;
217 excs = attr->getSetExceptions();
218 for (sal_Int32 j = 0; j < excs.getLength(); ++j) {
219 if ( excs[j]->getName() == "com.sun.star.beans.UnknownPropertyException" )
221 setUnknown = true;
222 } else if ( excs[j]->getName() == "com.sun.star.beans.PropertyVetoException" )
224 attrAttribs
225 |= css::beans::PropertyAttribute::CONSTRAINED;
228 if (getUnknown && setUnknown) {
229 attrAttribs |= css::beans::PropertyAttribute::OPTIONAL;
231 css::uno::Reference< css::reflection::XTypeDescription > t(
232 attr->getType());
233 for (;;)
235 t = resolveTypedefs(t);
236 sal_Int16 n;
237 if (t->getName().matchAsciiL(
238 RTL_CONSTASCII_STRINGPARAM(
239 "com.sun.star.beans.Ambiguous<")))
241 n = css::beans::PropertyAttribute::MAYBEAMBIGUOUS;
242 } else if (t->getName().matchAsciiL(
243 RTL_CONSTASCII_STRINGPARAM(
244 "com.sun.star.beans.Defaulted<")))
246 n = css::beans::PropertyAttribute::MAYBEDEFAULT;
247 } else if (t->getName().matchAsciiL(
248 RTL_CONSTASCII_STRINGPARAM(
249 "com.sun.star.beans.Optional<")))
251 n = css::beans::PropertyAttribute::MAYBEVOID;
252 } else {
253 break;
255 if ((attrAttribs & n) != 0) {
256 break;
258 attrAttribs |= n;
259 css::uno::Sequence<
260 css::uno::Reference< css::reflection::XTypeDescription > >
261 args(
262 css::uno::Reference<
263 css::reflection::XStructTypeDescription >(
265 css::uno::UNO_QUERY_THROW)->getTypeArguments());
266 if (args.getLength() != 1) {
267 throw css::uno::RuntimeException(
268 rtl::OUString(
269 "inconsistent UNO type registry"),
270 css::uno::Reference< css::uno::XInterface >());
272 t = args[0];
274 std::vector< rtl::OUString >::size_type handles
275 = handleNames->size();
276 if (handles > SAL_MAX_INT32) {
277 throw css::uno::RuntimeException(
278 rtl::OUString(
279 "interface type has too many attributes"),
280 css::uno::Reference< css::uno::XInterface >());
282 rtl::OUString name(members[i]->getMemberName());
283 if (!properties.insert(
284 PropertyMap::value_type(
285 name,
286 PropertyData(
287 css::beans::Property(
288 name, static_cast< sal_Int32 >(handles),
289 css::uno::Type(
290 t->getTypeClass(), t->getName()),
291 attrAttribs),
292 (std::find(absentBegin, absentEnd, name)
293 == absentEnd)))).
294 second)
296 throw css::uno::RuntimeException(
297 rtl::OUString(
298 "inconsistent UNO type registry"),
299 css::uno::Reference< css::uno::XInterface >());
301 handleNames->push_back(name);
307 css::uno::Reference< css::reflection::XTypeDescription > Data::resolveTypedefs(
308 css::uno::Reference< css::reflection::XTypeDescription > const & type)
310 css::uno::Reference< css::reflection::XTypeDescription > t(type);
311 while (t->getTypeClass() == css::uno::TypeClass_TYPEDEF) {
312 t = css::uno::Reference< css::reflection::XIndirectTypeDescription >(
313 t, css::uno::UNO_QUERY_THROW)->getReferencedType();
315 return t;
318 class Info: public cppu::WeakImplHelper1< css::beans::XPropertySetInfo > {
319 public:
320 explicit Info(Data * data): m_data(data) {}
322 virtual css::uno::Sequence< css::beans::Property > SAL_CALL getProperties()
323 throw (css::uno::RuntimeException);
325 virtual css::beans::Property SAL_CALL getPropertyByName(
326 rtl::OUString const & name)
327 throw (
328 css::beans::UnknownPropertyException, css::uno::RuntimeException);
330 virtual sal_Bool SAL_CALL hasPropertyByName(rtl::OUString const & name)
331 throw (css::uno::RuntimeException);
333 private:
334 rtl::Reference< Data > m_data;
337 css::uno::Sequence< css::beans::Property > Info::getProperties()
338 throw (css::uno::RuntimeException)
340 try {
341 OSL_ASSERT(m_data->properties.size() <= SAL_MAX_INT32);
342 css::uno::Sequence< css::beans::Property > s(
343 static_cast< sal_Int32 >(m_data->properties.size()));
344 sal_Int32 n = 0;
345 for (Data::PropertyMap::iterator i(m_data->properties.begin());
346 i != m_data->properties.end(); ++i)
348 if (i->second.present) {
349 s[n++] = i->second.property;
352 s.realloc(n);
353 return s;
354 } catch (std::bad_alloc &) {
355 //TODO OutOfMemoryException:
356 throw css::uno::RuntimeException(
357 rtl::OUString(), static_cast< cppu::OWeakObject * >(this));
361 css::beans::Property Info::getPropertyByName(rtl::OUString const & name)
362 throw (css::beans::UnknownPropertyException, css::uno::RuntimeException)
364 return m_data->get(static_cast< cppu::OWeakObject * >(this), name)->
365 second.property;
368 sal_Bool Info::hasPropertyByName(rtl::OUString const & name)
369 throw (css::uno::RuntimeException)
371 Data::PropertyMap::iterator i(m_data->properties.find(name));
372 return i != m_data->properties.end() && i->second.present;
375 typedef
376 std::multiset< css::uno::Reference< css::beans::XPropertyChangeListener > >
377 BoundListenerBag;
381 class PropertySetMixinImpl::BoundListeners::Impl {
382 public:
383 BoundListenerBag specificListeners;
384 BoundListenerBag unspecificListeners;
385 css::beans::PropertyChangeEvent event;
388 PropertySetMixinImpl::BoundListeners::BoundListeners(): m_impl(new Impl) {}
390 PropertySetMixinImpl::BoundListeners::~BoundListeners() {
391 delete m_impl;
394 void PropertySetMixinImpl::BoundListeners::notify() const {
395 for (BoundListenerBag::const_iterator i(m_impl->specificListeners.begin());
396 i != m_impl->specificListeners.end(); ++i)
398 try {
399 (*i)->propertyChange(m_impl->event);
400 } catch (css::lang::DisposedException &) {}
402 for (BoundListenerBag::const_iterator i(
403 m_impl->unspecificListeners.begin());
404 i != m_impl->unspecificListeners.end(); ++i)
406 try {
407 (*i)->propertyChange(m_impl->event);
408 } catch (css::lang::DisposedException &) {}
412 class PropertySetMixinImpl::Impl: public Data {
413 public:
414 Impl(
415 css::uno::Reference< css::uno::XComponentContext > const & context,
416 Implements theImplements,
417 css::uno::Sequence< rtl::OUString > const & absentOptional,
418 css::uno::Type const & type);
420 rtl::OUString translateHandle(
421 css::uno::Reference< css::uno::XInterface > const & object,
422 sal_Int32 handle) const;
424 void setProperty(
425 css::uno::Reference< css::uno::XInterface > const & object,
426 rtl::OUString const & name, css::uno::Any const & value,
427 bool isAmbiguous, bool isDefaulted, sal_Int16 illegalArgumentPosition)
428 const;
430 css::uno::Any getProperty(
431 css::uno::Reference< css::uno::XInterface > const & object,
432 rtl::OUString const & name, css::beans::PropertyState * state) const;
434 PropertySetMixinImpl::Implements implements;
435 css::uno::Sequence< rtl::OUString > handleMap;
437 typedef std::map< rtl::OUString, BoundListenerBag > BoundListenerMap;
439 typedef
440 std::multiset< css::uno::Reference< css::beans::XVetoableChangeListener > >
441 VetoListenerBag;
443 typedef std::map< rtl::OUString, VetoListenerBag > VetoListenerMap;
445 mutable osl::Mutex mutex;
446 BoundListenerMap boundListeners;
447 VetoListenerMap vetoListeners;
448 bool disposed;
450 private:
451 css::uno::Reference< css::reflection::XIdlClass > getReflection(
452 rtl::OUString const & typeName) const;
454 static css::uno::Any wrapValue(
455 css::uno::Reference< css::uno::XInterface > const & object,
456 css::uno::Any const & value,
457 css::uno::Reference< css::reflection::XIdlClass > const & type,
458 bool wrapAmbiguous, bool isAmbiguous, bool wrapDefaulted,
459 bool isDefaulted, bool wrapOptional);
461 css::uno::Reference< css::uno::XComponentContext > const & m_context;
462 css::uno::Sequence< rtl::OUString > m_absentOptional;
463 css::uno::Type m_type;
464 css::uno::Reference< css::reflection::XIdlClass > m_idlClass;
467 PropertySetMixinImpl::Impl::Impl(
468 css::uno::Reference< css::uno::XComponentContext > const & context,
469 Implements theImplements,
470 css::uno::Sequence< rtl::OUString > const & absentOptional,
471 css::uno::Type const & type):
472 implements(theImplements), disposed(false), m_context(context),
473 m_absentOptional(absentOptional), m_type(type)
475 OSL_ASSERT(
476 context.is()
477 && ((implements
478 & ~(IMPLEMENTS_PROPERTY_SET | IMPLEMENTS_FAST_PROPERTY_SET
479 | IMPLEMENTS_PROPERTY_ACCESS))
480 == 0));
481 m_idlClass = getReflection(m_type.getTypeName());
482 css::uno::Reference< css::reflection::XTypeDescription > ifc;
483 try {
484 ifc = css::uno::Reference< css::reflection::XTypeDescription >(
485 css::uno::Reference< css::container::XHierarchicalNameAccess >(
486 m_context->getValueByName(
487 rtl::OUString(
488 "/singletons/com.sun.star.reflection."
489 "theTypeDescriptionManager")),
490 css::uno::UNO_QUERY_THROW)->getByHierarchicalName(
491 m_type.getTypeName()),
492 css::uno::UNO_QUERY_THROW);
493 } catch (css::container::NoSuchElementException & e) {
494 throw css::uno::RuntimeException(
495 (rtl::OUString(
496 "unexpected"
497 " com.sun.star.container.NoSuchElementException: ")
498 + e.Message),
499 css::uno::Reference< css::uno::XInterface >());
501 std::vector< rtl::OUString > handleNames;
502 initProperties(ifc, m_absentOptional, &handleNames);
503 std::vector< rtl::OUString >::size_type size = handleNames.size();
504 OSL_ASSERT(size <= SAL_MAX_INT32);
505 handleMap.realloc(static_cast< sal_Int32 >(size));
506 std::copy(handleNames.begin(), handleNames.end(), handleMap.getArray());
509 rtl::OUString PropertySetMixinImpl::Impl::translateHandle(
510 css::uno::Reference< css::uno::XInterface > const & object,
511 sal_Int32 handle) const
513 if (handle < 0 || handle >= handleMap.getLength()) {
514 throw css::beans::UnknownPropertyException(
515 (rtl::OUString("bad handle ")
516 + rtl::OUString::valueOf(handle)),
517 object);
519 return handleMap[handle];
522 void PropertySetMixinImpl::Impl::setProperty(
523 css::uno::Reference< css::uno::XInterface > const & object,
524 rtl::OUString const & name, css::uno::Any const & value, bool isAmbiguous,
525 bool isDefaulted, sal_Int16 illegalArgumentPosition) const
527 PropertyMap::const_iterator i(properties.find(name));
528 if (i == properties.end()) {
529 throw css::beans::UnknownPropertyException(name, object);
531 if ((isAmbiguous
532 && ((i->second.property.Attributes
533 & css::beans::PropertyAttribute::MAYBEAMBIGUOUS)
534 == 0))
535 || (isDefaulted
536 && ((i->second.property.Attributes
537 & css::beans::PropertyAttribute::MAYBEDEFAULT)
538 == 0)))
540 throw css::lang::IllegalArgumentException(
541 (rtl::OUString(
542 "flagging as ambiguous/defaulted non-ambiguous/defaulted"
543 " property ")
544 + name),
545 object, illegalArgumentPosition);
547 css::uno::Reference< css::reflection::XIdlField2 > f(
548 m_idlClass->getField(name), css::uno::UNO_QUERY_THROW);
549 css::uno::Any o(object->queryInterface(m_type));
550 css::uno::Any v(
551 wrapValue(
552 object, value,
553 (css::uno::Reference< css::reflection::XIdlField2 >(
554 m_idlClass->getField(name), css::uno::UNO_QUERY_THROW)->
555 getType()),
556 ((i->second.property.Attributes
557 & css::beans::PropertyAttribute::MAYBEAMBIGUOUS)
558 != 0),
559 isAmbiguous,
560 ((i->second.property.Attributes
561 & css::beans::PropertyAttribute::MAYBEDEFAULT)
562 != 0),
563 isDefaulted,
564 ((i->second.property.Attributes
565 & css::beans::PropertyAttribute::MAYBEVOID)
566 != 0)));
567 try {
568 f->set(o, v);
569 } catch (css::lang::IllegalArgumentException & e) {
570 if (e.ArgumentPosition == 1) {
571 throw css::lang::IllegalArgumentException(
572 e.Message, object, illegalArgumentPosition);
573 } else {
574 throw css::uno::RuntimeException(
575 (rtl::OUString(
576 "unexpected"
577 " com.sun.star.lang.IllegalArgumentException: ")
578 + e.Message),
579 object);
581 } catch (css::lang::IllegalAccessException &) {
582 //TODO Clarify whether PropertyVetoException is the correct exception
583 // to throw when trying to set a read-only property:
584 throw css::beans::PropertyVetoException(
585 (rtl::OUString("cannot set read-only property ")
586 + name),
587 object);
588 } catch (css::lang::WrappedTargetRuntimeException & e) {
589 //FIXME A WrappedTargetRuntimeException from XIdlField2.get is not
590 // guaranteed to originate directly within XIdlField2.get (and thus have
591 // the expected semantics); it might also be passed through from lower
592 // layers.
593 if (e.TargetException.isExtractableTo(
594 getCppuType(
595 static_cast< css::beans::UnknownPropertyException * >(0)))
596 && ((i->second.property.Attributes
597 & css::beans::PropertyAttribute::OPTIONAL)
598 != 0))
600 throw css::beans::UnknownPropertyException(name, object);
601 } else if (e.TargetException.isExtractableTo(
602 getCppuType(
603 static_cast< css::beans::PropertyVetoException * >(
604 0)))
605 && ((i->second.property.Attributes
606 & css::beans::PropertyAttribute::CONSTRAINED)
607 != 0))
609 css::beans::PropertyVetoException exc;
610 e.TargetException >>= exc;
611 if (exc.Message.isEmpty() )
612 throw css::beans::PropertyVetoException("Invalid " + name, object);
613 else
614 throw exc;
615 } else {
616 throw css::lang::WrappedTargetException(
617 e.Message, object, e.TargetException);
622 css::uno::Any PropertySetMixinImpl::Impl::getProperty(
623 css::uno::Reference< css::uno::XInterface > const & object,
624 rtl::OUString const & name, css::beans::PropertyState * state) const
626 PropertyMap::const_iterator i(properties.find(name));
627 if (i == properties.end()) {
628 throw css::beans::UnknownPropertyException(name, object);
630 css::uno::Reference< css::reflection::XIdlField2 > field(
631 m_idlClass->getField(name), css::uno::UNO_QUERY_THROW);
632 css::uno::Any value;
633 try {
634 value = field->get(object->queryInterface(m_type));
635 } catch (css::lang::IllegalArgumentException & e) {
636 throw css::uno::RuntimeException(
637 (rtl::OUString(
638 "unexpected com.sun.star.lang.IllegalArgumentException: ")
639 + e.Message),
640 object);
641 } catch (css::lang::WrappedTargetRuntimeException & e) {
642 //FIXME A WrappedTargetRuntimeException from XIdlField2.get is not
643 // guaranteed to originate directly within XIdlField2.get (and thus have
644 // the expected semantics); it might also be passed through from lower
645 // layers.
646 if (e.TargetException.isExtractableTo(
647 getCppuType(
648 static_cast< css::beans::UnknownPropertyException * >(0)))
649 && ((i->second.property.Attributes
650 & css::beans::PropertyAttribute::OPTIONAL)
651 != 0))
653 throw css::beans::UnknownPropertyException(name, object);
654 } else {
655 throw css::lang::WrappedTargetException(
656 e.Message, object, e.TargetException);
659 bool undoAmbiguous
660 = ((i->second.property.Attributes
661 & css::beans::PropertyAttribute::MAYBEAMBIGUOUS)
662 != 0);
663 bool undoDefaulted
664 = ((i->second.property.Attributes
665 & css::beans::PropertyAttribute::MAYBEDEFAULT)
666 != 0);
667 bool undoOptional
668 = ((i->second.property.Attributes
669 & css::beans::PropertyAttribute::MAYBEVOID)
670 != 0);
671 bool isAmbiguous = false;
672 bool isDefaulted = false;
673 while (undoAmbiguous || undoDefaulted || undoOptional) {
674 if (undoAmbiguous
675 && value.getValueTypeName().matchAsciiL(
676 RTL_CONSTASCII_STRINGPARAM("com.sun.star.beans.Ambiguous<")))
678 css::uno::Reference< css::reflection::XIdlClass > ambiguous(
679 getReflection(value.getValueTypeName()));
680 try {
681 if (!(css::uno::Reference< css::reflection::XIdlField2 >(
682 ambiguous->getField(
683 rtl::OUString("IsAmbiguous")),
684 css::uno::UNO_QUERY_THROW)->get(value)
685 >>= isAmbiguous))
687 throw css::uno::RuntimeException(
688 rtl::OUString(
689 "unexpected type of"
690 " com.sun.star.beans.Ambiguous IsAmbiguous"
691 " member"),
692 object);
694 value = css::uno::Reference< css::reflection::XIdlField2 >(
695 ambiguous->getField(
696 rtl::OUString("Value")),
697 css::uno::UNO_QUERY_THROW)->get(value);
698 } catch (css::lang::IllegalArgumentException & e) {
699 throw css::uno::RuntimeException(
700 (rtl::OUString(
701 "unexpected com.sun.star.lang."
702 "IllegalArgumentException: ")
703 + e.Message),
704 object);
706 undoAmbiguous = false;
707 } else if (undoDefaulted
708 && value.getValueTypeName().matchAsciiL(
709 RTL_CONSTASCII_STRINGPARAM(
710 "com.sun.star.beans.Defaulted<")))
712 css::uno::Reference< css::reflection::XIdlClass > defaulted(
713 getReflection(value.getValueTypeName()));
714 try {
716 if (!(css::uno::Reference< css::reflection::XIdlField2 >(
717 defaulted->getField(
718 rtl::OUString("IsDefaulted")),
719 css::uno::UNO_QUERY_THROW)->get(value)
720 >>= isDefaulted))
722 throw css::uno::RuntimeException(
723 rtl::OUString(
724 "unexpected type of"
725 " com.sun.star.beans.Defaulted IsDefaulted"
726 " member"),
727 object);
729 value = css::uno::Reference< css::reflection::XIdlField2 >(
730 defaulted->getField(
731 rtl::OUString("Value")),
732 css::uno::UNO_QUERY_THROW)->get(value);
733 } catch (css::lang::IllegalArgumentException & e) {
734 throw css::uno::RuntimeException(
735 (rtl::OUString(
736 "unexpected com.sun.star.lang."
737 "IllegalArgumentException: ")
738 + e.Message),
739 object);
741 undoDefaulted = false;
742 } else if (undoOptional
743 && value.getValueTypeName().matchAsciiL(
744 RTL_CONSTASCII_STRINGPARAM(
745 "com.sun.star.beans.Optional<")))
747 css::uno::Reference< css::reflection::XIdlClass > optional(
748 getReflection(value.getValueTypeName()));
749 try {
750 bool present = false;
751 if (!(css::uno::Reference< css::reflection::XIdlField2 >(
752 optional->getField(
753 rtl::OUString("IsPresent")),
754 css::uno::UNO_QUERY_THROW)->get(value)
755 >>= present))
757 throw css::uno::RuntimeException(
758 rtl::OUString(
759 "unexpected type of com.sun.star.beans.Optional"
760 " IsPresent member"),
761 object);
763 if (!present) {
764 value.clear();
765 break;
767 value = css::uno::Reference< css::reflection::XIdlField2 >(
768 optional->getField(
769 rtl::OUString("Value")),
770 css::uno::UNO_QUERY_THROW)->get(value);
771 } catch (css::lang::IllegalArgumentException & e) {
772 throw css::uno::RuntimeException(
773 (rtl::OUString(
774 "unexpected com.sun.star.lang."
775 "IllegalArgumentException: ")
776 + e.Message),
777 object);
779 undoOptional = false;
780 } else {
781 throw css::uno::RuntimeException(
782 (rtl::OUString(
783 "unexpected type of attribute ")
784 + name),
785 object);
788 if (state != 0) {
789 //XXX If isAmbiguous && isDefaulted, arbitrarily choose AMBIGUOUS_VALUE
790 // over DEFAULT_VALUE:
791 *state = isAmbiguous
792 ? css::beans::PropertyState_AMBIGUOUS_VALUE
793 : isDefaulted
794 ? css::beans::PropertyState_DEFAULT_VALUE
795 : css::beans::PropertyState_DIRECT_VALUE;
797 return value;
800 css::uno::Reference< css::reflection::XIdlClass >
801 PropertySetMixinImpl::Impl::getReflection(rtl::OUString const & typeName) const
803 css::uno::Reference< css::lang::XMultiComponentFactory > factory(
804 m_context->getServiceManager(), css::uno::UNO_QUERY_THROW);
805 AutoDispose< css::reflection::XIdlReflection > refl;
806 try {
807 refl.ifc = css::uno::Reference< css::reflection::XIdlReflection >(
808 factory->createInstanceWithContext(
809 rtl::OUString(
810 "com.sun.star.reflection.CoreReflection"),
811 m_context),
812 css::uno::UNO_QUERY_THROW);
813 } catch (css::uno::RuntimeException &) {
814 throw;
815 } catch (css::uno::Exception & e) {
816 throw css::uno::DeploymentException(
817 (rtl::OUString(
818 "component context fails to supply service"
819 " com.sun.star.reflection.CoreReflection: ")
820 + e.Message),
821 m_context);
823 css::uno::Reference< css::reflection::XIdlClass > idlClass(
824 refl.ifc->forName(typeName), css::uno::UNO_QUERY_THROW);
825 refl.dispose();
826 return idlClass;
829 css::uno::Any PropertySetMixinImpl::Impl::wrapValue(
830 css::uno::Reference< css::uno::XInterface > const & object,
831 css::uno::Any const & value,
832 css::uno::Reference< css::reflection::XIdlClass > const & type,
833 bool wrapAmbiguous, bool isAmbiguous, bool wrapDefaulted, bool isDefaulted,
834 bool wrapOptional)
836 OSL_ASSERT(
837 (wrapAmbiguous || !isAmbiguous) && (wrapDefaulted || !isDefaulted));
838 if (wrapAmbiguous
839 && type->getName().matchAsciiL(
840 RTL_CONSTASCII_STRINGPARAM("com.sun.star.beans.Ambiguous<")))
842 css::uno::Any strct;
843 type->createObject(strct);
844 try {
845 css::uno::Reference< css::reflection::XIdlField2 > field(
846 type->getField(
847 rtl::OUString("Value")),
848 css::uno::UNO_QUERY_THROW);
849 field->set(
850 strct,
851 wrapValue(
852 object, value, field->getType(), false, false,
853 wrapDefaulted, isDefaulted, wrapOptional));
854 css::uno::Reference< css::reflection::XIdlField2 >(
855 type->getField(
856 rtl::OUString("IsAmbiguous")),
857 css::uno::UNO_QUERY_THROW)->set(
858 strct, css::uno::makeAny(isAmbiguous));
859 } catch (css::lang::IllegalArgumentException & e) {
860 throw css::uno::RuntimeException(
861 (rtl::OUString(
862 "unexpected"
863 " com.sun.star.lang.IllegalArgumentException: ")
864 + e.Message),
865 object);
866 } catch (css::lang::IllegalAccessException & e) {
867 throw css::uno::RuntimeException(
868 (rtl::OUString(
869 "unexpected"
870 " com.sun.star.lang.IllegalAccessException: ")
871 + e.Message),
872 object);
874 return strct;
875 } else if (wrapDefaulted
876 && type->getName().matchAsciiL(
877 RTL_CONSTASCII_STRINGPARAM("com.sun.star.beans.Defaulted<")))
879 css::uno::Any strct;
880 type->createObject(strct);
881 try {
882 css::uno::Reference< css::reflection::XIdlField2 > field(
883 type->getField(
884 rtl::OUString("Value")),
885 css::uno::UNO_QUERY_THROW);
886 field->set(
887 strct,
888 wrapValue(
889 object, value, field->getType(), wrapAmbiguous, isAmbiguous,
890 false, false, wrapOptional));
891 css::uno::Reference< css::reflection::XIdlField2 >(
892 type->getField(
893 rtl::OUString("IsDefaulted")),
894 css::uno::UNO_QUERY_THROW)->set(
895 strct, css::uno::makeAny(isDefaulted));
896 } catch (css::lang::IllegalArgumentException & e) {
897 throw css::uno::RuntimeException(
898 (rtl::OUString(
899 "unexpected"
900 " com.sun.star.lang.IllegalArgumentException: ")
901 + e.Message),
902 object);
903 } catch (css::lang::IllegalAccessException & e) {
904 throw css::uno::RuntimeException(
905 (rtl::OUString(
906 "unexpected"
907 " com.sun.star.lang.IllegalAccessException: ")
908 + e.Message),
909 object);
911 return strct;
912 } else if (wrapOptional
913 && type->getName().matchAsciiL(
914 RTL_CONSTASCII_STRINGPARAM("com.sun.star.beans.Optional<")))
916 css::uno::Any strct;
917 type->createObject(strct);
918 bool present = value.hasValue();
919 try {
920 css::uno::Reference< css::reflection::XIdlField2 >(
921 type->getField(
922 rtl::OUString("IsPresent")),
923 css::uno::UNO_QUERY_THROW)->set(
924 strct, css::uno::makeAny(present));
925 if (present) {
926 css::uno::Reference< css::reflection::XIdlField2 > field(
927 type->getField(
928 rtl::OUString("Value")),
929 css::uno::UNO_QUERY_THROW);
930 field->set(
931 strct,
932 wrapValue(
933 object, value, field->getType(), wrapAmbiguous,
934 isAmbiguous, wrapDefaulted, isDefaulted, false));
936 } catch (css::lang::IllegalArgumentException & e) {
937 throw css::uno::RuntimeException(
938 (rtl::OUString(
939 "unexpected"
940 " com.sun.star.lang.IllegalArgumentException: ")
941 + e.Message),
942 object);
943 } catch (css::lang::IllegalAccessException & e) {
944 throw css::uno::RuntimeException(
945 (rtl::OUString(
946 "unexpected"
947 " com.sun.star.lang.IllegalAccessException: ")
948 + e.Message),
949 object);
951 return strct;
952 } else {
953 if (wrapAmbiguous || wrapDefaulted || wrapOptional) {
954 throw css::uno::RuntimeException(
955 rtl::OUString(
956 "unexpected type of attribute"),
957 object);
959 return value;
963 PropertySetMixinImpl::PropertySetMixinImpl(
964 css::uno::Reference< css::uno::XComponentContext > const & context,
965 Implements implements,
966 css::uno::Sequence< rtl::OUString > const & absentOptional,
967 css::uno::Type const & type)
969 m_impl = new Impl(context, implements, absentOptional, type);
970 m_impl->acquire();
973 PropertySetMixinImpl::~PropertySetMixinImpl() {
974 m_impl->release();
977 void PropertySetMixinImpl::checkUnknown(rtl::OUString const & propertyName) {
978 if (!propertyName.isEmpty()) {
979 m_impl->get(
980 static_cast< css::beans::XPropertySet * >(this), propertyName);
984 void PropertySetMixinImpl::prepareSet(
985 rtl::OUString const & propertyName, css::uno::Any const & oldValue,
986 css::uno::Any const & newValue, BoundListeners * boundListeners)
988 Impl::PropertyMap::const_iterator it(m_impl->properties.find(propertyName));
989 OSL_ASSERT(it != m_impl->properties.end());
990 Impl::VetoListenerBag specificVeto;
991 Impl::VetoListenerBag unspecificVeto;
993 osl::MutexGuard g(m_impl->mutex);
994 if (m_impl->disposed) {
995 throw css::lang::DisposedException(
996 rtl::OUString("disposed"),
997 static_cast< css::beans::XPropertySet * >(this));
999 if ((it->second.property.Attributes
1000 & css::beans::PropertyAttribute::CONSTRAINED)
1001 != 0)
1003 Impl::VetoListenerMap::const_iterator i(
1004 m_impl->vetoListeners.find(propertyName));
1005 if (i != m_impl->vetoListeners.end()) {
1006 specificVeto = i->second;
1008 i = m_impl->vetoListeners.find(rtl::OUString());
1009 if (i != m_impl->vetoListeners.end()) {
1010 unspecificVeto = i->second;
1013 if ((it->second.property.Attributes
1014 & css::beans::PropertyAttribute::BOUND)
1015 != 0)
1017 OSL_ASSERT(boundListeners != 0);
1018 Impl::BoundListenerMap::const_iterator i(
1019 m_impl->boundListeners.find(propertyName));
1020 if (i != m_impl->boundListeners.end()) {
1021 boundListeners->m_impl->specificListeners = i->second;
1023 i = m_impl->boundListeners.find(rtl::OUString());
1024 if (i != m_impl->boundListeners.end()) {
1025 boundListeners->m_impl->unspecificListeners = i->second;
1029 if ((it->second.property.Attributes
1030 & css::beans::PropertyAttribute::CONSTRAINED)
1031 != 0)
1033 css::beans::PropertyChangeEvent event(
1034 static_cast< css::beans::XPropertySet * >(this), propertyName,
1035 false, it->second.property.Handle, oldValue, newValue);
1036 for (Impl::VetoListenerBag::iterator i(specificVeto.begin());
1037 i != specificVeto.end(); ++i)
1039 try {
1040 (*i)->vetoableChange(event);
1041 } catch (css::lang::DisposedException &) {}
1043 for (Impl::VetoListenerBag::iterator i(unspecificVeto.begin());
1044 i != unspecificVeto.end(); ++i)
1046 try {
1047 (*i)->vetoableChange(event);
1048 } catch (css::lang::DisposedException &) {}
1051 if ((it->second.property.Attributes & css::beans::PropertyAttribute::BOUND)
1052 != 0)
1054 OSL_ASSERT(boundListeners != 0);
1055 boundListeners->m_impl->event = css::beans::PropertyChangeEvent(
1056 static_cast< css::beans::XPropertySet * >(this), propertyName,
1057 false, it->second.property.Handle, oldValue, newValue);
1061 void PropertySetMixinImpl::dispose() {
1062 Impl::BoundListenerMap boundListeners;
1063 Impl::VetoListenerMap vetoListeners;
1065 osl::MutexGuard g(m_impl->mutex);
1066 boundListeners.swap(m_impl->boundListeners);
1067 vetoListeners.swap(m_impl->vetoListeners);
1068 m_impl->disposed = true;
1070 css::lang::EventObject event(
1071 static_cast< css::beans::XPropertySet * >(this));
1072 for (Impl::BoundListenerMap::iterator i(boundListeners.begin());
1073 i != boundListeners.end(); ++i)
1075 for (BoundListenerBag::iterator j(i->second.begin());
1076 j != i->second.end(); ++j)
1078 (*j)->disposing(event);
1081 for (Impl::VetoListenerMap::iterator i(vetoListeners.begin());
1082 i != vetoListeners.end(); ++i)
1084 for (Impl::VetoListenerBag::iterator j(i->second.begin());
1085 j != i->second.end(); ++j)
1087 (*j)->disposing(event);
1092 css::uno::Any PropertySetMixinImpl::queryInterface(css::uno::Type const & type)
1093 throw (css::uno::RuntimeException)
1095 if (((m_impl->implements & IMPLEMENTS_PROPERTY_SET) != 0
1096 && type == css::beans::XPropertySet::static_type()))
1098 css::uno::Reference< css::uno::XInterface > ifc(
1099 static_cast< css::beans::XPropertySet * >(this));
1100 return css::uno::Any(&ifc, type);
1101 } else if ((m_impl->implements & IMPLEMENTS_FAST_PROPERTY_SET) != 0
1102 && type == css::beans::XFastPropertySet::static_type())
1104 css::uno::Reference< css::uno::XInterface > ifc(
1105 static_cast< css::beans::XFastPropertySet * >(this));
1106 return css::uno::Any(&ifc, type);
1107 } else if ((m_impl->implements & IMPLEMENTS_PROPERTY_ACCESS) != 0
1108 && type == css::beans::XPropertyAccess::static_type())
1110 css::uno::Reference< css::uno::XInterface > ifc(
1111 static_cast< css::beans::XPropertyAccess * >(this));
1112 return css::uno::Any(&ifc, type);
1113 } else {
1114 return css::uno::Any();
1118 css::uno::Reference< css::beans::XPropertySetInfo >
1119 PropertySetMixinImpl::getPropertySetInfo() throw (css::uno::RuntimeException) {
1120 try {
1121 return new Info(m_impl);
1122 } catch (std::bad_alloc &) {
1123 //TODO OutOfMemoryException:
1124 throw css::uno::RuntimeException(
1125 rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1129 void PropertySetMixinImpl::setPropertyValue(
1130 rtl::OUString const & propertyName, css::uno::Any const & value)
1131 throw (
1132 css::beans::UnknownPropertyException, css::beans::PropertyVetoException,
1133 css::lang::IllegalArgumentException, css::lang::WrappedTargetException,
1134 css::uno::RuntimeException)
1136 try {
1137 m_impl->setProperty(
1138 static_cast< css::beans::XPropertySet * >(this), propertyName,
1139 value, false, false, 1);
1140 } catch (std::bad_alloc &) {
1141 //TODO OutOfMemoryException:
1142 throw css::uno::RuntimeException(
1143 rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1147 css::uno::Any PropertySetMixinImpl::getPropertyValue(
1148 rtl::OUString const & propertyName)
1149 throw (
1150 css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
1151 css::uno::RuntimeException)
1153 try {
1154 return m_impl->getProperty(
1155 static_cast< css::beans::XPropertySet * >(this), propertyName, 0);
1156 } catch (std::bad_alloc &) {
1157 //TODO OutOfMemoryException:
1158 throw css::uno::RuntimeException(
1159 rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1163 void PropertySetMixinImpl::addPropertyChangeListener(
1164 rtl::OUString const & propertyName,
1165 css::uno::Reference< css::beans::XPropertyChangeListener > const & listener)
1166 throw (
1167 css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
1168 css::uno::RuntimeException)
1170 css::uno::Reference< css::beans::XPropertyChangeListener >(
1171 listener, css::uno::UNO_QUERY_THROW); // reject NULL listener
1172 checkUnknown(propertyName);
1173 try {
1174 bool disposed;
1176 osl::MutexGuard g(m_impl->mutex);
1177 disposed = m_impl->disposed;
1178 if (!disposed) {
1179 m_impl->boundListeners[propertyName].insert(listener);
1182 if (disposed) {
1183 listener->disposing(
1184 css::lang::EventObject(
1185 static_cast< css::beans::XPropertySet * >(this)));
1187 } catch (std::bad_alloc &) {
1188 //TODO OutOfMemoryException:
1189 throw css::uno::RuntimeException(
1190 rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1194 void PropertySetMixinImpl::removePropertyChangeListener(
1195 rtl::OUString const & propertyName,
1196 css::uno::Reference< css::beans::XPropertyChangeListener > const & listener)
1197 throw (
1198 css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
1199 css::uno::RuntimeException)
1201 OSL_ASSERT(listener.is());
1202 checkUnknown(propertyName);
1203 try {
1204 osl::MutexGuard g(m_impl->mutex);
1205 Impl::BoundListenerMap::iterator i(
1206 m_impl->boundListeners.find(propertyName));
1207 if (i != m_impl->boundListeners.end()) {
1208 BoundListenerBag::iterator j(i->second.find(listener));
1209 if (j != i->second.end()) {
1210 i->second.erase(j);
1213 } catch (std::bad_alloc &) {
1214 //TODO OutOfMemoryException:
1215 throw css::uno::RuntimeException(
1216 rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1220 void PropertySetMixinImpl::addVetoableChangeListener(
1221 rtl::OUString const & propertyName,
1222 css::uno::Reference< css::beans::XVetoableChangeListener > const & listener)
1223 throw (
1224 css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
1225 css::uno::RuntimeException)
1227 css::uno::Reference< css::beans::XVetoableChangeListener >(
1228 listener, css::uno::UNO_QUERY_THROW); // reject NULL listener
1229 checkUnknown(propertyName);
1230 try {
1231 bool disposed;
1233 osl::MutexGuard g(m_impl->mutex);
1234 disposed = m_impl->disposed;
1235 if (!disposed) {
1236 m_impl->vetoListeners[propertyName].insert(listener);
1239 if (disposed) {
1240 listener->disposing(
1241 css::lang::EventObject(
1242 static_cast< css::beans::XPropertySet * >(this)));
1244 } catch (std::bad_alloc &) {
1245 //TODO OutOfMemoryException:
1246 throw css::uno::RuntimeException(
1247 rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1251 void PropertySetMixinImpl::removeVetoableChangeListener(
1252 rtl::OUString const & propertyName,
1253 css::uno::Reference< css::beans::XVetoableChangeListener > const & listener)
1254 throw (
1255 css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
1256 css::uno::RuntimeException)
1258 OSL_ASSERT(listener.is());
1259 checkUnknown(propertyName);
1260 try {
1261 osl::MutexGuard g(m_impl->mutex);
1262 Impl::VetoListenerMap::iterator i(
1263 m_impl->vetoListeners.find(propertyName));
1264 if (i != m_impl->vetoListeners.end()) {
1265 Impl::VetoListenerBag::iterator j(i->second.find(listener));
1266 if (j != i->second.end()) {
1267 i->second.erase(j);
1270 } catch (std::bad_alloc &) {
1271 //TODO OutOfMemoryException:
1272 throw css::uno::RuntimeException(
1273 rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1277 void PropertySetMixinImpl::setFastPropertyValue(
1278 sal_Int32 handle, css::uno::Any const & value)
1279 throw (
1280 css::beans::UnknownPropertyException, css::beans::PropertyVetoException,
1281 css::lang::IllegalArgumentException, css::lang::WrappedTargetException,
1282 css::uno::RuntimeException)
1284 try {
1285 m_impl->setProperty(
1286 static_cast< css::beans::XPropertySet * >(this),
1287 m_impl->translateHandle(
1288 static_cast< css::beans::XPropertySet * >(this), handle),
1289 value, false, false, 1);
1290 } catch (std::bad_alloc &) {
1291 //TODO OutOfMemoryException:
1292 throw css::uno::RuntimeException(
1293 rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1297 css::uno::Any PropertySetMixinImpl::getFastPropertyValue(sal_Int32 handle)
1298 throw (
1299 css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
1300 css::uno::RuntimeException)
1302 try {
1303 return m_impl->getProperty(
1304 static_cast< css::beans::XPropertySet * >(this),
1305 m_impl->translateHandle(
1306 static_cast< css::beans::XPropertySet * >(this), handle),
1308 } catch (std::bad_alloc &) {
1309 //TODO OutOfMemoryException:
1310 throw css::uno::RuntimeException(
1311 rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1315 css::uno::Sequence< css::beans::PropertyValue >
1316 PropertySetMixinImpl::getPropertyValues() throw (css::uno::RuntimeException) {
1317 try {
1318 css::uno::Sequence< css::beans::PropertyValue > s(
1319 m_impl->handleMap.getLength());
1320 sal_Int32 n = 0;
1321 for (sal_Int32 i = 0; i < m_impl->handleMap.getLength(); ++i) {
1322 try {
1323 s[n].Value = m_impl->getProperty(
1324 static_cast< css::beans::XPropertySet * >(this),
1325 m_impl->handleMap[i], &s[n].State);
1326 } catch (css::beans::UnknownPropertyException &) {
1327 continue;
1328 } catch (css::lang::WrappedTargetException & e) {
1329 throw css::lang::WrappedTargetRuntimeException(
1330 e.Message, static_cast< css::beans::XPropertySet * >(this),
1331 e.TargetException);
1333 s[n].Name = m_impl->handleMap[i];
1334 s[n].Handle = i;
1335 ++n;
1337 s.realloc(n);
1338 return s;
1339 } catch (std::bad_alloc &) {
1340 //TODO OutOfMemoryException:
1341 throw css::uno::RuntimeException(
1342 rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1346 void PropertySetMixinImpl::setPropertyValues(
1347 css::uno::Sequence< css::beans::PropertyValue > const & props)
1348 throw (
1349 css::beans::UnknownPropertyException, css::beans::PropertyVetoException,
1350 css::lang::IllegalArgumentException, css::lang::WrappedTargetException,
1351 css::uno::RuntimeException)
1353 try {
1354 for (sal_Int32 i = 0; i < props.getLength(); ++i) {
1355 if (props[i].Handle != -1
1356 && (props[i].Name
1357 != m_impl->translateHandle(
1358 static_cast< css::beans::XPropertySet * >(this),
1359 props[i].Handle)))
1361 throw css::beans::UnknownPropertyException(
1362 (rtl::OUString("name ")
1363 + props[i].Name
1364 + rtl::OUString(" does not match handle ")
1365 + rtl::OUString::valueOf(props[i].Handle)),
1366 static_cast< css::beans::XPropertySet * >(this));
1368 m_impl->setProperty(
1369 static_cast< css::beans::XPropertySet * >(this), props[i].Name,
1370 props[i].Value,
1371 props[i].State == css::beans::PropertyState_AMBIGUOUS_VALUE,
1372 props[i].State == css::beans::PropertyState_DEFAULT_VALUE, 0);
1374 } catch (std::bad_alloc &) {
1375 //TODO OutOfMemoryException:
1376 throw css::uno::RuntimeException(
1377 rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1381 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */