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 //*****************************************************************************************************************
DEFINE_XINTERFACE_10(RootItemContainer,OWeakObject,DIRECT_INTERFACE (::com::sun::star::lang::XTypeProvider),DIRECT_INTERFACE (::com::sun::star::container::XIndexContainer),DIRECT_INTERFACE (::com::sun::star::lang::XUnoTunnel),DIRECT_INTERFACE (::com::sun::star::lang::XSingleComponentFactory),DIRECT_INTERFACE (::com::sun::star::beans::XMultiPropertySet),DIRECT_INTERFACE (::com::sun::star::beans::XFastPropertySet),DIRECT_INTERFACE (::com::sun::star::beans::XPropertySet),DERIVED_INTERFACE (::com::sun::star::container::XIndexReplace,com::sun::star::container::XIndexContainer),DERIVED_INTERFACE (::com::sun::star::container::XIndexAccess,com::sun::star::container::XIndexReplace),DERIVED_INTERFACE (::com::sun::star::container::XElementAccess,::com::sun::star::container::XIndexAccess))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
RootItemContainer(const ConstItemContainer & rConstItemContainer)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
RootItemContainer(const Reference<XIndexAccess> & rSourceContainer)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
~RootItemContainer()168 RootItemContainer::~RootItemContainer()
169 {
170 }
171
172 // private
copyItemContainer(const std::vector<Sequence<PropertyValue>> & rSourceVector)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
deepCopyContainer(const Reference<XIndexAccess> & rSubContainer)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
getSomething(const::com::sun::star::uno::Sequence<sal_Int8> & rIdentifier)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
GetUnoTunnelId()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
GetImplementation(const::com::sun::star::uno::Reference<::com::sun::star::uno::XInterface> & rxIFace)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
hasElements()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
getCount()256 sal_Int32 SAL_CALL RootItemContainer::getCount()
257 throw ( RuntimeException )
258 {
259 ShareGuard aLock( m_aShareMutex );
260 return m_aItemVector.size();
261 }
262
getByIndex(sal_Int32 Index)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
insertByIndex(sal_Int32 Index,const Any & aItem)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
removeByIndex(sal_Int32 Index)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
replaceByIndex(sal_Int32 Index,const Any & aItem)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
createInstanceWithContext(const Reference<XComponentContext> &)328 Reference< XInterface > SAL_CALL RootItemContainer::createInstanceWithContext( const Reference< XComponentContext >& )
329 throw ( Exception, RuntimeException)
330 {
331 return (OWeakObject *)(new ItemContainer( m_aShareMutex ));
332 }
333
createInstanceWithArgumentsAndContext(const Sequence<Any> &,const Reference<XComponentContext> &)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
convertFastPropertyValue(Any & aConvertedValue,Any & aOldValue,sal_Int32 nHandle,const Any & aValue)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
setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const com::sun::star::uno::Any & aValue)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
getFastPropertyValue(com::sun::star::uno::Any & aValue,sal_Int32 nHandle) const378 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
getInfoHelper()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 function, 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
getPropertySetInfo()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
impl_getStaticPropertyDescriptor()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