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