xref: /trunk/main/xmloff/source/chart/MultiPropertySetHandler.hxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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 _MULTI_PROPERTY_SET_HANDLER_HXX
29 #define _MULTI_PROPERTY_SET_HANDLER_HXX
30 
31 #include    <rtl/ustring.hxx>
32 #include <com/sun/star/beans/XPropertySet.hpp>
33 #include <com/sun/star/beans/XMultiPropertySet.hpp>
34 
35 
36 /** @descr  MultiPropertySetHandler handles the two slightly different
37         interfaces XPropertySet and XMultiPorpertySet for accessing
38         properties of an object.
39 
40         It uses the classes PropertyWrapperBase and the template
41         PropertyWrapper for a type safe access to single properties.
42 
43         The function class OUStringComparison is used by a STL map to
44         sort the properties by names.
45 */
46 
47 /** @descr  Base class for the templated property wrappers.
48         Having a common base class allows to set a variable to the
49         property's value without explicit knowledge of its type.
50 */
51 class   PropertyWrapperBase
52 {
53 public:
54     /** @descr  Create a class instance and store the given name.
55         @param  rName   The name of the property.
56     */
57     PropertyWrapperBase (const ::rtl::OUString & rName)
58         :   msName (rName)
59     {}
60     virtual ~PropertyWrapperBase()
61     {}
62 
63     /** @descr  Abstract interface of a method for setting a variables
64             value to that of the property.
65     */
66     virtual void    SetValue    (const ::com::sun::star::uno::Any & rValue) = 0;
67 
68     const ::rtl::OUString msName;
69 };
70 
71 
72 
73 
74 /** @descr  For every property type there will be one instantiation of this
75         template class with its own and type specific version of SetValue.
76 */
77 template<class T> class PropertyWrapper : public PropertyWrapperBase
78 {
79 public:
80     /** @descr  Create a wrapper for a property of type T.
81     */
82     PropertyWrapper (const ::rtl::OUString & rName, T & rValue)
83         :   PropertyWrapperBase (rName),
84             mrValue (rValue)
85     {}
86 
87     /** descr   Set the given value inside an Any to the variable referenced
88         by the data member.
89     */
90     virtual void    SetValue    (const ::com::sun::star::uno::Any & rValue)
91     {
92         rValue >>= mrValue;
93     }
94 
95 private:
96     /// Reference to a variable.  Its value can be modified by a call to SetValue.
97     T   &   mrValue;
98 };
99 
100 
101 
102 
103 /** @descr  Function object for comparing two OUStrings.
104 */
105 class   OUStringComparison
106 {
107 public:
108     /// Compare two strings.  Returns true if the first is before the second.
109     inline  bool    operator()  (const ::rtl::OUString & a, const ::rtl::OUString & b) const
110     {
111         return (a.compareTo (b) < 0);
112     }
113 };
114 
115 
116 
117 
118 /** @descr  This class lets you get the values from an object that either
119         supports the interface XPropertySet or XMultiPropertySet.  If it
120         supports both interfaces then XMultiPropertySet is preferred.
121 
122         Using it works in three steps.
123         1.  Create an instance and pass a reference to the object from which to
124             get the property values.
125         2.  Make all properties whose values you want to get known to the object
126             by using the Add method.  This creates instances of a template class
127             that stores the properties name and a reference to the variable in
128             which to store its value.
129         3.  Finally call GetProperties to store the properties values into the
130             variables specified in step 2.  This uses either the XPropertySet or
131             (preferred) the XMultiPropertySet interface.
132 */
133 class   MultiPropertySetHandler
134 {
135 public:
136     /** @descr  Create a handler of the property set of the given
137             object.
138         @param  xObject A reference to any of the object's interfaces.
139             not neccessarily XPropertySet or XMultiPropertySet.  It
140             is casted later to one of the two of them.
141     */
142     MultiPropertySetHandler (::com::sun::star::uno::Reference<
143         ::com::sun::star::uno::XInterface> xObject);
144     ~MultiPropertySetHandler    (void);
145     /** @descr  Add a property to handle.  The type given implicitely by the
146             reference to a variable is used to create an instance of
147             the PropertyWrapper template class.
148         @param  sName   Name of the property.
149         @param  rValue  Reference to a variable whose value is set by the
150             call to GetProperties to the property's value.
151     */
152     template<class T> void  Add (const ::rtl::OUString & sName, T& rValue)
153     {
154         aPropertyList[sName] = new PropertyWrapper<T> (sName, rValue);
155     }
156 
157     /** @descr  Try to get the values for all properties added with the Add
158             method.  If possible it uses the XMultiPropertySet.  If that fails
159             (i.e. for an UnknownPropertyExcption) or if the interface is not
160             supported it uses the XPropertySet interface.
161         @return If none of the two interfaces is supported or using them both
162             fails then sal_False is returned.  Else True is returned.
163     */
164     inline  sal_Bool    GetProperties   (void);
165 
166 private:
167     /** @descr  Try to use the XMultiPropertySet interface to get the property
168             values.
169         @param  rNameList   A precomputed and sorted sequence of OUStrings
170             containing the properties names.
171         @return True if values could be derived.
172     */
173     inline  sal_Bool    MultiGet    (const ::com::sun::star::uno::Sequence<
174         ::rtl::OUString> & rNameList);
175 
176     /** @descr  Try to use the XPropertySet interface to get the property
177             values.
178         @param  rNameList   A precomputed and sorted sequence of OUStrings
179             containing the properties names.
180         @return True if values could be derived.
181     */
182     inline  sal_Bool    SingleGet   (const ::com::sun::star::uno::Sequence<
183         ::rtl::OUString> & rNameList);
184 
185     /** @descr  STL map that maps from property names to polymorphic instances of
186             PropertyWrapper.  It uses OUStringComparison for sorting
187             the property names.
188     */
189     ::std::map< ::rtl::OUString, PropertyWrapperBase*, OUStringComparison> aPropertyList;
190 
191     /// The object from which to get the property values.
192     ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface>    mxObject;
193 };
194 
195 
196 
197 //=====  Inline implementation of the methods declared above  ==========================
198 
199 MultiPropertySetHandler::MultiPropertySetHandler (::com::sun::star::uno::Reference<
200     ::com::sun::star::uno::XInterface> xObject)
201         :   mxObject (xObject)
202 {
203 }
204 
205 
206 
207 
208 MultiPropertySetHandler::~MultiPropertySetHandler (void)
209 {
210     ::std::map< ::rtl::OUString, PropertyWrapperBase*, OUStringComparison>::iterator I;
211     for (I=aPropertyList.begin(); I!=aPropertyList.end(); I++)
212         delete I->second;
213 }
214 
215 
216 /*
217 template<class T> void  MultiPropertySetHandler::Add (const ::rtl::OUString & sName, T& pValue)
218 {
219     aPropertyList[sName] = new PropertyWrapper<T> (sName, pValue);
220 }
221 */
222 
223 
224 
225 sal_Bool    MultiPropertySetHandler::GetProperties  (void)
226 {
227     ::std::map< ::rtl::OUString, PropertyWrapperBase*, OUStringComparison>::iterator I;
228     ::com::sun::star::uno::Sequence< ::rtl::OUString> aNameList (aPropertyList.size());
229     int i;
230     for (I=aPropertyList.begin(),i=0; I!=aPropertyList.end(); I++)
231         aNameList[i++] = I->second->msName;
232     if ( ! MultiGet(aNameList))
233         if ( ! SingleGet(aNameList))
234             return sal_False;
235     return sal_True;
236 }
237 
238 
239 
240 
241 sal_Bool    MultiPropertySetHandler::MultiGet   (const ::com::sun::star::uno::Sequence<
242     ::rtl::OUString> & rNameList)
243 {
244     ::com::sun::star::uno::Reference< ::com::sun::star::beans::XMultiPropertySet> xMultiSet (
245         mxObject, ::com::sun::star::uno::UNO_QUERY);
246     if (xMultiSet.is())
247         try
248         {
249             ::std::map< ::rtl::OUString, PropertyWrapperBase*, OUStringComparison>::iterator I;
250             int i;
251             ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any> aValueList =
252                 xMultiSet->getPropertyValues (rNameList);
253             for (I=aPropertyList.begin(),i=0; I!=aPropertyList.end(); I++)
254                 I->second->SetValue (aValueList[i++]);
255         }
256         catch (::com::sun::star::beans::UnknownPropertyException e)
257         {
258             return sal_False;
259         }
260     else
261         return sal_False;
262 
263     return sal_True;
264 }
265 
266 
267 
268 
269 sal_Bool    MultiPropertySetHandler::SingleGet  (const ::com::sun::star::uno::Sequence<
270     ::rtl::OUString> & rNameList)
271 {
272     ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet> xSingleSet (
273         mxObject, ::com::sun::star::uno::UNO_QUERY);
274     if (xSingleSet.is())
275         try
276         {
277             ::std::map< ::rtl::OUString, PropertyWrapperBase*, OUStringComparison>::iterator I;
278             int i;
279             for (I=aPropertyList.begin(),i=0; I!=aPropertyList.end(); I++)
280                 I->second->SetValue (xSingleSet->getPropertyValue (rNameList[i++]));
281         }
282         catch (::com::sun::star::beans::UnknownPropertyException e)
283         {
284             return sal_False;
285         }
286     else
287         return sal_False;
288 
289     return sal_True;
290 }
291 
292 
293 #endif
294 
295