CWS-TOOLING: integrate CWS os146
[LibreOffice.git] / comphelper / source / property / propertystatecontainer.cxx
blob341dc1b43a78a6f3d40341c712947742e19e7971
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
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.
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).
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.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_comphelper.hxx"
30 #include "comphelper/propertystatecontainer.hxx"
31 #include <rtl/ustrbuf.hxx>
33 //.........................................................................
34 namespace comphelper
36 //.........................................................................
38 using namespace ::com::sun::star::uno;
39 using namespace ::com::sun::star::beans;
40 using namespace ::com::sun::star::lang;
42 namespace
44 static ::rtl::OUString lcl_getUnknownPropertyErrorMessage( const ::rtl::OUString& _rPropertyName )
46 // TODO: perhaps it's time to think about resources in the comphelper module?
47 // Would be nice to have localized exception strings (a simply resource file containing
48 // strings only would suffice, and could be realized with an UNO service, so we do not
49 // need the dependency to the Tools project)
50 ::rtl::OUStringBuffer sMessage;
51 sMessage.appendAscii( "The property \"" );
52 sMessage.append( _rPropertyName );
53 sMessage.appendAscii( "\" is unknown." );
54 return sMessage.makeStringAndClear();
58 //=====================================================================
59 //= OPropertyStateContainer
60 //=====================================================================
61 //---------------------------------------------------------------------
62 OPropertyStateContainer::OPropertyStateContainer( ::cppu::OBroadcastHelper& _rBHelper )
63 :OPropertyContainer( _rBHelper )
67 //--------------------------------------------------------------------
68 Any SAL_CALL OPropertyStateContainer::queryInterface( const Type& _rType ) throw (RuntimeException)
70 Any aReturn = OPropertyContainer::queryInterface( _rType );
71 if ( !aReturn.hasValue() )
72 aReturn = OPropertyStateContainer_TBase::queryInterface( _rType );
73 return aReturn;
76 //--------------------------------------------------------------------
77 IMPLEMENT_FORWARD_XTYPEPROVIDER2( OPropertyStateContainer, OPropertyContainer, OPropertyStateContainer_TBase )
79 //--------------------------------------------------------------------
80 sal_Int32 OPropertyStateContainer::getHandleForName( const ::rtl::OUString& _rPropertyName ) SAL_THROW( ( UnknownPropertyException ) )
82 // look up the handle for the name
83 ::cppu::IPropertyArrayHelper& rPH = getInfoHelper();
84 sal_Int32 nHandle = rPH.getHandleByName( _rPropertyName );
86 if ( -1 == nHandle )
87 throw UnknownPropertyException( lcl_getUnknownPropertyErrorMessage( _rPropertyName ), static_cast< XPropertyState* >( this ) );
89 return nHandle;
92 //--------------------------------------------------------------------
93 PropertyState SAL_CALL OPropertyStateContainer::getPropertyState( const ::rtl::OUString& _rPropertyName ) throw (UnknownPropertyException, RuntimeException)
95 return getPropertyStateByHandle( getHandleForName( _rPropertyName ) );
98 //--------------------------------------------------------------------
99 Sequence< PropertyState > SAL_CALL OPropertyStateContainer::getPropertyStates( const Sequence< ::rtl::OUString >& _rPropertyNames ) throw (UnknownPropertyException, RuntimeException)
101 sal_Int32 nProperties = _rPropertyNames.getLength();
102 Sequence< PropertyState> aStates( nProperties );
103 if ( !nProperties )
104 return aStates;
106 #ifdef _DEBUG
107 // precondition: property sequence is sorted (the algorythm below relies on this)
109 const ::rtl::OUString* pNames = _rPropertyNames.getConstArray();
110 const ::rtl::OUString* pNamesCompare = pNames + 1;
111 const ::rtl::OUString* pNamesEnd = _rPropertyNames.getConstArray() + _rPropertyNames.getLength();
112 for ( ; pNamesCompare != pNamesEnd; ++pNames, ++pNamesCompare )
113 OSL_PRECOND( pNames->compareTo( *pNamesCompare ) < 0,
114 "OPropertyStateContainer::getPropertyStates: property sequence not sorted!" );
116 #endif
118 const ::rtl::OUString* pLookup = _rPropertyNames.getConstArray();
119 const ::rtl::OUString* pLookupEnd = pLookup + nProperties;
120 PropertyState* pStates = aStates.getArray();
122 cppu::IPropertyArrayHelper& rHelper = getInfoHelper();
123 Sequence< Property> aAllProperties = rHelper.getProperties();
124 sal_Int32 nAllProperties = aAllProperties.getLength();
125 const Property* pAllProperties = aAllProperties.getConstArray();
126 const Property* pAllPropertiesEnd = pAllProperties + nAllProperties;
128 osl::MutexGuard aGuard( rBHelper.rMutex );
129 for ( ; ( pAllProperties != pAllPropertiesEnd ) && ( pLookup != pLookupEnd ); ++pAllProperties )
131 #ifdef _DEBUG
132 if ( pAllProperties < pAllPropertiesEnd - 1 )
133 OSL_ENSURE( pAllProperties->Name.compareTo( (pAllProperties + 1)->Name ) < 0,
134 "OPropertyStateContainer::getPropertyStates: all-properties not sorted!" );
135 #endif
136 if ( pAllProperties->Name.equals( *pLookup ) )
138 *pStates++ = getPropertyState( *pLookup );
139 ++pLookup;
143 if ( pLookup != pLookupEnd )
144 // we run out of properties from the IPropertyArrayHelper, but still have properties to lookup
145 // -> we were asked for a nonexistent property
146 throw UnknownPropertyException( lcl_getUnknownPropertyErrorMessage( *pLookup ), static_cast< XPropertyState* >( this ) );
148 return aStates;
151 //--------------------------------------------------------------------
152 void SAL_CALL OPropertyStateContainer::setPropertyToDefault( const ::rtl::OUString& _rPropertyName ) throw (UnknownPropertyException, RuntimeException)
154 setPropertyToDefaultByHandle( getHandleForName( _rPropertyName ) );
157 //--------------------------------------------------------------------
158 Any SAL_CALL OPropertyStateContainer::getPropertyDefault( const ::rtl::OUString& _rPropertyName ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
160 Any aDefault;
161 getPropertyDefaultByHandle( getHandleForName( _rPropertyName ), aDefault );
162 return aDefault;
165 //--------------------------------------------------------------------
166 PropertyState OPropertyStateContainer::getPropertyStateByHandle( sal_Int32 _nHandle )
168 // simply compare the current and the default value
169 Any aCurrentValue; getFastPropertyValue( aCurrentValue, _nHandle );
170 Any aDefaultValue; getPropertyDefaultByHandle( _nHandle, aDefaultValue );
172 sal_Bool bEqual = uno_type_equalData(
173 const_cast< void* >( aCurrentValue.getValue() ), aCurrentValue.getValueType().getTypeLibType(),
174 const_cast< void* >( aDefaultValue.getValue() ), aDefaultValue.getValueType().getTypeLibType(),
175 reinterpret_cast< uno_QueryInterfaceFunc >(cpp_queryInterface),
176 reinterpret_cast< uno_ReleaseFunc >(cpp_release)
178 if ( bEqual )
179 return PropertyState_DEFAULT_VALUE;
180 else
181 return PropertyState_DIRECT_VALUE;
184 //--------------------------------------------------------------------
185 void OPropertyStateContainer::setPropertyToDefaultByHandle( sal_Int32 _nHandle )
187 Any aDefault;
188 getPropertyDefaultByHandle( _nHandle, aDefault );
189 setFastPropertyValue( _nHandle, aDefault );
192 //.........................................................................
193 } // namespace comphelper
194 //.........................................................................
196 #ifdef FS_PRIV_DEBUG
197 #define STATECONTAINER_TEST
198 #endif
200 #ifdef STATECONTAINER_TEST
201 #include <com/sun/star/beans/PropertyAttribute.hpp>
202 #include <comphelper/proparrhlp.hxx>
203 #include <comphelper/broadcasthelper.hxx>
205 //.........................................................................
206 namespace comphelper
208 //.........................................................................
210 using namespace ::com::sun::star::uno;
211 using namespace ::com::sun::star::beans;
213 //=====================================================================
214 //= Test - compiler test
215 //=====================================================================
216 typedef ::cppu::OWeakAggObject Test_RefCountBase;
217 class Test :public OMutexAndBroadcastHelper
218 ,public OPropertyStateContainer
219 ,public OPropertyArrayUsageHelper< Test >
220 ,public Test_RefCountBase
222 private:
223 ::rtl::OUString m_sStringProperty;
224 Reference< XInterface > m_xInterfaceProperty;
225 Any m_aMayBeVoidProperty;
227 protected:
228 Test( );
230 DECLARE_XINTERFACE( )
232 public:
233 static Test* Create( );
235 protected:
236 virtual Reference< XPropertySetInfo > SAL_CALL getPropertySetInfo( ) throw(RuntimeException);
237 virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
238 virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const;
240 protected:
241 // OPropertyStateContainer overridables
242 virtual void getPropertyDefaultByHandle( sal_Int32 _nHandle, Any& _rDefault ) const;
245 //---------------------------------------------------------------------
246 Test::Test( )
247 :OPropertyStateContainer( GetBroadcastHelper() )
249 registerProperty(
250 ::rtl::OUString::createFromAscii( "StringProperty" ),
252 PropertyAttribute::BOUND,
253 &m_sStringProperty,
254 ::getCppuType( &m_sStringProperty )
257 registerProperty(
258 ::rtl::OUString::createFromAscii( "InterfaceProperty" ),
260 PropertyAttribute::BOUND,
261 &m_xInterfaceProperty,
262 ::getCppuType( &m_xInterfaceProperty )
265 registerMayBeVoidProperty(
266 ::rtl::OUString::createFromAscii( "IntProperty" ),
268 PropertyAttribute::BOUND,
269 &m_aMayBeVoidProperty,
270 ::getCppuType( static_cast< sal_Int32* >( NULL ) )
273 registerPropertyNoMember(
274 ::rtl::OUString::createFromAscii( "OtherInterfaceProperty" ),
276 PropertyAttribute::BOUND | PropertyAttribute::MAYBEVOID,
277 ::getCppuType( static_cast< Reference< XInterface >* >( NULL ) ),
278 NULL
282 //---------------------------------------------------------------------
283 IMPLEMENT_FORWARD_XINTERFACE2( Test, Test_RefCountBase, OPropertyStateContainer )
285 //---------------------------------------------------------------------
286 void Test::getPropertyDefaultByHandle( sal_Int32 _nHandle, Any& _rDefault ) const
288 switch ( _nHandle )
290 case 1:
291 _rDefault = makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StringPropertyDefault" ) ) );
292 break;
293 case 2:
294 _rDefault = makeAny( Reference< XInterface >( ) );
295 break;
296 case 3:
297 // void
298 break;
299 case 4:
300 _rDefault = makeAny( Reference< XInterface >( ) );
301 break;
302 default:
303 OSL_ENSURE( sal_False, "Test::getPropertyDefaultByHandle: invalid handle!" );
307 //---------------------------------------------------------------------
308 Reference< XPropertySetInfo > SAL_CALL Test::getPropertySetInfo( ) throw(RuntimeException)
310 return createPropertySetInfo( getInfoHelper() );
313 //---------------------------------------------------------------------
314 ::cppu::IPropertyArrayHelper& SAL_CALL Test::getInfoHelper()
316 return *getArrayHelper();
319 //---------------------------------------------------------------------
320 ::cppu::IPropertyArrayHelper* Test::createArrayHelper( ) const
322 Sequence< Property > aProps;
323 describeProperties( aProps );
324 return new ::cppu::OPropertyArrayHelper( aProps );
327 //---------------------------------------------------------------------
328 Test* Test::Create( )
330 Test* pInstance = new Test;
331 return pInstance;
334 //.........................................................................
335 } // namespace comphelper
336 //.........................................................................
338 #endif