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