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 ) 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 { 250 ShareGuard aLock( m_aShareMutex ); 251 return ( !m_aItemVector.empty() ); 252 } 253 254 // XIndexAccess 255 sal_Int32 SAL_CALL RootItemContainer::getCount() 256 { 257 ShareGuard aLock( m_aShareMutex ); 258 return m_aItemVector.size(); 259 } 260 261 Any SAL_CALL RootItemContainer::getByIndex( sal_Int32 Index ) 262 { 263 ShareGuard aLock( m_aShareMutex ); 264 if ( sal_Int32( m_aItemVector.size()) > Index ) 265 return makeAny( m_aItemVector[Index] ); 266 else 267 throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this ); 268 } 269 270 // XIndexContainer 271 void SAL_CALL RootItemContainer::insertByIndex( sal_Int32 Index, const Any& aItem ) 272 { 273 Sequence< PropertyValue > aSeq; 274 if ( aItem >>= aSeq ) 275 { 276 ShareGuard aLock( m_aShareMutex ); 277 if ( sal_Int32( m_aItemVector.size()) == Index ) 278 m_aItemVector.push_back( aSeq ); 279 else if ( sal_Int32( m_aItemVector.size()) >Index ) 280 { 281 std::vector< Sequence< PropertyValue > >::iterator aIter = m_aItemVector.begin(); 282 aIter += Index; 283 m_aItemVector.insert( aIter, aSeq ); 284 } 285 else 286 throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this ); 287 } 288 else 289 throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( WRONG_TYPE_EXCEPTION )), 290 (OWeakObject *)this, 2 ); 291 } 292 293 void SAL_CALL RootItemContainer::removeByIndex( sal_Int32 Index ) 294 { 295 ShareGuard aLock( m_aShareMutex ); 296 if ( (sal_Int32)m_aItemVector.size() > Index ) 297 { 298 std::vector< Sequence< PropertyValue > >::iterator aIter = m_aItemVector.begin(); 299 aIter += Index; 300 m_aItemVector.erase( aIter ); 301 } 302 else 303 throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this ); 304 } 305 306 void SAL_CALL RootItemContainer::replaceByIndex( sal_Int32 Index, const Any& aItem ) 307 { 308 Sequence< PropertyValue > aSeq; 309 if ( aItem >>= aSeq ) 310 { 311 ShareGuard aLock( m_aShareMutex ); 312 if ( sal_Int32( m_aItemVector.size()) > Index ) 313 m_aItemVector[Index] = aSeq; 314 else 315 throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this ); 316 } 317 else 318 throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( WRONG_TYPE_EXCEPTION )), 319 (OWeakObject *)this, 2 ); 320 } 321 322 Reference< XInterface > SAL_CALL RootItemContainer::createInstanceWithContext( const Reference< XComponentContext >& ) 323 { 324 return (OWeakObject *)(new ItemContainer( m_aShareMutex )); 325 } 326 327 Reference< XInterface > SAL_CALL RootItemContainer::createInstanceWithArgumentsAndContext( const Sequence< Any >&, const Reference< XComponentContext >& ) 328 { 329 return (OWeakObject *)(new ItemContainer( m_aShareMutex )); 330 } 331 332 // XPropertySet helper 333 sal_Bool SAL_CALL RootItemContainer::convertFastPropertyValue( Any& aConvertedValue , 334 Any& aOldValue , 335 sal_Int32 nHandle , 336 const Any& aValue ) 337 { 338 // Initialize state with sal_False !!! 339 // (Handle can be invalid) 340 sal_Bool bReturn = sal_False; 341 342 switch( nHandle ) 343 { 344 case PROPHANDLE_UINAME: 345 bReturn = PropHelper::willPropertyBeChanged( 346 com::sun::star::uno::makeAny(m_aUIName), 347 aValue, 348 aOldValue, 349 aConvertedValue); 350 break; 351 } 352 353 // Return state of operation. 354 return bReturn ; 355 } 356 357 void SAL_CALL RootItemContainer::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle , 358 const com::sun::star::uno::Any& aValue ) 359 { 360 switch( nHandle ) 361 { 362 case PROPHANDLE_UINAME: 363 aValue >>= m_aUIName; 364 break; 365 } 366 } 367 368 void SAL_CALL RootItemContainer::getFastPropertyValue( com::sun::star::uno::Any& aValue , 369 sal_Int32 nHandle ) const 370 { 371 switch( nHandle ) 372 { 373 case PROPHANDLE_UINAME: 374 aValue <<= m_aUIName; 375 break; 376 } 377 } 378 379 ::cppu::IPropertyArrayHelper& SAL_CALL RootItemContainer::getInfoHelper() 380 { 381 // Optimize this method ! 382 // We initialize a static variable only one time. And we don't must use a mutex at every call! 383 // For the first call; pInfoHelper is NULL - for the second call pInfoHelper is different from NULL! 384 static ::cppu::OPropertyArrayHelper* pInfoHelper = NULL; 385 386 if( pInfoHelper == NULL ) 387 { 388 // Ready for multithreading 389 osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ; 390 391 // Control this pointer again, another instance can be faster then these! 392 if( pInfoHelper == NULL ) 393 { 394 // Define static member to give structure of properties to baseclass "OPropertySetHelper". 395 // "impl_getStaticPropertyDescriptor" is a non exported and static function, who will define a static propertytable. 396 // "sal_True" say: Table is sorted by name. 397 static ::cppu::OPropertyArrayHelper aInfoHelper( impl_getStaticPropertyDescriptor(), sal_True ); 398 pInfoHelper = &aInfoHelper; 399 } 400 } 401 402 return(*pInfoHelper); 403 } 404 405 com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > SAL_CALL RootItemContainer::getPropertySetInfo() 406 { 407 // Optimize this method ! 408 // We initialize a static variable only one time. And we don't must use a mutex at every call! 409 // For the first call; pInfo is NULL - for the second call pInfo is different from NULL! 410 static com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo >* pInfo = NULL; 411 412 if( pInfo == NULL ) 413 { 414 // Ready for multithreading 415 osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ; 416 // Control this pointer again, another instance can be faster then these! 417 if( pInfo == NULL ) 418 { 419 // Create structure of propertysetinfo for baseclass "OPropertySetHelper". 420 // (Use method "getInfoHelper()".) 421 static com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); 422 pInfo = &xInfo; 423 } 424 } 425 426 return (*pInfo); 427 } 428 429 const com::sun::star::uno::Sequence< com::sun::star::beans::Property > RootItemContainer::impl_getStaticPropertyDescriptor() 430 { 431 // Create a new static property array to initialize sequence! 432 // Table of all predefined properties of this class. Its used from OPropertySetHelper-class! 433 // Don't forget to change the defines (see begin of this file), if you add, change or delete a property in this list!!! 434 // It's necessary for methods of OPropertySetHelper. 435 // ATTENTION: 436 // YOU MUST SORT FOLLOW TABLE BY NAME ALPHABETICAL !!! 437 438 static const com::sun::star::beans::Property pProperties[] = 439 { 440 com::sun::star::beans::Property( PROPNAME_UINAME, PROPHANDLE_UINAME , 441 ::getCppuType((const rtl::OUString*)NULL), 442 com::sun::star::beans::PropertyAttribute::TRANSIENT ) 443 }; 444 // Use it to initialize sequence! 445 static const com::sun::star::uno::Sequence< com::sun::star::beans::Property > lPropertyDescriptor( pProperties, PROPCOUNT ); 446 // Return static "PropertyDescriptor" 447 return lPropertyDescriptor; 448 } 449 450 } // namespace framework 451