1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: propertystatecontainer.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_comphelper.hxx"
33 #include "comphelper/propertystatecontainer.hxx"
34 #include <rtl/ustrbuf.hxx>
36 //.........................................................................
39 //.........................................................................
41 using namespace ::com::sun::star::uno
;
42 using namespace ::com::sun::star::beans
;
43 using namespace ::com::sun::star::lang
;
47 static ::rtl::OUString
lcl_getUnknownPropertyErrorMessage( const ::rtl::OUString
& _rPropertyName
)
49 // TODO: perhaps it's time to think about resources in the comphelper module?
50 // Would be nice to have localized exception strings (a simply resource file containing
51 // strings only would suffice, and could be realized with an UNO service, so we do not
52 // need the dependency to the Tools project)
53 ::rtl::OUStringBuffer sMessage
;
54 sMessage
.appendAscii( "The property \"" );
55 sMessage
.append( _rPropertyName
);
56 sMessage
.appendAscii( "\" is unknown." );
57 return sMessage
.makeStringAndClear();
61 //=====================================================================
62 //= OPropertyStateContainer
63 //=====================================================================
64 //---------------------------------------------------------------------
65 OPropertyStateContainer::OPropertyStateContainer( ::cppu::OBroadcastHelper
& _rBHelper
)
66 :OPropertyContainer( _rBHelper
)
70 //--------------------------------------------------------------------
71 Any SAL_CALL
OPropertyStateContainer::queryInterface( const Type
& _rType
) throw (RuntimeException
)
73 Any aReturn
= OPropertyContainer::queryInterface( _rType
);
74 if ( !aReturn
.hasValue() )
75 aReturn
= OPropertyStateContainer_TBase::queryInterface( _rType
);
79 //--------------------------------------------------------------------
80 IMPLEMENT_FORWARD_XTYPEPROVIDER2( OPropertyStateContainer
, OPropertyContainer
, OPropertyStateContainer_TBase
)
82 //--------------------------------------------------------------------
83 sal_Int32
OPropertyStateContainer::getHandleForName( const ::rtl::OUString
& _rPropertyName
) SAL_THROW( ( UnknownPropertyException
) )
85 // look up the handle for the name
86 ::cppu::IPropertyArrayHelper
& rPH
= getInfoHelper();
87 sal_Int32 nHandle
= rPH
.getHandleByName( _rPropertyName
);
90 throw UnknownPropertyException( lcl_getUnknownPropertyErrorMessage( _rPropertyName
), static_cast< XPropertyState
* >( this ) );
95 //--------------------------------------------------------------------
96 PropertyState SAL_CALL
OPropertyStateContainer::getPropertyState( const ::rtl::OUString
& _rPropertyName
) throw (UnknownPropertyException
, RuntimeException
)
98 return getPropertyStateByHandle( getHandleForName( _rPropertyName
) );
101 //--------------------------------------------------------------------
102 Sequence
< PropertyState
> SAL_CALL
OPropertyStateContainer::getPropertyStates( const Sequence
< ::rtl::OUString
>& _rPropertyNames
) throw (UnknownPropertyException
, RuntimeException
)
104 sal_Int32 nProperties
= _rPropertyNames
.getLength();
105 Sequence
< PropertyState
> aStates( nProperties
);
110 // precondition: property sequence is sorted (the algorythm below relies on this)
112 const ::rtl::OUString
* pNames
= _rPropertyNames
.getConstArray();
113 const ::rtl::OUString
* pNamesCompare
= pNames
+ 1;
114 const ::rtl::OUString
* pNamesEnd
= _rPropertyNames
.getConstArray() + _rPropertyNames
.getLength();
115 for ( ; pNamesCompare
!= pNamesEnd
; ++pNames
, ++pNamesCompare
)
116 OSL_PRECOND( pNames
->compareTo( *pNamesCompare
) < 0,
117 "OPropertyStateContainer::getPropertyStates: property sequence not sorted!" );
121 const ::rtl::OUString
* pLookup
= _rPropertyNames
.getConstArray();
122 const ::rtl::OUString
* pLookupEnd
= pLookup
+ nProperties
;
123 PropertyState
* pStates
= aStates
.getArray();
125 cppu::IPropertyArrayHelper
& rHelper
= getInfoHelper();
126 Sequence
< Property
> aAllProperties
= rHelper
.getProperties();
127 sal_Int32 nAllProperties
= aAllProperties
.getLength();
128 const Property
* pAllProperties
= aAllProperties
.getConstArray();
129 const Property
* pAllPropertiesEnd
= pAllProperties
+ nAllProperties
;
131 osl::MutexGuard
aGuard( rBHelper
.rMutex
);
132 for ( ; ( pAllProperties
!= pAllPropertiesEnd
) && ( pLookup
!= pLookupEnd
); ++pAllProperties
)
135 if ( pAllProperties
< pAllPropertiesEnd
- 1 )
136 OSL_ENSURE( pAllProperties
->Name
.compareTo( (pAllProperties
+ 1)->Name
) < 0,
137 "OPropertyStateContainer::getPropertyStates: all-properties not sorted!" );
139 if ( pAllProperties
->Name
.equals( *pLookup
) )
141 *pStates
++ = getPropertyState( *pLookup
);
146 if ( pLookup
!= pLookupEnd
)
147 // we run out of properties from the IPropertyArrayHelper, but still have properties to lookup
148 // -> we were asked for a nonexistent property
149 throw UnknownPropertyException( lcl_getUnknownPropertyErrorMessage( *pLookup
), static_cast< XPropertyState
* >( this ) );
154 //--------------------------------------------------------------------
155 void SAL_CALL
OPropertyStateContainer::setPropertyToDefault( const ::rtl::OUString
& _rPropertyName
) throw (UnknownPropertyException
, RuntimeException
)
157 setPropertyToDefaultByHandle( getHandleForName( _rPropertyName
) );
160 //--------------------------------------------------------------------
161 Any SAL_CALL
OPropertyStateContainer::getPropertyDefault( const ::rtl::OUString
& _rPropertyName
) throw (UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
164 getPropertyDefaultByHandle( getHandleForName( _rPropertyName
), aDefault
);
168 //--------------------------------------------------------------------
169 PropertyState
OPropertyStateContainer::getPropertyStateByHandle( sal_Int32 _nHandle
)
171 // simply compare the current and the default value
172 Any aCurrentValue
; getFastPropertyValue( aCurrentValue
, _nHandle
);
173 Any aDefaultValue
; getPropertyDefaultByHandle( _nHandle
, aDefaultValue
);
175 sal_Bool bEqual
= uno_type_equalData(
176 const_cast< void* >( aCurrentValue
.getValue() ), aCurrentValue
.getValueType().getTypeLibType(),
177 const_cast< void* >( aDefaultValue
.getValue() ), aDefaultValue
.getValueType().getTypeLibType(),
178 reinterpret_cast< uno_QueryInterfaceFunc
>(cpp_queryInterface
),
179 reinterpret_cast< uno_ReleaseFunc
>(cpp_release
)
182 return PropertyState_DEFAULT_VALUE
;
184 return PropertyState_DIRECT_VALUE
;
187 //--------------------------------------------------------------------
188 void OPropertyStateContainer::setPropertyToDefaultByHandle( sal_Int32 _nHandle
)
191 getPropertyDefaultByHandle( _nHandle
, aDefault
);
192 setFastPropertyValue( _nHandle
, aDefault
);
195 //.........................................................................
196 } // namespace comphelper
197 //.........................................................................
200 #define STATECONTAINER_TEST
203 #ifdef STATECONTAINER_TEST
204 #include <com/sun/star/beans/PropertyAttribute.hpp>
205 #include <comphelper/proparrhlp.hxx>
206 #include <comphelper/broadcasthelper.hxx>
208 //.........................................................................
211 //.........................................................................
213 using namespace ::com::sun::star::uno
;
214 using namespace ::com::sun::star::beans
;
216 //=====================================================================
217 //= Test - compiler test
218 //=====================================================================
219 typedef ::cppu::OWeakAggObject Test_RefCountBase
;
220 class Test
:public OMutexAndBroadcastHelper
221 ,public OPropertyStateContainer
222 ,public OPropertyArrayUsageHelper
< Test
>
223 ,public Test_RefCountBase
226 ::rtl::OUString m_sStringProperty
;
227 Reference
< XInterface
> m_xInterfaceProperty
;
228 Any m_aMayBeVoidProperty
;
233 DECLARE_XINTERFACE( )
236 static Test
* Create( );
239 virtual Reference
< XPropertySetInfo
> SAL_CALL
getPropertySetInfo( ) throw(RuntimeException
);
240 virtual ::cppu::IPropertyArrayHelper
& SAL_CALL
getInfoHelper();
241 virtual ::cppu::IPropertyArrayHelper
* createArrayHelper( ) const;
244 // OPropertyStateContainer overridables
245 virtual void getPropertyDefaultByHandle( sal_Int32 _nHandle
, Any
& _rDefault
) const;
248 //---------------------------------------------------------------------
250 :OPropertyStateContainer( GetBroadcastHelper() )
253 ::rtl::OUString::createFromAscii( "StringProperty" ),
255 PropertyAttribute::BOUND
,
257 ::getCppuType( &m_sStringProperty
)
261 ::rtl::OUString::createFromAscii( "InterfaceProperty" ),
263 PropertyAttribute::BOUND
,
264 &m_xInterfaceProperty
,
265 ::getCppuType( &m_xInterfaceProperty
)
268 registerMayBeVoidProperty(
269 ::rtl::OUString::createFromAscii( "IntProperty" ),
271 PropertyAttribute::BOUND
,
272 &m_aMayBeVoidProperty
,
273 ::getCppuType( static_cast< sal_Int32
* >( NULL
) )
276 registerPropertyNoMember(
277 ::rtl::OUString::createFromAscii( "OtherInterfaceProperty" ),
279 PropertyAttribute::BOUND
| PropertyAttribute::MAYBEVOID
,
280 ::getCppuType( static_cast< Reference
< XInterface
>* >( NULL
) ),
285 //---------------------------------------------------------------------
286 IMPLEMENT_FORWARD_XINTERFACE2( Test
, Test_RefCountBase
, OPropertyStateContainer
)
288 //---------------------------------------------------------------------
289 void Test::getPropertyDefaultByHandle( sal_Int32 _nHandle
, Any
& _rDefault
) const
294 _rDefault
= makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StringPropertyDefault" ) ) );
297 _rDefault
= makeAny( Reference
< XInterface
>( ) );
303 _rDefault
= makeAny( Reference
< XInterface
>( ) );
306 OSL_ENSURE( sal_False
, "Test::getPropertyDefaultByHandle: invalid handle!" );
310 //---------------------------------------------------------------------
311 Reference
< XPropertySetInfo
> SAL_CALL
Test::getPropertySetInfo( ) throw(RuntimeException
)
313 return createPropertySetInfo( getInfoHelper() );
316 //---------------------------------------------------------------------
317 ::cppu::IPropertyArrayHelper
& SAL_CALL
Test::getInfoHelper()
319 return *getArrayHelper();
322 //---------------------------------------------------------------------
323 ::cppu::IPropertyArrayHelper
* Test::createArrayHelper( ) const
325 Sequence
< Property
> aProps
;
326 describeProperties( aProps
);
327 return new ::cppu::OPropertyArrayHelper( aProps
);
330 //---------------------------------------------------------------------
331 Test
* Test::Create( )
333 Test
* pInstance
= new Test
;
337 //.........................................................................
338 } // namespace comphelper
339 //.........................................................................