xref: /AOO41X/main/ucb/source/ucp/package/pkgdatasupplier.cxx (revision 2f86921c33504fdff5a030df6c0b258927045abb)
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_ucb.hxx"
26 
27 /**************************************************************************
28                                 TODO
29  **************************************************************************
30 
31  *************************************************************************/
32 
33 #include <vector>
34 #include <osl/diagnose.h>
35 #include <com/sun/star/container/XEnumeration.hpp>
36 #include <com/sun/star/container/XNamed.hpp>
37 #include <ucbhelper/contentidentifier.hxx>
38 #include <ucbhelper/providerhelper.hxx>
39 #include "pkgdatasupplier.hxx"
40 #include "pkgcontent.hxx"
41 #include "pkgprovider.hxx"
42 
43 #include "../inc/urihelper.hxx"
44 
45 using namespace com::sun::star;
46 using namespace package_ucp;
47 
48 namespace package_ucp
49 {
50 
51 //=========================================================================
52 //
53 // struct ResultListEntry.
54 //
55 //=========================================================================
56 
57 struct ResultListEntry
58 {
59     rtl::OUString                             aURL;
60     uno::Reference< ucb::XContentIdentifier > xId;
61     uno::Reference< ucb::XContent >           xContent;
62     uno::Reference< sdbc::XRow >              xRow;
63 
ResultListEntrypackage_ucp::ResultListEntry64     ResultListEntry( const rtl::OUString& rURL ) : aURL( rURL ) {}
65 };
66 
67 //=========================================================================
68 //
69 // ResultList.
70 //
71 //=========================================================================
72 
73 typedef std::vector< ResultListEntry* > ResultList;
74 
75 //=========================================================================
76 //
77 // struct DataSupplier_Impl.
78 //
79 //=========================================================================
80 
81 struct DataSupplier_Impl
82 {
83     osl::Mutex                                   m_aMutex;
84     ResultList                                   m_aResults;
85     rtl::Reference< Content >                    m_xContent;
86     uno::Reference< lang::XMultiServiceFactory > m_xSMgr;
87     uno::Reference< container::XEnumeration >    m_xFolderEnum;
88     sal_Int32                                    m_nOpenMode;
89     sal_Bool                                     m_bCountFinal;
90     sal_Bool                                     m_bThrowException;
91 
DataSupplier_Implpackage_ucp::DataSupplier_Impl92     DataSupplier_Impl(
93             const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
94             const rtl::Reference< Content >& rContent,
95             sal_Int32 nOpenMode )
96     : m_xContent( rContent ), m_xSMgr( rxSMgr ),
97       m_xFolderEnum( rContent->getIterator() ), m_nOpenMode( nOpenMode ),
98       m_bCountFinal( !m_xFolderEnum.is() ), m_bThrowException( m_bCountFinal )
99     {}
100     ~DataSupplier_Impl();
101 };
102 
103 //=========================================================================
~DataSupplier_Impl()104 DataSupplier_Impl::~DataSupplier_Impl()
105 {
106     ResultList::const_iterator it  = m_aResults.begin();
107     ResultList::const_iterator end = m_aResults.end();
108 
109     while ( it != end )
110     {
111         delete (*it);
112         it++;
113     }
114 }
115 
116 }
117 
118 //=========================================================================
119 //=========================================================================
120 //
121 // DataSupplier Implementation.
122 //
123 //=========================================================================
124 //=========================================================================
125 
DataSupplier(const uno::Reference<lang::XMultiServiceFactory> & rxSMgr,const rtl::Reference<Content> & rContent,sal_Int32 nOpenMode)126 DataSupplier::DataSupplier(
127                 const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
128                 const rtl::Reference< Content >& rContent,
129                 sal_Int32 nOpenMode )
130 : m_pImpl( new DataSupplier_Impl( rxSMgr, rContent, nOpenMode ) )
131 {
132 }
133 
134 //=========================================================================
135 // virtual
~DataSupplier()136 DataSupplier::~DataSupplier()
137 {
138     delete m_pImpl;
139 }
140 
141 //=========================================================================
142 // virtual
queryContentIdentifierString(sal_uInt32 nIndex)143 rtl::OUString DataSupplier::queryContentIdentifierString( sal_uInt32 nIndex )
144 {
145     osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
146 
147     if ( nIndex < m_pImpl->m_aResults.size() )
148     {
149         rtl::OUString aId = m_pImpl->m_aResults[ nIndex ]->aURL;
150         if ( aId.getLength() )
151         {
152             // Already cached.
153             return aId;
154         }
155     }
156 
157     if ( getResult( nIndex ) )
158     {
159         // Note: getResult fills m_pImpl->m_aResults[ nIndex ]->aURL.
160         return m_pImpl->m_aResults[ nIndex ]->aURL;
161     }
162     return rtl::OUString();
163 }
164 
165 //=========================================================================
166 // virtual
167 uno::Reference< ucb::XContentIdentifier >
queryContentIdentifier(sal_uInt32 nIndex)168 DataSupplier::queryContentIdentifier( sal_uInt32 nIndex )
169 {
170     osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
171 
172     if ( nIndex < m_pImpl->m_aResults.size() )
173     {
174         uno::Reference< ucb::XContentIdentifier > xId
175                                 = m_pImpl->m_aResults[ nIndex ]->xId;
176         if ( xId.is() )
177         {
178             // Already cached.
179             return xId;
180         }
181     }
182 
183     rtl::OUString aId = queryContentIdentifierString( nIndex );
184     if ( aId.getLength() )
185     {
186         uno::Reference< ucb::XContentIdentifier > xId
187             = new ::ucbhelper::ContentIdentifier( aId );
188         m_pImpl->m_aResults[ nIndex ]->xId = xId;
189         return xId;
190     }
191     return uno::Reference< ucb::XContentIdentifier >();
192 }
193 
194 //=========================================================================
195 // virtual
queryContent(sal_uInt32 nIndex)196 uno::Reference< ucb::XContent > DataSupplier::queryContent(
197                                                         sal_uInt32 nIndex )
198 {
199     osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
200 
201     if ( nIndex < m_pImpl->m_aResults.size() )
202     {
203         uno::Reference< ucb::XContent > xContent
204                                 = m_pImpl->m_aResults[ nIndex ]->xContent;
205         if ( xContent.is() )
206         {
207             // Already cached.
208             return xContent;
209         }
210     }
211 
212     uno::Reference< ucb::XContentIdentifier > xId
213         = queryContentIdentifier( nIndex );
214     if ( xId.is() )
215     {
216         try
217         {
218             uno::Reference< ucb::XContent > xContent
219                 = m_pImpl->m_xContent->getProvider()->queryContent( xId );
220             m_pImpl->m_aResults[ nIndex ]->xContent = xContent;
221             return xContent;
222 
223         }
224         catch ( ucb::IllegalIdentifierException const & )
225         {
226         }
227     }
228     return uno::Reference< ucb::XContent >();
229 }
230 
231 //=========================================================================
232 // virtual
getResult(sal_uInt32 nIndex)233 sal_Bool DataSupplier::getResult( sal_uInt32 nIndex )
234 {
235     osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
236 
237     if ( m_pImpl->m_aResults.size() > nIndex )
238     {
239         // Result already present.
240         return sal_True;
241     }
242 
243     // Result not (yet) present.
244 
245     if ( m_pImpl->m_bCountFinal )
246         return sal_False;
247 
248     // Try to obtain result...
249 
250     sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
251     sal_Bool bFound = sal_False;
252     sal_uInt32 nPos = nOldCount;
253 
254     while ( m_pImpl->m_xFolderEnum->hasMoreElements() )
255     {
256         try
257         {
258             uno::Reference< container::XNamed > xNamed;
259             m_pImpl->m_xFolderEnum->nextElement() >>= xNamed;
260 
261             if ( !xNamed.is() )
262             {
263                 OSL_ENSURE( sal_False,
264                             "DataSupplier::getResult - Got no XNamed!" );
265                 break;
266             }
267 
268             rtl::OUString aName = xNamed->getName();
269 
270             if ( !aName.getLength() )
271             {
272                 OSL_ENSURE( sal_False,
273                             "DataSupplier::getResult - Empty name!" );
274                 break;
275             }
276 
277             // Assemble URL for child.
278             rtl::OUString aURL = assembleChildURL( aName );
279 
280             m_pImpl->m_aResults.push_back( new ResultListEntry( aURL ) );
281 
282             if ( nPos == nIndex )
283             {
284                 // Result obtained.
285                 bFound = sal_True;
286                 break;
287             }
288 
289             nPos++;
290         }
291         catch ( container::NoSuchElementException const & )
292         {
293             m_pImpl->m_bThrowException = sal_True;
294             break;
295         }
296         catch ( lang::WrappedTargetException const & )
297         {
298             m_pImpl->m_bThrowException = sal_True;
299             break;
300         }
301     }
302 
303     if ( !bFound )
304         m_pImpl->m_bCountFinal = sal_True;
305 
306     rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
307     if ( xResultSet.is() )
308     {
309         // Callbacks follow!
310         aGuard.clear();
311 
312         if ( nOldCount < m_pImpl->m_aResults.size() )
313             xResultSet->rowCountChanged(
314                                     nOldCount, m_pImpl->m_aResults.size() );
315 
316         if ( m_pImpl->m_bCountFinal )
317             xResultSet->rowCountFinal();
318     }
319 
320     return bFound;
321 }
322 
323 //=========================================================================
324 // virtual
totalCount()325 sal_uInt32 DataSupplier::totalCount()
326 {
327     osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
328 
329     if ( m_pImpl->m_bCountFinal )
330         return m_pImpl->m_aResults.size();
331 
332     sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
333 
334     while ( m_pImpl->m_xFolderEnum->hasMoreElements() )
335     {
336         try
337         {
338             uno::Reference< container::XNamed > xNamed;
339             m_pImpl->m_xFolderEnum->nextElement() >>= xNamed;
340 
341             if ( !xNamed.is() )
342             {
343                 OSL_ENSURE( sal_False,
344                             "DataSupplier::getResult - Got no XNamed!" );
345                 break;
346             }
347 
348             rtl::OUString aName = xNamed->getName();
349 
350             if ( !aName.getLength() )
351             {
352                 OSL_ENSURE( sal_False,
353                             "DataSupplier::getResult - Empty name!" );
354                 break;
355             }
356 
357             // Assemble URL for child.
358             rtl::OUString aURL = assembleChildURL( aName );
359 
360             m_pImpl->m_aResults.push_back( new ResultListEntry( aURL ) );
361         }
362         catch ( container::NoSuchElementException const & )
363         {
364             m_pImpl->m_bThrowException = sal_True;
365             break;
366         }
367         catch ( lang::WrappedTargetException const & )
368         {
369             m_pImpl->m_bThrowException = sal_True;
370             break;
371         }
372     }
373 
374     m_pImpl->m_bCountFinal = sal_True;
375 
376     rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
377     if ( xResultSet.is() )
378     {
379         // Callbacks follow!
380         aGuard.clear();
381 
382         if ( nOldCount < m_pImpl->m_aResults.size() )
383             xResultSet->rowCountChanged(
384                                     nOldCount, m_pImpl->m_aResults.size() );
385 
386         xResultSet->rowCountFinal();
387     }
388 
389     return m_pImpl->m_aResults.size();
390 }
391 
392 //=========================================================================
393 // virtual
currentCount()394 sal_uInt32 DataSupplier::currentCount()
395 {
396     return m_pImpl->m_aResults.size();
397 }
398 
399 //=========================================================================
400 // virtual
isCountFinal()401 sal_Bool DataSupplier::isCountFinal()
402 {
403     return m_pImpl->m_bCountFinal;
404 }
405 
406 //=========================================================================
407 // virtual
queryPropertyValues(sal_uInt32 nIndex)408 uno::Reference< sdbc::XRow > DataSupplier::queryPropertyValues(
409                                                         sal_uInt32 nIndex  )
410 {
411     osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
412 
413     if ( nIndex < m_pImpl->m_aResults.size() )
414     {
415         uno::Reference< sdbc::XRow > xRow = m_pImpl->m_aResults[ nIndex ]->xRow;
416         if ( xRow.is() )
417         {
418             // Already cached.
419             return xRow;
420         }
421     }
422 
423     if ( getResult( nIndex ) )
424     {
425         uno::Reference< sdbc::XRow > xRow = Content::getPropertyValues(
426                         m_pImpl->m_xSMgr,
427                         getResultSet()->getProperties(),
428                         static_cast< ContentProvider * >(
429                             m_pImpl->m_xContent->getProvider().get() ),
430                         queryContentIdentifierString( nIndex ) );
431         m_pImpl->m_aResults[ nIndex ]->xRow = xRow;
432         return xRow;
433     }
434 
435     return uno::Reference< sdbc::XRow >();
436 }
437 
438 //=========================================================================
439 // virtual
releasePropertyValues(sal_uInt32 nIndex)440 void DataSupplier::releasePropertyValues( sal_uInt32 nIndex )
441 {
442     osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
443 
444     if ( nIndex < m_pImpl->m_aResults.size() )
445         m_pImpl->m_aResults[ nIndex ]->xRow = uno::Reference< sdbc::XRow >();
446 }
447 
448 //=========================================================================
449 // virtual
close()450 void DataSupplier::close()
451 {
452 }
453 
454 //=========================================================================
455 // virtual
validate()456 void DataSupplier::validate()
457     throw( ucb::ResultSetException )
458 {
459     if ( m_pImpl->m_bThrowException )
460         throw ucb::ResultSetException();
461 }
462 
463 //=========================================================================
assembleChildURL(const::rtl::OUString & aName)464 ::rtl::OUString DataSupplier::assembleChildURL( const ::rtl::OUString& aName )
465 {
466     rtl::OUString aURL;
467     rtl::OUString aContURL
468         = m_pImpl->m_xContent->getIdentifier()->getContentIdentifier();
469     sal_Int32 nParam = aContURL.indexOf( '?' );
470     if ( nParam >= 0 )
471     {
472         aURL = aContURL.copy( 0, nParam );
473 
474         sal_Int32 nPackageUrlEnd = aURL.lastIndexOf( '/' );
475         if ( nPackageUrlEnd != aURL.getLength() - 1 )
476             aURL += rtl::OUString::createFromAscii( "/" );
477 
478         aURL += ::ucb_impl::urihelper::encodeSegment( aName );
479         aURL += aContURL.copy( nParam );
480     }
481     else
482     {
483         aURL = aContURL;
484 
485         sal_Int32 nPackageUrlEnd = aURL.lastIndexOf( '/' );
486         if ( nPackageUrlEnd != aURL.getLength() - 1 )
487             aURL += rtl::OUString::createFromAscii( "/" );
488 
489         aURL += ::ucb_impl::urihelper::encodeSegment( aName );
490     }
491     return aURL;
492 }
493 
494 
495