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 3894 : AutoDispose() {}
90 :
91 3894 : ~AutoDispose() {
92 : try {
93 3894 : dispose();
94 0 : } catch (...) {}
95 3894 : }
96 :
97 7788 : void dispose() {
98 : css::uno::Reference< css::lang::XComponent > comp(
99 7788 : ifc, css::uno::UNO_QUERY);
100 7788 : if (comp.is()) {
101 3894 : comp->dispose();
102 : }
103 7788 : ifc.clear();
104 7788 : }
105 :
106 : css::uno::Reference< T > ifc;
107 :
108 : private:
109 : AutoDispose(AutoDispose &); // not defined
110 : void operator =(AutoDispose); // not defined
111 : };
112 :
113 58377 : struct PropertyData {
114 11682 : explicit PropertyData(
115 : css::beans::Property const & theProperty, bool thePresent):
116 11682 : property(theProperty), present(thePresent) {}
117 :
118 : css::beans::Property property;
119 : bool present;
120 : };
121 :
122 7777 : 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 3894 : 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 3894 : TypeSet seen;
138 3894 : initProperties(type, absentOptional, handleNames, &seen);
139 3894 : }
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 19470 : 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 19470 : resolveTypedefs(type), css::uno::UNO_QUERY_THROW);
172 19470 : if (seen->insert(ifc->getName()).second) {
173 : css::uno::Sequence<
174 : css::uno::Reference< css::reflection::XTypeDescription > > bases(
175 15576 : ifc->getBaseTypes());
176 31152 : for (sal_Int32 i = 0; i < bases.getLength(); ++i) {
177 15576 : initProperties(bases[i], absentOptional, handleNames, seen);
178 : }
179 : css::uno::Sequence<
180 : css::uno::Reference<
181 : css::reflection::XInterfaceMemberTypeDescription > > members(
182 31152 : ifc->getMembers());
183 15576 : rtl::OUString const * absentBegin = absentOptional.getConstArray();
184 : rtl::OUString const * absentEnd =
185 15576 : absentBegin + absentOptional.getLength();
186 58410 : for (sal_Int32 i = 0; i < members.getLength(); ++i) {
187 42834 : if (members[i]->getTypeClass()
188 : == css::uno::TypeClass_INTERFACE_ATTRIBUTE)
189 : {
190 : css::uno::Reference<
191 : css::reflection::XInterfaceAttributeTypeDescription2 > attr(
192 11682 : members[i], css::uno::UNO_QUERY_THROW);
193 11682 : sal_Int16 attrAttribs = 0;
194 11682 : if (attr->isBound()) {
195 0 : attrAttribs |= css::beans::PropertyAttribute::BOUND;
196 : }
197 11682 : bool setUnknown = false;
198 11682 : if (attr->isReadOnly()) {
199 7788 : attrAttribs |= css::beans::PropertyAttribute::READONLY;
200 7788 : setUnknown = true;
201 : }
202 : css::uno::Sequence<
203 : css::uno::Reference<
204 : css::reflection::XCompoundTypeDescription > > excs(
205 23364 : attr->getGetExceptions());
206 11682 : 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 11682 : 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 11682 : excs = attr->getSetExceptions();
218 11682 : 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 11682 : if (getUnknown && setUnknown) {
229 0 : attrAttribs |= css::beans::PropertyAttribute::OPTIONAL;
230 : }
231 : css::uno::Reference< css::reflection::XTypeDescription > t(
232 23364 : attr->getType());
233 : for (;;)
234 : {
235 11682 : t = resolveTypedefs(t);
236 : sal_Int16 n;
237 35046 : if (t->getName().matchAsciiL(
238 : RTL_CONSTASCII_STRINGPARAM(
239 35046 : "com.sun.star.beans.Ambiguous<")))
240 : {
241 0 : n = css::beans::PropertyAttribute::MAYBEAMBIGUOUS;
242 35046 : } else if (t->getName().matchAsciiL(
243 : RTL_CONSTASCII_STRINGPARAM(
244 35046 : "com.sun.star.beans.Defaulted<")))
245 : {
246 0 : n = css::beans::PropertyAttribute::MAYBEDEFAULT;
247 35046 : } else if (t->getName().matchAsciiL(
248 : RTL_CONSTASCII_STRINGPARAM(
249 35046 : "com.sun.star.beans.Optional<")))
250 : {
251 0 : n = css::beans::PropertyAttribute::MAYBEVOID;
252 : } else {
253 23364 : break;
254 : }
255 0 : if ((attrAttribs & n) != 0) {
256 0 : 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 : "inconsistent UNO type registry"),
270 0 : css::uno::Reference< css::uno::XInterface >());
271 : }
272 0 : t = args[0];
273 0 : }
274 : std::vector< rtl::OUString >::size_type handles
275 11682 : = handleNames->size();
276 11682 : if (handles > SAL_MAX_INT32) {
277 : throw css::uno::RuntimeException(
278 : rtl::OUString(
279 : "interface type has too many attributes"),
280 0 : css::uno::Reference< css::uno::XInterface >());
281 : }
282 23364 : rtl::OUString name(members[i]->getMemberName());
283 23364 : 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 23364 : t->getTypeClass(), t->getName()),
291 : attrAttribs),
292 11682 : (std::find(absentBegin, absentEnd, name)
293 46728 : == absentEnd)))).
294 23364 : second)
295 : {
296 : throw css::uno::RuntimeException(
297 : rtl::OUString(
298 : "inconsistent UNO type registry"),
299 0 : css::uno::Reference< css::uno::XInterface >());
300 : }
301 23364 : handleNames->push_back(name);
302 : }
303 15576 : }
304 19470 : }
305 19470 : }
306 :
307 31152 : css::uno::Reference< css::reflection::XTypeDescription > Data::resolveTypedefs(
308 : css::uno::Reference< css::reflection::XTypeDescription > const & type)
309 : {
310 31152 : css::uno::Reference< css::reflection::XTypeDescription > t(type);
311 62304 : while (t->getTypeClass() == css::uno::TypeClass_TYPEDEF) {
312 0 : t = css::uno::Reference< css::reflection::XIndirectTypeDescription >(
313 0 : t, css::uno::UNO_QUERY_THROW)->getReferencedType();
314 : }
315 31152 : return t;
316 : }
317 :
318 0 : class Info: public cppu::WeakImplHelper1< css::beans::XPropertySetInfo > {
319 : public:
320 0 : explicit Info(Data * data): m_data(data) {}
321 :
322 : virtual css::uno::Sequence< css::beans::Property > SAL_CALL getProperties()
323 : throw (css::uno::RuntimeException);
324 :
325 : virtual css::beans::Property SAL_CALL getPropertyByName(
326 : rtl::OUString const & name)
327 : throw (
328 : css::beans::UnknownPropertyException, css::uno::RuntimeException);
329 :
330 : virtual sal_Bool SAL_CALL hasPropertyByName(rtl::OUString const & name)
331 : throw (css::uno::RuntimeException);
332 :
333 : private:
334 : rtl::Reference< Data > m_data;
335 : };
336 :
337 0 : css::uno::Sequence< css::beans::Property > Info::getProperties()
338 : throw (css::uno::RuntimeException)
339 : {
340 : try {
341 : OSL_ASSERT(m_data->properties.size() <= SAL_MAX_INT32);
342 : css::uno::Sequence< css::beans::Property > s(
343 0 : static_cast< sal_Int32 >(m_data->properties.size()));
344 0 : sal_Int32 n = 0;
345 0 : for (Data::PropertyMap::iterator i(m_data->properties.begin());
346 0 : i != m_data->properties.end(); ++i)
347 : {
348 0 : if (i->second.present) {
349 0 : s[n++] = i->second.property;
350 : }
351 : }
352 0 : s.realloc(n);
353 0 : return s;
354 0 : } catch (std::bad_alloc &) {
355 : //TODO OutOfMemoryException:
356 : throw css::uno::RuntimeException(
357 0 : rtl::OUString(), static_cast< cppu::OWeakObject * >(this));
358 : }
359 : }
360 :
361 0 : css::beans::Property Info::getPropertyByName(rtl::OUString const & name)
362 : throw (css::beans::UnknownPropertyException, css::uno::RuntimeException)
363 : {
364 0 : return m_data->get(static_cast< cppu::OWeakObject * >(this), name)->
365 0 : second.property;
366 : }
367 :
368 0 : sal_Bool Info::hasPropertyByName(rtl::OUString const & name)
369 : throw (css::uno::RuntimeException)
370 : {
371 0 : Data::PropertyMap::iterator i(m_data->properties.find(name));
372 0 : return i != m_data->properties.end() && i->second.present;
373 : }
374 :
375 : typedef
376 : std::multiset< css::uno::Reference< css::beans::XPropertyChangeListener > >
377 : BoundListenerBag;
378 :
379 : }
380 :
381 0 : class PropertySetMixinImpl::BoundListeners::Impl {
382 : public:
383 : BoundListenerBag specificListeners;
384 : BoundListenerBag unspecificListeners;
385 : css::beans::PropertyChangeEvent event;
386 : };
387 :
388 0 : PropertySetMixinImpl::BoundListeners::BoundListeners(): m_impl(new Impl) {}
389 :
390 0 : PropertySetMixinImpl::BoundListeners::~BoundListeners() {
391 0 : delete m_impl;
392 0 : }
393 :
394 0 : void PropertySetMixinImpl::BoundListeners::notify() const {
395 0 : for (BoundListenerBag::const_iterator i(m_impl->specificListeners.begin());
396 0 : i != m_impl->specificListeners.end(); ++i)
397 : {
398 : try {
399 0 : (*i)->propertyChange(m_impl->event);
400 0 : } catch (css::lang::DisposedException &) {}
401 : }
402 0 : for (BoundListenerBag::const_iterator i(
403 0 : m_impl->unspecificListeners.begin());
404 0 : i != m_impl->unspecificListeners.end(); ++i)
405 : {
406 : try {
407 0 : (*i)->propertyChange(m_impl->event);
408 0 : } catch (css::lang::DisposedException &) {}
409 : }
410 0 : }
411 :
412 7766 : 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);
419 :
420 : rtl::OUString translateHandle(
421 : css::uno::Reference< css::uno::XInterface > const & object,
422 : sal_Int32 handle) const;
423 :
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;
429 :
430 : css::uno::Any getProperty(
431 : css::uno::Reference< css::uno::XInterface > const & object,
432 : rtl::OUString const & name, css::beans::PropertyState * state) const;
433 :
434 : PropertySetMixinImpl::Implements implements;
435 : css::uno::Sequence< rtl::OUString > handleMap;
436 :
437 : typedef std::map< rtl::OUString, BoundListenerBag > BoundListenerMap;
438 :
439 : typedef
440 : std::multiset< css::uno::Reference< css::beans::XVetoableChangeListener > >
441 : VetoListenerBag;
442 :
443 : typedef std::map< rtl::OUString, VetoListenerBag > VetoListenerMap;
444 :
445 : mutable osl::Mutex mutex;
446 : BoundListenerMap boundListeners;
447 : VetoListenerMap vetoListeners;
448 : bool disposed;
449 :
450 : private:
451 : css::uno::Reference< css::reflection::XIdlClass > getReflection(
452 : rtl::OUString const & typeName) const;
453 :
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);
460 :
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;
465 : };
466 :
467 3894 : 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 3894 : m_absentOptional(absentOptional), m_type(type)
474 : {
475 : OSL_ASSERT(
476 : context.is()
477 : && ((implements
478 : & ~(IMPLEMENTS_PROPERTY_SET | IMPLEMENTS_FAST_PROPERTY_SET
479 : | IMPLEMENTS_PROPERTY_ACCESS))
480 : == 0));
481 3894 : m_idlClass = getReflection(m_type.getTypeName());
482 3894 : css::uno::Reference< css::reflection::XTypeDescription > ifc;
483 : try {
484 7788 : ifc = css::uno::Reference< css::reflection::XTypeDescription >(
485 : css::uno::Reference< css::container::XHierarchicalNameAccess >(
486 3894 : m_context->getValueByName(
487 : rtl::OUString(
488 : "/singletons/com.sun.star.reflection."
489 3894 : "theTypeDescriptionManager")),
490 7788 : css::uno::UNO_QUERY_THROW)->getByHierarchicalName(
491 3894 : m_type.getTypeName()),
492 3894 : css::uno::UNO_QUERY_THROW);
493 0 : } catch (css::container::NoSuchElementException & e) {
494 : throw css::uno::RuntimeException(
495 : (rtl::OUString(
496 : "unexpected"
497 : " com.sun.star.container.NoSuchElementException: ")
498 0 : + e.Message),
499 0 : css::uno::Reference< css::uno::XInterface >());
500 : }
501 7788 : std::vector< rtl::OUString > handleNames;
502 3894 : initProperties(ifc, m_absentOptional, &handleNames);
503 3894 : std::vector< rtl::OUString >::size_type size = handleNames.size();
504 : OSL_ASSERT(size <= SAL_MAX_INT32);
505 3894 : handleMap.realloc(static_cast< sal_Int32 >(size));
506 7788 : std::copy(handleNames.begin(), handleNames.end(), handleMap.getArray());
507 3894 : }
508 :
509 0 : rtl::OUString PropertySetMixinImpl::Impl::translateHandle(
510 : css::uno::Reference< css::uno::XInterface > const & object,
511 : sal_Int32 handle) const
512 : {
513 0 : if (handle < 0 || handle >= handleMap.getLength()) {
514 : throw css::beans::UnknownPropertyException(
515 : (rtl::OUString("bad handle ")
516 0 : + rtl::OUString::valueOf(handle)),
517 0 : object);
518 : }
519 0 : return handleMap[handle];
520 : }
521 :
522 60 : 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
526 : {
527 60 : PropertyMap::const_iterator i(properties.find(name));
528 60 : if (i == properties.end()) {
529 0 : throw css::beans::UnknownPropertyException(name, object);
530 : }
531 60 : if ((isAmbiguous
532 0 : && ((i->second.property.Attributes
533 0 : & css::beans::PropertyAttribute::MAYBEAMBIGUOUS)
534 : == 0))
535 120 : || (isDefaulted
536 0 : && ((i->second.property.Attributes
537 0 : & css::beans::PropertyAttribute::MAYBEDEFAULT)
538 : == 0)))
539 : {
540 : throw css::lang::IllegalArgumentException(
541 : (rtl::OUString(
542 : "flagging as ambiguous/defaulted non-ambiguous/defaulted"
543 : " property ")
544 0 : + name),
545 0 : object, illegalArgumentPosition);
546 : }
547 : css::uno::Reference< css::reflection::XIdlField2 > f(
548 60 : m_idlClass->getField(name), css::uno::UNO_QUERY_THROW);
549 120 : 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 180 : m_idlClass->getField(name), css::uno::UNO_QUERY_THROW)->
555 60 : getType()),
556 60 : ((i->second.property.Attributes
557 60 : & css::beans::PropertyAttribute::MAYBEAMBIGUOUS)
558 : != 0),
559 : isAmbiguous,
560 60 : ((i->second.property.Attributes
561 60 : & css::beans::PropertyAttribute::MAYBEDEFAULT)
562 : != 0),
563 : isDefaulted,
564 60 : ((i->second.property.Attributes
565 60 : & css::beans::PropertyAttribute::MAYBEVOID)
566 360 : != 0)));
567 : try {
568 60 : f->set(o, v);
569 0 : } catch (css::lang::IllegalArgumentException & e) {
570 0 : if (e.ArgumentPosition == 1) {
571 : throw css::lang::IllegalArgumentException(
572 0 : e.Message, object, illegalArgumentPosition);
573 : } else {
574 : throw css::uno::RuntimeException(
575 : (rtl::OUString(
576 : "unexpected"
577 : " com.sun.star.lang.IllegalArgumentException: ")
578 0 : + e.Message),
579 0 : object);
580 : }
581 0 : } 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 0 : + name),
587 0 : object);
588 0 : } 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 0 : if (e.TargetException.isExtractableTo(
594 : getCppuType(
595 0 : static_cast< css::beans::UnknownPropertyException * >(0)))
596 0 : && ((i->second.property.Attributes
597 0 : & css::beans::PropertyAttribute::OPTIONAL)
598 : != 0))
599 : {
600 0 : throw css::beans::UnknownPropertyException(name, object);
601 0 : } else if (e.TargetException.isExtractableTo(
602 : getCppuType(
603 : static_cast< css::beans::PropertyVetoException * >(
604 0 : 0)))
605 0 : && ((i->second.property.Attributes
606 0 : & css::beans::PropertyAttribute::CONSTRAINED)
607 : != 0))
608 : {
609 0 : css::beans::PropertyVetoException exc;
610 0 : e.TargetException >>= exc;
611 0 : if (exc.Message.isEmpty() )
612 0 : throw css::beans::PropertyVetoException("Invalid " + name, object);
613 : else
614 0 : throw exc;
615 : } else {
616 : throw css::lang::WrappedTargetException(
617 0 : e.Message, object, e.TargetException);
618 : }
619 60 : }
620 60 : }
621 :
622 60 : 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
625 : {
626 60 : PropertyMap::const_iterator i(properties.find(name));
627 60 : if (i == properties.end()) {
628 0 : throw css::beans::UnknownPropertyException(name, object);
629 : }
630 : css::uno::Reference< css::reflection::XIdlField2 > field(
631 60 : m_idlClass->getField(name), css::uno::UNO_QUERY_THROW);
632 60 : css::uno::Any value;
633 : try {
634 60 : value = field->get(object->queryInterface(m_type));
635 0 : } catch (css::lang::IllegalArgumentException & e) {
636 : throw css::uno::RuntimeException(
637 : (rtl::OUString(
638 : "unexpected com.sun.star.lang.IllegalArgumentException: ")
639 0 : + e.Message),
640 0 : object);
641 0 : } 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 0 : if (e.TargetException.isExtractableTo(
647 : getCppuType(
648 0 : static_cast< css::beans::UnknownPropertyException * >(0)))
649 0 : && ((i->second.property.Attributes
650 0 : & css::beans::PropertyAttribute::OPTIONAL)
651 : != 0))
652 : {
653 0 : throw css::beans::UnknownPropertyException(name, object);
654 : } else {
655 : throw css::lang::WrappedTargetException(
656 0 : e.Message, object, e.TargetException);
657 : }
658 : }
659 : bool undoAmbiguous
660 60 : = ((i->second.property.Attributes
661 60 : & css::beans::PropertyAttribute::MAYBEAMBIGUOUS)
662 60 : != 0);
663 : bool undoDefaulted
664 60 : = ((i->second.property.Attributes
665 60 : & css::beans::PropertyAttribute::MAYBEDEFAULT)
666 60 : != 0);
667 : bool undoOptional
668 60 : = ((i->second.property.Attributes
669 60 : & css::beans::PropertyAttribute::MAYBEVOID)
670 60 : != 0);
671 60 : bool isAmbiguous = false;
672 60 : bool isDefaulted = false;
673 120 : while (undoAmbiguous || undoDefaulted || undoOptional) {
674 0 : if (undoAmbiguous
675 0 : && value.getValueTypeName().matchAsciiL(
676 0 : RTL_CONSTASCII_STRINGPARAM("com.sun.star.beans.Ambiguous<")))
677 : {
678 : css::uno::Reference< css::reflection::XIdlClass > ambiguous(
679 0 : getReflection(value.getValueTypeName()));
680 : try {
681 0 : if (!(css::uno::Reference< css::reflection::XIdlField2 >(
682 0 : ambiguous->getField(
683 0 : rtl::OUString("IsAmbiguous")),
684 0 : css::uno::UNO_QUERY_THROW)->get(value)
685 0 : >>= isAmbiguous))
686 : {
687 : throw css::uno::RuntimeException(
688 : rtl::OUString(
689 : "unexpected type of"
690 : " com.sun.star.beans.Ambiguous IsAmbiguous"
691 : " member"),
692 0 : object);
693 : }
694 0 : value = css::uno::Reference< css::reflection::XIdlField2 >(
695 0 : ambiguous->getField(
696 0 : rtl::OUString("Value")),
697 0 : css::uno::UNO_QUERY_THROW)->get(value);
698 0 : } catch (css::lang::IllegalArgumentException & e) {
699 : throw css::uno::RuntimeException(
700 : (rtl::OUString(
701 : "unexpected com.sun.star.lang."
702 : "IllegalArgumentException: ")
703 0 : + e.Message),
704 0 : object);
705 : }
706 0 : undoAmbiguous = false;
707 0 : } else if (undoDefaulted
708 0 : && value.getValueTypeName().matchAsciiL(
709 : RTL_CONSTASCII_STRINGPARAM(
710 0 : "com.sun.star.beans.Defaulted<")))
711 : {
712 : css::uno::Reference< css::reflection::XIdlClass > defaulted(
713 0 : getReflection(value.getValueTypeName()));
714 : try {
715 :
716 0 : if (!(css::uno::Reference< css::reflection::XIdlField2 >(
717 0 : defaulted->getField(
718 0 : rtl::OUString("IsDefaulted")),
719 0 : css::uno::UNO_QUERY_THROW)->get(value)
720 0 : >>= isDefaulted))
721 : {
722 : throw css::uno::RuntimeException(
723 : rtl::OUString(
724 : "unexpected type of"
725 : " com.sun.star.beans.Defaulted IsDefaulted"
726 : " member"),
727 0 : object);
728 : }
729 0 : value = css::uno::Reference< css::reflection::XIdlField2 >(
730 0 : defaulted->getField(
731 0 : rtl::OUString("Value")),
732 0 : css::uno::UNO_QUERY_THROW)->get(value);
733 0 : } catch (css::lang::IllegalArgumentException & e) {
734 : throw css::uno::RuntimeException(
735 : (rtl::OUString(
736 : "unexpected com.sun.star.lang."
737 : "IllegalArgumentException: ")
738 0 : + e.Message),
739 0 : object);
740 : }
741 0 : undoDefaulted = false;
742 0 : } else if (undoOptional
743 0 : && value.getValueTypeName().matchAsciiL(
744 : RTL_CONSTASCII_STRINGPARAM(
745 0 : "com.sun.star.beans.Optional<")))
746 : {
747 : css::uno::Reference< css::reflection::XIdlClass > optional(
748 0 : getReflection(value.getValueTypeName()));
749 : try {
750 0 : bool present = false;
751 0 : if (!(css::uno::Reference< css::reflection::XIdlField2 >(
752 0 : optional->getField(
753 0 : rtl::OUString("IsPresent")),
754 0 : css::uno::UNO_QUERY_THROW)->get(value)
755 0 : >>= present))
756 : {
757 : throw css::uno::RuntimeException(
758 : rtl::OUString(
759 : "unexpected type of com.sun.star.beans.Optional"
760 : " IsPresent member"),
761 0 : object);
762 : }
763 0 : if (!present) {
764 0 : value.clear();
765 0 : break;
766 : }
767 0 : value = css::uno::Reference< css::reflection::XIdlField2 >(
768 0 : optional->getField(
769 0 : rtl::OUString("Value")),
770 0 : css::uno::UNO_QUERY_THROW)->get(value);
771 0 : } catch (css::lang::IllegalArgumentException & e) {
772 : throw css::uno::RuntimeException(
773 : (rtl::OUString(
774 : "unexpected com.sun.star.lang."
775 : "IllegalArgumentException: ")
776 0 : + e.Message),
777 0 : object);
778 : }
779 0 : undoOptional = false;
780 : } else {
781 : throw css::uno::RuntimeException(
782 : (rtl::OUString(
783 : "unexpected type of attribute ")
784 0 : + name),
785 0 : object);
786 : }
787 : }
788 60 : 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 0 : : css::beans::PropertyState_DIRECT_VALUE;
796 : }
797 60 : return value;
798 : }
799 :
800 : css::uno::Reference< css::reflection::XIdlClass >
801 3894 : PropertySetMixinImpl::Impl::getReflection(rtl::OUString const & typeName) const
802 : {
803 : css::uno::Reference< css::lang::XMultiComponentFactory > factory(
804 3894 : m_context->getServiceManager(), css::uno::UNO_QUERY_THROW);
805 7788 : AutoDispose< css::reflection::XIdlReflection > refl;
806 : try {
807 7788 : refl.ifc = css::uno::Reference< css::reflection::XIdlReflection >(
808 3894 : factory->createInstanceWithContext(
809 : rtl::OUString(
810 : "com.sun.star.reflection.CoreReflection"),
811 3894 : m_context),
812 3894 : css::uno::UNO_QUERY_THROW);
813 0 : } catch (css::uno::RuntimeException &) {
814 0 : throw;
815 0 : } 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 0 : + e.Message),
821 0 : m_context);
822 : }
823 : css::uno::Reference< css::reflection::XIdlClass > idlClass(
824 3894 : refl.ifc->forName(typeName), css::uno::UNO_QUERY_THROW);
825 3894 : refl.dispose();
826 7788 : return idlClass;
827 : }
828 :
829 60 : 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)
835 : {
836 : OSL_ASSERT(
837 : (wrapAmbiguous || !isAmbiguous) && (wrapDefaulted || !isDefaulted));
838 180 : if (wrapAmbiguous
839 60 : && type->getName().matchAsciiL(
840 60 : RTL_CONSTASCII_STRINGPARAM("com.sun.star.beans.Ambiguous<")))
841 : {
842 0 : css::uno::Any strct;
843 0 : type->createObject(strct);
844 : try {
845 : css::uno::Reference< css::reflection::XIdlField2 > field(
846 0 : type->getField(
847 0 : rtl::OUString("Value")),
848 0 : css::uno::UNO_QUERY_THROW);
849 0 : field->set(
850 : strct,
851 : wrapValue(
852 0 : object, value, field->getType(), false, false,
853 0 : wrapDefaulted, isDefaulted, wrapOptional));
854 : css::uno::Reference< css::reflection::XIdlField2 >(
855 0 : type->getField(
856 0 : rtl::OUString("IsAmbiguous")),
857 0 : css::uno::UNO_QUERY_THROW)->set(
858 0 : strct, css::uno::makeAny(isAmbiguous));
859 0 : } catch (css::lang::IllegalArgumentException & e) {
860 : throw css::uno::RuntimeException(
861 : (rtl::OUString(
862 : "unexpected"
863 : " com.sun.star.lang.IllegalArgumentException: ")
864 0 : + e.Message),
865 0 : object);
866 0 : } catch (css::lang::IllegalAccessException & e) {
867 : throw css::uno::RuntimeException(
868 : (rtl::OUString(
869 : "unexpected"
870 : " com.sun.star.lang.IllegalAccessException: ")
871 0 : + e.Message),
872 0 : object);
873 : }
874 0 : return strct;
875 180 : } else if (wrapDefaulted
876 60 : && type->getName().matchAsciiL(
877 60 : RTL_CONSTASCII_STRINGPARAM("com.sun.star.beans.Defaulted<")))
878 : {
879 0 : css::uno::Any strct;
880 0 : type->createObject(strct);
881 : try {
882 : css::uno::Reference< css::reflection::XIdlField2 > field(
883 0 : type->getField(
884 0 : rtl::OUString("Value")),
885 0 : css::uno::UNO_QUERY_THROW);
886 0 : field->set(
887 : strct,
888 : wrapValue(
889 0 : object, value, field->getType(), wrapAmbiguous, isAmbiguous,
890 0 : false, false, wrapOptional));
891 : css::uno::Reference< css::reflection::XIdlField2 >(
892 0 : type->getField(
893 0 : rtl::OUString("IsDefaulted")),
894 0 : css::uno::UNO_QUERY_THROW)->set(
895 0 : strct, css::uno::makeAny(isDefaulted));
896 0 : } catch (css::lang::IllegalArgumentException & e) {
897 : throw css::uno::RuntimeException(
898 : (rtl::OUString(
899 : "unexpected"
900 : " com.sun.star.lang.IllegalArgumentException: ")
901 0 : + e.Message),
902 0 : object);
903 0 : } catch (css::lang::IllegalAccessException & e) {
904 : throw css::uno::RuntimeException(
905 : (rtl::OUString(
906 : "unexpected"
907 : " com.sun.star.lang.IllegalAccessException: ")
908 0 : + e.Message),
909 0 : object);
910 : }
911 0 : return strct;
912 180 : } else if (wrapOptional
913 60 : && type->getName().matchAsciiL(
914 60 : RTL_CONSTASCII_STRINGPARAM("com.sun.star.beans.Optional<")))
915 : {
916 0 : css::uno::Any strct;
917 0 : type->createObject(strct);
918 0 : bool present = value.hasValue();
919 : try {
920 : css::uno::Reference< css::reflection::XIdlField2 >(
921 0 : type->getField(
922 0 : rtl::OUString("IsPresent")),
923 0 : css::uno::UNO_QUERY_THROW)->set(
924 0 : strct, css::uno::makeAny(present));
925 0 : if (present) {
926 : css::uno::Reference< css::reflection::XIdlField2 > field(
927 0 : type->getField(
928 0 : rtl::OUString("Value")),
929 0 : css::uno::UNO_QUERY_THROW);
930 0 : field->set(
931 : strct,
932 : wrapValue(
933 0 : object, value, field->getType(), wrapAmbiguous,
934 0 : isAmbiguous, wrapDefaulted, isDefaulted, false));
935 : }
936 0 : } catch (css::lang::IllegalArgumentException & e) {
937 : throw css::uno::RuntimeException(
938 : (rtl::OUString(
939 : "unexpected"
940 : " com.sun.star.lang.IllegalArgumentException: ")
941 0 : + e.Message),
942 0 : object);
943 0 : } catch (css::lang::IllegalAccessException & e) {
944 : throw css::uno::RuntimeException(
945 : (rtl::OUString(
946 : "unexpected"
947 : " com.sun.star.lang.IllegalAccessException: ")
948 0 : + e.Message),
949 0 : object);
950 : }
951 0 : return strct;
952 : } else {
953 60 : if (wrapAmbiguous || wrapDefaulted || wrapOptional) {
954 : throw css::uno::RuntimeException(
955 : rtl::OUString(
956 : "unexpected type of attribute"),
957 0 : object);
958 : }
959 60 : return value;
960 : }
961 : }
962 :
963 3894 : PropertySetMixinImpl::PropertySetMixinImpl(
964 : css::uno::Reference< css::uno::XComponentContext > const & context,
965 : Implements implements,
966 : css::uno::Sequence< rtl::OUString > const & absentOptional,
967 3894 : css::uno::Type const & type)
968 : {
969 3894 : m_impl = new Impl(context, implements, absentOptional, type);
970 3894 : m_impl->acquire();
971 3894 : }
972 :
973 7766 : PropertySetMixinImpl::~PropertySetMixinImpl() {
974 3883 : m_impl->release();
975 3883 : }
976 :
977 0 : void PropertySetMixinImpl::checkUnknown(rtl::OUString const & propertyName) {
978 0 : if (!propertyName.isEmpty()) {
979 : m_impl->get(
980 0 : static_cast< css::beans::XPropertySet * >(this), propertyName);
981 : }
982 0 : }
983 :
984 0 : void PropertySetMixinImpl::prepareSet(
985 : rtl::OUString const & propertyName, css::uno::Any const & oldValue,
986 : css::uno::Any const & newValue, BoundListeners * boundListeners)
987 : {
988 0 : Impl::PropertyMap::const_iterator it(m_impl->properties.find(propertyName));
989 : OSL_ASSERT(it != m_impl->properties.end());
990 0 : Impl::VetoListenerBag specificVeto;
991 0 : Impl::VetoListenerBag unspecificVeto;
992 : {
993 0 : osl::MutexGuard g(m_impl->mutex);
994 0 : if (m_impl->disposed) {
995 : throw css::lang::DisposedException(
996 : rtl::OUString("disposed"),
997 0 : static_cast< css::beans::XPropertySet * >(this));
998 : }
999 0 : if ((it->second.property.Attributes
1000 0 : & css::beans::PropertyAttribute::CONSTRAINED)
1001 : != 0)
1002 : {
1003 : Impl::VetoListenerMap::const_iterator i(
1004 0 : m_impl->vetoListeners.find(propertyName));
1005 0 : if (i != m_impl->vetoListeners.end()) {
1006 0 : specificVeto = i->second;
1007 : }
1008 0 : i = m_impl->vetoListeners.find(rtl::OUString());
1009 0 : if (i != m_impl->vetoListeners.end()) {
1010 0 : unspecificVeto = i->second;
1011 : }
1012 : }
1013 0 : if ((it->second.property.Attributes
1014 0 : & css::beans::PropertyAttribute::BOUND)
1015 : != 0)
1016 : {
1017 : OSL_ASSERT(boundListeners != 0);
1018 : Impl::BoundListenerMap::const_iterator i(
1019 0 : m_impl->boundListeners.find(propertyName));
1020 0 : if (i != m_impl->boundListeners.end()) {
1021 0 : boundListeners->m_impl->specificListeners = i->second;
1022 : }
1023 0 : i = m_impl->boundListeners.find(rtl::OUString());
1024 0 : if (i != m_impl->boundListeners.end()) {
1025 0 : boundListeners->m_impl->unspecificListeners = i->second;
1026 : }
1027 0 : }
1028 : }
1029 0 : if ((it->second.property.Attributes
1030 0 : & css::beans::PropertyAttribute::CONSTRAINED)
1031 : != 0)
1032 : {
1033 : css::beans::PropertyChangeEvent event(
1034 : static_cast< css::beans::XPropertySet * >(this), propertyName,
1035 0 : false, it->second.property.Handle, oldValue, newValue);
1036 0 : for (Impl::VetoListenerBag::iterator i(specificVeto.begin());
1037 0 : i != specificVeto.end(); ++i)
1038 : {
1039 : try {
1040 0 : (*i)->vetoableChange(event);
1041 0 : } catch (css::lang::DisposedException &) {}
1042 : }
1043 0 : for (Impl::VetoListenerBag::iterator i(unspecificVeto.begin());
1044 0 : i != unspecificVeto.end(); ++i)
1045 : {
1046 : try {
1047 0 : (*i)->vetoableChange(event);
1048 0 : } catch (css::lang::DisposedException &) {}
1049 0 : }
1050 : }
1051 0 : if ((it->second.property.Attributes & css::beans::PropertyAttribute::BOUND)
1052 : != 0)
1053 : {
1054 : OSL_ASSERT(boundListeners != 0);
1055 0 : boundListeners->m_impl->event = css::beans::PropertyChangeEvent(
1056 : static_cast< css::beans::XPropertySet * >(this), propertyName,
1057 0 : false, it->second.property.Handle, oldValue, newValue);
1058 0 : }
1059 0 : }
1060 :
1061 0 : void PropertySetMixinImpl::dispose() {
1062 0 : Impl::BoundListenerMap boundListeners;
1063 0 : Impl::VetoListenerMap vetoListeners;
1064 : {
1065 0 : osl::MutexGuard g(m_impl->mutex);
1066 0 : boundListeners.swap(m_impl->boundListeners);
1067 0 : vetoListeners.swap(m_impl->vetoListeners);
1068 0 : m_impl->disposed = true;
1069 : }
1070 : css::lang::EventObject event(
1071 0 : static_cast< css::beans::XPropertySet * >(this));
1072 0 : for (Impl::BoundListenerMap::iterator i(boundListeners.begin());
1073 0 : i != boundListeners.end(); ++i)
1074 : {
1075 0 : for (BoundListenerBag::iterator j(i->second.begin());
1076 0 : j != i->second.end(); ++j)
1077 : {
1078 0 : (*j)->disposing(event);
1079 : }
1080 : }
1081 0 : for (Impl::VetoListenerMap::iterator i(vetoListeners.begin());
1082 0 : i != vetoListeners.end(); ++i)
1083 : {
1084 0 : for (Impl::VetoListenerBag::iterator j(i->second.begin());
1085 0 : j != i->second.end(); ++j)
1086 : {
1087 0 : (*j)->disposing(event);
1088 : }
1089 0 : }
1090 0 : }
1091 :
1092 582 : css::uno::Any PropertySetMixinImpl::queryInterface(css::uno::Type const & type)
1093 : throw (css::uno::RuntimeException)
1094 : {
1095 1164 : if (((m_impl->implements & IMPLEMENTS_PROPERTY_SET) != 0
1096 582 : && type == css::beans::XPropertySet::static_type()))
1097 : {
1098 : css::uno::Reference< css::uno::XInterface > ifc(
1099 60 : static_cast< css::beans::XPropertySet * >(this));
1100 60 : return css::uno::Any(&ifc, type);
1101 1044 : } else if ((m_impl->implements & IMPLEMENTS_FAST_PROPERTY_SET) != 0
1102 522 : && type == css::beans::XFastPropertySet::static_type())
1103 : {
1104 : css::uno::Reference< css::uno::XInterface > ifc(
1105 0 : static_cast< css::beans::XFastPropertySet * >(this));
1106 0 : return css::uno::Any(&ifc, type);
1107 1044 : } else if ((m_impl->implements & IMPLEMENTS_PROPERTY_ACCESS) != 0
1108 522 : && type == css::beans::XPropertyAccess::static_type())
1109 : {
1110 : css::uno::Reference< css::uno::XInterface > ifc(
1111 0 : static_cast< css::beans::XPropertyAccess * >(this));
1112 0 : return css::uno::Any(&ifc, type);
1113 : } else {
1114 522 : return css::uno::Any();
1115 : }
1116 : }
1117 :
1118 : css::uno::Reference< css::beans::XPropertySetInfo >
1119 0 : PropertySetMixinImpl::getPropertySetInfo() throw (css::uno::RuntimeException) {
1120 : try {
1121 0 : return new Info(m_impl);
1122 0 : } catch (std::bad_alloc &) {
1123 : //TODO OutOfMemoryException:
1124 : throw css::uno::RuntimeException(
1125 0 : rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1126 : }
1127 : }
1128 :
1129 60 : 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)
1135 : {
1136 : try {
1137 : m_impl->setProperty(
1138 : static_cast< css::beans::XPropertySet * >(this), propertyName,
1139 60 : value, false, false, 1);
1140 0 : } catch (std::bad_alloc &) {
1141 : //TODO OutOfMemoryException:
1142 : throw css::uno::RuntimeException(
1143 0 : rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1144 : }
1145 60 : }
1146 :
1147 60 : css::uno::Any PropertySetMixinImpl::getPropertyValue(
1148 : rtl::OUString const & propertyName)
1149 : throw (
1150 : css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
1151 : css::uno::RuntimeException)
1152 : {
1153 : try {
1154 : return m_impl->getProperty(
1155 60 : static_cast< css::beans::XPropertySet * >(this), propertyName, 0);
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 0 : 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)
1169 : {
1170 : css::uno::Reference< css::beans::XPropertyChangeListener >(
1171 0 : listener, css::uno::UNO_QUERY_THROW); // reject NULL listener
1172 0 : checkUnknown(propertyName);
1173 : try {
1174 : bool disposed;
1175 : {
1176 0 : osl::MutexGuard g(m_impl->mutex);
1177 0 : disposed = m_impl->disposed;
1178 0 : if (!disposed) {
1179 0 : m_impl->boundListeners[propertyName].insert(listener);
1180 0 : }
1181 : }
1182 0 : if (disposed) {
1183 0 : listener->disposing(
1184 : css::lang::EventObject(
1185 0 : static_cast< css::beans::XPropertySet * >(this)));
1186 : }
1187 0 : } catch (std::bad_alloc &) {
1188 : //TODO OutOfMemoryException:
1189 : throw css::uno::RuntimeException(
1190 0 : rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1191 : }
1192 0 : }
1193 :
1194 0 : 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)
1200 : {
1201 : OSL_ASSERT(listener.is());
1202 0 : checkUnknown(propertyName);
1203 : try {
1204 0 : osl::MutexGuard g(m_impl->mutex);
1205 : Impl::BoundListenerMap::iterator i(
1206 0 : m_impl->boundListeners.find(propertyName));
1207 0 : if (i != m_impl->boundListeners.end()) {
1208 0 : BoundListenerBag::iterator j(i->second.find(listener));
1209 0 : if (j != i->second.end()) {
1210 0 : i->second.erase(j);
1211 : }
1212 0 : }
1213 0 : } catch (std::bad_alloc &) {
1214 : //TODO OutOfMemoryException:
1215 : throw css::uno::RuntimeException(
1216 0 : rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1217 : }
1218 0 : }
1219 :
1220 0 : 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)
1226 : {
1227 : css::uno::Reference< css::beans::XVetoableChangeListener >(
1228 0 : listener, css::uno::UNO_QUERY_THROW); // reject NULL listener
1229 0 : checkUnknown(propertyName);
1230 : try {
1231 : bool disposed;
1232 : {
1233 0 : osl::MutexGuard g(m_impl->mutex);
1234 0 : disposed = m_impl->disposed;
1235 0 : if (!disposed) {
1236 0 : m_impl->vetoListeners[propertyName].insert(listener);
1237 0 : }
1238 : }
1239 0 : if (disposed) {
1240 0 : listener->disposing(
1241 : css::lang::EventObject(
1242 0 : static_cast< css::beans::XPropertySet * >(this)));
1243 : }
1244 0 : } catch (std::bad_alloc &) {
1245 : //TODO OutOfMemoryException:
1246 : throw css::uno::RuntimeException(
1247 0 : rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1248 : }
1249 0 : }
1250 :
1251 0 : 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)
1257 : {
1258 : OSL_ASSERT(listener.is());
1259 0 : checkUnknown(propertyName);
1260 : try {
1261 0 : osl::MutexGuard g(m_impl->mutex);
1262 : Impl::VetoListenerMap::iterator i(
1263 0 : m_impl->vetoListeners.find(propertyName));
1264 0 : if (i != m_impl->vetoListeners.end()) {
1265 0 : Impl::VetoListenerBag::iterator j(i->second.find(listener));
1266 0 : if (j != i->second.end()) {
1267 0 : i->second.erase(j);
1268 : }
1269 0 : }
1270 0 : } catch (std::bad_alloc &) {
1271 : //TODO OutOfMemoryException:
1272 : throw css::uno::RuntimeException(
1273 0 : rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1274 : }
1275 0 : }
1276 :
1277 0 : 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)
1283 : {
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 0 : value, false, false, 1);
1290 0 : } catch (std::bad_alloc &) {
1291 : //TODO OutOfMemoryException:
1292 : throw css::uno::RuntimeException(
1293 0 : rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1294 : }
1295 0 : }
1296 :
1297 0 : css::uno::Any PropertySetMixinImpl::getFastPropertyValue(sal_Int32 handle)
1298 : throw (
1299 : css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
1300 : css::uno::RuntimeException)
1301 : {
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),
1307 0 : 0);
1308 0 : } catch (std::bad_alloc &) {
1309 : //TODO OutOfMemoryException:
1310 : throw css::uno::RuntimeException(
1311 0 : rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1312 : }
1313 : }
1314 :
1315 : css::uno::Sequence< css::beans::PropertyValue >
1316 0 : PropertySetMixinImpl::getPropertyValues() throw (css::uno::RuntimeException) {
1317 : try {
1318 : css::uno::Sequence< css::beans::PropertyValue > s(
1319 0 : m_impl->handleMap.getLength());
1320 0 : sal_Int32 n = 0;
1321 0 : for (sal_Int32 i = 0; i < m_impl->handleMap.getLength(); ++i) {
1322 : try {
1323 0 : s[n].Value = m_impl->getProperty(
1324 : static_cast< css::beans::XPropertySet * >(this),
1325 0 : m_impl->handleMap[i], &s[n].State);
1326 0 : } catch (css::beans::UnknownPropertyException &) {
1327 0 : continue;
1328 0 : } catch (css::lang::WrappedTargetException & e) {
1329 : throw css::lang::WrappedTargetRuntimeException(
1330 : e.Message, static_cast< css::beans::XPropertySet * >(this),
1331 0 : e.TargetException);
1332 : }
1333 0 : s[n].Name = m_impl->handleMap[i];
1334 0 : s[n].Handle = i;
1335 0 : ++n;
1336 : }
1337 0 : s.realloc(n);
1338 0 : return s;
1339 0 : } catch (std::bad_alloc &) {
1340 : //TODO OutOfMemoryException:
1341 : throw css::uno::RuntimeException(
1342 0 : rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1343 : }
1344 : }
1345 :
1346 0 : 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)
1352 : {
1353 : try {
1354 0 : for (sal_Int32 i = 0; i < props.getLength(); ++i) {
1355 0 : if (props[i].Handle != -1
1356 0 : && (props[i].Name
1357 0 : != m_impl->translateHandle(
1358 : static_cast< css::beans::XPropertySet * >(this),
1359 0 : props[i].Handle)))
1360 : {
1361 : throw css::beans::UnknownPropertyException(
1362 : (rtl::OUString("name ")
1363 0 : + props[i].Name
1364 0 : + rtl::OUString(" does not match handle ")
1365 0 : + rtl::OUString::valueOf(props[i].Handle)),
1366 0 : static_cast< css::beans::XPropertySet * >(this));
1367 : }
1368 : m_impl->setProperty(
1369 0 : static_cast< css::beans::XPropertySet * >(this), props[i].Name,
1370 0 : props[i].Value,
1371 0 : props[i].State == css::beans::PropertyState_AMBIGUOUS_VALUE,
1372 0 : props[i].State == css::beans::PropertyState_DEFAULT_VALUE, 0);
1373 : }
1374 0 : } catch (std::bad_alloc &) {
1375 : //TODO OutOfMemoryException:
1376 : throw css::uno::RuntimeException(
1377 0 : rtl::OUString(), static_cast< css::beans::XPropertySet * >(this));
1378 : }
1379 0 : }
1380 :
1381 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|