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