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_dbaccess.hxx"
26 
27 /**************************************************************************
28 								TODO
29  **************************************************************************
30 
31  *************************************************************************/
32 
33 #include <vector>
34 
35 #ifndef _UCBHELPER_CONTENTIDENTIFIER_HXX
36 #include <ucbhelper/contentidentifier.hxx>
37 #endif
38 #ifndef _UCBHELPER_PROVIDERHELPER_HXX
39 #include <ucbhelper/providerhelper.hxx>
40 #endif
41 
42 #ifndef DBA_DATASUPPLIER_HXX
43 #include "myucp_datasupplier.hxx"
44 #endif
45 #ifndef DBA_CONTENTHELPER_HXX
46 #include "ContentHelper.hxx"
47 #endif
48 #ifndef _COM_SUN_STAR_CONTAINER_XHIERARCHICALNAMEACCESS_HPP_
49 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
50 #endif
51 #ifndef _TOOLS_DEBUG_HXX
52 #include <tools/debug.hxx>
53 #endif
54 
55 using namespace ::com::sun::star::uno;
56 using namespace ::com::sun::star::ucb;
57 using namespace ::com::sun::star::beans;
58 using namespace ::com::sun::star::lang;
59 using namespace ::com::sun::star::sdbc;
60 using namespace ::com::sun::star::io;
61 using namespace ::com::sun::star::container;
62 
63 // @@@ Adjust namespace name.
64 using namespace dbaccess;
65 
66 // @@@ Adjust namespace name.
67 namespace dbaccess
68 {
69 
70 //=========================================================================
71 //
72 // struct ResultListEntry.
73 //
74 //=========================================================================
75 
76 struct ResultListEntry
77 {
78 	rtl::OUString						aId;
79 	Reference< XContentIdentifier >		xId;
80 	::rtl::Reference< OContentHelper > 	xContent;
81 	Reference< XRow > 					xRow;
82 	const ContentProperties& 			rData;
83 
ResultListEntrydbaccess::ResultListEntry84 	ResultListEntry( const ContentProperties& rEntry ) : rData( rEntry ) {}
85 };
86 
87 //=========================================================================
88 //
89 // ResultList.
90 //
91 //=========================================================================
92 
93 typedef std::vector< ResultListEntry* > ResultList;
94 
95 //=========================================================================
96 //
97 // struct DataSupplier_Impl.
98 //
99 //=========================================================================
100 
101 struct DataSupplier_Impl
102 {
103 	osl::Mutex					                 m_aMutex;
104 	ResultList					                 m_aResults;
105 	rtl::Reference< ODocumentContainer >     	     m_xContent;
106 	Reference< XMultiServiceFactory >			 m_xSMgr;
107   	sal_Int32					                 m_nOpenMode;
108   	sal_Bool					                 m_bCountFinal;
109 
DataSupplier_Impldbaccess::DataSupplier_Impl110 	DataSupplier_Impl( const Reference< XMultiServiceFactory >& rxSMgr,
111 						const rtl::Reference< ODocumentContainer >& rContent,
112 					   sal_Int32 nOpenMode )
113 	: m_xContent(rContent)
114 	, m_xSMgr( rxSMgr )
115 	, m_nOpenMode( nOpenMode )
116 	, m_bCountFinal( sal_False ) {}
117 	~DataSupplier_Impl();
118 };
119 
120 //=========================================================================
~DataSupplier_Impl()121 DataSupplier_Impl::~DataSupplier_Impl()
122 {
123 	ResultList::const_iterator it  = m_aResults.begin();
124 	ResultList::const_iterator end = m_aResults.end();
125 
126 	while ( it != end )
127 	{
128 		delete (*it);
129 		it++;
130 	}
131 }
132 
133 }
134 
135 //=========================================================================
136 //=========================================================================
137 //
138 // DataSupplier Implementation.
139 //
140 //=========================================================================
141 //=========================================================================
DBG_NAME(DataSupplier)142 DBG_NAME(DataSupplier)
143 
144 DataSupplier::DataSupplier( const Reference< XMultiServiceFactory >& rxSMgr,
145 						   const rtl::Reference< ODocumentContainer >& rContent,
146 							sal_Int32 nOpenMode )
147 : m_pImpl( new DataSupplier_Impl( rxSMgr, rContent,nOpenMode ) )
148 {
149     DBG_CTOR(DataSupplier,NULL);
150 
151 }
152 
153 //=========================================================================
154 // virtual
~DataSupplier()155 DataSupplier::~DataSupplier()
156 {
157 
158     DBG_DTOR(DataSupplier,NULL);
159 }
160 
161 //=========================================================================
162 // virtual
queryContentIdentifierString(sal_uInt32 nIndex)163 rtl::OUString DataSupplier::queryContentIdentifierString( sal_uInt32 nIndex )
164 {
165 	osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
166 
167 	if ( (size_t)nIndex < m_pImpl->m_aResults.size() )
168 	{
169 		rtl::OUString aId = m_pImpl->m_aResults[ nIndex ]->aId;
170 		if ( aId.getLength() )
171 		{
172 			// Already cached.
173 			return aId;
174 		}
175 	}
176 
177 	if ( getResult( nIndex ) )
178 	{
179 		rtl::OUString aId
180 			= m_pImpl->m_xContent->getIdentifier()->getContentIdentifier();
181 
182 		if ( aId.getLength() )
183 			aId += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/"));
184 
185 		aId += m_pImpl->m_aResults[ nIndex ]->rData.aTitle;
186 
187 		m_pImpl->m_aResults[ nIndex ]->aId = aId;
188 		return aId;
189 	}
190 	return rtl::OUString();
191 }
192 
193 //=========================================================================
194 // virtual
195 Reference< XContentIdentifier >
queryContentIdentifier(sal_uInt32 nIndex)196 DataSupplier::queryContentIdentifier( sal_uInt32 nIndex )
197 {
198 	osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
199 
200 	if ( (size_t)nIndex < m_pImpl->m_aResults.size() )
201 	{
202 		Reference< XContentIdentifier > xId = m_pImpl->m_aResults[ nIndex ]->xId;
203 		if ( xId.is() )
204 		{
205 			// Already cached.
206 			return xId;
207 		}
208 	}
209 
210 	rtl::OUString aId = queryContentIdentifierString( nIndex );
211 	if ( aId.getLength() )
212 	{
213 		Reference< XContentIdentifier > xId = new ::ucbhelper::ContentIdentifier( aId );
214 		m_pImpl->m_aResults[ nIndex ]->xId = xId;
215 		return xId;
216 	}
217 	return Reference< XContentIdentifier >();
218 }
219 
220 //=========================================================================
221 // virtual
222 Reference< XContent >
queryContent(sal_uInt32 _nIndex)223 DataSupplier::queryContent( sal_uInt32 _nIndex )
224 {
225 	osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
226 
227 	if ( (size_t)_nIndex < m_pImpl->m_aResults.size() )
228 	{
229 		Reference< XContent > xContent = m_pImpl->m_aResults[ _nIndex ]->xContent.get();
230 		if ( xContent.is() )
231 		{
232 			// Already cached.
233 			return xContent;
234 		}
235 	}
236 
237 	Reference< XContentIdentifier > xId = queryContentIdentifier( _nIndex );
238 	if ( xId.is() )
239 	{
240 		try
241 		{
242 			Reference< XContent > xContent;
243 			::rtl::OUString sName = xId->getContentIdentifier();
244 			sal_Int32 nIndex = sName.lastIndexOf('/') + 1;
245 			sName = sName.getToken(0,'/',nIndex);
246 
247 			m_pImpl->m_aResults[ _nIndex ]->xContent = m_pImpl->m_xContent->getContent(sName);
248 
249 			xContent = m_pImpl->m_aResults[ _nIndex ]->xContent.get();
250 			return xContent;
251 
252 		}
253 		catch ( IllegalIdentifierException& )
254 		{
255 		}
256 	}
257 	return Reference< XContent >();
258 }
259 
260 //=========================================================================
261 // virtual
getResult(sal_uInt32 nIndex)262 sal_Bool DataSupplier::getResult( sal_uInt32 nIndex )
263 {
264 	osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
265 
266 	if ( (size_t)nIndex < m_pImpl->m_aResults.size() )
267 	{
268 		// Result already present.
269 		return sal_True;
270 	}
271 
272 	// Result not (yet) present.
273 
274 	if ( m_pImpl->m_bCountFinal )
275 		return sal_False;
276 
277 	// Try to obtain result...
278 
279 	sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
280 	sal_Bool bFound = sal_False;
281 	sal_uInt32 nPos = nOldCount;
282 
283 	// @@@ Obtain data and put it into result list...
284 	Sequence< ::rtl::OUString> aSeq = m_pImpl->m_xContent->getElementNames();
285 	if ( nIndex < sal::static_int_cast< sal_uInt32 >( aSeq.getLength() ) )
286 	{
287 		const ::rtl::OUString* pIter = aSeq.getConstArray();
288 		const ::rtl::OUString* pEnd	  = pIter + aSeq.getLength();
289 		for(pIter = pIter + nPos;pIter != pEnd;++pIter,++nPos)
290 		{
291 			m_pImpl->m_aResults.push_back(
292 							new ResultListEntry( m_pImpl->m_xContent->getContent(*pIter)->getContentProperties() ) );
293 
294 			if ( nPos == nIndex )
295 			{
296 				// Result obtained.
297 				bFound = sal_True;
298 				break;
299 			}
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 ( (size_t)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 	// @@@ Obtain data and put it into result list...
335 	Sequence< ::rtl::OUString> aSeq = m_pImpl->m_xContent->getElementNames();
336 	const ::rtl::OUString* pIter = aSeq.getConstArray();
337 	const ::rtl::OUString* pEnd	  = pIter + aSeq.getLength();
338 	for(;pIter != pEnd;++pIter)
339 		m_pImpl->m_aResults.push_back(
340 						new ResultListEntry( m_pImpl->m_xContent->getContent(*pIter)->getContentProperties() ) );
341 
342 	m_pImpl->m_bCountFinal = sal_True;
343 
344 	rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
345 	if ( xResultSet.is() )
346 	{
347 		// Callbacks follow!
348 		aGuard.clear();
349 
350 		if ( (size_t)nOldCount < m_pImpl->m_aResults.size() )
351 			xResultSet->rowCountChanged(
352 									nOldCount, m_pImpl->m_aResults.size() );
353 
354 		xResultSet->rowCountFinal();
355 	}
356 
357 	return m_pImpl->m_aResults.size();
358 }
359 
360 //=========================================================================
361 // virtual
currentCount()362 sal_uInt32 DataSupplier::currentCount()
363 {
364 	return m_pImpl->m_aResults.size();
365 }
366 
367 //=========================================================================
368 // virtual
isCountFinal()369 sal_Bool DataSupplier::isCountFinal()
370 {
371 	return m_pImpl->m_bCountFinal;
372 }
373 
374 //=========================================================================
375 // virtual
376 Reference< XRow >
queryPropertyValues(sal_uInt32 nIndex)377 DataSupplier::queryPropertyValues( sal_uInt32 nIndex  )
378 {
379 	osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
380 
381 	if ( (size_t)nIndex < m_pImpl->m_aResults.size() )
382 	{
383 		Reference< XRow > xRow = m_pImpl->m_aResults[ nIndex ]->xRow;
384 		if ( xRow.is() )
385 		{
386 			// Already cached.
387 			return xRow;
388 		}
389 	}
390 
391 	if ( getResult( nIndex ) )
392 	{
393 		if ( !m_pImpl->m_aResults[ nIndex ]->xContent.is() )
394 			queryContent(nIndex);
395 
396 		Reference< XRow > xRow = m_pImpl->m_aResults[ nIndex ]->xContent->getPropertyValues(getResultSet()->getProperties());
397 		m_pImpl->m_aResults[ nIndex ]->xRow = xRow;
398 		return xRow;
399 	}
400 
401 	return Reference< XRow >();
402 }
403 
404 //=========================================================================
405 // virtual
releasePropertyValues(sal_uInt32 nIndex)406 void DataSupplier::releasePropertyValues( sal_uInt32 nIndex )
407 {
408 	osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
409 
410 	if ( (size_t)nIndex < m_pImpl->m_aResults.size() )
411 		m_pImpl->m_aResults[ nIndex ]->xRow = Reference< XRow >();
412 }
413 
414 //=========================================================================
415 // virtual
close()416 void DataSupplier::close()
417 {
418 }
419 
420 //=========================================================================
421 // virtual
validate()422 void DataSupplier::validate()
423 	throw( ResultSetException )
424 {
425 }
426 
427