xref: /trunk/main/ucb/source/ucp/hierarchy/hierarchydatasupplier.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_ucb.hxx"
30 
31 /**************************************************************************
32                                 TODO
33  **************************************************************************
34 
35  *************************************************************************/
36 
37 #include <vector>
38 #include <ucbhelper/contentidentifier.hxx>
39 #include "hierarchydatasupplier.hxx"
40 #include "hierarchyprovider.hxx"
41 #include "hierarchycontent.hxx"
42 
43 using namespace com::sun::star;
44 using namespace hierarchy_ucp;
45 
46 namespace hierarchy_ucp
47 {
48 
49 //=========================================================================
50 //
51 // struct ResultListEntry.
52 //
53 //=========================================================================
54 
55 struct ResultListEntry
56 {
57     rtl::OUString                             aId;
58     uno::Reference< ucb::XContentIdentifier > xId;
59     uno::Reference< ucb::XContent >           xContent;
60     uno::Reference< sdbc::XRow >              xRow;
61     HierarchyEntryData                        aData;
62 
63     ResultListEntry( const HierarchyEntryData& rEntry ) : aData( rEntry ) {}
64 };
65 
66 //=========================================================================
67 //
68 // ResultList.
69 //
70 //=========================================================================
71 
72 typedef std::vector< ResultListEntry* > ResultList;
73 
74 //=========================================================================
75 //
76 // struct DataSupplier_Impl.
77 //
78 //=========================================================================
79 
80 struct DataSupplier_Impl
81 {
82     osl::Mutex                                      m_aMutex;
83     ResultList                                      m_aResults;
84     rtl::Reference< HierarchyContent >              m_xContent;
85     uno::Reference< lang::XMultiServiceFactory >    m_xSMgr;
86     HierarchyEntry                                  m_aFolder;
87     HierarchyEntry::iterator                        m_aIterator;
88     sal_Int32                                       m_nOpenMode;
89     sal_Bool                                        m_bCountFinal;
90 
91     DataSupplier_Impl(
92         const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
93         const rtl::Reference< HierarchyContent >& rContent,
94         sal_Int32 nOpenMode )
95     : m_xContent( rContent ), m_xSMgr( rxSMgr ),
96       m_aFolder( rxSMgr,
97                  static_cast< HierarchyContentProvider * >(
98                      rContent->getProvider().get() ),
99                  rContent->getIdentifier()->getContentIdentifier() ),
100       m_nOpenMode( nOpenMode ), m_bCountFinal( sal_False ) {}
101     ~DataSupplier_Impl();
102 };
103 
104 //=========================================================================
105 DataSupplier_Impl::~DataSupplier_Impl()
106 {
107     ResultList::const_iterator it  = m_aResults.begin();
108     ResultList::const_iterator end = m_aResults.end();
109 
110     while ( it != end )
111     {
112         delete (*it);
113         it++;
114     }
115 }
116 
117 }
118 
119 //=========================================================================
120 //=========================================================================
121 //
122 // HierarchyResultSetDataSupplier Implementation.
123 //
124 //=========================================================================
125 //=========================================================================
126 
127 HierarchyResultSetDataSupplier::HierarchyResultSetDataSupplier(
128                 const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
129                 const rtl::Reference< HierarchyContent >& rContent,
130                 sal_Int32 nOpenMode )
131 : m_pImpl( new DataSupplier_Impl( rxSMgr, rContent, nOpenMode ) )
132 {
133 }
134 
135 //=========================================================================
136 // virtual
137 HierarchyResultSetDataSupplier::~HierarchyResultSetDataSupplier()
138 {
139     delete m_pImpl;
140 }
141 
142 //=========================================================================
143 // virtual
144 rtl::OUString HierarchyResultSetDataSupplier::queryContentIdentifierString(
145                                                         sal_uInt32 nIndex )
146 {
147     osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
148 
149     if ( nIndex < m_pImpl->m_aResults.size() )
150     {
151         rtl::OUString aId = m_pImpl->m_aResults[ nIndex ]->aId;
152         if ( aId.getLength() )
153         {
154             // Already cached.
155             return aId;
156         }
157     }
158 
159     if ( getResult( nIndex ) )
160     {
161         rtl::OUString aId
162             = m_pImpl->m_xContent->getIdentifier()->getContentIdentifier();
163 
164         if ( ( aId.lastIndexOf( '/' ) + 1 ) != aId.getLength() )
165             aId += rtl::OUString::createFromAscii( "/" );
166 
167         aId += m_pImpl->m_aResults[ nIndex ]->aData.getName();
168 
169         m_pImpl->m_aResults[ nIndex ]->aId = aId;
170         return aId;
171     }
172     return rtl::OUString();
173 }
174 
175 //=========================================================================
176 // virtual
177 uno::Reference< ucb::XContentIdentifier >
178 HierarchyResultSetDataSupplier::queryContentIdentifier( sal_uInt32 nIndex )
179 {
180     osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
181 
182     if ( nIndex < m_pImpl->m_aResults.size() )
183     {
184         uno::Reference< ucb::XContentIdentifier > xId
185                                 = m_pImpl->m_aResults[ nIndex ]->xId;
186         if ( xId.is() )
187         {
188             // Already cached.
189             return xId;
190         }
191     }
192 
193     rtl::OUString aId = queryContentIdentifierString( nIndex );
194     if ( aId.getLength() )
195     {
196         uno::Reference< ucb::XContentIdentifier > xId
197             = new ::ucbhelper::ContentIdentifier( aId );
198         m_pImpl->m_aResults[ nIndex ]->xId = xId;
199         return xId;
200     }
201     return uno::Reference< ucb::XContentIdentifier >();
202 }
203 
204 //=========================================================================
205 // virtual
206 uno::Reference< ucb::XContent >
207 HierarchyResultSetDataSupplier::queryContent( sal_uInt32 nIndex )
208 {
209     osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
210 
211     if ( nIndex < m_pImpl->m_aResults.size() )
212     {
213         uno::Reference< ucb::XContent > xContent
214                                 = m_pImpl->m_aResults[ nIndex ]->xContent;
215         if ( xContent.is() )
216         {
217             // Already cached.
218             return xContent;
219         }
220     }
221 
222     uno::Reference< ucb::XContentIdentifier > xId
223         = queryContentIdentifier( nIndex );
224     if ( xId.is() )
225     {
226         try
227         {
228             uno::Reference< ucb::XContent > xContent
229                 = m_pImpl->m_xContent->getProvider()->queryContent( xId );
230             m_pImpl->m_aResults[ nIndex ]->xContent = xContent;
231             return xContent;
232 
233         }
234         catch ( ucb::IllegalIdentifierException const & )
235         {
236         }
237     }
238     return uno::Reference< ucb::XContent >();
239 }
240 
241 //=========================================================================
242 // virtual
243 sal_Bool HierarchyResultSetDataSupplier::getResult( sal_uInt32 nIndex )
244 {
245     osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
246 
247     if ( m_pImpl->m_aResults.size() > nIndex )
248     {
249         // Result already present.
250         return sal_True;
251     }
252 
253     // Result not (yet) present.
254 
255     if ( m_pImpl->m_bCountFinal )
256         return sal_False;
257 
258     // Try to obtain result...
259 
260     sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
261     sal_Bool bFound = sal_False;
262     sal_uInt32 nPos = nOldCount;
263 
264     while ( m_pImpl->m_aFolder.next( m_pImpl->m_aIterator ) )
265     {
266         const HierarchyEntryData& rResult = *m_pImpl->m_aIterator;
267         if ( checkResult( rResult ) )
268         {
269             m_pImpl->m_aResults.push_back( new ResultListEntry( rResult ) );
270 
271             if ( nPos == nIndex )
272             {
273                 // Result obtained.
274                 bFound = sal_True;
275                 break;
276             }
277         }
278         nPos++;
279     }
280 
281     if ( !bFound )
282         m_pImpl->m_bCountFinal = sal_True;
283 
284     rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
285     if ( xResultSet.is() )
286     {
287         // Callbacks follow!
288         aGuard.clear();
289 
290         if ( nOldCount < m_pImpl->m_aResults.size() )
291             xResultSet->rowCountChanged(
292                                     nOldCount, m_pImpl->m_aResults.size() );
293 
294         if ( m_pImpl->m_bCountFinal )
295             xResultSet->rowCountFinal();
296     }
297 
298     return bFound;
299 }
300 
301 //=========================================================================
302 // virtual
303 sal_uInt32 HierarchyResultSetDataSupplier::totalCount()
304 {
305     osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
306 
307     if ( m_pImpl->m_bCountFinal )
308         return m_pImpl->m_aResults.size();
309 
310     sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
311 
312     while ( m_pImpl->m_aFolder.next( m_pImpl->m_aIterator ) )
313     {
314         const HierarchyEntryData& rResult = *m_pImpl->m_aIterator;
315         if ( checkResult( rResult ) )
316             m_pImpl->m_aResults.push_back( new ResultListEntry( rResult ) );
317     }
318 
319     m_pImpl->m_bCountFinal = sal_True;
320 
321     rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
322     if ( xResultSet.is() )
323     {
324         // Callbacks follow!
325         aGuard.clear();
326 
327         if ( nOldCount < m_pImpl->m_aResults.size() )
328             xResultSet->rowCountChanged(
329                                     nOldCount, m_pImpl->m_aResults.size() );
330 
331         xResultSet->rowCountFinal();
332     }
333 
334     return m_pImpl->m_aResults.size();
335 }
336 
337 //=========================================================================
338 // virtual
339 sal_uInt32 HierarchyResultSetDataSupplier::currentCount()
340 {
341     return m_pImpl->m_aResults.size();
342 }
343 
344 //=========================================================================
345 // virtual
346 sal_Bool HierarchyResultSetDataSupplier::isCountFinal()
347 {
348     return m_pImpl->m_bCountFinal;
349 }
350 
351 //=========================================================================
352 // virtual
353 uno::Reference< sdbc::XRow >
354 HierarchyResultSetDataSupplier::queryPropertyValues( sal_uInt32 nIndex  )
355 {
356     osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
357 
358     if ( nIndex < m_pImpl->m_aResults.size() )
359     {
360         uno::Reference< sdbc::XRow > xRow
361             = m_pImpl->m_aResults[ nIndex ]->xRow;
362         if ( xRow.is() )
363         {
364             // Already cached.
365             return xRow;
366         }
367     }
368 
369     if ( getResult( nIndex ) )
370     {
371         static rtl::OUString aFolderType(
372             rtl::OUString::createFromAscii( HIERARCHY_FOLDER_CONTENT_TYPE ) );
373         static rtl::OUString aLinkType(
374             rtl::OUString::createFromAscii( HIERARCHY_LINK_CONTENT_TYPE ) );
375 
376         HierarchyContentProperties aData(
377             m_pImpl->m_aResults[ nIndex ]->aData );
378 
379         uno::Reference< sdbc::XRow > xRow
380             = HierarchyContent::getPropertyValues(
381                 m_pImpl->m_xSMgr,
382                 getResultSet()->getProperties(),
383                 aData,
384                 static_cast< HierarchyContentProvider * >(
385                     m_pImpl->m_xContent->getProvider().get() ),
386                 queryContentIdentifierString( nIndex ) );
387         m_pImpl->m_aResults[ nIndex ]->xRow = xRow;
388         return xRow;
389     }
390 
391     return uno::Reference< sdbc::XRow >();
392 }
393 
394 //=========================================================================
395 // virtual
396 void HierarchyResultSetDataSupplier::releasePropertyValues( sal_uInt32 nIndex )
397 {
398     osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
399 
400     if ( nIndex < m_pImpl->m_aResults.size() )
401         m_pImpl->m_aResults[ nIndex ]->xRow = uno::Reference< sdbc::XRow >();
402 }
403 
404 //=========================================================================
405 // virtual
406 void HierarchyResultSetDataSupplier::close()
407 {
408 }
409 
410 //=========================================================================
411 // virtual
412 void HierarchyResultSetDataSupplier::validate()
413     throw( ucb::ResultSetException )
414 {
415 }
416 
417 //=========================================================================
418 sal_Bool HierarchyResultSetDataSupplier::checkResult(
419                                     const HierarchyEntryData& rResult )
420 {
421     switch ( m_pImpl->m_nOpenMode )
422     {
423         case ucb::OpenMode::FOLDERS:
424             if ( rResult.getType() == HierarchyEntryData::LINK )
425             {
426                 // Entry is a link.
427                 return sal_False;
428             }
429             break;
430 
431         case ucb::OpenMode::DOCUMENTS:
432             if ( rResult.getType() == HierarchyEntryData::FOLDER )
433             {
434                 // Entry is a folder.
435                 return sal_False;
436             }
437             break;
438 
439         case ucb::OpenMode::ALL:
440         default:
441             break;
442     }
443 
444     return sal_True;
445 }
446 
447