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 //.........................................................................
36 //.........................................................................
38 using namespace ::com::sun::star::uno
;
39 using namespace ::com::sun::star::beans
;
40 using namespace ::com::sun::star::lang
;
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
);
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
);
87 throw UnknownPropertyException( lcl_getUnknownPropertyErrorMessage( _rPropertyName
), static_cast< XPropertyState
* >( this ) );
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
);
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!" );
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
)
132 if ( pAllProperties
< pAllPropertiesEnd
- 1 )
133 OSL_ENSURE( pAllProperties
->Name
.compareTo( (pAllProperties
+ 1)->Name
) < 0,
134 "OPropertyStateContainer::getPropertyStates: all-properties not sorted!" );
136 if ( pAllProperties
->Name
.equals( *pLookup
) )
138 *pStates
++ = getPropertyState( *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 ) );
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
)
161 getPropertyDefaultByHandle( getHandleForName( _rPropertyName
), 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
)
179 return PropertyState_DEFAULT_VALUE
;
181 return PropertyState_DIRECT_VALUE
;
184 //--------------------------------------------------------------------
185 void OPropertyStateContainer::setPropertyToDefaultByHandle( sal_Int32 _nHandle
)
188 getPropertyDefaultByHandle( _nHandle
, aDefault
);
189 setFastPropertyValue( _nHandle
, aDefault
);
192 //.........................................................................
193 } // namespace comphelper
194 //.........................................................................
197 #define STATECONTAINER_TEST
200 #ifdef STATECONTAINER_TEST
201 #include <com/sun/star/beans/PropertyAttribute.hpp>
202 #include <comphelper/proparrhlp.hxx>
203 #include <comphelper/broadcasthelper.hxx>
205 //.........................................................................
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
223 ::rtl::OUString m_sStringProperty
;
224 Reference
< XInterface
> m_xInterfaceProperty
;
225 Any m_aMayBeVoidProperty
;
230 DECLARE_XINTERFACE( )
233 static Test
* Create( );
236 virtual Reference
< XPropertySetInfo
> SAL_CALL
getPropertySetInfo( ) throw(RuntimeException
);
237 virtual ::cppu::IPropertyArrayHelper
& SAL_CALL
getInfoHelper();
238 virtual ::cppu::IPropertyArrayHelper
* createArrayHelper( ) const;
241 // OPropertyStateContainer overridables
242 virtual void getPropertyDefaultByHandle( sal_Int32 _nHandle
, Any
& _rDefault
) const;
245 //---------------------------------------------------------------------
247 :OPropertyStateContainer( GetBroadcastHelper() )
250 ::rtl::OUString::createFromAscii( "StringProperty" ),
252 PropertyAttribute::BOUND
,
254 ::getCppuType( &m_sStringProperty
)
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
) ),
282 //---------------------------------------------------------------------
283 IMPLEMENT_FORWARD_XINTERFACE2( Test
, Test_RefCountBase
, OPropertyStateContainer
)
285 //---------------------------------------------------------------------
286 void Test::getPropertyDefaultByHandle( sal_Int32 _nHandle
, Any
& _rDefault
) const
291 _rDefault
= makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StringPropertyDefault" ) ) );
294 _rDefault
= makeAny( Reference
< XInterface
>( ) );
300 _rDefault
= makeAny( Reference
< XInterface
>( ) );
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
;
334 //.........................................................................
335 } // namespace comphelper
336 //.........................................................................