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