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_ucbhelper.hxx"
30 
31 /**************************************************************************
32 								TODO
33  **************************************************************************
34 
35  *************************************************************************/
36 
37 #include <vector>
38 
39 #include "ucbhelper/contentidentifier.hxx"
40 #include "ucbhelper/providerhelper.hxx"
41 
42 #include "myucp_datasupplier.hxx"
43 #include "myucp_content.hxx"
44 
45 using namespace com::sun::star;
46 
47 // @@@ Adjust namespace name.
48 namespace myucp
49 {
50 
51 //=========================================================================
52 //
53 // struct ResultListEntry.
54 //
55 //=========================================================================
56 
57 struct ResultListEntry
58 {
59 	rtl::OUString						      aId;
60 	uno::Reference< ucb::XContentIdentifier > xId;
61 	uno::Reference< ucb::XContent > 		  xContent;
62 	uno::Reference< sdbc::XRow > 			  xRow;
63 	const ContentProperties& 		          rData;
64 
65 	ResultListEntry( const ContentProperties& rEntry ) : rData( rEntry ) {}
66 };
67 
68 //=========================================================================
69 //
70 // ResultList.
71 //
72 //=========================================================================
73 
74 typedef std::vector< ResultListEntry* > ResultList;
75 
76 //=========================================================================
77 //
78 // struct DataSupplier_Impl.
79 //
80 //=========================================================================
81 
82 struct DataSupplier_Impl
83 {
84 	osl::Mutex					                 m_aMutex;
85 	ResultList					                 m_aResults;
86 	rtl::Reference< Content >     	             m_xContent;
87 	uno::Reference< lang::XMultiServiceFactory > m_xSMgr;
88 // @@@ The data source and an iterator for it
89 //	Entry 		 	      	  		             m_aFolder;
90 //	Entry::iterator 		  		             m_aIterator;
91   	sal_Int32					                 m_nOpenMode;
92   	sal_Bool					                 m_bCountFinal;
93 
94 	DataSupplier_Impl( const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
95 	                   const rtl::Reference< Content >& rContent,
96 					   sal_Int32 nOpenMode )
97 	: m_xContent( rContent ), m_xSMgr( rxSMgr ),
98 //	  m_aFolder( rxSMgr, rContent->getIdentifier()->getContentIdentifier() ),
99 	  m_nOpenMode( nOpenMode ), m_bCountFinal( sal_False ) {}
100 	~DataSupplier_Impl();
101 };
102 
103 //=========================================================================
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 // DataSupplier Implementation.
120 //
121 //=========================================================================
122 //=========================================================================
123 
124 DataSupplier::DataSupplier( const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
125 							const rtl::Reference< Content >& rContent,
126 							sal_Int32 nOpenMode )
127 : m_pImpl( new DataSupplier_Impl( rxSMgr, rContent, nOpenMode ) )
128 {
129 }
130 
131 //=========================================================================
132 // virtual
133 DataSupplier::~DataSupplier()
134 {
135 	delete m_pImpl;
136 }
137 
138 //=========================================================================
139 // virtual
140 rtl::OUString DataSupplier::queryContentIdentifierString( sal_uInt32 nIndex )
141 {
142 	osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
143 
144 	if ( nIndex < m_pImpl->m_aResults.size() )
145 	{
146 		rtl::OUString aId = m_pImpl->m_aResults[ nIndex ]->aId;
147 		if ( aId.getLength() )
148 		{
149 			// Already cached.
150 			return aId;
151 		}
152 	}
153 
154 	if ( getResult( nIndex ) )
155 	{
156 		rtl::OUString aId
157 			= m_pImpl->m_xContent->getIdentifier()->getContentIdentifier();
158 
159 		aId += m_pImpl->m_aResults[ nIndex ]->rData.aTitle;
160 
161 		m_pImpl->m_aResults[ nIndex ]->aId = aId;
162 		return aId;
163 	}
164 	return rtl::OUString();
165 }
166 
167 //=========================================================================
168 // virtual
169 uno::Reference< ucb::XContentIdentifier >
170 DataSupplier::queryContentIdentifier( sal_uInt32 nIndex )
171 {
172 	osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
173 
174 	if ( nIndex < m_pImpl->m_aResults.size() )
175 	{
176 		uno::Reference< ucb::XContentIdentifier > xId
177 								= m_pImpl->m_aResults[ nIndex ]->xId;
178 		if ( xId.is() )
179 		{
180 			// Already cached.
181 			return xId;
182 		}
183 	}
184 
185 	rtl::OUString aId = queryContentIdentifierString( nIndex );
186 	if ( aId.getLength() )
187 	{
188 		uno::Reference< ucb::XContentIdentifier > xId
189             = new ::ucbhelper::ContentIdentifier( aId );
190 		m_pImpl->m_aResults[ nIndex ]->xId = xId;
191 		return xId;
192 	}
193 	return uno::Reference< ucb::XContentIdentifier >();
194 }
195 
196 //=========================================================================
197 // virtual
198 uno::Reference< ucb::XContent >
199 DataSupplier::queryContent( sal_uInt32 nIndex )
200 {
201 	osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
202 
203 	if ( nIndex < m_pImpl->m_aResults.size() )
204 	{
205 		uno::Reference< ucb::XContent > xContent
206 								= m_pImpl->m_aResults[ nIndex ]->xContent;
207 		if ( xContent.is() )
208 		{
209 			// Already cached.
210 			return xContent;
211 		}
212 	}
213 
214 	uno::Reference< ucb::XContentIdentifier > xId
215         = queryContentIdentifier( nIndex );
216 	if ( xId.is() )
217 	{
218 		try
219 		{
220 			uno::Reference< ucb::XContent > xContent
221 				= m_pImpl->m_xContent->getProvider()->queryContent( xId );
222 			m_pImpl->m_aResults[ nIndex ]->xContent = xContent;
223 			return xContent;
224 
225 		}
226 		catch ( ucb::IllegalIdentifierException& )
227 		{
228 		}
229 	}
230 	return uno::Reference< ucb::XContent >();
231 }
232 
233 //=========================================================================
234 // virtual
235 sal_Bool DataSupplier::getResult( sal_uInt32 nIndex )
236 {
237 	osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
238 
239 	if ( m_pImpl->m_aResults.size() > nIndex )
240 	{
241 		// Result already present.
242 		return sal_True;
243 	}
244 
245 	// Result not (yet) present.
246 
247 	if ( m_pImpl->m_bCountFinal )
248 		return sal_False;
249 
250 	// Try to obtain result...
251 
252 	sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
253 	sal_Bool bFound = sal_False;
254 
255 	// @@@ Obtain data and put it into result list...
256 /*
257 	sal_uInt32 nPos = nOldCount;
258 	while ( m_pImpl->m_aFolder.next( m_pImpl->m_aIterator ) )
259 	{
260 		m_pImpl->m_aResults.push_back(
261 						new ResultListEntry( *m_pImpl->m_aIterator ) );
262 
263 		if ( nPos == nIndex )
264 		{
265 			// Result obtained.
266 			bFound = sal_True;
267 			break;
268 		}
269 
270 		nPos++;
271 	}
272 */
273 
274 	if ( !bFound )
275 		m_pImpl->m_bCountFinal = sal_True;
276 
277 	rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
278 	if ( xResultSet.is() )
279 	{
280 		// Callbacks follow!
281 		aGuard.clear();
282 
283 		if ( nOldCount < m_pImpl->m_aResults.size() )
284 			xResultSet->rowCountChanged(
285 									nOldCount, m_pImpl->m_aResults.size() );
286 
287 		if ( m_pImpl->m_bCountFinal )
288 			xResultSet->rowCountFinal();
289 	}
290 
291 	return bFound;
292 }
293 
294 //=========================================================================
295 // virtual
296 sal_uInt32 DataSupplier::totalCount()
297 {
298 	osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
299 
300 	if ( m_pImpl->m_bCountFinal )
301 		return m_pImpl->m_aResults.size();
302 
303 	sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
304 
305 	// @@@ Obtain data and put it into result list...
306 /*
307 	while ( m_pImpl->m_aFolder.next( m_pImpl->m_aIterator ) )
308 		m_pImpl->m_aResults.push_back(
309 						new ResultListEntry( *m_pImpl->m_aIterator ) );
310 */
311 	m_pImpl->m_bCountFinal = sal_True;
312 
313 	rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
314 	if ( xResultSet.is() )
315 	{
316 		// Callbacks follow!
317 		aGuard.clear();
318 
319 		if ( nOldCount < m_pImpl->m_aResults.size() )
320 			xResultSet->rowCountChanged(
321 									nOldCount, m_pImpl->m_aResults.size() );
322 
323 		xResultSet->rowCountFinal();
324 	}
325 
326 	return m_pImpl->m_aResults.size();
327 }
328 
329 //=========================================================================
330 // virtual
331 sal_uInt32 DataSupplier::currentCount()
332 {
333 	return m_pImpl->m_aResults.size();
334 }
335 
336 //=========================================================================
337 // virtual
338 sal_Bool DataSupplier::isCountFinal()
339 {
340 	return m_pImpl->m_bCountFinal;
341 }
342 
343 //=========================================================================
344 // virtual
345 uno::Reference< sdbc::XRow >
346 DataSupplier::queryPropertyValues( sal_uInt32 nIndex  )
347 {
348 	osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
349 
350 	if ( nIndex < m_pImpl->m_aResults.size() )
351 	{
352 		uno::Reference< sdbc::XRow > xRow = m_pImpl->m_aResults[ nIndex ]->xRow;
353 		if ( xRow.is() )
354 		{
355 			// Already cached.
356 			return xRow;
357 		}
358 	}
359 
360 	if ( getResult( nIndex ) )
361 	{
362 		uno::Reference< sdbc::XRow > xRow = Content::getPropertyValues(
363 									m_pImpl->m_xSMgr,
364 									getResultSet()->getProperties(),
365 									m_pImpl->m_aResults[ nIndex ]->rData,
366 									m_pImpl->m_xContent->getProvider().get(),
367 									queryContentIdentifierString( nIndex ) );
368 		m_pImpl->m_aResults[ nIndex ]->xRow = xRow;
369 		return xRow;
370 	}
371 
372 	return uno::Reference< sdbc::XRow >();
373 }
374 
375 //=========================================================================
376 // virtual
377 void DataSupplier::releasePropertyValues( sal_uInt32 nIndex )
378 {
379 	osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
380 
381 	if ( nIndex < m_pImpl->m_aResults.size() )
382 		m_pImpl->m_aResults[ nIndex ]->xRow = uno::Reference< sdbc::XRow >();
383 }
384 
385 //=========================================================================
386 // virtual
387 void DataSupplier::close()
388 {
389 }
390 
391 //=========================================================================
392 // virtual
393 void DataSupplier::validate()
394 	throw( ucb::ResultSetException )
395 {
396 }
397 
398 } // namespace
399