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 <ucbhelper/providerhelper.hxx>
36 #include "odma_datasupplier.hxx"
37 #include "odma_content.hxx"
38 #include "odma_contentprops.hxx"
39 #include "odma_provider.hxx"
40 #include "odma_lib.hxx"
41 
42 using namespace com::sun::star::beans;
43 using namespace com::sun::star::lang;
44 using namespace com::sun::star::ucb;
45 using namespace com::sun::star::uno;
46 using namespace com::sun::star::sdbc;
47 
48 using namespace odma;
49 
50 namespace odma
51 {
52 
53 //=========================================================================
54 //
55 // struct ResultListEntry.
56 //
57 //=========================================================================
58 
59 struct ResultListEntry
60 {
61 	::rtl::OUString					    aId;
62 	Reference< XContentIdentifier >     xId;
63 	Reference< XContent > 			    xContent;
64 	Reference< XRow > 				    xRow;
65 	::rtl::Reference<ContentProperties>	rData;
66 
ResultListEntryodma::ResultListEntry67 	ResultListEntry( const ::rtl::Reference<ContentProperties>& rEntry ) : rData( rEntry ) {}
68 };
69 
70 //=========================================================================
71 //
72 // ResultList.
73 //
74 //=========================================================================
75 
76 typedef std::vector< ResultListEntry* > ResultList;
77 
78 //=========================================================================
79 //
80 // struct DataSupplier_Impl.
81 //
82 //=========================================================================
83 
84 struct DataSupplier_Impl
85 {
86 	osl::Mutex					      m_aMutex;
87 	ResultList					      m_aResults;
88 	rtl::Reference< Content >     	  m_xContent;
89 	Reference< XMultiServiceFactory > m_xSMgr;
90 // @@@ The data source and an iterator for it
91 //	Entry 		 	      	  		  m_aFolder;
92 //	Entry::iterator 		  		  m_aIterator;
93   	sal_Int32					      m_nOpenMode;
94   	sal_Bool					      m_bCountFinal;
95 
DataSupplier_Implodma::DataSupplier_Impl96 	DataSupplier_Impl( const Reference< XMultiServiceFactory >& rxSMgr,
97 	                   const rtl::Reference< Content >& rContent,
98 					   sal_Int32 nOpenMode )
99 	: m_xContent( rContent ), m_xSMgr( rxSMgr ),
100 //	  m_aFolder( rxSMgr, rContent->getIdentifier()->getContentIdentifier() ),
101 	  m_nOpenMode( nOpenMode ), m_bCountFinal( sal_False ) {}
102 	~DataSupplier_Impl();
103 };
104 
105 //=========================================================================
~DataSupplier_Impl()106 DataSupplier_Impl::~DataSupplier_Impl()
107 {
108 	ResultList::const_iterator it  = m_aResults.begin();
109 	ResultList::const_iterator end = m_aResults.end();
110 
111 	while ( it != end )
112 	{
113 		delete (*it);
114 		it++;
115 	}
116 }
117 
118 }
119 
120 //=========================================================================
121 //=========================================================================
122 //
123 // DataSupplier Implementation.
124 //
125 //=========================================================================
126 //=========================================================================
127 
DataSupplier(const Reference<XMultiServiceFactory> & rxSMgr,const rtl::Reference<::odma::Content> & rContent,sal_Int32 nOpenMode)128 DataSupplier::DataSupplier( const Reference<XMultiServiceFactory >& rxSMgr,
129 						   const rtl::Reference< ::odma::Content >& rContent,
130 							sal_Int32 nOpenMode )
131 : m_pImpl( new DataSupplier_Impl( rxSMgr, rContent, nOpenMode ) )
132 {
133 }
134 
135 //=========================================================================
136 // virtual
~DataSupplier()137 DataSupplier::~DataSupplier()
138 {
139 	delete m_pImpl;
140 }
141 
142 //=========================================================================
143 // virtual
queryContentIdentifierString(sal_uInt32 nIndex)144 ::rtl::OUString DataSupplier::queryContentIdentifierString( sal_uInt32 nIndex )
145 {
146 	osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
147 
148 	if ( nIndex < m_pImpl->m_aResults.size() )
149 	{
150 		::rtl::OUString aId = m_pImpl->m_aResults[ nIndex ]->aId;
151 		if ( aId.getLength() )
152 		{
153 			// Already cached.
154 			return aId;
155 		}
156 	}
157 
158 	if ( getResult( nIndex ) )
159 	{
160 		::rtl::OUString aId
161 			= m_pImpl->m_xContent->getIdentifier()->getContentIdentifier();
162 
163 		aId += m_pImpl->m_aResults[ nIndex ]->rData->m_sTitle;
164 
165 		m_pImpl->m_aResults[ nIndex ]->aId = aId;
166 		return aId;
167 	}
168 	return ::rtl::OUString();
169 }
170 
171 //=========================================================================
172 // virtual
queryContentIdentifier(sal_uInt32 nIndex)173 Reference< XContentIdentifier > DataSupplier::queryContentIdentifier(
174 														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 		Reference< 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 		Reference< XContentIdentifier > xId
193             = new ucbhelper::ContentIdentifier( aId );
194 		m_pImpl->m_aResults[ nIndex ]->xId = xId;
195 		return xId;
196 	}
197 	return Reference< XContentIdentifier >();
198 }
199 
200 //=========================================================================
201 // virtual
queryContent(sal_uInt32 nIndex)202 Reference< XContent > DataSupplier::queryContent( sal_uInt32 nIndex )
203 {
204 	osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
205 
206 	if ( nIndex < m_pImpl->m_aResults.size() )
207 	{
208 		Reference< XContent > xContent
209 								= m_pImpl->m_aResults[ nIndex ]->xContent;
210 		if ( xContent.is() )
211 		{
212 			// Already cached.
213 			return xContent;
214 		}
215 	}
216 
217 	Reference< XContentIdentifier > xId = queryContentIdentifier( nIndex );
218 	if ( xId.is() )
219 	{
220 		try
221 		{
222 			Reference< XContent > xContent
223 				= m_pImpl->m_xContent->getProvider()->queryContent( xId );
224 			m_pImpl->m_aResults[ nIndex ]->xContent = xContent;
225 			return xContent;
226 
227 		}
228 		catch ( IllegalIdentifierException& )
229 		{
230 		}
231 	}
232 	return Reference< XContent >();
233 }
234 
235 //=========================================================================
236 // virtual
getResult(sal_uInt32 nIndex)237 sal_Bool DataSupplier::getResult( sal_uInt32 nIndex )
238 {
239 	osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
240 
241 	if ( m_pImpl->m_aResults.size() > nIndex )
242 	{
243 		// Result already present.
244 		return sal_True;
245 	}
246 
247 	// Result not (yet) present.
248 
249 	if ( m_pImpl->m_bCountFinal )
250 		return sal_False;
251 
252 	// Try to obtain result...
253 
254 	sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
255 	sal_Bool bFound = sal_False;
256 //	sal_uInt32 nPos = nOldCount;
257 
258 	// @@@ Obtain data and put it into result list...
259 /*
260 	while ( m_pImpl->m_aFolder.next( m_pImpl->m_aIterator ) )
261 	{
262 		m_pImpl->m_aResults.push_back(
263 						new ResultListEntry( *m_pImpl->m_aIterator ) );
264 
265 		if ( nPos == nIndex )
266 		{
267 			// Result obtained.
268 			bFound = sal_True;
269 			break;
270 		}
271 
272 		nPos++;
273 	}
274 */
275 	// now query for all documents in the DMS
276 	OSL_ENSURE(ContentProvider::getHandle(),"No Handle!");
277 	sal_Char* pQueryId		= new sal_Char[ODM_QUERYID_MAX];
278 	sal_Char* lpszDMSList	= new sal_Char[ODM_DMSID_MAX];
279 
280 	ODMSTATUS odm = NODMGetDMS(ODMA_ODMA_REGNAME, lpszDMSList);
281 	lpszDMSList[strlen(lpszDMSList)+1] = '\0';
282 
283 	::rtl::OString sQuery("SELECT ODM_DOCID, ODM_NAME");
284 
285 	DWORD dwFlags = ODM_SPECIFIC;
286 	odm = NODMQueryExecute(ContentProvider::getHandle(), sQuery,dwFlags, lpszDMSList, pQueryId );
287 	if(odm != ODM_SUCCESS)
288 		return sal_False;
289 
290 	sal_uInt16 nCount		= 10;
291 	sal_uInt16 nMaxCount	= 10;
292 	sal_Char* lpszDocId		= new sal_Char[ODM_DOCID_MAX * nMaxCount];
293 	sal_Char* lpszDocName	= new sal_Char[ODM_NAME_MAX * nMaxCount];
294 
295 
296 	::rtl::OUString sContentType(RTL_CONSTASCII_USTRINGPARAM(ODMA_CONTENT_TYPE));
297 	sal_uInt32 nCurrentCount = 0;
298 	do
299 	{
300 		if(nCount >= nMaxCount)
301 		{
302 			nCount = nMaxCount;
303 			odm = NODMQueryGetResults(ContentProvider::getHandle(), pQueryId,lpszDocId, lpszDocName, ODM_NAME_MAX, (WORD*)&nCount);
304 			nCurrentCount += nCount;
305 		}
306 		if(odm == ODM_SUCCESS && nIndex < nCurrentCount)
307 		{
308 			bFound = sal_True;
309 			for(sal_uInt16 i = 0; i < nCount; ++i)
310 			{
311 				::rtl::Reference<ContentProperties> rProps = new ContentProperties();
312 				rProps->m_sDocumentId	= ::rtl::OString(&lpszDocId[ODM_DOCID_MAX*i]);
313 				rProps->m_sContentType	= sContentType;
314 				m_pImpl->m_xContent->getContentProvider()->append(rProps);
315 				m_pImpl->m_aResults.push_back( new ResultListEntry(rProps));
316 			}
317 		}
318 	}
319 	while(nCount > nMaxCount);
320 
321 
322 	// now close the query
323 	odm = NODMQueryClose(ContentProvider::getHandle(), pQueryId);
324 
325 	delete [] lpszDMSList;
326 	delete [] pQueryId;
327 	delete [] lpszDocId;
328 	delete [] lpszDocName;
329 
330 	if ( !bFound )
331 		m_pImpl->m_bCountFinal = sal_True;
332 
333 	rtl::Reference< ucbhelper::ResultSet > xResultSet = getResultSet();
334 	if ( xResultSet.is() )
335 	{
336 		// Callbacks follow!
337 		aGuard.clear();
338 
339 		if ( nOldCount < m_pImpl->m_aResults.size() )
340 			xResultSet->rowCountChanged(
341 									nOldCount, m_pImpl->m_aResults.size() );
342 
343 		if ( m_pImpl->m_bCountFinal )
344 			xResultSet->rowCountFinal();
345 	}
346 
347 	return bFound;
348 }
349 
350 //=========================================================================
351 // virtual
totalCount()352 sal_uInt32 DataSupplier::totalCount()
353 {
354 	osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
355 
356 	if ( m_pImpl->m_bCountFinal )
357 		return m_pImpl->m_aResults.size();
358 
359 	sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
360 
361 	// @@@ Obtain data and put it into result list...
362 /*
363 	while ( m_pImpl->m_aFolder.next( m_pImpl->m_aIterator ) )
364 		m_pImpl->m_aResults.push_back(
365 						new ResultListEntry( *m_pImpl->m_aIterator ) );
366 */
367 	m_pImpl->m_bCountFinal = sal_True;
368 
369 	rtl::Reference< ucbhelper::ResultSet > xResultSet = getResultSet();
370 	if ( xResultSet.is() )
371 	{
372 		// Callbacks follow!
373 		aGuard.clear();
374 
375 		if ( nOldCount < m_pImpl->m_aResults.size() )
376 			xResultSet->rowCountChanged(
377 									nOldCount, m_pImpl->m_aResults.size() );
378 
379 		xResultSet->rowCountFinal();
380 	}
381 
382 	return m_pImpl->m_aResults.size();
383 }
384 
385 //=========================================================================
386 // virtual
currentCount()387 sal_uInt32 DataSupplier::currentCount()
388 {
389 	return m_pImpl->m_aResults.size();
390 }
391 
392 //=========================================================================
393 // virtual
isCountFinal()394 sal_Bool DataSupplier::isCountFinal()
395 {
396 	return m_pImpl->m_bCountFinal;
397 }
398 
399 //=========================================================================
400 // virtual
queryPropertyValues(sal_uInt32 nIndex)401 Reference< XRow > DataSupplier::queryPropertyValues( sal_uInt32 nIndex  )
402 {
403 	osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
404 
405 	if ( nIndex < m_pImpl->m_aResults.size() )
406 	{
407 		Reference< XRow > xRow = m_pImpl->m_aResults[ nIndex ]->xRow;
408 		if ( xRow.is() )
409 		{
410 			// Already cached.
411 			return xRow;
412 		}
413 	}
414 
415 	if ( getResult( nIndex ) )
416 	{
417 		Reference< XRow > xRow = Content::getPropertyValues(
418 									m_pImpl->m_xSMgr,
419 									getResultSet()->getProperties(),
420 									m_pImpl->m_aResults[ nIndex ]->rData,
421 									m_pImpl->m_xContent->getProvider(),
422 									queryContentIdentifierString( nIndex ) );
423 		m_pImpl->m_aResults[ nIndex ]->xRow = xRow;
424 		return xRow;
425 	}
426 
427 	return Reference< XRow >();
428 }
429 
430 //=========================================================================
431 // virtual
releasePropertyValues(sal_uInt32 nIndex)432 void DataSupplier::releasePropertyValues( sal_uInt32 nIndex )
433 {
434 	osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
435 
436 	if ( nIndex < m_pImpl->m_aResults.size() )
437 		m_pImpl->m_aResults[ nIndex ]->xRow = Reference< XRow >();
438 }
439 
440 //=========================================================================
441 // virtual
close()442 void DataSupplier::close()
443 {
444 }
445 
446 //=========================================================================
447 // virtual
validate()448 void DataSupplier::validate()
449 	throw( ResultSetException )
450 {
451 }
452