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/itemcontainer.hxx>
30 #include <uielement/constitemcontainer.hxx>
31 #include <threadhelp/resetableguard.hxx>
32
33 //_________________________________________________________________________________________________________________
34 // other includes
35 //_________________________________________________________________________________________________________________
36
37 using namespace cppu;
38 using namespace com::sun::star::uno;
39 using namespace com::sun::star::lang;
40 using namespace com::sun::star::beans;
41 using namespace com::sun::star::container;
42
43 const char WRONG_TYPE_EXCEPTION[] = "Type must be com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >";
44
45 namespace framework
46 {
47
48 //*****************************************************************************************************************
49 // XInterface, XTypeProvider
50 //*****************************************************************************************************************
51
ItemContainer(const ShareableMutex & rMutex)52 ItemContainer::ItemContainer( const ShareableMutex& rMutex ) :
53 m_aShareMutex( rMutex )
54 {
55 }
56
57
ItemContainer(const ConstItemContainer & rConstItemContainer,const ShareableMutex & rMutex)58 ItemContainer::ItemContainer( const ConstItemContainer& rConstItemContainer, const ShareableMutex& rMutex ) : m_aShareMutex( rMutex )
59 {
60 copyItemContainer( rConstItemContainer.m_aItemVector, rMutex );
61 }
62
ItemContainer(const Reference<XIndexAccess> & rSourceContainer,const ShareableMutex & rMutex)63 ItemContainer::ItemContainer( const Reference< XIndexAccess >& rSourceContainer, const ShareableMutex& rMutex ) :
64 m_aShareMutex( rMutex )
65 {
66 if ( rSourceContainer.is() )
67 {
68 sal_Int32 nCount = rSourceContainer->getCount();
69 try
70 {
71 for ( sal_Int32 i = 0; i < nCount; i++ )
72 {
73 Sequence< PropertyValue > aPropSeq;
74 if ( rSourceContainer->getByIndex( i ) >>= aPropSeq )
75 {
76 sal_Int32 nContainerIndex = -1;
77 Reference< XIndexAccess > xIndexAccess;
78 for ( sal_Int32 j = 0; j < aPropSeq.getLength(); j++ )
79 {
80 if ( aPropSeq[j].Name.equalsAscii( "ItemDescriptorContainer" ))
81 {
82 aPropSeq[j].Value >>= xIndexAccess;
83 nContainerIndex = j;
84 break;
85 }
86 }
87
88 if ( xIndexAccess.is() && nContainerIndex >= 0 )
89 aPropSeq[nContainerIndex].Value <<= deepCopyContainer( xIndexAccess, rMutex );
90
91 m_aItemVector.push_back( aPropSeq );
92 }
93 }
94 }
95 catch ( IndexOutOfBoundsException& )
96 {
97 }
98 }
99 }
100
~ItemContainer()101 ItemContainer::~ItemContainer()
102 {
103 }
104
105 // private
copyItemContainer(const std::vector<Sequence<PropertyValue>> & rSourceVector,const ShareableMutex & rMutex)106 void ItemContainer::copyItemContainer( const std::vector< Sequence< PropertyValue > >& rSourceVector, const ShareableMutex& rMutex )
107 {
108 const sal_uInt32 nCount = rSourceVector.size();
109 for ( sal_uInt32 i = 0; i < nCount; ++i )
110 {
111 sal_Int32 nContainerIndex = -1;
112 Sequence< PropertyValue > aPropSeq( rSourceVector[i] );
113 Reference< XIndexAccess > xIndexAccess;
114 for ( sal_Int32 j = 0; j < aPropSeq.getLength(); j++ )
115 {
116 if ( aPropSeq[j].Name.equalsAscii( "ItemDescriptorContainer" ))
117 {
118 aPropSeq[j].Value >>= xIndexAccess;
119 nContainerIndex = j;
120 break;
121 }
122 }
123
124 if ( xIndexAccess.is() && nContainerIndex >= 0 )
125 aPropSeq[nContainerIndex].Value <<= deepCopyContainer( xIndexAccess, rMutex );
126
127 m_aItemVector.push_back( aPropSeq );
128 }
129 }
130
deepCopyContainer(const Reference<XIndexAccess> & rSubContainer,const ShareableMutex & rMutex)131 Reference< XIndexAccess > ItemContainer::deepCopyContainer( const Reference< XIndexAccess >& rSubContainer, const ShareableMutex& rMutex )
132 {
133 Reference< XIndexAccess > xReturn;
134 if ( rSubContainer.is() )
135 {
136 ConstItemContainer* pSource = ConstItemContainer::GetImplementation( rSubContainer );
137 ItemContainer* pSubContainer( 0 );
138 if ( pSource )
139 pSubContainer = new ItemContainer( *pSource, rMutex );
140 else
141 pSubContainer = new ItemContainer( rSubContainer, rMutex );
142 xReturn = Reference< XIndexAccess >( static_cast< OWeakObject* >( pSubContainer ), UNO_QUERY );
143 }
144
145 return xReturn;
146 }
147
148 // XUnoTunnel
getSomething(const::com::sun::star::uno::Sequence<sal_Int8> & rIdentifier)149 sal_Int64 ItemContainer::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& rIdentifier ) throw(::com::sun::star::uno::RuntimeException)
150 {
151 if( ( rIdentifier.getLength() == 16 ) && ( 0 == rtl_compareMemory( ItemContainer::GetUnoTunnelId().getConstArray(), rIdentifier.getConstArray(), 16 ) ) )
152 return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >( this ));
153
154 return 0;
155 }
156
GetUnoTunnelId()157 const Sequence< sal_Int8 >& ItemContainer::GetUnoTunnelId() throw()
158 {
159 static ::com::sun::star::uno::Sequence< sal_Int8 > * pSeq = NULL;
160 if( !pSeq )
161 {
162 ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() );
163 if( !pSeq )
164 {
165 static ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( 16 );
166 rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
167 pSeq = &aSeq;
168 }
169 }
170 return *pSeq;
171 }
172
GetImplementation(const::com::sun::star::uno::Reference<::com::sun::star::uno::XInterface> & rxIFace)173 ItemContainer* ItemContainer::GetImplementation( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rxIFace ) throw()
174 {
175 ::com::sun::star::uno::Reference< ::com::sun::star::lang::XUnoTunnel > xUT( rxIFace, ::com::sun::star::uno::UNO_QUERY );
176 return xUT.is() ? reinterpret_cast< ItemContainer* >(sal::static_int_cast< sal_IntPtr >(
177 xUT->getSomething( ItemContainer::GetUnoTunnelId() ))) : NULL;
178 }
179
180 // XElementAccess
hasElements()181 sal_Bool SAL_CALL ItemContainer::hasElements()
182 throw ( RuntimeException )
183 {
184 ShareGuard aLock( m_aShareMutex );
185 return ( !m_aItemVector.empty() );
186 }
187
188 // XIndexAccess
getCount()189 sal_Int32 SAL_CALL ItemContainer::getCount()
190 throw ( RuntimeException )
191 {
192 ShareGuard aLock( m_aShareMutex );
193 return m_aItemVector.size();
194 }
195
getByIndex(sal_Int32 Index)196 Any SAL_CALL ItemContainer::getByIndex( sal_Int32 Index )
197 throw ( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
198 {
199 ShareGuard aLock( m_aShareMutex );
200 if ( sal_Int32( m_aItemVector.size()) > Index )
201 return makeAny( m_aItemVector[Index] );
202 else
203 throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this );
204 }
205
206 // XIndexContainer
insertByIndex(sal_Int32 Index,const Any & aItem)207 void SAL_CALL ItemContainer::insertByIndex( sal_Int32 Index, const Any& aItem )
208 throw ( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
209 {
210 Sequence< PropertyValue > aSeq;
211 if ( aItem >>= aSeq )
212 {
213 ShareGuard aLock( m_aShareMutex );
214 if ( sal_Int32( m_aItemVector.size()) == Index )
215 m_aItemVector.push_back( aSeq );
216 else if ( sal_Int32( m_aItemVector.size()) >Index )
217 {
218 std::vector< Sequence< PropertyValue > >::iterator aIter = m_aItemVector.begin();
219 aIter += Index;
220 m_aItemVector.insert( aIter, aSeq );
221 }
222 else
223 throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this );
224 }
225 else
226 throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( WRONG_TYPE_EXCEPTION )),
227 (OWeakObject *)this, 2 );
228 }
229
removeByIndex(sal_Int32 Index)230 void SAL_CALL ItemContainer::removeByIndex( sal_Int32 Index )
231 throw ( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
232 {
233 ShareGuard aLock( m_aShareMutex );
234 if ( (sal_Int32)m_aItemVector.size() > Index )
235 {
236 std::vector< Sequence< PropertyValue > >::iterator aIter = m_aItemVector.begin();
237 aIter += Index;
238 m_aItemVector.erase( aIter );
239 }
240 else
241 throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this );
242 }
243
replaceByIndex(sal_Int32 Index,const Any & aItem)244 void SAL_CALL ItemContainer::replaceByIndex( sal_Int32 Index, const Any& aItem )
245 throw ( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
246 {
247 Sequence< PropertyValue > aSeq;
248 if ( aItem >>= aSeq )
249 {
250 ShareGuard aLock( m_aShareMutex );
251 if ( sal_Int32( m_aItemVector.size()) > Index )
252 m_aItemVector[Index] = aSeq;
253 else
254 throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this );
255 }
256 else
257 throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( WRONG_TYPE_EXCEPTION )),
258 (OWeakObject *)this, 2 );
259 }
260
261 } // namespace framework
262
263