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 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_framework.hxx" 26 //_________________________________________________________________________________________________________________ 27 // my own includes 28 //_________________________________________________________________________________________________________________ 29 #include <uielement/rootitemcontainer.hxx> 30 31 #ifndef __FRAMEWORK_UIELEMENT_ITEMCONTAINER_HHX_ 32 #include <uielement/itemcontainer.hxx> 33 #endif 34 35 #ifndef __FRAMEWORK_UIELEMENT_CONSTITEMCONTAINER_HHX_ 36 #include <uielement/constitemcontainer.hxx> 37 #endif 38 #include <threadhelp/resetableguard.hxx> 39 #include <general.h> 40 #include <properties.h> 41 42 //_________________________________________________________________________________________________________________ 43 // interface includes 44 //_________________________________________________________________________________________________________________ 45 #include <com/sun/star/beans/PropertyAttribute.hpp> 46 47 //_________________________________________________________________________________________________________________ 48 // other includes 49 //_________________________________________________________________________________________________________________ 50 51 using namespace cppu; 52 using namespace com::sun::star::uno; 53 using namespace com::sun::star::lang; 54 using namespace com::sun::star::beans; 55 using namespace com::sun::star::container; 56 57 const char WRONG_TYPE_EXCEPTION[] = "Type must be com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >"; 58 59 const int PROPHANDLE_UINAME = 1; 60 const int PROPCOUNT = 1; 61 const rtl::OUString PROPNAME_UINAME( RTL_CONSTASCII_USTRINGPARAM( "UIName" )); 62 63 namespace framework 64 { 65 66 //***************************************************************************************************************** 67 // XInterface, XTypeProvider 68 //***************************************************************************************************************** 69 DEFINE_XINTERFACE_10 ( RootItemContainer , 70 OWeakObject , 71 DIRECT_INTERFACE( ::com::sun::star::lang::XTypeProvider ), 72 DIRECT_INTERFACE( ::com::sun::star::container::XIndexContainer ), 73 DIRECT_INTERFACE( ::com::sun::star::lang::XUnoTunnel ), 74 DIRECT_INTERFACE( ::com::sun::star::lang::XSingleComponentFactory ), 75 DIRECT_INTERFACE( ::com::sun::star::beans::XMultiPropertySet ), 76 DIRECT_INTERFACE( ::com::sun::star::beans::XFastPropertySet ), 77 DIRECT_INTERFACE( ::com::sun::star::beans::XPropertySet ), 78 DERIVED_INTERFACE( ::com::sun::star::container::XIndexReplace, com::sun::star::container::XIndexContainer ), 79 DERIVED_INTERFACE( ::com::sun::star::container::XIndexAccess, com::sun::star::container::XIndexReplace ), 80 DERIVED_INTERFACE( ::com::sun::star::container::XElementAccess, ::com::sun::star::container::XIndexAccess ) 81 ) 82 83 DEFINE_XTYPEPROVIDER_10 ( RootItemContainer , 84 ::com::sun::star::lang::XTypeProvider , 85 ::com::sun::star::container::XIndexContainer , 86 ::com::sun::star::container::XIndexReplace , 87 ::com::sun::star::container::XIndexAccess , 88 ::com::sun::star::container::XElementAccess , 89 ::com::sun::star::beans::XMultiPropertySet , 90 ::com::sun::star::beans::XFastPropertySet , 91 ::com::sun::star::beans::XPropertySet , 92 ::com::sun::star::lang::XUnoTunnel , 93 ::com::sun::star::lang::XSingleComponentFactory 94 ) 95 96 RootItemContainer::RootItemContainer() 97 : ThreadHelpBase ( ) 98 , ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType >( m_aLock.getShareableOslMutex() ) 99 , ::cppu::OPropertySetHelper ( *(static_cast< ::cppu::OBroadcastHelper* >(this)) ) 100 , ::cppu::OWeakObject() 101 { 102 } 103 104 RootItemContainer::RootItemContainer( const ConstItemContainer& rConstItemContainer ) 105 : ThreadHelpBase ( ) 106 , ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType >( m_aLock.getShareableOslMutex() ) 107 , ::cppu::OPropertySetHelper ( *(static_cast< ::cppu::OBroadcastHelper* >(this)) ) 108 , ::cppu::OWeakObject() 109 { 110 m_aUIName = rConstItemContainer.m_aUIName; 111 copyItemContainer( rConstItemContainer.m_aItemVector ); 112 } 113 114 RootItemContainer::RootItemContainer( const Reference< XIndexAccess >& rSourceContainer ) 115 : ThreadHelpBase ( ) 116 , ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType >( m_aLock.getShareableOslMutex() ) 117 , ::cppu::OPropertySetHelper ( *(static_cast< ::cppu::OBroadcastHelper* >(this)) ) 118 , ::cppu::OWeakObject() 119 { 120 // We also have to copy the UIName property 121 try 122 { 123 Reference< XPropertySet > xPropSet( rSourceContainer, UNO_QUERY ); 124 if ( xPropSet.is() ) 125 { 126 xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UIName" ))) >>= m_aUIName; 127 } 128 } 129 catch ( Exception& ) 130 { 131 } 132 133 if ( rSourceContainer.is() ) 134 { 135 sal_Int32 nCount = rSourceContainer->getCount(); 136 try 137 { 138 for ( sal_Int32 i = 0; i < nCount; i++ ) 139 { 140 Sequence< PropertyValue > aPropSeq; 141 if ( rSourceContainer->getByIndex( i ) >>= aPropSeq ) 142 { 143 sal_Int32 nContainerIndex = -1; 144 Reference< XIndexAccess > xIndexAccess; 145 for ( sal_Int32 j = 0; j < aPropSeq.getLength(); j++ ) 146 { 147 if ( aPropSeq[j].Name.equalsAscii( "ItemDescriptorContainer" )) 148 { 149 aPropSeq[j].Value >>= xIndexAccess; 150 nContainerIndex = j; 151 break; 152 } 153 } 154 155 if ( xIndexAccess.is() && nContainerIndex >= 0 ) 156 aPropSeq[nContainerIndex].Value <<= deepCopyContainer( xIndexAccess ); 157 158 m_aItemVector.push_back( aPropSeq ); 159 } 160 } 161 } 162 catch ( IndexOutOfBoundsException& ) 163 { 164 } 165 } 166 } 167 168 RootItemContainer::~RootItemContainer() 169 { 170 } 171 172 // private 173 void RootItemContainer::copyItemContainer( const std::vector< Sequence< PropertyValue > >& rSourceVector ) 174 { 175 const sal_uInt32 nCount = rSourceVector.size(); 176 m_aItemVector.reserve(nCount); 177 for ( sal_uInt32 i = 0; i < nCount; i++ ) 178 { 179 sal_Int32 nContainerIndex = -1; 180 Sequence< PropertyValue > aPropSeq( rSourceVector[i] ); 181 Reference< XIndexAccess > xIndexAccess; 182 for ( sal_Int32 j = 0; j < aPropSeq.getLength(); j++ ) 183 { 184 if ( aPropSeq[j].Name.equalsAscii( "ItemDescriptorContainer" )) 185 { 186 aPropSeq[j].Value >>= xIndexAccess; 187 nContainerIndex = j; 188 break; 189 } 190 } 191 192 if ( xIndexAccess.is() && nContainerIndex >= 0 ) 193 aPropSeq[nContainerIndex].Value <<= deepCopyContainer( xIndexAccess ); 194 195 m_aItemVector.push_back( aPropSeq ); 196 } 197 } 198 199 Reference< XIndexAccess > RootItemContainer::deepCopyContainer( const Reference< XIndexAccess >& rSubContainer ) 200 { 201 Reference< XIndexAccess > xReturn; 202 if ( rSubContainer.is() ) 203 { 204 ConstItemContainer* pSource = ConstItemContainer::GetImplementation( rSubContainer ); 205 ItemContainer* pSubContainer( 0 ); 206 if ( pSource ) 207 pSubContainer = new ItemContainer( *pSource, m_aShareMutex ); 208 else 209 pSubContainer = new ItemContainer( rSubContainer, m_aShareMutex ); 210 xReturn = Reference< XIndexAccess >( static_cast< OWeakObject* >( pSubContainer ), UNO_QUERY ); 211 } 212 213 return xReturn; 214 } 215 216 // XUnoTunnel 217 sal_Int64 RootItemContainer::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& rIdentifier ) throw(::com::sun::star::uno::RuntimeException) 218 { 219 if( ( rIdentifier.getLength() == 16 ) && ( 0 == rtl_compareMemory( RootItemContainer::GetUnoTunnelId().getConstArray(), rIdentifier.getConstArray(), 16 ) ) ) 220 return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >( this )); 221 return 0; 222 } 223 224 const Sequence< sal_Int8 >& RootItemContainer::GetUnoTunnelId() throw() 225 { 226 static ::com::sun::star::uno::Sequence< sal_Int8 > * pSeq = NULL; 227 if( !pSeq ) 228 { 229 ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ); 230 if( !pSeq ) 231 { 232 static ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( 16 ); 233 rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True ); 234 pSeq = &aSeq; 235 } 236 } 237 return *pSeq; 238 } 239 240 RootItemContainer* RootItemContainer::GetImplementation( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rxIFace ) throw() 241 { 242 ::com::sun::star::uno::Reference< ::com::sun::star::lang::XUnoTunnel > xUT( rxIFace, ::com::sun::star::uno::UNO_QUERY ); 243 return xUT.is() ? reinterpret_cast< RootItemContainer* >(sal::static_int_cast< sal_IntPtr >( 244 xUT->getSomething( RootItemContainer::GetUnoTunnelId() ))) : NULL; 245 } 246 247 // XElementAccess 248 sal_Bool SAL_CALL RootItemContainer::hasElements() 249 throw ( RuntimeException ) 250 { 251 ShareGuard aLock( m_aShareMutex ); 252 return ( !m_aItemVector.empty() ); 253 } 254 255 // XIndexAccess 256 sal_Int32 SAL_CALL RootItemContainer::getCount() 257 throw ( RuntimeException ) 258 { 259 ShareGuard aLock( m_aShareMutex ); 260 return m_aItemVector.size(); 261 } 262 263 Any SAL_CALL RootItemContainer::getByIndex( sal_Int32 Index ) 264 throw ( IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) 265 { 266 ShareGuard aLock( m_aShareMutex ); 267 if ( sal_Int32( m_aItemVector.size()) > Index ) 268 return makeAny( m_aItemVector[Index] ); 269 else 270 throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this ); 271 } 272 273 // XIndexContainer 274 void SAL_CALL RootItemContainer::insertByIndex( sal_Int32 Index, const Any& aItem ) 275 throw ( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) 276 { 277 Sequence< PropertyValue > aSeq; 278 if ( aItem >>= aSeq ) 279 { 280 ShareGuard aLock( m_aShareMutex ); 281 if ( sal_Int32( m_aItemVector.size()) == Index ) 282 m_aItemVector.push_back( aSeq ); 283 else if ( sal_Int32( m_aItemVector.size()) >Index ) 284 { 285 std::vector< Sequence< PropertyValue > >::iterator aIter = m_aItemVector.begin(); 286 aIter += Index; 287 m_aItemVector.insert( aIter, aSeq ); 288 } 289 else 290 throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this ); 291 } 292 else 293 throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( WRONG_TYPE_EXCEPTION )), 294 (OWeakObject *)this, 2 ); 295 } 296 297 void SAL_CALL RootItemContainer::removeByIndex( sal_Int32 Index ) 298 throw ( IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) 299 { 300 ShareGuard aLock( m_aShareMutex ); 301 if ( (sal_Int32)m_aItemVector.size() > Index ) 302 { 303 std::vector< Sequence< PropertyValue > >::iterator aIter = m_aItemVector.begin(); 304 aIter += Index; 305 m_aItemVector.erase( aIter ); 306 } 307 else 308 throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this ); 309 } 310 311 void SAL_CALL RootItemContainer::replaceByIndex( sal_Int32 Index, const Any& aItem ) 312 throw ( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) 313 { 314 Sequence< PropertyValue > aSeq; 315 if ( aItem >>= aSeq ) 316 { 317 ShareGuard aLock( m_aShareMutex ); 318 if ( sal_Int32( m_aItemVector.size()) > Index ) 319 m_aItemVector[Index] = aSeq; 320 else 321 throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this ); 322 } 323 else 324 throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( WRONG_TYPE_EXCEPTION )), 325 (OWeakObject *)this, 2 ); 326 } 327 328 Reference< XInterface > SAL_CALL RootItemContainer::createInstanceWithContext( const Reference< XComponentContext >& ) 329 throw ( Exception, RuntimeException) 330 { 331 return (OWeakObject *)(new ItemContainer( m_aShareMutex )); 332 } 333 334 Reference< XInterface > SAL_CALL RootItemContainer::createInstanceWithArgumentsAndContext( const Sequence< Any >&, const Reference< XComponentContext >& ) 335 throw (Exception, RuntimeException) 336 { 337 return (OWeakObject *)(new ItemContainer( m_aShareMutex )); 338 } 339 340 // XPropertySet helper 341 sal_Bool SAL_CALL RootItemContainer::convertFastPropertyValue( Any& aConvertedValue , 342 Any& aOldValue , 343 sal_Int32 nHandle , 344 const Any& aValue ) 345 throw( com::sun::star::lang::IllegalArgumentException ) 346 { 347 // Initialize state with sal_False !!! 348 // (Handle can be invalid) 349 sal_Bool bReturn = sal_False; 350 351 switch( nHandle ) 352 { 353 case PROPHANDLE_UINAME: 354 bReturn = PropHelper::willPropertyBeChanged( 355 com::sun::star::uno::makeAny(m_aUIName), 356 aValue, 357 aOldValue, 358 aConvertedValue); 359 break; 360 } 361 362 // Return state of operation. 363 return bReturn ; 364 } 365 366 void SAL_CALL RootItemContainer::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle , 367 const com::sun::star::uno::Any& aValue ) 368 throw( com::sun::star::uno::Exception ) 369 { 370 switch( nHandle ) 371 { 372 case PROPHANDLE_UINAME: 373 aValue >>= m_aUIName; 374 break; 375 } 376 } 377 378 void SAL_CALL RootItemContainer::getFastPropertyValue( com::sun::star::uno::Any& aValue , 379 sal_Int32 nHandle ) const 380 { 381 switch( nHandle ) 382 { 383 case PROPHANDLE_UINAME: 384 aValue <<= m_aUIName; 385 break; 386 } 387 } 388 389 ::cppu::IPropertyArrayHelper& SAL_CALL RootItemContainer::getInfoHelper() 390 { 391 // Optimize this method ! 392 // We initialize a static variable only one time. And we don't must use a mutex at every call! 393 // For the first call; pInfoHelper is NULL - for the second call pInfoHelper is different from NULL! 394 static ::cppu::OPropertyArrayHelper* pInfoHelper = NULL; 395 396 if( pInfoHelper == NULL ) 397 { 398 // Ready for multithreading 399 osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ; 400 401 // Control this pointer again, another instance can be faster then these! 402 if( pInfoHelper == NULL ) 403 { 404 // Define static member to give structure of properties to baseclass "OPropertySetHelper". 405 // "impl_getStaticPropertyDescriptor" is a non exported and static funtion, who will define a static propertytable. 406 // "sal_True" say: Table is sorted by name. 407 static ::cppu::OPropertyArrayHelper aInfoHelper( impl_getStaticPropertyDescriptor(), sal_True ); 408 pInfoHelper = &aInfoHelper; 409 } 410 } 411 412 return(*pInfoHelper); 413 } 414 415 com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > SAL_CALL RootItemContainer::getPropertySetInfo() 416 throw (::com::sun::star::uno::RuntimeException) 417 { 418 // Optimize this method ! 419 // We initialize a static variable only one time. And we don't must use a mutex at every call! 420 // For the first call; pInfo is NULL - for the second call pInfo is different from NULL! 421 static com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo >* pInfo = NULL; 422 423 if( pInfo == NULL ) 424 { 425 // Ready for multithreading 426 osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ; 427 // Control this pointer again, another instance can be faster then these! 428 if( pInfo == NULL ) 429 { 430 // Create structure of propertysetinfo for baseclass "OPropertySetHelper". 431 // (Use method "getInfoHelper()".) 432 static com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); 433 pInfo = &xInfo; 434 } 435 } 436 437 return (*pInfo); 438 } 439 440 const com::sun::star::uno::Sequence< com::sun::star::beans::Property > RootItemContainer::impl_getStaticPropertyDescriptor() 441 { 442 // Create a new static property array to initialize sequence! 443 // Table of all predefined properties of this class. Its used from OPropertySetHelper-class! 444 // Don't forget to change the defines (see begin of this file), if you add, change or delete a property in this list!!! 445 // It's necessary for methods of OPropertySetHelper. 446 // ATTENTION: 447 // YOU MUST SORT FOLLOW TABLE BY NAME ALPHABETICAL !!! 448 449 static const com::sun::star::beans::Property pProperties[] = 450 { 451 com::sun::star::beans::Property( PROPNAME_UINAME, PROPHANDLE_UINAME , 452 ::getCppuType((const rtl::OUString*)NULL), 453 com::sun::star::beans::PropertyAttribute::TRANSIENT ) 454 }; 455 // Use it to initialize sequence! 456 static const com::sun::star::uno::Sequence< com::sun::star::beans::Property > lPropertyDescriptor( pProperties, PROPCOUNT ); 457 // Return static "PropertyDescriptor" 458 return lPropertyDescriptor; 459 } 460 461 } // namespace framework 462 463