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