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 : #include <sal/config.h>
21 :
22 : #include <algorithm>
23 : #include <cassert>
24 : #include <exception>
25 : #include <map>
26 : #include <set>
27 : #include <vector>
28 :
29 : #include <com/sun/star/beans/Property.hpp>
30 : #include <com/sun/star/beans/PropertyChangeEvent.hpp>
31 : #include <com/sun/star/beans/PropertyAttribute.hpp>
32 : #include <com/sun/star/beans/PropertyValue.hpp>
33 : #include <com/sun/star/beans/PropertyVetoException.hpp>
34 : #include <com/sun/star/beans/UnknownPropertyException.hpp>
35 : #include <com/sun/star/beans/XFastPropertySet.hpp>
36 : #include <com/sun/star/beans/XPropertyAccess.hpp>
37 : #include <com/sun/star/beans/XPropertyChangeListener.hpp>
38 : #include <com/sun/star/beans/XPropertySet.hpp>
39 : #include <com/sun/star/beans/XPropertySetInfo.hpp>
40 : #include <com/sun/star/beans/XVetoableChangeListener.hpp>
41 : #include <com/sun/star/container/NoSuchElementException.hpp>
42 : #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
43 : #include <com/sun/star/lang/DisposedException.hpp>
44 : #include <com/sun/star/lang/EventObject.hpp>
45 : #include <com/sun/star/lang/IllegalAccessException.hpp>
46 : #include <com/sun/star/lang/IllegalArgumentException.hpp>
47 : #include <com/sun/star/lang/WrappedTargetException.hpp>
48 : #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
49 : #include <com/sun/star/reflection/XCompoundTypeDescription.hpp>
50 : #include <com/sun/star/reflection/XIdlClass.hpp>
51 : #include <com/sun/star/reflection/XIdlField2.hpp>
52 : #include <com/sun/star/reflection/XIndirectTypeDescription.hpp>
53 : #include <com/sun/star/reflection/XInterfaceAttributeTypeDescription2.hpp>
54 : #include <com/sun/star/reflection/XInterfaceMemberTypeDescription.hpp>
55 : #include <com/sun/star/reflection/XInterfaceTypeDescription2.hpp>
56 : #include <com/sun/star/reflection/XStructTypeDescription.hpp>
57 : #include <com/sun/star/reflection/XTypeDescription.hpp>
58 : #include <com/sun/star/reflection/theCoreReflection.hpp>
59 : #include <com/sun/star/uno/Any.hxx>
60 : #include <com/sun/star/uno/DeploymentException.hpp>
61 : #include <com/sun/star/uno/Exception.hpp>
62 : #include <com/sun/star/uno/Reference.hxx>
63 : #include <com/sun/star/uno/RuntimeException.hpp>
64 : #include <com/sun/star/uno/Sequence.hxx>
65 : #include <com/sun/star/uno/Type.hxx>
66 : #include <com/sun/star/uno/TypeClass.hpp>
67 : #include <com/sun/star/uno/XComponentContext.hpp>
68 : #include <com/sun/star/uno/XInterface.hpp>
69 : #include <cppuhelper/implbase1.hxx>
70 : #include <cppuhelper/propertysetmixin.hxx>
71 : #include <cppuhelper/weak.hxx>
72 : #include <osl/mutex.hxx>
73 : #include <rtl/ref.hxx>
74 : #include <rtl/ustring.hxx>
75 : #include <sal/types.h>
76 : #include <salhelper/simplereferenceobject.hxx>
77 :
78 : using cppu::PropertySetMixinImpl;
79 :
80 : namespace {
81 :
82 151974 : struct PropertyData {
83 30402 : explicit PropertyData(
84 : css::beans::Property const & theProperty, bool thePresent):
85 30402 : property(theProperty), present(thePresent) {}
86 :
87 : css::beans::Property property;
88 : bool present;
89 : };
90 :
91 19962 : struct Data: public salhelper::SimpleReferenceObject {
92 : typedef std::map< rtl::OUString, PropertyData > PropertyMap;
93 :
94 : PropertyMap properties;
95 :
96 : PropertyMap::const_iterator get(
97 : css::uno::Reference< css::uno::XInterface > const & object,
98 : rtl::OUString const & name) const;
99 :
100 : protected:
101 9987 : void initProperties(
102 : css::uno::Reference< css::reflection::XTypeDescription > const & type,
103 : css::uno::Sequence< rtl::OUString > const & absentOptional,
104 : std::vector< rtl::OUString > * handleNames)
105 : {
106 9987 : TypeSet seen;
107 9987 : initProperties(type, absentOptional, handleNames, &seen);
108 9987 : }
109 :
110 : private:
111 : typedef std::set< rtl::OUString > TypeSet;
112 :
113 : void initProperties(
114 : css::uno::Reference< css::reflection::XTypeDescription > const & type,
115 : css::uno::Sequence< rtl::OUString > const & absentOptional,
116 : std::vector< rtl::OUString > * handleNames, TypeSet * seen);
117 :
118 : static css::uno::Reference< css::reflection::XTypeDescription >
119 : resolveTypedefs(
120 : css::uno::Reference< css::reflection::XTypeDescription > const & type);
121 : };
122 :
123 0 : Data::PropertyMap::const_iterator Data::get(
124 : css::uno::Reference< css::uno::XInterface > const & object,
125 : rtl::OUString const & name) const
126 : {
127 0 : PropertyMap::const_iterator i(properties.find(name));
128 0 : if (i == properties.end() || !i->second.present) {
129 0 : throw css::beans::UnknownPropertyException(name, object);
130 : }
131 0 : return i;
132 : }
133 :
134 50029 : void Data::initProperties(
135 : css::uno::Reference< css::reflection::XTypeDescription > const & type,
136 : css::uno::Sequence< rtl::OUString > const & absentOptional,
137 : std::vector< rtl::OUString > * handleNames, TypeSet * seen)
138 : {
139 : css::uno::Reference< css::reflection::XInterfaceTypeDescription2 > ifc(
140 50029 : resolveTypedefs(type), css::uno::UNO_QUERY_THROW);
141 50029 : if (seen->insert(ifc->getName()).second) {
142 : css::uno::Sequence<
143 : css::uno::Reference< css::reflection::XTypeDescription > > bases(
144 40010 : ifc->getBaseTypes());
145 80052 : for (sal_Int32 i = 0; i < bases.getLength(); ++i) {
146 40042 : initProperties(bases[i], absentOptional, handleNames, seen);
147 : }
148 : css::uno::Sequence<
149 : css::uno::Reference<
150 : css::reflection::XInterfaceMemberTypeDescription > > members(
151 80020 : ifc->getMembers());
152 40010 : rtl::OUString const * absentBegin = absentOptional.getConstArray();
153 : rtl::OUString const * absentEnd =
154 40010 : absentBegin + absentOptional.getLength();
155 150442 : for (sal_Int32 i = 0; i < members.getLength(); ++i) {
156 110432 : if (members[i]->getTypeClass()
157 : == css::uno::TypeClass_INTERFACE_ATTRIBUTE)
158 : {
159 : css::uno::Reference<
160 : css::reflection::XInterfaceAttributeTypeDescription2 > attr(
161 30402 : members[i], css::uno::UNO_QUERY_THROW);
162 30402 : sal_Int16 attrAttribs = 0;
163 30402 : if (attr->isBound()) {
164 457 : attrAttribs |= css::beans::PropertyAttribute::BOUND;
165 : }
166 30402 : bool setUnknown = false;
167 30402 : if (attr->isReadOnly()) {
168 19963 : attrAttribs |= css::beans::PropertyAttribute::READONLY;
169 19963 : setUnknown = true;
170 : }
171 : css::uno::Sequence<
172 : css::uno::Reference<
173 : css::reflection::XCompoundTypeDescription > > excs(
174 60804 : attr->getGetExceptions());
175 30402 : bool getUnknown = false;
176 : //XXX Special interpretation of getter/setter exceptions only
177 : // works if the specified exceptions are of the exact type, not
178 : // of a supertype:
179 30402 : for (sal_Int32 j = 0; j < excs.getLength(); ++j) {
180 407 : if ( excs[j]->getName() == "com.sun.star.beans.UnknownPropertyException" )
181 : {
182 407 : getUnknown = true;
183 407 : break;
184 : }
185 : }
186 30402 : excs = attr->getSetExceptions();
187 30848 : for (sal_Int32 j = 0; j < excs.getLength(); ++j) {
188 446 : if ( excs[j]->getName() == "com.sun.star.beans.UnknownPropertyException" )
189 : {
190 407 : setUnknown = true;
191 39 : } else if ( excs[j]->getName() == "com.sun.star.beans.PropertyVetoException" )
192 : {
193 : attrAttribs
194 15 : |= css::beans::PropertyAttribute::CONSTRAINED;
195 : }
196 : }
197 30402 : if (getUnknown && setUnknown) {
198 407 : attrAttribs |= css::beans::PropertyAttribute::OPTIONAL;
199 : }
200 : css::uno::Reference< css::reflection::XTypeDescription > t(
201 60804 : attr->getType());
202 : for (;;)
203 : {
204 30403 : t = resolveTypedefs(t);
205 : sal_Int16 n;
206 91209 : if (t->getName().startsWith(
207 60806 : "com.sun.star.beans.Ambiguous<"))
208 : {
209 0 : n = css::beans::PropertyAttribute::MAYBEAMBIGUOUS;
210 91209 : } else if (t->getName().startsWith(
211 60806 : "com.sun.star.beans.Defaulted<"))
212 : {
213 0 : n = css::beans::PropertyAttribute::MAYBEDEFAULT;
214 91209 : } else if (t->getName().startsWith(
215 60806 : "com.sun.star.beans.Optional<"))
216 : {
217 1 : n = css::beans::PropertyAttribute::MAYBEVOID;
218 : } else {
219 60804 : break;
220 : }
221 1 : if ((attrAttribs & n) != 0) {
222 0 : break;
223 : }
224 1 : attrAttribs |= n;
225 : css::uno::Sequence<
226 : css::uno::Reference< css::reflection::XTypeDescription > >
227 : args(
228 : css::uno::Reference<
229 : css::reflection::XStructTypeDescription >(
230 2 : t, css::uno::UNO_QUERY_THROW)->
231 1 : getTypeArguments());
232 1 : if (args.getLength() != 1) {
233 : throw css::uno::RuntimeException(
234 0 : "inconsistent UNO type registry");
235 : }
236 1 : t = args[0];
237 1 : }
238 : std::vector< rtl::OUString >::size_type handles
239 30402 : = handleNames->size();
240 30402 : if (handles > SAL_MAX_INT32) {
241 : throw css::uno::RuntimeException(
242 0 : "interface type has too many attributes");
243 : }
244 60804 : rtl::OUString name(members[i]->getMemberName());
245 60804 : if (!properties.insert(
246 : PropertyMap::value_type(
247 : name,
248 : PropertyData(
249 : css::beans::Property(
250 : name, static_cast< sal_Int32 >(handles),
251 : css::uno::Type(
252 60804 : t->getTypeClass(), t->getName()),
253 : attrAttribs),
254 30402 : (std::find(absentBegin, absentEnd, name)
255 121608 : == absentEnd)))).
256 30402 : second)
257 : {
258 : throw css::uno::RuntimeException(
259 0 : "inconsistent UNO type registry");
260 : }
261 60804 : handleNames->push_back(name);
262 : }
263 40010 : }
264 50029 : }
265 50029 : }
266 :
267 80432 : css::uno::Reference< css::reflection::XTypeDescription > Data::resolveTypedefs(
268 : css::uno::Reference< css::reflection::XTypeDescription > const & type)
269 : {
270 80432 : css::uno::Reference< css::reflection::XTypeDescription > t(type);
271 160883 : while (t->getTypeClass() == css::uno::TypeClass_TYPEDEF) {
272 38 : t = css::uno::Reference< css::reflection::XIndirectTypeDescription >(
273 57 : t, css::uno::UNO_QUERY_THROW)->getReferencedType();
274 : }
275 80432 : return t;
276 : }
277 :
278 0 : class Info: public cppu::WeakImplHelper1< css::beans::XPropertySetInfo > {
279 : public:
280 0 : explicit Info(Data * data): m_data(data) {}
281 :
282 : virtual css::uno::Sequence< css::beans::Property > SAL_CALL getProperties()
283 : throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
284 :
285 : virtual css::beans::Property SAL_CALL getPropertyByName(
286 : rtl::OUString const & name)
287 : throw (
288 : css::beans::UnknownPropertyException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
289 :
290 : virtual sal_Bool SAL_CALL hasPropertyByName(rtl::OUString const & name)
291 : throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
292 :
293 : private:
294 : rtl::Reference< Data > m_data;
295 : };
296 :
297 0 : css::uno::Sequence< css::beans::Property > Info::getProperties()
298 : throw (css::uno::RuntimeException, std::exception)
299 : {
300 : assert(m_data->properties.size() <= SAL_MAX_INT32);
301 : css::uno::Sequence< css::beans::Property > s(
302 0 : static_cast< sal_Int32 >(m_data->properties.size()));
303 0 : sal_Int32 n = 0;
304 0 : for (Data::PropertyMap::iterator i(m_data->properties.begin());
305 0 : i != m_data->properties.end(); ++i)
306 : {
307 0 : if (i->second.present) {
308 0 : s[n++] = i->second.property;
309 : }
310 : }
311 0 : s.realloc(n);
312 0 : return s;
313 : }
314 :
315 0 : css::beans::Property Info::getPropertyByName(rtl::OUString const & name)
316 : throw (css::beans::UnknownPropertyException, css::uno::RuntimeException, std::exception)
317 : {
318 0 : return m_data->get(static_cast< cppu::OWeakObject * >(this), name)->
319 0 : second.property;
320 : }
321 :
322 0 : sal_Bool Info::hasPropertyByName(rtl::OUString const & name)
323 : throw (css::uno::RuntimeException, std::exception)
324 : {
325 0 : Data::PropertyMap::iterator i(m_data->properties.find(name));
326 0 : return i != m_data->properties.end() && i->second.present;
327 : }
328 :
329 : typedef
330 : std::multiset< css::uno::Reference< css::beans::XPropertyChangeListener > >
331 : BoundListenerBag;
332 :
333 : }
334 :
335 0 : class PropertySetMixinImpl::BoundListeners::Impl {
336 : public:
337 : BoundListenerBag specificListeners;
338 : BoundListenerBag unspecificListeners;
339 : css::beans::PropertyChangeEvent event;
340 : };
341 :
342 0 : PropertySetMixinImpl::BoundListeners::BoundListeners(): m_impl(new Impl) {}
343 :
344 0 : PropertySetMixinImpl::BoundListeners::~BoundListeners() {
345 0 : delete m_impl;
346 0 : }
347 :
348 0 : void PropertySetMixinImpl::BoundListeners::notify() const {
349 0 : for (BoundListenerBag::const_iterator i(m_impl->specificListeners.begin());
350 0 : i != m_impl->specificListeners.end(); ++i)
351 : {
352 : try {
353 0 : (*i)->propertyChange(m_impl->event);
354 0 : } catch (css::lang::DisposedException &) {}
355 : }
356 0 : for (BoundListenerBag::const_iterator i(
357 0 : m_impl->unspecificListeners.begin());
358 0 : i != m_impl->unspecificListeners.end(); ++i)
359 : {
360 : try {
361 0 : (*i)->propertyChange(m_impl->event);
362 0 : } catch (css::lang::DisposedException &) {}
363 : }
364 0 : }
365 :
366 19950 : class PropertySetMixinImpl::Impl: public Data {
367 : public:
368 : Impl(
369 : css::uno::Reference< css::uno::XComponentContext > const & context,
370 : Implements theImplements,
371 : css::uno::Sequence< rtl::OUString > const & absentOptional,
372 : css::uno::Type const & type);
373 :
374 : rtl::OUString translateHandle(
375 : css::uno::Reference< css::uno::XInterface > const & object,
376 : sal_Int32 handle) const;
377 :
378 : void setProperty(
379 : css::uno::Reference< css::uno::XInterface > const & object,
380 : rtl::OUString const & name, css::uno::Any const & value,
381 : bool isAmbiguous, bool isDefaulted, sal_Int16 illegalArgumentPosition)
382 : const;
383 :
384 : css::uno::Any getProperty(
385 : css::uno::Reference< css::uno::XInterface > const & object,
386 : rtl::OUString const & name, css::beans::PropertyState * state) const;
387 :
388 : PropertySetMixinImpl::Implements implements;
389 : css::uno::Sequence< rtl::OUString > handleMap;
390 :
391 : typedef std::map< rtl::OUString, BoundListenerBag > BoundListenerMap;
392 :
393 : typedef
394 : std::multiset< css::uno::Reference< css::beans::XVetoableChangeListener > >
395 : VetoListenerBag;
396 :
397 : typedef std::map< rtl::OUString, VetoListenerBag > VetoListenerMap;
398 :
399 : mutable osl::Mutex mutex;
400 : BoundListenerMap boundListeners;
401 : VetoListenerMap vetoListeners;
402 : bool disposed;
403 :
404 : private:
405 : css::uno::Reference< css::reflection::XIdlClass > getReflection(
406 : rtl::OUString const & typeName) const;
407 :
408 : static css::uno::Any wrapValue(
409 : css::uno::Reference< css::uno::XInterface > const & object,
410 : css::uno::Any const & value,
411 : css::uno::Reference< css::reflection::XIdlClass > const & type,
412 : bool wrapAmbiguous, bool isAmbiguous, bool wrapDefaulted,
413 : bool isDefaulted, bool wrapOptional);
414 :
415 : css::uno::Reference< css::uno::XComponentContext > const & m_context;
416 : css::uno::Sequence< rtl::OUString > m_absentOptional;
417 : css::uno::Type m_type;
418 : css::uno::Reference< css::reflection::XIdlClass > m_idlClass;
419 : };
420 :
421 9987 : PropertySetMixinImpl::Impl::Impl(
422 : css::uno::Reference< css::uno::XComponentContext > const & context,
423 : Implements theImplements,
424 : css::uno::Sequence< rtl::OUString > const & absentOptional,
425 : css::uno::Type const & type):
426 : implements(theImplements), disposed(false), m_context(context),
427 9987 : m_absentOptional(absentOptional), m_type(type)
428 : {
429 : assert(context.is());
430 : assert(
431 : (implements
432 : & ~(IMPLEMENTS_PROPERTY_SET | IMPLEMENTS_FAST_PROPERTY_SET
433 : | IMPLEMENTS_PROPERTY_ACCESS))
434 : == 0);
435 9987 : m_idlClass = getReflection(m_type.getTypeName());
436 9987 : css::uno::Reference< css::reflection::XTypeDescription > ifc;
437 : try {
438 19974 : ifc = css::uno::Reference< css::reflection::XTypeDescription >(
439 : css::uno::Reference< css::container::XHierarchicalNameAccess >(
440 9987 : m_context->getValueByName(
441 : "/singletons/com.sun.star.reflection."
442 9987 : "theTypeDescriptionManager"),
443 19974 : css::uno::UNO_QUERY_THROW)->getByHierarchicalName(
444 9987 : m_type.getTypeName()),
445 9987 : css::uno::UNO_QUERY_THROW);
446 0 : } catch (css::container::NoSuchElementException & e) {
447 : throw css::uno::RuntimeException(
448 : "unexpected com.sun.star.container.NoSuchElementException: "
449 0 : + e.Message);
450 : }
451 19974 : std::vector< rtl::OUString > handleNames;
452 9987 : initProperties(ifc, m_absentOptional, &handleNames);
453 9987 : std::vector< rtl::OUString >::size_type size = handleNames.size();
454 : assert(size <= SAL_MAX_INT32);
455 9987 : handleMap.realloc(static_cast< sal_Int32 >(size));
456 19974 : std::copy(handleNames.begin(), handleNames.end(), handleMap.getArray());
457 9987 : }
458 :
459 0 : rtl::OUString PropertySetMixinImpl::Impl::translateHandle(
460 : css::uno::Reference< css::uno::XInterface > const & object,
461 : sal_Int32 handle) const
462 : {
463 0 : if (handle < 0 || handle >= handleMap.getLength()) {
464 : throw css::beans::UnknownPropertyException(
465 0 : "bad handle " + rtl::OUString::number(handle), object);
466 : }
467 0 : return handleMap[handle];
468 : }
469 :
470 851 : void PropertySetMixinImpl::Impl::setProperty(
471 : css::uno::Reference< css::uno::XInterface > const & object,
472 : rtl::OUString const & name, css::uno::Any const & value, bool isAmbiguous,
473 : bool isDefaulted, sal_Int16 illegalArgumentPosition) const
474 : {
475 851 : PropertyMap::const_iterator i(properties.find(name));
476 851 : if (i == properties.end()) {
477 0 : throw css::beans::UnknownPropertyException(name, object);
478 : }
479 851 : if ((isAmbiguous
480 0 : && ((i->second.property.Attributes
481 0 : & css::beans::PropertyAttribute::MAYBEAMBIGUOUS)
482 : == 0))
483 1702 : || (isDefaulted
484 0 : && ((i->second.property.Attributes
485 0 : & css::beans::PropertyAttribute::MAYBEDEFAULT)
486 : == 0)))
487 : {
488 : throw css::lang::IllegalArgumentException(
489 : ("flagging as ambiguous/defaulted non-ambiguous/defaulted property "
490 0 : + name),
491 0 : object, illegalArgumentPosition);
492 : }
493 : css::uno::Reference< css::reflection::XIdlField2 > f(
494 851 : m_idlClass->getField(name), css::uno::UNO_QUERY_THROW);
495 1702 : css::uno::Any o(object->queryInterface(m_type));
496 : css::uno::Any v(
497 : wrapValue(
498 : object, value,
499 : (css::uno::Reference< css::reflection::XIdlField2 >(
500 2553 : m_idlClass->getField(name), css::uno::UNO_QUERY_THROW)->
501 851 : getType()),
502 851 : ((i->second.property.Attributes
503 851 : & css::beans::PropertyAttribute::MAYBEAMBIGUOUS)
504 : != 0),
505 : isAmbiguous,
506 851 : ((i->second.property.Attributes
507 851 : & css::beans::PropertyAttribute::MAYBEDEFAULT)
508 : != 0),
509 : isDefaulted,
510 851 : ((i->second.property.Attributes
511 851 : & css::beans::PropertyAttribute::MAYBEVOID)
512 5106 : != 0)));
513 : try {
514 851 : f->set(o, v);
515 0 : } catch (css::lang::IllegalArgumentException & e) {
516 0 : if (e.ArgumentPosition == 1) {
517 : throw css::lang::IllegalArgumentException(
518 0 : e.Message, object, illegalArgumentPosition);
519 : } else {
520 : throw css::uno::RuntimeException(
521 : ("unexpected com.sun.star.lang.IllegalArgumentException: "
522 0 : + e.Message),
523 0 : object);
524 : }
525 0 : } catch (css::lang::IllegalAccessException &) {
526 : //TODO Clarify whether PropertyVetoException is the correct exception
527 : // to throw when trying to set a read-only property:
528 : throw css::beans::PropertyVetoException(
529 0 : "cannot set read-only property " + name, object);
530 0 : } catch (css::lang::WrappedTargetRuntimeException & e) {
531 : //FIXME A WrappedTargetRuntimeException from XIdlField2.get is not
532 : // guaranteed to originate directly within XIdlField2.get (and thus have
533 : // the expected semantics); it might also be passed through from lower
534 : // layers.
535 0 : if (e.TargetException.isExtractableTo(
536 0 : cppu::UnoType<css::beans::UnknownPropertyException>::get())
537 0 : && ((i->second.property.Attributes
538 0 : & css::beans::PropertyAttribute::OPTIONAL)
539 : != 0))
540 : {
541 0 : throw css::beans::UnknownPropertyException(name, object);
542 0 : } else if (e.TargetException.isExtractableTo(
543 0 : cppu::UnoType<css::beans::PropertyVetoException>::get())
544 0 : && ((i->second.property.Attributes
545 0 : & css::beans::PropertyAttribute::CONSTRAINED)
546 : != 0))
547 : {
548 0 : css::beans::PropertyVetoException exc;
549 0 : e.TargetException >>= exc;
550 0 : if (exc.Message.isEmpty() )
551 0 : throw css::beans::PropertyVetoException("Invalid " + name, object);
552 : else
553 0 : throw exc;
554 : } else {
555 : throw css::lang::WrappedTargetException(
556 0 : e.Message, object, e.TargetException);
557 : }
558 851 : }
559 851 : }
560 :
561 851 : css::uno::Any PropertySetMixinImpl::Impl::getProperty(
562 : css::uno::Reference< css::uno::XInterface > const & object,
563 : rtl::OUString const & name, css::beans::PropertyState * state) const
564 : {
565 851 : PropertyMap::const_iterator i(properties.find(name));
566 851 : if (i == properties.end()) {
567 0 : throw css::beans::UnknownPropertyException(name, object);
568 : }
569 : css::uno::Reference< css::reflection::XIdlField2 > field(
570 851 : m_idlClass->getField(name), css::uno::UNO_QUERY_THROW);
571 851 : css::uno::Any value;
572 : try {
573 851 : value = field->get(object->queryInterface(m_type));
574 0 : } catch (css::lang::IllegalArgumentException & e) {
575 : throw css::uno::RuntimeException(
576 : ("unexpected com.sun.star.lang.IllegalArgumentException: "
577 0 : + e.Message),
578 0 : object);
579 0 : } catch (css::lang::WrappedTargetRuntimeException & e) {
580 : //FIXME A WrappedTargetRuntimeException from XIdlField2.get is not
581 : // guaranteed to originate directly within XIdlField2.get (and thus have
582 : // the expected semantics); it might also be passed through from lower
583 : // layers.
584 0 : if (e.TargetException.isExtractableTo(
585 0 : cppu::UnoType<css::beans::UnknownPropertyException>::get())
586 0 : && ((i->second.property.Attributes
587 0 : & css::beans::PropertyAttribute::OPTIONAL)
588 : != 0))
589 : {
590 0 : throw css::beans::UnknownPropertyException(name, object);
591 : } else {
592 : throw css::lang::WrappedTargetException(
593 0 : e.Message, object, e.TargetException);
594 : }
595 : }
596 : bool undoAmbiguous
597 851 : = ((i->second.property.Attributes
598 851 : & css::beans::PropertyAttribute::MAYBEAMBIGUOUS)
599 851 : != 0);
600 : bool undoDefaulted
601 851 : = ((i->second.property.Attributes
602 851 : & css::beans::PropertyAttribute::MAYBEDEFAULT)
603 851 : != 0);
604 : bool undoOptional
605 851 : = ((i->second.property.Attributes
606 851 : & css::beans::PropertyAttribute::MAYBEVOID)
607 851 : != 0);
608 851 : bool isAmbiguous = false;
609 851 : bool isDefaulted = false;
610 1702 : while (undoAmbiguous || undoDefaulted || undoOptional) {
611 0 : if (undoAmbiguous
612 0 : && value.getValueTypeName().startsWith(
613 0 : "com.sun.star.beans.Ambiguous<"))
614 : {
615 : css::uno::Reference< css::reflection::XIdlClass > ambiguous(
616 0 : getReflection(value.getValueTypeName()));
617 : try {
618 0 : if (!(css::uno::Reference< css::reflection::XIdlField2 >(
619 0 : ambiguous->getField("IsAmbiguous"),
620 0 : css::uno::UNO_QUERY_THROW)->get(value)
621 0 : >>= isAmbiguous))
622 : {
623 : throw css::uno::RuntimeException(
624 : ("unexpected type of com.sun.star.beans.Ambiguous"
625 : " IsAmbiguous member"),
626 0 : object);
627 : }
628 0 : value = css::uno::Reference< css::reflection::XIdlField2 >(
629 0 : ambiguous->getField("Value"), css::uno::UNO_QUERY_THROW)->
630 0 : get(value);
631 0 : } catch (css::lang::IllegalArgumentException & e) {
632 : throw css::uno::RuntimeException(
633 : ("unexpected com.sun.star.lang.IllegalArgumentException: "
634 0 : + e.Message),
635 0 : object);
636 : }
637 0 : undoAmbiguous = false;
638 0 : } else if (undoDefaulted
639 0 : && value.getValueTypeName().startsWith(
640 0 : "com.sun.star.beans.Defaulted<"))
641 : {
642 : css::uno::Reference< css::reflection::XIdlClass > defaulted(
643 0 : getReflection(value.getValueTypeName()));
644 : try {
645 :
646 0 : if (!(css::uno::Reference< css::reflection::XIdlField2 >(
647 0 : defaulted->getField("IsDefaulted"),
648 0 : css::uno::UNO_QUERY_THROW)->get(value)
649 0 : >>= isDefaulted))
650 : {
651 : throw css::uno::RuntimeException(
652 : ("unexpected type of com.sun.star.beans.Defaulted"
653 : " IsDefaulted member"),
654 0 : object);
655 : }
656 0 : value = css::uno::Reference< css::reflection::XIdlField2 >(
657 0 : defaulted->getField("Value"), css::uno::UNO_QUERY_THROW)->
658 0 : get(value);
659 0 : } catch (css::lang::IllegalArgumentException & e) {
660 : throw css::uno::RuntimeException(
661 : ("unexpected com.sun.star.lang.IllegalArgumentException: "
662 0 : + e.Message),
663 0 : object);
664 : }
665 0 : undoDefaulted = false;
666 0 : } else if (undoOptional
667 0 : && value.getValueTypeName().startsWith(
668 0 : "com.sun.star.beans.Optional<"))
669 : {
670 : css::uno::Reference< css::reflection::XIdlClass > optional(
671 0 : getReflection(value.getValueTypeName()));
672 : try {
673 0 : bool present = false;
674 0 : if (!(css::uno::Reference< css::reflection::XIdlField2 >(
675 0 : optional->getField("IsPresent"),
676 0 : css::uno::UNO_QUERY_THROW)->get(value)
677 0 : >>= present))
678 : {
679 : throw css::uno::RuntimeException(
680 : ("unexpected type of com.sun.star.beans.Optional"
681 : " IsPresent member"),
682 0 : object);
683 : }
684 0 : if (!present) {
685 0 : value.clear();
686 0 : break;
687 : }
688 0 : value = css::uno::Reference< css::reflection::XIdlField2 >(
689 0 : optional->getField("Value"), css::uno::UNO_QUERY_THROW)->
690 0 : get(value);
691 0 : } catch (css::lang::IllegalArgumentException & e) {
692 : throw css::uno::RuntimeException(
693 : ("unexpected com.sun.star.lang.IllegalArgumentException: "
694 0 : + e.Message),
695 0 : object);
696 : }
697 0 : undoOptional = false;
698 : } else {
699 : throw css::uno::RuntimeException(
700 0 : "unexpected type of attribute " + name, object);
701 : }
702 : }
703 851 : if (state != 0) {
704 : //XXX If isAmbiguous && isDefaulted, arbitrarily choose AMBIGUOUS_VALUE
705 : // over DEFAULT_VALUE:
706 : *state = isAmbiguous
707 : ? css::beans::PropertyState_AMBIGUOUS_VALUE
708 : : isDefaulted
709 : ? css::beans::PropertyState_DEFAULT_VALUE
710 0 : : css::beans::PropertyState_DIRECT_VALUE;
711 : }
712 851 : return value;
713 : }
714 :
715 : css::uno::Reference< css::reflection::XIdlClass >
716 9987 : PropertySetMixinImpl::Impl::getReflection(rtl::OUString const & typeName) const
717 : {
718 : return css::uno::Reference< css::reflection::XIdlClass >(
719 19974 : css::reflection::theCoreReflection::get(m_context)->forName(typeName),
720 19974 : css::uno::UNO_SET_THROW);
721 : }
722 :
723 851 : css::uno::Any PropertySetMixinImpl::Impl::wrapValue(
724 : css::uno::Reference< css::uno::XInterface > const & object,
725 : css::uno::Any const & value,
726 : css::uno::Reference< css::reflection::XIdlClass > const & type,
727 : bool wrapAmbiguous, bool isAmbiguous, bool wrapDefaulted, bool isDefaulted,
728 : bool wrapOptional)
729 : {
730 : assert(wrapAmbiguous || !isAmbiguous);
731 : assert(wrapDefaulted || !isDefaulted);
732 2553 : if (wrapAmbiguous
733 1702 : && type->getName().startsWith("com.sun.star.beans.Ambiguous<"))
734 : {
735 0 : css::uno::Any strct;
736 0 : type->createObject(strct);
737 : try {
738 : css::uno::Reference< css::reflection::XIdlField2 > field(
739 0 : type->getField("Value"), css::uno::UNO_QUERY_THROW);
740 0 : field->set(
741 : strct,
742 : wrapValue(
743 0 : object, value, field->getType(), false, false,
744 0 : wrapDefaulted, isDefaulted, wrapOptional));
745 : css::uno::Reference< css::reflection::XIdlField2 >(
746 0 : type->getField("IsAmbiguous"), css::uno::UNO_QUERY_THROW)->set(
747 0 : strct, css::uno::makeAny(isAmbiguous));
748 0 : } catch (css::lang::IllegalArgumentException & e) {
749 : throw css::uno::RuntimeException(
750 : ("unexpected com.sun.star.lang.IllegalArgumentException: "
751 0 : + e.Message),
752 0 : object);
753 0 : } catch (css::lang::IllegalAccessException & e) {
754 : throw css::uno::RuntimeException(
755 : ("unexpected com.sun.star.lang.IllegalAccessException: "
756 0 : + e.Message),
757 0 : object);
758 : }
759 0 : return strct;
760 2553 : } else if (wrapDefaulted
761 1702 : && type->getName().startsWith("com.sun.star.beans.Defaulted<"))
762 : {
763 0 : css::uno::Any strct;
764 0 : type->createObject(strct);
765 : try {
766 : css::uno::Reference< css::reflection::XIdlField2 > field(
767 0 : type->getField("Value"), css::uno::UNO_QUERY_THROW);
768 0 : field->set(
769 : strct,
770 : wrapValue(
771 0 : object, value, field->getType(), wrapAmbiguous, isAmbiguous,
772 0 : false, false, wrapOptional));
773 : css::uno::Reference< css::reflection::XIdlField2 >(
774 0 : type->getField("IsDefaulted"), css::uno::UNO_QUERY_THROW)->set(
775 0 : strct, css::uno::makeAny(isDefaulted));
776 0 : } catch (css::lang::IllegalArgumentException & e) {
777 : throw css::uno::RuntimeException(
778 : ("unexpected com.sun.star.lang.IllegalArgumentException: "
779 0 : + e.Message),
780 0 : object);
781 0 : } catch (css::lang::IllegalAccessException & e) {
782 : throw css::uno::RuntimeException(
783 : ("unexpected com.sun.star.lang.IllegalAccessException: "
784 0 : + e.Message),
785 0 : object);
786 : }
787 0 : return strct;
788 2553 : } else if (wrapOptional
789 1702 : && type->getName().startsWith("com.sun.star.beans.Optional<"))
790 : {
791 0 : css::uno::Any strct;
792 0 : type->createObject(strct);
793 0 : bool present = value.hasValue();
794 : try {
795 : css::uno::Reference< css::reflection::XIdlField2 >(
796 0 : type->getField("IsPresent"), css::uno::UNO_QUERY_THROW)->set(
797 0 : strct, css::uno::makeAny(present));
798 0 : if (present) {
799 : css::uno::Reference< css::reflection::XIdlField2 > field(
800 0 : type->getField("Value"), css::uno::UNO_QUERY_THROW);
801 0 : field->set(
802 : strct,
803 : wrapValue(
804 0 : object, value, field->getType(), wrapAmbiguous,
805 0 : isAmbiguous, wrapDefaulted, isDefaulted, false));
806 : }
807 0 : } catch (css::lang::IllegalArgumentException & e) {
808 : throw css::uno::RuntimeException(
809 : ("unexpected com.sun.star.lang.IllegalArgumentException: "
810 0 : + e.Message),
811 0 : object);
812 0 : } catch (css::lang::IllegalAccessException & e) {
813 : throw css::uno::RuntimeException(
814 : ("unexpected com.sun.star.lang.IllegalAccessException: "
815 0 : + e.Message),
816 0 : object);
817 : }
818 0 : return strct;
819 : } else {
820 851 : if (wrapAmbiguous || wrapDefaulted || wrapOptional) {
821 : throw css::uno::RuntimeException(
822 0 : "unexpected type of attribute", object);
823 : }
824 851 : return value;
825 : }
826 : }
827 :
828 9987 : PropertySetMixinImpl::PropertySetMixinImpl(
829 : css::uno::Reference< css::uno::XComponentContext > const & context,
830 : Implements implements,
831 : css::uno::Sequence< rtl::OUString > const & absentOptional,
832 9987 : css::uno::Type const & type)
833 : {
834 9987 : m_impl = new Impl(context, implements, absentOptional, type);
835 9987 : m_impl->acquire();
836 9987 : }
837 :
838 19950 : PropertySetMixinImpl::~PropertySetMixinImpl() {
839 9975 : m_impl->release();
840 9975 : }
841 :
842 0 : void PropertySetMixinImpl::checkUnknown(rtl::OUString const & propertyName) {
843 0 : if (!propertyName.isEmpty()) {
844 : m_impl->get(
845 0 : static_cast< css::beans::XPropertySet * >(this), propertyName);
846 : }
847 0 : }
848 :
849 0 : void PropertySetMixinImpl::prepareSet(
850 : rtl::OUString const & propertyName, css::uno::Any const & oldValue,
851 : css::uno::Any const & newValue, BoundListeners * boundListeners)
852 : {
853 0 : Impl::PropertyMap::const_iterator it(m_impl->properties.find(propertyName));
854 : assert(it != m_impl->properties.end());
855 0 : Impl::VetoListenerBag specificVeto;
856 0 : Impl::VetoListenerBag unspecificVeto;
857 : {
858 0 : osl::MutexGuard g(m_impl->mutex);
859 0 : if (m_impl->disposed) {
860 : throw css::lang::DisposedException(
861 0 : "disposed", static_cast< css::beans::XPropertySet * >(this));
862 : }
863 0 : if ((it->second.property.Attributes
864 0 : & css::beans::PropertyAttribute::CONSTRAINED)
865 : != 0)
866 : {
867 : Impl::VetoListenerMap::const_iterator i(
868 0 : m_impl->vetoListeners.find(propertyName));
869 0 : if (i != m_impl->vetoListeners.end()) {
870 0 : specificVeto = i->second;
871 : }
872 0 : i = m_impl->vetoListeners.find("");
873 0 : if (i != m_impl->vetoListeners.end()) {
874 0 : unspecificVeto = i->second;
875 : }
876 : }
877 0 : if ((it->second.property.Attributes
878 0 : & css::beans::PropertyAttribute::BOUND)
879 : != 0)
880 : {
881 : assert(boundListeners != 0);
882 : Impl::BoundListenerMap::const_iterator i(
883 0 : m_impl->boundListeners.find(propertyName));
884 0 : if (i != m_impl->boundListeners.end()) {
885 0 : boundListeners->m_impl->specificListeners = i->second;
886 : }
887 0 : i = m_impl->boundListeners.find("");
888 0 : if (i != m_impl->boundListeners.end()) {
889 0 : boundListeners->m_impl->unspecificListeners = i->second;
890 : }
891 0 : }
892 : }
893 0 : if ((it->second.property.Attributes
894 0 : & css::beans::PropertyAttribute::CONSTRAINED)
895 : != 0)
896 : {
897 : css::beans::PropertyChangeEvent event(
898 : static_cast< css::beans::XPropertySet * >(this), propertyName,
899 0 : false, it->second.property.Handle, oldValue, newValue);
900 0 : for (Impl::VetoListenerBag::iterator i(specificVeto.begin());
901 0 : i != specificVeto.end(); ++i)
902 : {
903 : try {
904 0 : (*i)->vetoableChange(event);
905 0 : } catch (css::lang::DisposedException &) {}
906 : }
907 0 : for (Impl::VetoListenerBag::iterator i(unspecificVeto.begin());
908 0 : i != unspecificVeto.end(); ++i)
909 : {
910 : try {
911 0 : (*i)->vetoableChange(event);
912 0 : } catch (css::lang::DisposedException &) {}
913 0 : }
914 : }
915 0 : if ((it->second.property.Attributes & css::beans::PropertyAttribute::BOUND)
916 : != 0)
917 : {
918 : assert(boundListeners != 0);
919 0 : boundListeners->m_impl->event = css::beans::PropertyChangeEvent(
920 : static_cast< css::beans::XPropertySet * >(this), propertyName,
921 0 : false, it->second.property.Handle, oldValue, newValue);
922 0 : }
923 0 : }
924 :
925 8 : void PropertySetMixinImpl::dispose() {
926 8 : Impl::BoundListenerMap boundListeners;
927 16 : Impl::VetoListenerMap vetoListeners;
928 : {
929 8 : osl::MutexGuard g(m_impl->mutex);
930 8 : boundListeners.swap(m_impl->boundListeners);
931 8 : vetoListeners.swap(m_impl->vetoListeners);
932 8 : m_impl->disposed = true;
933 : }
934 : css::lang::EventObject event(
935 16 : static_cast< css::beans::XPropertySet * >(this));
936 24 : for (Impl::BoundListenerMap::iterator i(boundListeners.begin());
937 16 : i != boundListeners.end(); ++i)
938 : {
939 0 : for (BoundListenerBag::iterator j(i->second.begin());
940 0 : j != i->second.end(); ++j)
941 : {
942 0 : (*j)->disposing(event);
943 : }
944 : }
945 24 : for (Impl::VetoListenerMap::iterator i(vetoListeners.begin());
946 16 : i != vetoListeners.end(); ++i)
947 : {
948 0 : for (Impl::VetoListenerBag::iterator j(i->second.begin());
949 0 : j != i->second.end(); ++j)
950 : {
951 0 : (*j)->disposing(event);
952 : }
953 8 : }
954 8 : }
955 :
956 1427 : css::uno::Any PropertySetMixinImpl::queryInterface(css::uno::Type const & type)
957 : throw (css::uno::RuntimeException, std::exception)
958 : {
959 2854 : if (((m_impl->implements & IMPLEMENTS_PROPERTY_SET) != 0
960 1427 : && type == css::beans::XPropertySet::static_type()))
961 : {
962 : css::uno::Reference< css::uno::XInterface > ifc(
963 851 : static_cast< css::beans::XPropertySet * >(this));
964 851 : return css::uno::Any(&ifc, type);
965 1152 : } else if ((m_impl->implements & IMPLEMENTS_FAST_PROPERTY_SET) != 0
966 576 : && type == css::beans::XFastPropertySet::static_type())
967 : {
968 : css::uno::Reference< css::uno::XInterface > ifc(
969 0 : static_cast< css::beans::XFastPropertySet * >(this));
970 0 : return css::uno::Any(&ifc, type);
971 1152 : } else if ((m_impl->implements & IMPLEMENTS_PROPERTY_ACCESS) != 0
972 576 : && type == css::beans::XPropertyAccess::static_type())
973 : {
974 : css::uno::Reference< css::uno::XInterface > ifc(
975 0 : static_cast< css::beans::XPropertyAccess * >(this));
976 0 : return css::uno::Any(&ifc, type);
977 : } else {
978 576 : return css::uno::Any();
979 : }
980 : }
981 :
982 : css::uno::Reference< css::beans::XPropertySetInfo >
983 0 : PropertySetMixinImpl::getPropertySetInfo()
984 : throw (css::uno::RuntimeException, std::exception)
985 : {
986 0 : return new Info(m_impl);
987 : }
988 :
989 851 : void PropertySetMixinImpl::setPropertyValue(
990 : rtl::OUString const & propertyName, css::uno::Any const & value)
991 : throw (
992 : css::beans::UnknownPropertyException, css::beans::PropertyVetoException,
993 : css::lang::IllegalArgumentException, css::lang::WrappedTargetException,
994 : css::uno::RuntimeException, std::exception)
995 : {
996 : m_impl->setProperty(
997 : static_cast< css::beans::XPropertySet * >(this), propertyName, value,
998 851 : false, false, 1);
999 851 : }
1000 :
1001 851 : css::uno::Any PropertySetMixinImpl::getPropertyValue(
1002 : rtl::OUString const & propertyName)
1003 : throw (
1004 : css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
1005 : css::uno::RuntimeException, std::exception)
1006 : {
1007 : return m_impl->getProperty(
1008 851 : static_cast< css::beans::XPropertySet * >(this), propertyName, 0);
1009 : }
1010 :
1011 0 : void PropertySetMixinImpl::addPropertyChangeListener(
1012 : rtl::OUString const & propertyName,
1013 : css::uno::Reference< css::beans::XPropertyChangeListener > const & listener)
1014 : throw (
1015 : css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
1016 : css::uno::RuntimeException, std::exception)
1017 : {
1018 : css::uno::Reference< css::beans::XPropertyChangeListener >(
1019 0 : listener, css::uno::UNO_SET_THROW); // reject NULL listener
1020 0 : checkUnknown(propertyName);
1021 : bool disposed;
1022 : {
1023 0 : osl::MutexGuard g(m_impl->mutex);
1024 0 : disposed = m_impl->disposed;
1025 0 : if (!disposed) {
1026 0 : m_impl->boundListeners[propertyName].insert(listener);
1027 0 : }
1028 : }
1029 0 : if (disposed) {
1030 0 : listener->disposing(
1031 : css::lang::EventObject(
1032 0 : static_cast< css::beans::XPropertySet * >(this)));
1033 : }
1034 0 : }
1035 :
1036 0 : void PropertySetMixinImpl::removePropertyChangeListener(
1037 : rtl::OUString const & propertyName,
1038 : css::uno::Reference< css::beans::XPropertyChangeListener > const & listener)
1039 : throw (
1040 : css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
1041 : css::uno::RuntimeException, std::exception)
1042 : {
1043 : assert(listener.is());
1044 0 : checkUnknown(propertyName);
1045 0 : osl::MutexGuard g(m_impl->mutex);
1046 : Impl::BoundListenerMap::iterator i(
1047 0 : m_impl->boundListeners.find(propertyName));
1048 0 : if (i != m_impl->boundListeners.end()) {
1049 0 : BoundListenerBag::iterator j(i->second.find(listener));
1050 0 : if (j != i->second.end()) {
1051 0 : i->second.erase(j);
1052 : }
1053 0 : }
1054 0 : }
1055 :
1056 0 : void PropertySetMixinImpl::addVetoableChangeListener(
1057 : rtl::OUString const & propertyName,
1058 : css::uno::Reference< css::beans::XVetoableChangeListener > const & listener)
1059 : throw (
1060 : css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
1061 : css::uno::RuntimeException, std::exception)
1062 : {
1063 : css::uno::Reference< css::beans::XVetoableChangeListener >(
1064 0 : listener, css::uno::UNO_SET_THROW); // reject NULL listener
1065 0 : checkUnknown(propertyName);
1066 : bool disposed;
1067 : {
1068 0 : osl::MutexGuard g(m_impl->mutex);
1069 0 : disposed = m_impl->disposed;
1070 0 : if (!disposed) {
1071 0 : m_impl->vetoListeners[propertyName].insert(listener);
1072 0 : }
1073 : }
1074 0 : if (disposed) {
1075 0 : listener->disposing(
1076 : css::lang::EventObject(
1077 0 : static_cast< css::beans::XPropertySet * >(this)));
1078 : }
1079 0 : }
1080 :
1081 0 : void PropertySetMixinImpl::removeVetoableChangeListener(
1082 : rtl::OUString const & propertyName,
1083 : css::uno::Reference< css::beans::XVetoableChangeListener > const & listener)
1084 : throw (
1085 : css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
1086 : css::uno::RuntimeException, std::exception)
1087 : {
1088 : assert(listener.is());
1089 0 : checkUnknown(propertyName);
1090 0 : osl::MutexGuard g(m_impl->mutex);
1091 0 : Impl::VetoListenerMap::iterator i(m_impl->vetoListeners.find(propertyName));
1092 0 : if (i != m_impl->vetoListeners.end()) {
1093 0 : Impl::VetoListenerBag::iterator j(i->second.find(listener));
1094 0 : if (j != i->second.end()) {
1095 0 : i->second.erase(j);
1096 : }
1097 0 : }
1098 0 : }
1099 :
1100 0 : void PropertySetMixinImpl::setFastPropertyValue(
1101 : sal_Int32 handle, css::uno::Any const & value)
1102 : throw (
1103 : css::beans::UnknownPropertyException, css::beans::PropertyVetoException,
1104 : css::lang::IllegalArgumentException, css::lang::WrappedTargetException,
1105 : css::uno::RuntimeException, std::exception)
1106 : {
1107 : m_impl->setProperty(
1108 : static_cast< css::beans::XPropertySet * >(this),
1109 : m_impl->translateHandle(
1110 : static_cast< css::beans::XPropertySet * >(this), handle),
1111 0 : value, false, false, 1);
1112 0 : }
1113 :
1114 0 : css::uno::Any PropertySetMixinImpl::getFastPropertyValue(sal_Int32 handle)
1115 : throw (
1116 : css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
1117 : css::uno::RuntimeException, std::exception)
1118 : {
1119 : return m_impl->getProperty(
1120 : static_cast< css::beans::XPropertySet * >(this),
1121 : m_impl->translateHandle(
1122 : static_cast< css::beans::XPropertySet * >(this), handle),
1123 0 : 0);
1124 : }
1125 :
1126 : css::uno::Sequence< css::beans::PropertyValue >
1127 0 : PropertySetMixinImpl::getPropertyValues()
1128 : throw (css::uno::RuntimeException, std::exception)
1129 : {
1130 : css::uno::Sequence< css::beans::PropertyValue > s(
1131 0 : m_impl->handleMap.getLength());
1132 0 : sal_Int32 n = 0;
1133 0 : for (sal_Int32 i = 0; i < m_impl->handleMap.getLength(); ++i) {
1134 : try {
1135 0 : s[n].Value = m_impl->getProperty(
1136 : static_cast< css::beans::XPropertySet * >(this),
1137 0 : m_impl->handleMap[i], &s[n].State);
1138 0 : } catch (css::beans::UnknownPropertyException &) {
1139 0 : continue;
1140 0 : } catch (css::lang::WrappedTargetException & e) {
1141 : throw css::lang::WrappedTargetRuntimeException(
1142 : e.Message, static_cast< css::beans::XPropertySet * >(this),
1143 0 : e.TargetException);
1144 : }
1145 0 : s[n].Name = m_impl->handleMap[i];
1146 0 : s[n].Handle = i;
1147 0 : ++n;
1148 : }
1149 0 : s.realloc(n);
1150 0 : return s;
1151 : }
1152 :
1153 0 : void PropertySetMixinImpl::setPropertyValues(
1154 : css::uno::Sequence< css::beans::PropertyValue > const & props)
1155 : throw (
1156 : css::beans::UnknownPropertyException, css::beans::PropertyVetoException,
1157 : css::lang::IllegalArgumentException, css::lang::WrappedTargetException,
1158 : css::uno::RuntimeException, std::exception)
1159 : {
1160 0 : for (sal_Int32 i = 0; i < props.getLength(); ++i) {
1161 0 : if (props[i].Handle != -1
1162 0 : && (props[i].Name
1163 0 : != m_impl->translateHandle(
1164 : static_cast< css::beans::XPropertySet * >(this),
1165 0 : props[i].Handle)))
1166 : {
1167 : throw css::beans::UnknownPropertyException(
1168 0 : ("name " + props[i].Name + " does not match handle "
1169 0 : + rtl::OUString::number(props[i].Handle)),
1170 0 : static_cast< css::beans::XPropertySet * >(this));
1171 : }
1172 : m_impl->setProperty(
1173 0 : static_cast< css::beans::XPropertySet * >(this), props[i].Name,
1174 0 : props[i].Value,
1175 0 : props[i].State == css::beans::PropertyState_AMBIGUOUS_VALUE,
1176 0 : props[i].State == css::beans::PropertyState_DEFAULT_VALUE, 0);
1177 : }
1178 0 : }
1179 :
1180 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|