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: rootitemcontainer.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_framework.hxx"
33 //_________________________________________________________________________________________________________________
35 //_________________________________________________________________________________________________________________
36 #include <uielement/rootitemcontainer.hxx>
38 #ifndef __FRAMEWORK_UIELEMENT_ITEMCONTAINER_HHX_
39 #include <uielement/itemcontainer.hxx>
42 #ifndef __FRAMEWORK_UIELEMENT_CONSTITEMCONTAINER_HHX_
43 #include <uielement/constitemcontainer.hxx>
45 #include <threadhelp/resetableguard.hxx>
47 #include <properties.h>
49 //_________________________________________________________________________________________________________________
51 //_________________________________________________________________________________________________________________
52 #include <com/sun/star/beans/PropertyAttribute.hpp>
54 //_________________________________________________________________________________________________________________
56 //_________________________________________________________________________________________________________________
59 using namespace com::sun::star::uno
;
60 using namespace com::sun::star::lang
;
61 using namespace com::sun::star::beans
;
62 using namespace com::sun::star::container
;
64 const char WRONG_TYPE_EXCEPTION
[] = "Type must be com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >";
66 const int PROPHANDLE_UINAME
= 1;
67 const int PROPCOUNT
= 1;
68 const rtl::OUString
PROPNAME_UINAME( RTL_CONSTASCII_USTRINGPARAM( "UIName" ));
73 //*****************************************************************************************************************
74 // XInterface, XTypeProvider
75 //*****************************************************************************************************************
76 DEFINE_XINTERFACE_10 ( RootItemContainer
,
78 DIRECT_INTERFACE( ::com::sun::star::lang::XTypeProvider
),
79 DIRECT_INTERFACE( ::com::sun::star::container::XIndexContainer
),
80 DIRECT_INTERFACE( ::com::sun::star::lang::XUnoTunnel
),
81 DIRECT_INTERFACE( ::com::sun::star::lang::XSingleComponentFactory
),
82 DIRECT_INTERFACE( ::com::sun::star::beans::XMultiPropertySet
),
83 DIRECT_INTERFACE( ::com::sun::star::beans::XFastPropertySet
),
84 DIRECT_INTERFACE( ::com::sun::star::beans::XPropertySet
),
85 DERIVED_INTERFACE( ::com::sun::star::container::XIndexReplace
, com::sun::star::container::XIndexContainer
),
86 DERIVED_INTERFACE( ::com::sun::star::container::XIndexAccess
, com::sun::star::container::XIndexReplace
),
87 DERIVED_INTERFACE( ::com::sun::star::container::XElementAccess
, ::com::sun::star::container::XIndexAccess
)
90 DEFINE_XTYPEPROVIDER_10 ( RootItemContainer
,
91 ::com::sun::star::lang::XTypeProvider
,
92 ::com::sun::star::container::XIndexContainer
,
93 ::com::sun::star::container::XIndexReplace
,
94 ::com::sun::star::container::XIndexAccess
,
95 ::com::sun::star::container::XElementAccess
,
96 ::com::sun::star::beans::XMultiPropertySet
,
97 ::com::sun::star::beans::XFastPropertySet
,
98 ::com::sun::star::beans::XPropertySet
,
99 ::com::sun::star::lang::XUnoTunnel
,
100 ::com::sun::star::lang::XSingleComponentFactory
103 RootItemContainer::RootItemContainer()
105 , ::cppu::OBroadcastHelperVar
< ::cppu::OMultiTypeInterfaceContainerHelper
, ::cppu::OMultiTypeInterfaceContainerHelper::keyType
>( m_aLock
.getShareableOslMutex() )
106 , ::cppu::OPropertySetHelper ( *(static_cast< ::cppu::OBroadcastHelper
* >(this)) )
107 , ::cppu::OWeakObject()
111 RootItemContainer::RootItemContainer( const ConstItemContainer
& rConstItemContainer
)
113 , ::cppu::OBroadcastHelperVar
< ::cppu::OMultiTypeInterfaceContainerHelper
, ::cppu::OMultiTypeInterfaceContainerHelper::keyType
>( m_aLock
.getShareableOslMutex() )
114 , ::cppu::OPropertySetHelper ( *(static_cast< ::cppu::OBroadcastHelper
* >(this)) )
115 , ::cppu::OWeakObject()
117 m_aUIName
= rConstItemContainer
.m_aUIName
;
118 copyItemContainer( rConstItemContainer
.m_aItemVector
);
121 RootItemContainer::RootItemContainer( const Reference
< XIndexAccess
>& rSourceContainer
)
123 , ::cppu::OBroadcastHelperVar
< ::cppu::OMultiTypeInterfaceContainerHelper
, ::cppu::OMultiTypeInterfaceContainerHelper::keyType
>( m_aLock
.getShareableOslMutex() )
124 , ::cppu::OPropertySetHelper ( *(static_cast< ::cppu::OBroadcastHelper
* >(this)) )
125 , ::cppu::OWeakObject()
127 // We also have to copy the UIName property
130 Reference
< XPropertySet
> xPropSet( rSourceContainer
, UNO_QUERY
);
133 rtl::OUString aUIName
;
134 xPropSet
->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UIName" ))) >>= m_aUIName
;
141 if ( rSourceContainer
.is() )
143 sal_Int32 nCount
= rSourceContainer
->getCount();
146 for ( sal_Int32 i
= 0; i
< nCount
; i
++ )
148 Sequence
< PropertyValue
> aPropSeq
;
149 if ( rSourceContainer
->getByIndex( i
) >>= aPropSeq
)
151 sal_Int32 nContainerIndex
= -1;
152 Reference
< XIndexAccess
> xIndexAccess
;
153 for ( sal_Int32 j
= 0; j
< aPropSeq
.getLength(); j
++ )
155 if ( aPropSeq
[j
].Name
.equalsAscii( "ItemDescriptorContainer" ))
157 aPropSeq
[j
].Value
>>= xIndexAccess
;
163 if ( xIndexAccess
.is() && nContainerIndex
>= 0 )
164 aPropSeq
[nContainerIndex
].Value
<<= deepCopyContainer( xIndexAccess
);
166 m_aItemVector
.push_back( aPropSeq
);
170 catch ( IndexOutOfBoundsException
& )
176 RootItemContainer::~RootItemContainer()
181 void RootItemContainer::copyItemContainer( const std::vector
< Sequence
< PropertyValue
> >& rSourceVector
)
183 const sal_uInt32 nCount
= rSourceVector
.size();
184 m_aItemVector
.reserve(nCount
);
185 for ( sal_uInt32 i
= 0; i
< nCount
; i
++ )
187 sal_Int32 nContainerIndex
= -1;
188 Sequence
< PropertyValue
> aPropSeq( rSourceVector
[i
] );
189 Reference
< XIndexAccess
> xIndexAccess
;
190 for ( sal_Int32 j
= 0; j
< aPropSeq
.getLength(); j
++ )
192 if ( aPropSeq
[j
].Name
.equalsAscii( "ItemDescriptorContainer" ))
194 aPropSeq
[j
].Value
>>= xIndexAccess
;
200 if ( xIndexAccess
.is() && nContainerIndex
>= 0 )
201 aPropSeq
[nContainerIndex
].Value
<<= deepCopyContainer( xIndexAccess
);
203 m_aItemVector
.push_back( aPropSeq
);
207 Reference
< XIndexAccess
> RootItemContainer::deepCopyContainer( const Reference
< XIndexAccess
>& rSubContainer
)
209 Reference
< XIndexAccess
> xReturn
;
210 if ( rSubContainer
.is() )
212 ConstItemContainer
* pSource
= ConstItemContainer::GetImplementation( rSubContainer
);
213 ItemContainer
* pSubContainer( 0 );
215 pSubContainer
= new ItemContainer( *pSource
, m_aShareMutex
);
217 pSubContainer
= new ItemContainer( rSubContainer
, m_aShareMutex
);
218 xReturn
= Reference
< XIndexAccess
>( static_cast< OWeakObject
* >( pSubContainer
), UNO_QUERY
);
225 sal_Int64
RootItemContainer::getSomething( const ::com::sun::star::uno::Sequence
< sal_Int8
>& rIdentifier
) throw(::com::sun::star::uno::RuntimeException
)
227 if( ( rIdentifier
.getLength() == 16 ) && ( 0 == rtl_compareMemory( RootItemContainer::GetUnoTunnelId().getConstArray(), rIdentifier
.getConstArray(), 16 ) ) )
228 return sal::static_int_cast
< sal_Int64
>( reinterpret_cast< sal_IntPtr
>( this ));
232 const Sequence
< sal_Int8
>& RootItemContainer::GetUnoTunnelId() throw()
234 static ::com::sun::star::uno::Sequence
< sal_Int8
> * pSeq
= NULL
;
237 ::osl::Guard
< ::osl::Mutex
> aGuard( ::osl::Mutex::getGlobalMutex() );
240 static ::com::sun::star::uno::Sequence
< sal_Int8
> aSeq( 16 );
241 rtl_createUuid( (sal_uInt8
*)aSeq
.getArray(), 0, sal_True
);
248 RootItemContainer
* RootItemContainer::GetImplementation( const ::com::sun::star::uno::Reference
< ::com::sun::star::uno::XInterface
>& rxIFace
) throw()
250 ::com::sun::star::uno::Reference
< ::com::sun::star::lang::XUnoTunnel
> xUT( rxIFace
, ::com::sun::star::uno::UNO_QUERY
);
251 return xUT
.is() ? reinterpret_cast< RootItemContainer
* >(sal::static_int_cast
< sal_IntPtr
>(
252 xUT
->getSomething( RootItemContainer::GetUnoTunnelId() ))) : NULL
;
256 sal_Bool SAL_CALL
RootItemContainer::hasElements()
257 throw ( RuntimeException
)
259 ShareGuard
aLock( m_aShareMutex
);
260 return ( !m_aItemVector
.empty() );
264 sal_Int32 SAL_CALL
RootItemContainer::getCount()
265 throw ( RuntimeException
)
267 ShareGuard
aLock( m_aShareMutex
);
268 return m_aItemVector
.size();
271 Any SAL_CALL
RootItemContainer::getByIndex( sal_Int32 Index
)
272 throw ( IndexOutOfBoundsException
, WrappedTargetException
, RuntimeException
)
274 ShareGuard
aLock( m_aShareMutex
);
275 if ( sal_Int32( m_aItemVector
.size()) > Index
)
276 return makeAny( m_aItemVector
[Index
] );
278 throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject
*)this );
282 void SAL_CALL
RootItemContainer::insertByIndex( sal_Int32 Index
, const Any
& aItem
)
283 throw ( IllegalArgumentException
, IndexOutOfBoundsException
, WrappedTargetException
, RuntimeException
)
285 Sequence
< PropertyValue
> aSeq
;
286 if ( aItem
>>= aSeq
)
288 ShareGuard
aLock( m_aShareMutex
);
289 if ( sal_Int32( m_aItemVector
.size()) == Index
)
290 m_aItemVector
.push_back( aSeq
);
291 else if ( sal_Int32( m_aItemVector
.size()) >Index
)
293 std::vector
< Sequence
< PropertyValue
> >::iterator aIter
= m_aItemVector
.begin();
295 m_aItemVector
.insert( aIter
, aSeq
);
298 throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject
*)this );
301 throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( WRONG_TYPE_EXCEPTION
)),
302 (OWeakObject
*)this, 2 );
305 void SAL_CALL
RootItemContainer::removeByIndex( sal_Int32 Index
)
306 throw ( IndexOutOfBoundsException
, WrappedTargetException
, RuntimeException
)
308 ShareGuard
aLock( m_aShareMutex
);
309 if ( (sal_Int32
)m_aItemVector
.size() > Index
)
311 std::vector
< Sequence
< PropertyValue
> >::iterator aIter
= m_aItemVector
.begin();
313 m_aItemVector
.erase( aIter
);
316 throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject
*)this );
319 void SAL_CALL
RootItemContainer::replaceByIndex( sal_Int32 Index
, const Any
& aItem
)
320 throw ( IllegalArgumentException
, IndexOutOfBoundsException
, WrappedTargetException
, RuntimeException
)
322 Sequence
< PropertyValue
> aSeq
;
323 if ( aItem
>>= aSeq
)
325 ShareGuard
aLock( m_aShareMutex
);
326 if ( sal_Int32( m_aItemVector
.size()) > Index
)
327 m_aItemVector
[Index
] = aSeq
;
329 throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject
*)this );
332 throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( WRONG_TYPE_EXCEPTION
)),
333 (OWeakObject
*)this, 2 );
336 Reference
< XInterface
> SAL_CALL
RootItemContainer::createInstanceWithContext( const Reference
< XComponentContext
>& )
337 throw ( Exception
, RuntimeException
)
339 return (OWeakObject
*)(new ItemContainer( m_aShareMutex
));
342 Reference
< XInterface
> SAL_CALL
RootItemContainer::createInstanceWithArgumentsAndContext( const Sequence
< Any
>&, const Reference
< XComponentContext
>& )
343 throw (Exception
, RuntimeException
)
345 return (OWeakObject
*)(new ItemContainer( m_aShareMutex
));
348 // XPropertySet helper
349 sal_Bool SAL_CALL
RootItemContainer::convertFastPropertyValue( Any
& aConvertedValue
,
353 throw( com::sun::star::lang::IllegalArgumentException
)
355 // Initialize state with FALSE !!!
356 // (Handle can be invalid)
357 sal_Bool bReturn
= sal_False
;
361 case PROPHANDLE_UINAME
:
362 bReturn
= PropHelper::willPropertyBeChanged(
363 com::sun::star::uno::makeAny(m_aUIName
),
370 // Return state of operation.
374 void SAL_CALL
RootItemContainer::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle
,
375 const com::sun::star::uno::Any
& aValue
)
376 throw( com::sun::star::uno::Exception
)
380 case PROPHANDLE_UINAME
:
381 aValue
>>= m_aUIName
;
386 void SAL_CALL
RootItemContainer::getFastPropertyValue( com::sun::star::uno::Any
& aValue
,
387 sal_Int32 nHandle
) const
391 case PROPHANDLE_UINAME
:
392 aValue
<<= m_aUIName
;
397 ::cppu::IPropertyArrayHelper
& SAL_CALL
RootItemContainer::getInfoHelper()
399 // Optimize this method !
400 // We initialize a static variable only one time. And we don't must use a mutex at every call!
401 // For the first call; pInfoHelper is NULL - for the second call pInfoHelper is different from NULL!
402 static ::cppu::OPropertyArrayHelper
* pInfoHelper
= NULL
;
404 if( pInfoHelper
== NULL
)
406 // Ready for multithreading
407 osl::MutexGuard
aGuard( osl::Mutex::getGlobalMutex() ) ;
409 // Control this pointer again, another instance can be faster then these!
410 if( pInfoHelper
== NULL
)
412 // Define static member to give structure of properties to baseclass "OPropertySetHelper".
413 // "impl_getStaticPropertyDescriptor" is a non exported and static funtion, who will define a static propertytable.
414 // "sal_True" say: Table is sorted by name.
415 static ::cppu::OPropertyArrayHelper
aInfoHelper( impl_getStaticPropertyDescriptor(), sal_True
);
416 pInfoHelper
= &aInfoHelper
;
420 return(*pInfoHelper
);
423 com::sun::star::uno::Reference
< com::sun::star::beans::XPropertySetInfo
> SAL_CALL
RootItemContainer::getPropertySetInfo()
424 throw (::com::sun::star::uno::RuntimeException
)
426 // Optimize this method !
427 // We initialize a static variable only one time. And we don't must use a mutex at every call!
428 // For the first call; pInfo is NULL - for the second call pInfo is different from NULL!
429 static com::sun::star::uno::Reference
< com::sun::star::beans::XPropertySetInfo
>* pInfo
= NULL
;
433 // Ready for multithreading
434 osl::MutexGuard
aGuard( osl::Mutex::getGlobalMutex() ) ;
435 // Control this pointer again, another instance can be faster then these!
438 // Create structure of propertysetinfo for baseclass "OPropertySetHelper".
439 // (Use method "getInfoHelper()".)
440 static com::sun::star::uno::Reference
< com::sun::star::beans::XPropertySetInfo
> xInfo( createPropertySetInfo( getInfoHelper() ) );
448 const com::sun::star::uno::Sequence
< com::sun::star::beans::Property
> RootItemContainer::impl_getStaticPropertyDescriptor()
450 // Create a new static property array to initialize sequence!
451 // Table of all predefined properties of this class. Its used from OPropertySetHelper-class!
452 // Don't forget to change the defines (see begin of this file), if you add, change or delete a property in this list!!!
453 // It's necessary for methods of OPropertySetHelper.
455 // YOU MUST SORT FOLLOW TABLE BY NAME ALPHABETICAL !!!
457 static const com::sun::star::beans::Property pProperties
[] =
459 com::sun::star::beans::Property( PROPNAME_UINAME
, PROPHANDLE_UINAME
,
460 ::getCppuType((const rtl::OUString
*)NULL
),
461 com::sun::star::beans::PropertyAttribute::TRANSIENT
)
463 // Use it to initialize sequence!
464 static const com::sun::star::uno::Sequence
< com::sun::star::beans::Property
> lPropertyDescriptor( pProperties
, PROPCOUNT
);
465 // Return static "PropertyDescriptor"
466 return lPropertyDescriptor
;
469 } // namespace framework