1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #ifndef INCLUDED_CPPUHELPER_PROPERTYSETMIXIN_HXX
29 #define INCLUDED_CPPUHELPER_PROPERTYSETMIXIN_HXX \
30     INCLUDED_CPPUHELPER_PROPERTYSETMIXIN_HXX
31 
32 #include "sal/config.h"
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/XPropertySet.hpp"
38 #include "com/sun/star/lang/IllegalArgumentException.hpp"
39 #include "com/sun/star/lang/WrappedTargetException.hpp"
40 #include "com/sun/star/uno/Reference.hxx"
41 #include "com/sun/star/uno/RuntimeException.hpp"
42 #include "com/sun/star/uno/Sequence.hxx"
43 #include "sal/types.h"
44 
45 /// @HTML
46 
47 namespace com { namespace sun { namespace star {
48     namespace beans {
49         class XPropertyChangeListener;
50         class XPropertySetInfo;
51         class XVetoableChangeListener;
52         struct PropertyValue;
53     }
54     namespace uno {
55         class Any;
56         class Type;
57         class XComponentContext;
58     }
59 } } }
60 namespace rtl { class OUString; }
61 
62 namespace cppu {
63 
64 template< typename T > class PropertySetMixin;
65 
66 // Suppress warnings about virtual functions but non-virtual destructor:
67 #if defined _MSC_VER
68 #pragma warning(push)
69 #pragma warning(disable: 4265)
70 #endif
71 
72 /**
73    @short A helper base class for <code>cppu::PropertySetMixin</code>.
74 
75    @descr See the documentation of <code>cppu::PropertySetMixin</code> for
76    further details.
77 
78    @descr That <code>cppu::PropertySetMixin</code> is derived from this
79    base class should be considered an implementation detail.  The functionality
80    of <code>cppu::PropertySetMixin</code> that is inherited from this base
81    class and is visible to subclasses of
82    <code>cppu::PropertySetMixin</code> should be treated by such
83    subclasses as being provided by <code>cppu::PropertySetMixin</code>
84    directly (e.g., in such subclasses, use
85    &ldquo;<code>PropertySetMixin::Implements</code>&rdquo; instead of
86    &ldquo;<code>PropertySetMixinImpl::Implements</code>&rdquo;).
87 
88    @since UDK 3.2.1
89 */
90 class PropertySetMixinImpl:
91     public com::sun::star::beans::XPropertySet,
92     public com::sun::star::beans::XFastPropertySet,
93     public com::sun::star::beans::XPropertyAccess
94 {
95 protected:
96     /**
97        @short Flags used by subclasses of
98        <code>cppu::PropertySetMixin</code> to specify what UNO interface
99        types shall be supported.
100     */
101     enum Implements {
102         /**
103            @short Flag specifying that the UNO interface type
104            <code>com::sun::star::beans::XPropertySet</code> shall be supported.
105         */
106         IMPLEMENTS_PROPERTY_SET = 1,
107 
108         /**
109            @short Flag specifying that the UNO interface type
110            <code>com::sun::star::beans::XFastPropertySet</code> shall be
111            supported.
112         */
113         IMPLEMENTS_FAST_PROPERTY_SET = 2,
114 
115         /**
116            @short Flag specifying that the UNO interface type
117            <code>com::sun::star::beans::XPropertyAccess</code> shall be
118            supported.
119         */
120         IMPLEMENTS_PROPERTY_ACCESS = 4
121     };
122 
123     /**
124        @short A class used by subclasses of
125        <code>cppu::PropertySetMixin</code> when implementing UNO interface
126        type attribute setter functions.
127 
128        @descr This class is not thread safe; that is, the constructor,
129        <code>notify</code>, and the destructor must be called from the same
130        thread.
131 
132        @descr See <code>cppu::PropertySetMixinImpl::prepareSet</code> for
133        further details.
134     */
135     class BoundListeners {
136     public:
137         /**
138            @short The constructor.
139 
140            @descr May throw <code>std::bad_alloc</code>.
141         */
142         BoundListeners();
143 
144         /**
145            @short The destructor.
146 
147            @descr Does not throw.
148         */
149         ~BoundListeners();
150 
151         /**
152            @short Notifies any
153            <code>com::sun::star::beans::XPropertyChangeListener</code>s.
154 
155            @descr May throw <code>com::sun::star::uno::RuntimeException</code>
156            and <code>std::bad_alloc</code>.
157 
158            @descr See <code>cppu::PropertySetMixinImpl::prepareSet</code>
159            for further details.
160          */
161         void notify() const;
162 
163     private:
164         BoundListeners(BoundListeners &); // not defined
165         void operator =(BoundListeners); // not defined
166 
167         class Impl;
168         Impl * m_impl;
169 
170         friend class PropertySetMixinImpl;
171     };
172 
173     /**
174        @short A function used by subclasses of
175        <code>cppu::PropertySetMixin</code> when implementing UNO interface
176        type attribute setter functions.
177 
178        @descr First, this function checks whether this instance has already been
179        disposed (see <code>cppu::PropertySetMixinImpl::dispose</code>),
180        and throws a <code>com::sun::star::lang::DisposedException</code> if
181        applicable.  For a constrained attribute (whose setter can explicitly
182        raise <code>com::sun::star::beans::PropertyVetoException</code>), this
183        function notifies any
184        <code>com::sun::star::beans::XVetoableChangeListener</code>s.  For a
185        bound attribute, this function modifies the passed-in
186        <code>boundListeners</code> so that it can afterwards be used to notify
187        any <code>com::sun::star::beans::XPropertyChangeListener</code>s.  This
188        function should be called before storing the new attribute value, and
189        <code>boundListeners->notify()</code> should be called exactly once after
190        storing the new attribute value (in case the attribute is bound;
191        otherwise, calling <code>boundListeners->notify()</code> is ignored).
192        Furthermore, <code>boundListeners->notify()</code> and this function have
193        to be called from the same thread.
194 
195        @descr May throw
196        <code>com::sun::star::beans::PropertyVetoException</code>,
197        <code>com::sun::star::uno::RuntimeException</code> (and
198        <code>com::sun::star::lang::DisposedException</code> in particular), and
199        <code>std::bad_alloc</code>.
200 
201        @param propertyName  the name of the property (which is the same as the
202        name of the attribute that is going to be set)
203 
204        @param oldValue the property value corresponding to the old attribute
205        value.  This is only used as
206        <code>com::sun::star::beans::PropertyChangeEvent::OldValue</code>, which
207        is rather useless, anyway (see &ldquo;Using the Observer Pattern&rdquo;
208        in <a href="http://tools.openoffice.org/CodingGuidelines.sxw">
209        <cite>OpenOffice.org Coding Guidelines</cite></a>).  If the attribute
210        that is going to be set is neither bound nor constrained, or if
211        <code>com::sun::star::beans::PropertyChangeEvent::OldValue</code> should
212        not be set, a <code>VOID</code> <code>Any</code> can be used instead.
213 
214        @param newValue the property value corresponding to the new
215        attribute value.  This is only used as
216        <code>com::sun::star::beans::PropertyChangeEvent::NewValue</code>, which
217        is rather useless, anyway (see &ldquo;Using the Observer Pattern&rdquo;
218        in <a href="http://tools.openoffice.org/CodingGuidelines.sxw">
219        <cite>OpenOffice.org Coding Guidelines</cite></a>), <em>unless</em> the
220        attribute that is going to be set is constrained.  If the attribute
221        that is going to be set is neither bound nor constrained, or if it is
222        only bound but
223        <code>com::sun::star::beans::PropertyChangeEvent::NewValue</code> should
224        not be set, a <code>VOID</code> <code>Any</code> can be used instead.
225 
226        @param boundListeners  a pointer to a fresh
227        <code>cppu::PropertySetMixinImpl::BoundListeners</code> instance
228        (which has not been passed to this function before, and on which
229        <code>notify</code> has not yet been called); may only be null if the
230        attribute that is going to be set is not bound
231     */
232     void prepareSet(
233         rtl::OUString const & propertyName,
234         com::sun::star::uno::Any const & oldValue,
235         com::sun::star::uno::Any const & newValue,
236         BoundListeners * boundListeners);
237 
238     /**
239        @short Mark this instance as being disposed.
240 
241        @descr See <code>com::sun::star::lang::XComponent</code> for the general
242        concept of disposing UNO objects.  On the first call to this function,
243        all registered listeners
244        (<code>com::sun::star::beans::XPropertyChangeListener</code>s and
245        <code>com::sun::star::beans::XVetoableChangeListener</code>s) are
246        notified of the disposing source.  Any subsequent calls to this function
247        are ignored.
248 
249        @descr May throw <code>com::sun::star::uno::RuntimeException</code> and
250        <code>std::bad_alloc</code>.
251      */
252     void dispose();
253 
254     /**
255        @short A function used by subclasses of
256        <code>cppu::PropertySetMixin</code> when implementing
257        <code>com::sun::star::uno::XInterface::queryInterface</code>.
258 
259        @descr This function checks for support of any of the UNO interface types
260        specified in the call of the <code>cppu::PropertySetMixin</code>
261        constructor.  It does not check for any other UNO interface types (not
262        even for <code>com::sun::star::uno::XInterface</code>), and should not
263        be used directly as the implementation of
264        <code>com::sun::star::uno::XInterface::queryInterface</code> of this UNO
265        object.
266     */
267     virtual com::sun::star::uno::Any SAL_CALL queryInterface(
268         com::sun::star::uno::Type const & type)
269         throw (com::sun::star::uno::RuntimeException);
270 
271     // @see com::sun::star::beans::XPropertySet::getPropertySetInfo
272     virtual
273     com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo >
274     SAL_CALL getPropertySetInfo() throw (com::sun::star::uno::RuntimeException);
275 
276     // @see com::sun::star::beans::XPropertySet::setPropertyValue
277     virtual void SAL_CALL setPropertyValue(
278         rtl::OUString const & propertyName,
279         com::sun::star::uno::Any const & value)
280         throw (
281             com::sun::star::beans::UnknownPropertyException,
282             com::sun::star::beans::PropertyVetoException,
283             com::sun::star::lang::IllegalArgumentException,
284             com::sun::star::lang::WrappedTargetException,
285             com::sun::star::uno::RuntimeException);
286 
287     // @see com::sun::star::beans::XPropertySet::getPropertyValue
288     virtual com::sun::star::uno::Any SAL_CALL getPropertyValue(
289         rtl::OUString const & propertyName)
290         throw (
291             com::sun::star::beans::UnknownPropertyException,
292             com::sun::star::lang::WrappedTargetException,
293             com::sun::star::uno::RuntimeException);
294 
295     /**
296        @short Adds a
297        <code>com::sun::star::beans::XPropertyChangeListener</code>.
298 
299        @descr If a listener is added more than once, it will receive all
300        relevant notifications multiple times.
301 
302        @see com::sun::star::beans::XPropertySet::addPropertyChangeListener
303     */
304     virtual void SAL_CALL addPropertyChangeListener(
305         rtl::OUString const & propertyName,
306         com::sun::star::uno::Reference<
307         com::sun::star::beans::XPropertyChangeListener > const & listener)
308         throw (
309             com::sun::star::beans::UnknownPropertyException,
310             com::sun::star::lang::WrappedTargetException,
311             com::sun::star::uno::RuntimeException);
312 
313     // @see com::sun::star::beans::XPropertySet::removePropertyChangeListener
314     virtual void SAL_CALL removePropertyChangeListener(
315         rtl::OUString const & propertyName,
316         com::sun::star::uno::Reference<
317         com::sun::star::beans::XPropertyChangeListener > const & listener)
318         throw (
319             com::sun::star::beans::UnknownPropertyException,
320             com::sun::star::lang::WrappedTargetException,
321             com::sun::star::uno::RuntimeException);
322 
323     /**
324        @short Adds a
325        <code>com::sun::star::beans::XVetoableChangeListener</code>.
326 
327        @descr If a listener is added more than once, it will receive all
328        relevant notifications multiple times.
329 
330        @see com::sun::star::beans::XPropertySet::addVetoableChangeListener
331     */
332     virtual void SAL_CALL addVetoableChangeListener(
333         rtl::OUString const & propertyName,
334         com::sun::star::uno::Reference<
335         com::sun::star::beans::XVetoableChangeListener > const & listener)
336         throw (
337             com::sun::star::beans::UnknownPropertyException,
338             com::sun::star::lang::WrappedTargetException,
339             com::sun::star::uno::RuntimeException);
340 
341     // @see com::sun::star::beans::XPropertySet::removeVetoableChangeListener
342     virtual void SAL_CALL removeVetoableChangeListener(
343         rtl::OUString const & propertyName,
344         com::sun::star::uno::Reference<
345         com::sun::star::beans::XVetoableChangeListener > const & listener)
346         throw (
347             com::sun::star::beans::UnknownPropertyException,
348             com::sun::star::lang::WrappedTargetException,
349             com::sun::star::uno::RuntimeException);
350 
351     // @see com::sun::star::beans::XFastPropertySet::setFastPropertyValue
352     virtual void SAL_CALL setFastPropertyValue(
353         sal_Int32 handle, com::sun::star::uno::Any const & value)
354         throw (
355             com::sun::star::beans::UnknownPropertyException,
356             com::sun::star::beans::PropertyVetoException,
357             com::sun::star::lang::IllegalArgumentException,
358             com::sun::star::lang::WrappedTargetException,
359             com::sun::star::uno::RuntimeException);
360 
361     // @see com::sun::star::beans::XFastPropertySet::getFastPropertyValue
362     virtual com::sun::star::uno::Any SAL_CALL getFastPropertyValue(
363         sal_Int32 handle)
364         throw (
365             com::sun::star::beans::UnknownPropertyException,
366             com::sun::star::lang::WrappedTargetException,
367             com::sun::star::uno::RuntimeException);
368 
369     // @see com::sun::star::beans::XPropertyAccess::getPropertyValues
370     virtual
371     com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >
372     SAL_CALL getPropertyValues() throw (com::sun::star::uno::RuntimeException);
373 
374     // @see com::sun::star::beans::XPropertyAccess::setPropertyValues
375     virtual void SAL_CALL setPropertyValues(
376         com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >
377         const & props)
378         throw (
379             com::sun::star::beans::UnknownPropertyException,
380             com::sun::star::beans::PropertyVetoException,
381             com::sun::star::lang::IllegalArgumentException,
382             com::sun::star::lang::WrappedTargetException,
383             com::sun::star::uno::RuntimeException);
384 
385 private:
386     PropertySetMixinImpl(PropertySetMixinImpl &); // not defined
387     void operator =(PropertySetMixinImpl &); // not defined
388 
389     PropertySetMixinImpl(
390         com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
391         const & context,
392         Implements implements,
393         com::sun::star::uno::Sequence< rtl::OUString > const & absentOptional,
394         com::sun::star::uno::Type const & type);
395 
396     class Impl;
397     Impl * m_impl;
398 
399     friend class Impl;
400     template< typename T > friend class PropertySetMixin;
401 
402     ~PropertySetMixinImpl();
403 
404     void checkUnknown(rtl::OUString const & propertyName);
405 };
406 
407 /**
408    @short A helper mixin to implement certain UNO interfaces related to property
409    set handling on top of the attributes of a given UNO interface type.
410 
411    @descr The UNO interface type is specified by the type parameter
412    <code>T</code> (which must correspond to a UNO interface type).
413 
414    @descr No specializations of this class template should be added by client
415    code.
416 
417    @since UDK 3.2.1
418 */
419 template< typename T > class PropertySetMixin: public PropertySetMixinImpl {
420 protected:
421     /**
422        @short The constructor.
423 
424        @descr May throw <code>com::sun::star::uno::RuntimeException</code> and
425        <code>std::bad_alloc</code>.
426 
427        @param context  the component context used by this class template; must
428        not be null, and must supply the service
429        <code>com.sun.star.reflection.CoreReflection</code> and the singleton
430        <code>com.sun.star.reflection.theTypeDescriptionManager</code>
431 
432        @param implements  a combination of zero or more flags specifying what
433        UNO interface types shall be supported
434 
435        @param absentOptional  a list of optional properties that are not
436        present, and should thus not be visible via
437        <code>com::sun::star::beans::XPropertySet::getPropertySetInfo</code>,
438        <code>com::sun::star::beans::XPropertySet::addPropertyChangeListener<!--
439        --></code>, <code>com::sun::star::beans::XPropertySet::<!--
440        -->removePropertyChangeListener</code>,
441        <code>com::sun::star::beans::XPropertySet::addVetoableChangeListener<!--
442        --></code>, and <code>com::sun::star::beans::XPropertySet::<!--
443        -->removeVetoableChangeListener</code>.  For consistency reasons, the
444        given <code>absentOptional</code> should only contain the names of
445        attributes that represent optional properties that are not present (that
446        is, the attribute getters and setters always throw a
447        <code>com::sun::star::beans::UnknownPropertyException</code>), and should
448        contain each such name only once.  If an optional property is not present
449        (that is, the corresponding attribute getter and setter always throw a
450        <code>com::sun::star::beans::UnknownPropertyException</code>) but is not
451        contained in the given <code>absentOptional</code>, then it will be
452        visible via
453        <code>com::sun::star::beans::XPropertySet::getPropertySetInfo</code> as a
454        <code>com::sun::star::beans::Property</code> with a set
455        <code>com::sun::star::beans::PropertyAttribute::OPTIONAL</code>.  If the
456        given <code>implements</code> specifies that
457        <code>com::sun::star::beans::XPropertySet</code> is not supported, then
458        the given <code>absentOptional</code> is effectively ignored and can be
459        empty.
460     */
461     PropertySetMixin(
462         com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
463         const & context,
464         Implements implements,
465         com::sun::star::uno::Sequence< rtl::OUString > const & absentOptional):
466         PropertySetMixinImpl(
467             context, implements, absentOptional, T::static_type())
468     {}
469 
470     /**
471        @short The destructor.
472 
473        @descr Does not throw.
474     */
475     ~PropertySetMixin() {}
476 
477 private:
478     PropertySetMixin(PropertySetMixin &); // not defined
479     void operator =(PropertySetMixin); // not defined
480 };
481 
482 #if defined _MSC_VER
483 #pragma warning(pop)
484 #endif
485 
486 }
487 
488 #endif
489