xref: /AOO41X/main/ucb/source/ucp/hierarchy/hierarchydatasupplier.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 <ucbhelper/contentidentifier.hxx>
35 #include "hierarchydatasupplier.hxx"
36 #include "hierarchyprovider.hxx"
37 #include "hierarchycontent.hxx"
38 
39 using namespace com::sun::star;
40 using namespace hierarchy_ucp;
41 
42 namespace hierarchy_ucp
43 {
44 
45 //=========================================================================
46 //
47 // struct ResultListEntry.
48 //
49 //=========================================================================
50 
51 struct ResultListEntry
52 {
53     rtl::OUString                             aId;
54     uno::Reference< ucb::XContentIdentifier > xId;
55     uno::Reference< ucb::XContent >           xContent;
56     uno::Reference< sdbc::XRow >              xRow;
57     HierarchyEntryData                        aData;
58 
ResultListEntryhierarchy_ucp::ResultListEntry59     ResultListEntry( const HierarchyEntryData& rEntry ) : aData( rEntry ) {}
60 };
61 
62 //=========================================================================
63 //
64 // ResultList.
65 //
66 //=========================================================================
67 
68 typedef std::vector< ResultListEntry* > ResultList;
69 
70 //=========================================================================
71 //
72 // struct DataSupplier_Impl.
73 //
74 //=========================================================================
75 
76 struct DataSupplier_Impl
77 {
78     osl::Mutex                                      m_aMutex;
79     ResultList                                      m_aResults;
80     rtl::Reference< HierarchyContent >              m_xContent;
81     uno::Reference< lang::XMultiServiceFactory >    m_xSMgr;
82     HierarchyEntry                                  m_aFolder;
83     HierarchyEntry::iterator                        m_aIterator;
84     sal_Int32                                       m_nOpenMode;
85     sal_Bool                                        m_bCountFinal;
86 
DataSupplier_Implhierarchy_ucp::DataSupplier_Impl87     DataSupplier_Impl(
88         const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
89         const rtl::Reference< HierarchyContent >& rContent,
90         sal_Int32 nOpenMode )
91     : m_xContent( rContent ), m_xSMgr( rxSMgr ),
92       m_aFolder( rxSMgr,
93                  static_cast< HierarchyContentProvider * >(
94                      rContent->getProvider().get() ),
95                  rContent->getIdentifier()->getContentIdentifier() ),
96       m_nOpenMode( nOpenMode ), m_bCountFinal( sal_False ) {}
97     ~DataSupplier_Impl();
98 };
99 
100 //=========================================================================
~DataSupplier_Impl()101 DataSupplier_Impl::~DataSupplier_Impl()
102 {
103     ResultList::const_iterator it  = m_aResults.begin();
104     ResultList::const_iterator end = m_aResults.end();
105 
106     while ( it != end )
107     {
108         delete (*it);
109         it++;
110     }
111 }
112 
113 }
114 
115 //=========================================================================
116 //=========================================================================
117 //
118 // HierarchyResultSetDataSupplier Implementation.
119 //
120 //=========================================================================
121 //=========================================================================
122 
HierarchyResultSetDataSupplier(const uno::Reference<lang::XMultiServiceFactory> & rxSMgr,const rtl::Reference<HierarchyContent> & rContent,sal_Int32 nOpenMode)123 HierarchyResultSetDataSupplier::HierarchyResultSetDataSupplier(
124                 const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
125                 const rtl::Reference< HierarchyContent >& rContent,
126                 sal_Int32 nOpenMode )
127 : m_pImpl( new DataSupplier_Impl( rxSMgr, rContent, nOpenMode ) )
128 {
129 }
130 
131 //=========================================================================
132 // virtual
~HierarchyResultSetDataSupplier()133 HierarchyResultSetDataSupplier::~HierarchyResultSetDataSupplier()
134 {
135     delete m_pImpl;
136 }
137 
138 //=========================================================================
139 // virtual
queryContentIdentifierString(sal_uInt32 nIndex)140 rtl::OUString HierarchyResultSetDataSupplier::queryContentIdentifierString(
141                                                         sal_uInt32 nIndex )
142 {
143     osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
144 
145     if ( nIndex < m_pImpl->m_aResults.size() )
146     {
147         rtl::OUString aId = m_pImpl->m_aResults[ nIndex ]->aId;
148         if ( aId.getLength() )
149         {
150             // Already cached.
151             return aId;
152         }
153     }
154 
155     if ( getResult( nIndex ) )
156     {
157         rtl::OUString aId
158             = m_pImpl->m_xContent->getIdentifier()->getContentIdentifier();
159 
160         if ( ( aId.lastIndexOf( '/' ) + 1 ) != aId.getLength() )
161             aId += rtl::OUString::createFromAscii( "/" );
162 
163         aId += m_pImpl->m_aResults[ nIndex ]->aData.getName();
164 
165         m_pImpl->m_aResults[ nIndex ]->aId = aId;
166         return aId;
167     }
168     return rtl::OUString();
169 }
170 
171 //=========================================================================
172 // virtual
173 uno::Reference< ucb::XContentIdentifier >
queryContentIdentifier(sal_uInt32 nIndex)174 HierarchyResultSetDataSupplier::queryContentIdentifier( sal_uInt32 nIndex )
175 {
176     osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
177 
178     if ( nIndex < m_pImpl->m_aResults.size() )
179     {
180         uno::Reference< ucb::XContentIdentifier > xId
181                                 = m_pImpl->m_aResults[ nIndex ]->xId;
182         if ( xId.is() )
183         {
184             // Already cached.
185             return xId;
186         }
187     }
188 
189     rtl::OUString aId = queryContentIdentifierString( nIndex );
190     if ( aId.getLength() )
191     {
192         uno::Reference< ucb::XContentIdentifier > xId
193             = new ::ucbhelper::ContentIdentifier( aId );
194         m_pImpl->m_aResults[ nIndex ]->xId = xId;
195         return xId;
196     }
197     return uno::Reference< ucb::XContentIdentifier >();
198 }
199 
200 //=========================================================================
201 // virtual
202 uno::Reference< ucb::XContent >
queryContent(sal_uInt32 nIndex)203 HierarchyResultSetDataSupplier::queryContent( sal_uInt32 nIndex )
204 {
205     osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
206 
207     if ( nIndex < m_pImpl->m_aResults.size() )
208     {
209         uno::Reference< ucb::XContent > xContent
210                                 = m_pImpl->m_aResults[ nIndex ]->xContent;
211         if ( xContent.is() )
212         {
213             // Already cached.
214             return xContent;
215         }
216     }
217 
218     uno::Reference< ucb::XContentIdentifier > xId
219         = queryContentIdentifier( nIndex );
220     if ( xId.is() )
221     {
222         try
223         {
224             uno::Reference< ucb::XContent > xContent
225                 = m_pImpl->m_xContent->getProvider()->queryContent( xId );
226             m_pImpl->m_aResults[ nIndex ]->xContent = xContent;
227             return xContent;
228 
229         }
230         catch ( ucb::IllegalIdentifierException const & )
231         {
232         }
233     }
234     return uno::Reference< ucb::XContent >();
235 }
236 
237 //=========================================================================
238 // virtual
getResult(sal_uInt32 nIndex)239 sal_Bool HierarchyResultSetDataSupplier::getResult( sal_uInt32 nIndex )
240 {
241     osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
242 
243     if ( m_pImpl->m_aResults.size() > nIndex )
244     {
245         // Result already present.
246         return sal_True;
247     }
248 
249     // Result not (yet) present.
250 
251     if ( m_pImpl->m_bCountFinal )
252         return sal_False;
253 
254     // Try to obtain result...
255 
256     sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
257     sal_Bool bFound = sal_False;
258     sal_uInt32 nPos = nOldCount;
259 
260     while ( m_pImpl->m_aFolder.next( m_pImpl->m_aIterator ) )
261     {
262         const HierarchyEntryData& rResult = *m_pImpl->m_aIterator;
263         if ( checkResult( rResult ) )
264         {
265             m_pImpl->m_aResults.push_back( new ResultListEntry( rResult ) );
266 
267             if ( nPos == nIndex )
268             {
269                 // Result obtained.
270                 bFound = sal_True;
271                 break;
272             }
273         }
274         nPos++;
275     }
276 
277     if ( !bFound )
278         m_pImpl->m_bCountFinal = sal_True;
279 
280     rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
281     if ( xResultSet.is() )
282     {
283         // Callbacks follow!
284         aGuard.clear();
285 
286         if ( nOldCount < m_pImpl->m_aResults.size() )
287             xResultSet->rowCountChanged(
288                                     nOldCount, m_pImpl->m_aResults.size() );
289 
290         if ( m_pImpl->m_bCountFinal )
291             xResultSet->rowCountFinal();
292     }
293 
294     return bFound;
295 }
296 
297 //=========================================================================
298 // virtual
totalCount()299 sal_uInt32 HierarchyResultSetDataSupplier::totalCount()
300 {
301     osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
302 
303     if ( m_pImpl->m_bCountFinal )
304         return m_pImpl->m_aResults.size();
305 
306     sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
307 
308     while ( m_pImpl->m_aFolder.next( m_pImpl->m_aIterator ) )
309     {
310         const HierarchyEntryData& rResult = *m_pImpl->m_aIterator;
311         if ( checkResult( rResult ) )
312             m_pImpl->m_aResults.push_back( new ResultListEntry( rResult ) );
313     }
314 
315     m_pImpl->m_bCountFinal = sal_True;
316 
317     rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
318     if ( xResultSet.is() )
319     {
320         // Callbacks follow!
321         aGuard.clear();
322 
323         if ( nOldCount < m_pImpl->m_aResults.size() )
324             xResultSet->rowCountChanged(
325                                     nOldCount, m_pImpl->m_aResults.size() );
326 
327         xResultSet->rowCountFinal();
328     }
329 
330     return m_pImpl->m_aResults.size();
331 }
332 
333 //=========================================================================
334 // virtual
currentCount()335 sal_uInt32 HierarchyResultSetDataSupplier::currentCount()
336 {
337     return m_pImpl->m_aResults.size();
338 }
339 
340 //=========================================================================
341 // virtual
isCountFinal()342 sal_Bool HierarchyResultSetDataSupplier::isCountFinal()
343 {
344     return m_pImpl->m_bCountFinal;
345 }
346 
347 //=========================================================================
348 // virtual
349 uno::Reference< sdbc::XRow >
queryPropertyValues(sal_uInt32 nIndex)350 HierarchyResultSetDataSupplier::queryPropertyValues( sal_uInt32 nIndex  )
351 {
352     osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
353 
354     if ( nIndex < m_pImpl->m_aResults.size() )
355     {
356         uno::Reference< sdbc::XRow > xRow
357             = m_pImpl->m_aResults[ nIndex ]->xRow;
358         if ( xRow.is() )
359         {
360             // Already cached.
361             return xRow;
362         }
363     }
364 
365     if ( getResult( nIndex ) )
366     {
367         static rtl::OUString aFolderType(
368             rtl::OUString::createFromAscii( HIERARCHY_FOLDER_CONTENT_TYPE ) );
369         static rtl::OUString aLinkType(
370             rtl::OUString::createFromAscii( HIERARCHY_LINK_CONTENT_TYPE ) );
371 
372         HierarchyContentProperties aData(
373             m_pImpl->m_aResults[ nIndex ]->aData );
374 
375         uno::Reference< sdbc::XRow > xRow
376             = HierarchyContent::getPropertyValues(
377                 m_pImpl->m_xSMgr,
378                 getResultSet()->getProperties(),
379                 aData,
380                 static_cast< HierarchyContentProvider * >(
381                     m_pImpl->m_xContent->getProvider().get() ),
382                 queryContentIdentifierString( nIndex ) );
383         m_pImpl->m_aResults[ nIndex ]->xRow = xRow;
384         return xRow;
385     }
386 
387     return uno::Reference< sdbc::XRow >();
388 }
389 
390 //=========================================================================
391 // virtual
releasePropertyValues(sal_uInt32 nIndex)392 void HierarchyResultSetDataSupplier::releasePropertyValues( sal_uInt32 nIndex )
393 {
394     osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
395 
396     if ( nIndex < m_pImpl->m_aResults.size() )
397         m_pImpl->m_aResults[ nIndex ]->xRow = uno::Reference< sdbc::XRow >();
398 }
399 
400 //=========================================================================
401 // virtual
close()402 void HierarchyResultSetDataSupplier::close()
403 {
404 }
405 
406 //=========================================================================
407 // virtual
validate()408 void HierarchyResultSetDataSupplier::validate()
409     throw( ucb::ResultSetException )
410 {
411 }
412 
413 //=========================================================================
checkResult(const HierarchyEntryData & rResult)414 sal_Bool HierarchyResultSetDataSupplier::checkResult(
415                                     const HierarchyEntryData& rResult )
416 {
417     switch ( m_pImpl->m_nOpenMode )
418     {
419         case ucb::OpenMode::FOLDERS:
420             if ( rResult.getType() == HierarchyEntryData::LINK )
421             {
422                 // Entry is a link.
423                 return sal_False;
424             }
425             break;
426 
427         case ucb::OpenMode::DOCUMENTS:
428             if ( rResult.getType() == HierarchyEntryData::FOLDER )
429             {
430                 // Entry is a folder.
431                 return sal_False;
432             }
433             break;
434 
435         case ucb::OpenMode::ALL:
436         default:
437             break;
438     }
439 
440     return sal_True;
441 }
442 
443