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 _COMPHELPER_PROPERTY_AGGREGATION_HXX_ 25 #define _COMPHELPER_PROPERTY_AGGREGATION_HXX_ 26 27 #include <com/sun/star/uno/XAggregation.hpp> 28 #include <comphelper/propstate.hxx> 29 #include "comphelper/comphelperdllapi.h" 30 31 #include <map> 32 33 //========================================================================= 34 //= property helper classes 35 //========================================================================= 36 37 //......................................................................... 38 namespace comphelper 39 { 40 //......................................................................... 41 42 //================================================================== 43 //= OPropertyAccessor 44 //= internal helper class for OPropertyArrayAggregationHelper 45 //================================================================== 46 namespace internal 47 { 48 struct OPropertyAccessor 49 { 50 sal_Int32 nOriginalHandle; 51 sal_Int32 nPos; 52 sal_Bool bAggregate; 53 OPropertyAccessorcomphelper::internal::OPropertyAccessor54 OPropertyAccessor(sal_Int32 _nOriginalHandle, sal_Int32 _nPos, sal_Bool _bAggregate) 55 :nOriginalHandle(_nOriginalHandle) ,nPos(_nPos) ,bAggregate(_bAggregate) { } OPropertyAccessorcomphelper::internal::OPropertyAccessor56 OPropertyAccessor() 57 :nOriginalHandle(-1) ,nPos(-1) ,bAggregate(sal_False) { } 58 operator ==comphelper::internal::OPropertyAccessor59 sal_Bool operator==(const OPropertyAccessor& rOb) const { return nPos == rOb.nPos; } operator <comphelper::internal::OPropertyAccessor60 sal_Bool operator <(const OPropertyAccessor& rOb) const { return nPos < rOb.nPos; } 61 }; 62 63 typedef std::map< sal_Int32, OPropertyAccessor, ::std::less< sal_Int32 > > PropertyAccessorMap; 64 typedef PropertyAccessorMap::iterator PropertyAccessorMapIterator; 65 typedef PropertyAccessorMap::const_iterator ConstPropertyAccessorMapIterator; 66 } 67 68 //================================================================== 69 /** 70 * used as callback for a OPropertyArrayAggregationHelper 71 */ 72 class IPropertyInfoService 73 { 74 public: 75 /** get the preferred handle for the given property 76 @param _rName the property name 77 @return the handle the property should be referred by, or -1 if there are no 78 preferences for the given property 79 */ 80 virtual sal_Int32 getPreferedPropertyId(const ::rtl::OUString& _rName) = 0; 81 }; 82 83 /** 84 * used for implementing an cppu::IPropertyArrayHelper for classes 85 * aggregating property sets 86 */ 87 88 #define DEFAULT_AGGREGATE_PROPERTY_ID 10000 89 //------------------------------------------------------------------ 90 class COMPHELPER_DLLPUBLIC OPropertyArrayAggregationHelper: public ::cppu::IPropertyArrayHelper 91 { 92 friend class OPropertySetAggregationHelper; 93 protected: 94 95 ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property> m_aProperties; 96 internal::PropertyAccessorMap m_aPropertyAccessors; 97 98 public: 99 /** construct the object. 100 @param _rProperties the properties of the object doing the aggregation. These properties 101 are used without any checks, so the caller has to ensure that the names and 102 handles are valid. 103 @param _rAggProperties the properties of the aggregate, usually got via an call to getProperties on the 104 XPropertySetInfo of the aggregate. 105 The names of the properties are used without any checks, so the caller has to ensure 106 that there are no doubles. 107 The handles are stored for later quick access, but the outside-handles the 108 aggregate properties get depend from the following two parameters. 109 @param _pInfoService 110 If not NULL, the object pointed to is used to calc handles which should be used 111 for referring the aggregate's properties from outside. 112 If one of the properties returned from the info service conflict with other handles 113 alread present (e.g. through _rProperties), the property is handled as if -1 was returned. 114 If NULL (or, for a special property, a call to getPreferedPropertyId returns -1), 115 the aggregate property(ies) get a new handle which they can be referred by from outside. 116 @param _nFirstAggregateId 117 if the object is about to create new handles for the aggregate properties, it uses 118 id's ascending from this given id. 119 No checks are made if the handle range determined by _nFirstAggregateId conflicts with other 120 handles within _rProperties. 121 */ 122 OPropertyArrayAggregationHelper(const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property>& _rProperties, 123 const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property>& _rAggProperties, 124 IPropertyInfoService* _pInfoService = NULL, 125 sal_Int32 _nFirstAggregateId = DEFAULT_AGGREGATE_PROPERTY_ID); 126 127 128 /// inherited from IPropertyArrayHelper 129 virtual sal_Bool SAL_CALL fillPropertyMembersByHandle( ::rtl::OUString* _pPropName, sal_Int16* _pAttributes, 130 sal_Int32 _nHandle) ; 131 132 /// inherited from IPropertyArrayHelper 133 virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property> SAL_CALL getProperties(); 134 /// inherited from IPropertyArrayHelper 135 virtual ::com::sun::star::beans::Property SAL_CALL getPropertyByName(const ::rtl::OUString& _rPropertyName) 136 throw(::com::sun::star::beans::UnknownPropertyException); 137 138 /// inherited from IPropertyArrayHelper 139 virtual sal_Bool SAL_CALL hasPropertyByName(const ::rtl::OUString& _rPropertyName) ; 140 /// inherited from IPropertyArrayHelper 141 virtual sal_Int32 SAL_CALL getHandleByName(const ::rtl::OUString & _rPropertyName); 142 /// inherited from IPropertyArrayHelper 143 virtual sal_Int32 SAL_CALL fillHandles( /*out*/sal_Int32* _pHandles, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& _rPropNames ); 144 145 /** returns information about a property of the aggregate. 146 @param _pPropName points to a string to receive the property name. No name is returned if this is NULL. 147 @param _pOriginalHandle points to a sal_Int32 to receive the original property hande. No original handle is returned 148 if this is NULL. 149 @param _nHandle the handle of the property as got by, for instance, fillHandles 150 151 @return sal_True, if _nHandle marks an aggregate property, otherwise sal_False 152 */ 153 virtual sal_Bool SAL_CALL fillAggregatePropertyInfoByHandle(::rtl::OUString* _pPropName, sal_Int32* _pOriginalHandle, 154 sal_Int32 _nHandle) const; 155 156 /** returns information about a property given by handle 157 */ 158 sal_Bool getPropertyByHandle( sal_Int32 _nHandle, ::com::sun::star::beans::Property& _rProperty ) const; 159 160 161 enum PropertyOrigin 162 { 163 AGGREGATE_PROPERTY, 164 DELEGATOR_PROPERTY, 165 UNKNOWN_PROPERTY 166 }; 167 /** prefer this one over the XPropertySetInfo of the aggregate! 168 169 <p>The reason is that OPropertyArrayAggregationHelper is the only instance which really knows 170 which properties of the aggregate are to be exposed. <br/> 171 172 For instance, some derivee of OPropertySetAggregationHelper may decide to create an 173 OPropertyArrayAggregationHelper which contains only a subset of the aggregate properties. This way, 174 some of the aggregate properties may be hidded to the public.<br/> 175 176 When using the XPropertySetInfo of the aggregate set to determine the existence of a property, then this 177 would return false positives.</p> 178 */ 179 PropertyOrigin classifyProperty( const ::rtl::OUString& _rName ); 180 181 protected: 182 const ::com::sun::star::beans::Property* findPropertyByName(const ::rtl::OUString& _rName) const; 183 }; 184 185 //================================================================== 186 namespace internal 187 { 188 class PropertyForwarder; 189 } 190 191 /** 192 * helper class for implementing the property-set-related interfaces 193 * for an object doin' aggregation 194 * supports at least XPropertySet and XMultiPropertySet 195 * 196 */ 197 class COMPHELPER_DLLPUBLIC OPropertySetAggregationHelper :public OPropertyStateHelper 198 ,public ::com::sun::star::beans::XPropertiesChangeListener 199 ,public ::com::sun::star::beans::XVetoableChangeListener 200 { 201 friend class internal::PropertyForwarder; 202 203 protected: 204 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyState> m_xAggregateState; 205 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet> m_xAggregateSet; 206 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XMultiPropertySet> m_xAggregateMultiSet; 207 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XFastPropertySet> m_xAggregateFastSet; 208 209 internal::PropertyForwarder* m_pForwarder; 210 sal_Bool m_bListening : 1; 211 212 public: 213 OPropertySetAggregationHelper( ::cppu::OBroadcastHelper& rBHelper ); 214 215 virtual ::com::sun::star::uno::Any SAL_CALL queryInterface(const ::com::sun::star::uno::Type& aType) throw(::com::sun::star::uno::RuntimeException); 216 217 // XEventListener 218 virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw (::com::sun::star::uno::RuntimeException); 219 220 // XFastPropertySet 221 virtual void SAL_CALL setFastPropertyValue(sal_Int32 nHandle, const ::com::sun::star::uno::Any& aValue) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); 222 virtual ::com::sun::star::uno::Any SAL_CALL getFastPropertyValue(sal_Int32 nHandle) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); 223 224 // XPropertySet 225 virtual void SAL_CALL addPropertyChangeListener(const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& xListener) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); 226 virtual void SAL_CALL addVetoableChangeListener(const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); 227 228 // XPropertiesChangeListener 229 virtual void SAL_CALL propertiesChange(const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyChangeEvent >& evt) throw(::com::sun::star::uno::RuntimeException); 230 231 // XVetoableChangeListener 232 virtual void SAL_CALL vetoableChange(const ::com::sun::star::beans::PropertyChangeEvent& aEvent) throw(::com::sun::star::beans::PropertyVetoException, ::com::sun::star::uno::RuntimeException); 233 234 // XMultiPropertySet 235 virtual void SAL_CALL setPropertyValues(const ::com::sun::star::uno::Sequence< ::rtl::OUString >& PropertyNames, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& Values) throw(::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); 236 virtual void SAL_CALL addPropertiesChangeListener(const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertiesChangeListener >& xListener) throw(::com::sun::star::uno::RuntimeException); 237 238 // XPropertyState 239 virtual ::com::sun::star::beans::PropertyState SAL_CALL getPropertyState(const ::rtl::OUString& PropertyName) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); 240 virtual void SAL_CALL setPropertyToDefault(const ::rtl::OUString& PropertyName) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); 241 virtual ::com::sun::star::uno::Any SAL_CALL getPropertyDefault(const ::rtl::OUString& aPropertyName) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); 242 243 // OPropertySetHelper 244 /** still waiting to be overwritten ... 245 you <B>must<B/> use an OPropertyArrayAggregationHelper here, as the implementation strongly relies on this. 246 */ 247 virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() = 0; 248 249 /** only implemented for "forwarded" properties, every other property must be handled 250 in the derivee, and will assert if passed herein 251 */ 252 virtual sal_Bool SAL_CALL convertFastPropertyValue( ::com::sun::star::uno::Any& _rConvertedValue, ::com::sun::star::uno::Any& _rOldValue, sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue ) throw(::com::sun::star::lang::IllegalArgumentException); 253 254 /** only implemented for "forwarded" properties, every other property must be handled 255 in the derivee, and will assert if passed herein 256 */ 257 virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue ) throw ( ::com::sun::star::uno::Exception ); 258 259 protected: 260 ~OPropertySetAggregationHelper(); 261 262 virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle) const; 263 virtual void SAL_CALL disposing(); 264 265 sal_Int32 getOriginalHandle( sal_Int32 _nHandle ) const; 266 ::rtl::OUString getPropertyName( sal_Int32 _nHandle ) const; 267 268 /** declares the property with the given (public) handle as one to be forwarded to the aggregate 269 270 Sometimes, you might want to <em>overwrite</em> properties at the aggregate. That is, 271 though the aggregate implements this property, and still is to hold the property value, 272 you want to do additional handling upon setting the property, but then forward the value 273 to the aggregate. 274 275 Use this method to declare such properties. 276 277 When a "forwarded property" is set from outside, the class first calls 278 <member>forwardingPropertyValue</member> for any preprocessing, then forwards the property 279 value to the aggregate, and then calls <member>forwardedPropertyValue</member>. 280 281 When you declare a property as "forwarded", the class takes care for some multi-threading 282 issues, for instance, it won't fire any property change notifications which result from 283 forwarding a property value, unless it's safe to do so (i.e. unless our mutex is 284 released). 285 286 @see forwardingPropertyValue 287 @see forwardedPropertyValue 288 */ 289 void declareForwardedProperty( sal_Int32 _nHandle ); 290 291 /** checks whether we're actually forwarding a property value to our aggregate 292 293 @see declareForwardedProperty 294 @see forwardingPropertyValue 295 @see forwardedPropertyValue 296 */ 297 bool isCurrentlyForwardingProperty( sal_Int32 _nHandle ) const; 298 299 /** called immediately before a property value which is overwritten in this instance 300 is forwarded to the aggregate 301 302 @see declareForwardedProperty 303 @see forwardedPropertyValue 304 */ 305 virtual void SAL_CALL forwardingPropertyValue( sal_Int32 _nHandle ); 306 307 /** called immediately after a property value which is overwritten in this instance 308 has been forwarded to the aggregate 309 310 @see declareForwardedProperty 311 @see forwardingPropertyValue 312 */ 313 virtual void SAL_CALL forwardedPropertyValue( sal_Int32 _nHandle, bool _bSuccess ); 314 315 /// must be called before aggregation, if aggregation is used 316 void setAggregation(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >&) throw( ::com::sun::star::lang::IllegalArgumentException ); 317 void startListening(); 318 }; 319 320 //......................................................................... 321 } // namespace comphelper 322 //......................................................................... 323 324 #endif // _COMPHELPER_PROPERTY_AGGREGATION_HXX_ 325 326