xref: /trunk/main/xmlhelp/source/cxxhelp/provider/resultsetforquery.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
1*89dcb3daSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*89dcb3daSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*89dcb3daSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*89dcb3daSAndrew Rist  * distributed with this work for additional information
6*89dcb3daSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*89dcb3daSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*89dcb3daSAndrew Rist  * "License"); you may not use this file except in compliance
9*89dcb3daSAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*89dcb3daSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*89dcb3daSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*89dcb3daSAndrew Rist  * software distributed under the License is distributed on an
15*89dcb3daSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*89dcb3daSAndrew Rist  * KIND, either express or implied.  See the License for the
17*89dcb3daSAndrew Rist  * specific language governing permissions and limitations
18*89dcb3daSAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*89dcb3daSAndrew Rist  *************************************************************/
21*89dcb3daSAndrew Rist 
22*89dcb3daSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_xmlhelp.hxx"
26cdf0e10cSrcweir #include <com/sun/star/ucb/Command.hpp>
27cdf0e10cSrcweir #include <com/sun/star/ucb/XCommandEnvironment.hpp>
28cdf0e10cSrcweir #include <com/sun/star/i18n/XExtendedTransliteration.hpp>
29cdf0e10cSrcweir #include <com/sun/star/ucb/XCommandProcessor.hpp>
30cdf0e10cSrcweir #include <com/sun/star/lang/Locale.hpp>
31cdf0e10cSrcweir #include <com/sun/star/script/XInvocation.hpp>
32cdf0e10cSrcweir 
33cdf0e10cSrcweir #ifndef INCLUDED_STL_ALGORITHM
34cdf0e10cSrcweir #include <algorithm>
35cdf0e10cSrcweir #define INCLUDED_STL_ALGORITHM
36cdf0e10cSrcweir #endif
37cdf0e10cSrcweir #ifndef INCLUDED_STL_SET
38cdf0e10cSrcweir #include <set>
39cdf0e10cSrcweir #define INCLUDED_STL_SET
40cdf0e10cSrcweir #endif
41cdf0e10cSrcweir 
42cdf0e10cSrcweir #include <qe/Query.hxx>
43cdf0e10cSrcweir #include <qe/DocGenerator.hxx>
44cdf0e10cSrcweir #include "resultsetforquery.hxx"
45cdf0e10cSrcweir #include "databases.hxx"
46cdf0e10cSrcweir 
47cdf0e10cSrcweir // For testing
48cdf0e10cSrcweir // #define LOGGING
49cdf0e10cSrcweir 
50cdf0e10cSrcweir using namespace std;
51cdf0e10cSrcweir using namespace chelp;
52cdf0e10cSrcweir using namespace xmlsearch::excep;
53cdf0e10cSrcweir using namespace xmlsearch::qe;
54cdf0e10cSrcweir using namespace com::sun::star;
55cdf0e10cSrcweir using namespace com::sun::star::ucb;
56cdf0e10cSrcweir using namespace com::sun::star::i18n;
57cdf0e10cSrcweir using namespace com::sun::star::uno;
58cdf0e10cSrcweir using namespace com::sun::star::lang;
59cdf0e10cSrcweir 
60cdf0e10cSrcweir struct HitItem
61cdf0e10cSrcweir {
62cdf0e10cSrcweir     rtl::OUString   m_aURL;
63cdf0e10cSrcweir     float           m_fScore;
64cdf0e10cSrcweir 
HitItemHitItem65cdf0e10cSrcweir     HitItem( void ) {}
HitItemHitItem66cdf0e10cSrcweir     HitItem( const rtl::OUString& aURL, float fScore )
67cdf0e10cSrcweir         : m_aURL( aURL )
68cdf0e10cSrcweir         , m_fScore( fScore )
69cdf0e10cSrcweir     {}
operator <HitItem70cdf0e10cSrcweir     bool operator < ( const HitItem& rHitItem ) const
71cdf0e10cSrcweir     {
72cdf0e10cSrcweir         return rHitItem.m_fScore < m_fScore;
73cdf0e10cSrcweir     }
74cdf0e10cSrcweir };
75cdf0e10cSrcweir 
ResultSetForQuery(const uno::Reference<lang::XMultiServiceFactory> & xMSF,const uno::Reference<XContentProvider> & xProvider,sal_Int32 nOpenMode,const uno::Sequence<beans::Property> & seq,const uno::Sequence<NumberedSortingInfo> & seqSort,URLParameter & aURLParameter,Databases * pDatabases)76cdf0e10cSrcweir ResultSetForQuery::ResultSetForQuery( const uno::Reference< lang::XMultiServiceFactory >&  xMSF,
77cdf0e10cSrcweir                                       const uno::Reference< XContentProvider >&  xProvider,
78cdf0e10cSrcweir                                       sal_Int32 nOpenMode,
79cdf0e10cSrcweir                                       const uno::Sequence< beans::Property >& seq,
80cdf0e10cSrcweir                                       const uno::Sequence< NumberedSortingInfo >& seqSort,
81cdf0e10cSrcweir                                       URLParameter& aURLParameter,
82cdf0e10cSrcweir                                       Databases* pDatabases )
83cdf0e10cSrcweir     : ResultSetBase( xMSF,xProvider,nOpenMode,seq,seqSort ),
84cdf0e10cSrcweir       m_pDatabases( pDatabases ),
85cdf0e10cSrcweir       m_aURLParameter( aURLParameter )
86cdf0e10cSrcweir {
87cdf0e10cSrcweir     Reference< XTransliteration > xTrans(
88cdf0e10cSrcweir         xMSF->createInstance( rtl::OUString::createFromAscii( "com.sun.star.i18n.Transliteration" ) ),
89cdf0e10cSrcweir         UNO_QUERY );
90cdf0e10cSrcweir     Locale aLocale( aURLParameter.get_language(),
91cdf0e10cSrcweir                     rtl::OUString(),
92cdf0e10cSrcweir                     rtl::OUString() );
93cdf0e10cSrcweir     if(xTrans.is())
94cdf0e10cSrcweir         xTrans->loadModule(TransliterationModules_UPPERCASE_LOWERCASE,
95cdf0e10cSrcweir                            aLocale );
96cdf0e10cSrcweir 
97cdf0e10cSrcweir     // Access Lucene via XInvocation
98cdf0e10cSrcweir     Reference< script::XInvocation > xInvocation(
99cdf0e10cSrcweir         xMSF->createInstance( rtl::OUString::createFromAscii( "com.sun.star.help.HelpSearch" ) ),
100cdf0e10cSrcweir         UNO_QUERY );
101cdf0e10cSrcweir 
102cdf0e10cSrcweir     vector< vector< rtl::OUString > > queryList;
103cdf0e10cSrcweir     {
104cdf0e10cSrcweir         sal_Int32 idx;
105cdf0e10cSrcweir         rtl::OUString query = m_aURLParameter.get_query();
106cdf0e10cSrcweir         while( query.getLength() )
107cdf0e10cSrcweir         {
108cdf0e10cSrcweir             idx = query.indexOf( sal_Unicode( ' ' ) );
109cdf0e10cSrcweir             if( idx == -1 )
110cdf0e10cSrcweir                 idx = query.getLength();
111cdf0e10cSrcweir 
112cdf0e10cSrcweir             vector< rtl::OUString > currentQuery;
113cdf0e10cSrcweir             rtl::OUString tmp(query.copy( 0,idx ));
114cdf0e10cSrcweir             rtl:: OUString toliterate = tmp;
115cdf0e10cSrcweir             if(xTrans.is()) {
116cdf0e10cSrcweir                 Sequence<sal_Int32> aSeq;
117cdf0e10cSrcweir                 toliterate = xTrans->transliterate(
118cdf0e10cSrcweir                     tmp,0,tmp.getLength(),aSeq);
119cdf0e10cSrcweir             }
120cdf0e10cSrcweir 
121cdf0e10cSrcweir             currentQuery.push_back( toliterate );
122cdf0e10cSrcweir             queryList.push_back( currentQuery );
123cdf0e10cSrcweir 
124cdf0e10cSrcweir             int nCpy = 1 + idx;
125cdf0e10cSrcweir             if( nCpy >= query.getLength() )
126cdf0e10cSrcweir                 query = rtl::OUString();
127cdf0e10cSrcweir             else
128cdf0e10cSrcweir                 query = query.copy( 1 + idx );
129cdf0e10cSrcweir         }
130cdf0e10cSrcweir     }
131cdf0e10cSrcweir 
132cdf0e10cSrcweir     vector< rtl::OUString > aCompleteResultVector;
133cdf0e10cSrcweir     if( xInvocation.is() )
134cdf0e10cSrcweir     {
135cdf0e10cSrcweir         rtl::OUString scope = m_aURLParameter.get_scope();
136cdf0e10cSrcweir         bool bCaptionsOnly = ( scope.compareToAscii( "Heading" ) == 0 );
137cdf0e10cSrcweir         sal_Int32 hitCount = m_aURLParameter.get_hitCount();
138cdf0e10cSrcweir 
139cdf0e10cSrcweir #ifdef LOGGING
140cdf0e10cSrcweir         FILE* pFile = fopen( "d:\\resultset_out.txt", "w" );
141cdf0e10cSrcweir #endif
142cdf0e10cSrcweir 
143cdf0e10cSrcweir         IndexFolderIterator aIndexFolderIt( *pDatabases, m_aURLParameter.get_module(), m_aURLParameter.get_language() );
144cdf0e10cSrcweir         rtl::OUString idxDir;
145cdf0e10cSrcweir         bool bExtension = false;
146cdf0e10cSrcweir         int iDir = 0;
147cdf0e10cSrcweir         vector< vector<HitItem>* > aIndexFolderResultVectorVector;
148cdf0e10cSrcweir 
149cdf0e10cSrcweir         bool bTemporary;
150cdf0e10cSrcweir         while( (idxDir = aIndexFolderIt.nextIndexFolder( bExtension, bTemporary )).getLength() > 0 )
151cdf0e10cSrcweir         {
152cdf0e10cSrcweir             vector<HitItem> aIndexFolderResultVector;
153cdf0e10cSrcweir 
154cdf0e10cSrcweir             try
155cdf0e10cSrcweir             {
156cdf0e10cSrcweir                 vector< vector<HitItem>* > aQueryListResultVectorVector;
157cdf0e10cSrcweir                 set< rtl::OUString > aSet,aCurrent,aResultSet;
158cdf0e10cSrcweir 
159cdf0e10cSrcweir                 int nQueryListSize = queryList.size();
160cdf0e10cSrcweir                 if( nQueryListSize > 1 )
161cdf0e10cSrcweir                     hitCount = 2000;
162cdf0e10cSrcweir 
163cdf0e10cSrcweir                 for( int i = 0; i < nQueryListSize; ++i )
164cdf0e10cSrcweir                 {
165cdf0e10cSrcweir                     vector<HitItem>* pQueryResultVector;
166cdf0e10cSrcweir                     if( nQueryListSize > 1 )
167cdf0e10cSrcweir                     {
168cdf0e10cSrcweir                         pQueryResultVector = new vector<HitItem>();
169cdf0e10cSrcweir                         aQueryListResultVectorVector.push_back( pQueryResultVector );
170cdf0e10cSrcweir                     }
171cdf0e10cSrcweir                     else
172cdf0e10cSrcweir                     {
173cdf0e10cSrcweir                         pQueryResultVector = &aIndexFolderResultVector;
174cdf0e10cSrcweir                     }
175cdf0e10cSrcweir                     pQueryResultVector->reserve( hitCount );
176cdf0e10cSrcweir 
177cdf0e10cSrcweir                     int nParamCount = bCaptionsOnly ? 7 : 6;
178cdf0e10cSrcweir                     Sequence<uno::Any> aParamsSeq( nParamCount );
179cdf0e10cSrcweir 
180cdf0e10cSrcweir                     aParamsSeq[0] = uno::makeAny( rtl::OUString::createFromAscii( "-lang" ) );
181cdf0e10cSrcweir                     aParamsSeq[1] = uno::makeAny( m_aURLParameter.get_language() );
182cdf0e10cSrcweir 
183cdf0e10cSrcweir                     aParamsSeq[2] = uno::makeAny( rtl::OUString::createFromAscii( "-index" ) );
184cdf0e10cSrcweir                     rtl::OUString aSystemPath;
185cdf0e10cSrcweir                     osl::FileBase::getSystemPathFromFileURL( idxDir, aSystemPath );
186cdf0e10cSrcweir                     aParamsSeq[3] = uno::makeAny( aSystemPath );
187cdf0e10cSrcweir 
188cdf0e10cSrcweir                     aParamsSeq[4] = uno::makeAny( rtl::OUString::createFromAscii( "-query" ) );
189cdf0e10cSrcweir 
190cdf0e10cSrcweir                     const std::vector< rtl::OUString >& aListItem = queryList[i];
191cdf0e10cSrcweir                     ::rtl::OUString aNewQueryStr = aListItem[0];
192cdf0e10cSrcweir                     aParamsSeq[5] = uno::makeAny( aNewQueryStr );
193cdf0e10cSrcweir 
194cdf0e10cSrcweir                     if( bCaptionsOnly )
195cdf0e10cSrcweir                         aParamsSeq[6] = uno::makeAny( rtl::OUString::createFromAscii( "-caption" ) );
196cdf0e10cSrcweir 
197cdf0e10cSrcweir                     Sequence< sal_Int16 > aOutParamIndex;
198cdf0e10cSrcweir                     Sequence< uno::Any > aOutParam;
199cdf0e10cSrcweir 
200cdf0e10cSrcweir                     uno::Any aRet = xInvocation->invoke( rtl::OUString::createFromAscii( "search" ),
201cdf0e10cSrcweir                         aParamsSeq, aOutParamIndex, aOutParam );
202cdf0e10cSrcweir 
203cdf0e10cSrcweir                     Sequence< float > aScoreSeq;
204cdf0e10cSrcweir                     int nScoreCount = 0;
205cdf0e10cSrcweir                     int nOutParamCount = aOutParam.getLength();
206cdf0e10cSrcweir                     if( nOutParamCount == 1 )
207cdf0e10cSrcweir                     {
208cdf0e10cSrcweir                         const uno::Any* pScoreAnySeq = aOutParam.getConstArray();
209cdf0e10cSrcweir                         if( pScoreAnySeq[0] >>= aScoreSeq )
210cdf0e10cSrcweir                             nScoreCount = aScoreSeq.getLength();
211cdf0e10cSrcweir                     }
212cdf0e10cSrcweir 
213cdf0e10cSrcweir                     Sequence<rtl::OUString> aRetSeq;
214cdf0e10cSrcweir                     if( aRet >>= aRetSeq )
215cdf0e10cSrcweir                     {
216cdf0e10cSrcweir                         if( nQueryListSize > 1 )
217cdf0e10cSrcweir                             aSet.clear();
218cdf0e10cSrcweir 
219cdf0e10cSrcweir                         const rtl::OUString* pRetSeq = aRetSeq.getConstArray();
220cdf0e10cSrcweir                         int nCount = aRetSeq.getLength();
221cdf0e10cSrcweir                         if( nCount > hitCount )
222cdf0e10cSrcweir                             nCount = hitCount;
223cdf0e10cSrcweir                         for( int j = 0 ; j < nCount ; ++j )
224cdf0e10cSrcweir                         {
225cdf0e10cSrcweir                             float fScore = 0.0;
226cdf0e10cSrcweir                             if( j < nScoreCount )
227cdf0e10cSrcweir                                 fScore = aScoreSeq[j];
228cdf0e10cSrcweir 
229cdf0e10cSrcweir                             rtl::OUString aURL = pRetSeq[j];
230cdf0e10cSrcweir                             pQueryResultVector->push_back( HitItem( aURL, fScore ) );
231cdf0e10cSrcweir                             if( nQueryListSize > 1 )
232cdf0e10cSrcweir                                 aSet.insert( aURL );
233cdf0e10cSrcweir 
234cdf0e10cSrcweir #ifdef LOGGING
235cdf0e10cSrcweir                             if( pFile )
236cdf0e10cSrcweir                             {
237cdf0e10cSrcweir                                 rtl::OString tmp(rtl::OUStringToOString( aURL, RTL_TEXTENCODING_UTF8));
238cdf0e10cSrcweir                                 fprintf( pFile, "Dir %d, Query %d, Item: score=%f, URL=%s\n", iDir, i, fScore, tmp.getStr() );
239cdf0e10cSrcweir                             }
240cdf0e10cSrcweir #endif
241cdf0e10cSrcweir                         }
242cdf0e10cSrcweir                     }
243cdf0e10cSrcweir 
244cdf0e10cSrcweir                     // intersect
245cdf0e10cSrcweir                     if( nQueryListSize > 1 )
246cdf0e10cSrcweir                     {
247cdf0e10cSrcweir                         if( i == 0 )
248cdf0e10cSrcweir                         {
249cdf0e10cSrcweir                             aResultSet = aSet;
250cdf0e10cSrcweir                         }
251cdf0e10cSrcweir                         else
252cdf0e10cSrcweir                         {
253cdf0e10cSrcweir                             aCurrent = aResultSet;
254cdf0e10cSrcweir                             aResultSet.clear();
255cdf0e10cSrcweir                             set_intersection( aSet.begin(),aSet.end(),
256cdf0e10cSrcweir                                               aCurrent.begin(),aCurrent.end(),
257cdf0e10cSrcweir                                               inserter(aResultSet,aResultSet.begin()));
258cdf0e10cSrcweir                         }
259cdf0e10cSrcweir                     }
260cdf0e10cSrcweir                 }
261cdf0e10cSrcweir 
262cdf0e10cSrcweir                 // Combine results in aIndexFolderResultVector
263cdf0e10cSrcweir                 if( nQueryListSize > 1 )
264cdf0e10cSrcweir                 {
265cdf0e10cSrcweir                     for( int n = 0 ; n < nQueryListSize ; ++n )
266cdf0e10cSrcweir                     {
267cdf0e10cSrcweir                         vector<HitItem>* pQueryResultVector = aQueryListResultVectorVector[n];
268cdf0e10cSrcweir                         vector<HitItem>& rQueryResultVector = *pQueryResultVector;
269cdf0e10cSrcweir 
270cdf0e10cSrcweir                         int nItemCount = rQueryResultVector.size();
271cdf0e10cSrcweir                         for( int i = 0 ; i < nItemCount ; ++i )
272cdf0e10cSrcweir                         {
273cdf0e10cSrcweir                             const HitItem& rItem = rQueryResultVector[ i ];
274cdf0e10cSrcweir                             set< rtl::OUString >::iterator it;
275cdf0e10cSrcweir                             if( (it = aResultSet.find( rItem.m_aURL )) != aResultSet.end() )
276cdf0e10cSrcweir                             {
277cdf0e10cSrcweir                                 HitItem aItemCopy( rItem );
278cdf0e10cSrcweir                                 aItemCopy.m_fScore /= nQueryListSize;   // To get average score
279cdf0e10cSrcweir                                 if( n == 0 )
280cdf0e10cSrcweir                                 {
281cdf0e10cSrcweir                                     // Use first pass to create entry
282cdf0e10cSrcweir                                     aIndexFolderResultVector.push_back( aItemCopy );
283cdf0e10cSrcweir 
284cdf0e10cSrcweir #ifdef LOGGING
285cdf0e10cSrcweir                                     if( pFile )
286cdf0e10cSrcweir                                     {
287cdf0e10cSrcweir                                         rtl::OString tmp(rtl::OUStringToOString( aItemCopy.m_aURL, RTL_TEXTENCODING_UTF8));
288cdf0e10cSrcweir                                         fprintf( pFile, "Combine: Query %d (first pass), Item %d: score=%f (%f), URL=%s\n", n, i, aItemCopy.m_fScore, rItem.m_fScore, tmp.getStr() );
289cdf0e10cSrcweir                                     }
290cdf0e10cSrcweir #endif
291cdf0e10cSrcweir                                 }
292cdf0e10cSrcweir                                 else
293cdf0e10cSrcweir                                 {
294cdf0e10cSrcweir                                     // Find entry in vector
295cdf0e10cSrcweir                                     int nCount = aIndexFolderResultVector.size();
296cdf0e10cSrcweir                                     for( int j = 0 ; j < nCount ; ++j )
297cdf0e10cSrcweir                                     {
298cdf0e10cSrcweir                                         HitItem& rFindItem = aIndexFolderResultVector[ j ];
299cdf0e10cSrcweir                                         if( rFindItem.m_aURL.equals( aItemCopy.m_aURL ) )
300cdf0e10cSrcweir                                         {
301cdf0e10cSrcweir #ifdef LOGGING
302cdf0e10cSrcweir                                             if( pFile )
303cdf0e10cSrcweir                                             {
304cdf0e10cSrcweir                                                 rtl::OString tmp(rtl::OUStringToOString( aItemCopy.m_aURL, RTL_TEXTENCODING_UTF8));
305cdf0e10cSrcweir                                                 fprintf( pFile, "Combine: Query %d, Item %d: score=%f + %f = %f, URL=%s\n", n, i,
306cdf0e10cSrcweir                                                     rFindItem.m_fScore, aItemCopy.m_fScore, rFindItem.m_fScore + aItemCopy.m_fScore, tmp.getStr() );
307cdf0e10cSrcweir                                             }
308cdf0e10cSrcweir #endif
309cdf0e10cSrcweir 
310cdf0e10cSrcweir                                             rFindItem.m_fScore += aItemCopy.m_fScore;
311cdf0e10cSrcweir                                             break;
312cdf0e10cSrcweir                                         }
313cdf0e10cSrcweir                                     }
314cdf0e10cSrcweir                                 }
315cdf0e10cSrcweir                             }
316cdf0e10cSrcweir                         }
317cdf0e10cSrcweir 
318cdf0e10cSrcweir                         delete pQueryResultVector;
319cdf0e10cSrcweir                     }
320cdf0e10cSrcweir 
321cdf0e10cSrcweir                     sort( aIndexFolderResultVector.begin(), aIndexFolderResultVector.end() );
322cdf0e10cSrcweir                 }
323cdf0e10cSrcweir 
324cdf0e10cSrcweir                 vector<HitItem>* pIndexFolderHitItemVector = new vector<HitItem>( aIndexFolderResultVector );
325cdf0e10cSrcweir                 aIndexFolderResultVectorVector.push_back( pIndexFolderHitItemVector );
326cdf0e10cSrcweir                 aIndexFolderResultVector.clear();
327cdf0e10cSrcweir             }
328cdf0e10cSrcweir             catch( const Exception& )
329cdf0e10cSrcweir             {
330cdf0e10cSrcweir             }
331cdf0e10cSrcweir 
332cdf0e10cSrcweir             ++iDir;
333cdf0e10cSrcweir 
334cdf0e10cSrcweir             if( bTemporary )
335cdf0e10cSrcweir                 aIndexFolderIt.deleteTempIndexFolder( idxDir );
336cdf0e10cSrcweir 
337cdf0e10cSrcweir         }   // Iterator
338cdf0e10cSrcweir 
339cdf0e10cSrcweir 
340cdf0e10cSrcweir         int nVectorCount = aIndexFolderResultVectorVector.size();
341cdf0e10cSrcweir         vector<HitItem>::size_type* pCurrentVectorIndex = new vector<HitItem>::size_type[nVectorCount];
342cdf0e10cSrcweir         for( int j = 0 ; j < nVectorCount ; ++j )
343cdf0e10cSrcweir             pCurrentVectorIndex[j] = 0;
344cdf0e10cSrcweir 
345cdf0e10cSrcweir #ifdef LOGGING
346cdf0e10cSrcweir         if( pFile )
347cdf0e10cSrcweir         {
348cdf0e10cSrcweir             for( int k = 0 ; k < nVectorCount ; ++k )
349cdf0e10cSrcweir             {
350cdf0e10cSrcweir                 vector<HitItem>& rIndexFolderVector = *aIndexFolderResultVectorVector[k];
351cdf0e10cSrcweir                 int nItemCount = rIndexFolderVector.size();
352cdf0e10cSrcweir 
353cdf0e10cSrcweir                 fprintf( pFile, "Vector %d, %d elements\n", k, nItemCount );
354cdf0e10cSrcweir 
355cdf0e10cSrcweir                 for( int i = 0 ; i < nItemCount ; ++i )
356cdf0e10cSrcweir                 {
357cdf0e10cSrcweir                     const HitItem& rItem = rIndexFolderVector[ i ];
358cdf0e10cSrcweir                     rtl::OString tmp(rtl::OUStringToOString(rItem.m_aURL, RTL_TEXTENCODING_UTF8));
359cdf0e10cSrcweir                     fprintf( pFile, "    Item_vector%d, %d/%d: score=%f, URL=%s\n", k, i, nItemCount, rItem.m_fScore, tmp.getStr() );
360cdf0e10cSrcweir                 }
361cdf0e10cSrcweir             }
362cdf0e10cSrcweir         }
363cdf0e10cSrcweir #endif
364cdf0e10cSrcweir 
365cdf0e10cSrcweir         sal_Int32 nTotalHitCount = m_aURLParameter.get_hitCount();
366cdf0e10cSrcweir         sal_Int32 nHitCount = 0;
367cdf0e10cSrcweir         while( nHitCount < nTotalHitCount )
368cdf0e10cSrcweir         {
369cdf0e10cSrcweir             int iVectorWithBestScore = -1;
370cdf0e10cSrcweir             float fBestScore = 0.0;
371cdf0e10cSrcweir             for( int k = 0 ; k < nVectorCount ; ++k )
372cdf0e10cSrcweir             {
373cdf0e10cSrcweir                 vector<HitItem>& rIndexFolderVector = *aIndexFolderResultVectorVector[k];
374cdf0e10cSrcweir                 if( pCurrentVectorIndex[k] < rIndexFolderVector.size() )
375cdf0e10cSrcweir                 {
376cdf0e10cSrcweir                     const HitItem& rItem = rIndexFolderVector[ pCurrentVectorIndex[k] ];
377cdf0e10cSrcweir 
378cdf0e10cSrcweir                     if( fBestScore < rItem.m_fScore )
379cdf0e10cSrcweir                     {
380cdf0e10cSrcweir                         fBestScore = rItem.m_fScore;
381cdf0e10cSrcweir                         iVectorWithBestScore = k;
382cdf0e10cSrcweir                     }
383cdf0e10cSrcweir                 }
384cdf0e10cSrcweir             }
385cdf0e10cSrcweir 
386cdf0e10cSrcweir             if( iVectorWithBestScore == -1 )    // No item left at all
387cdf0e10cSrcweir                 break;
388cdf0e10cSrcweir 
389cdf0e10cSrcweir             vector<HitItem>& rIndexFolderVector = *aIndexFolderResultVectorVector[iVectorWithBestScore];
390cdf0e10cSrcweir             const HitItem& rItem = rIndexFolderVector[ pCurrentVectorIndex[iVectorWithBestScore] ];
391cdf0e10cSrcweir 
392cdf0e10cSrcweir             pCurrentVectorIndex[iVectorWithBestScore]++;
393cdf0e10cSrcweir 
394cdf0e10cSrcweir             aCompleteResultVector.push_back( rItem.m_aURL );
395cdf0e10cSrcweir             ++nHitCount;
396cdf0e10cSrcweir         }
397cdf0e10cSrcweir 
398cdf0e10cSrcweir         delete[] pCurrentVectorIndex;
399cdf0e10cSrcweir         for( int n = 0 ; n < nVectorCount ; ++n )
400cdf0e10cSrcweir         {
401cdf0e10cSrcweir             vector<HitItem>* pIndexFolderVector = aIndexFolderResultVectorVector[n];
402cdf0e10cSrcweir             delete pIndexFolderVector;
403cdf0e10cSrcweir         }
404cdf0e10cSrcweir 
405cdf0e10cSrcweir #ifdef LOGGING
406cdf0e10cSrcweir         fclose( pFile );
407cdf0e10cSrcweir #endif
408cdf0e10cSrcweir     }
409cdf0e10cSrcweir 
410cdf0e10cSrcweir     sal_Int32 replIdx = rtl::OUString::createFromAscii( "#HLP#" ).getLength();
411cdf0e10cSrcweir     rtl::OUString replWith = rtl::OUString::createFromAscii( "vnd.sun.star.help://" );
412cdf0e10cSrcweir 
413cdf0e10cSrcweir     int nResultCount = aCompleteResultVector.size();
414cdf0e10cSrcweir     for( int r = 0 ; r < nResultCount ; ++r )
415cdf0e10cSrcweir     {
416cdf0e10cSrcweir         rtl::OUString aURL = aCompleteResultVector[r];
417cdf0e10cSrcweir         rtl::OUString aResultStr = replWith + aURL.copy(replIdx);
418cdf0e10cSrcweir         m_aPath.push_back( aResultStr );
419cdf0e10cSrcweir     }
420cdf0e10cSrcweir 
421cdf0e10cSrcweir     m_aItems.resize( m_aPath.size() );
422cdf0e10cSrcweir     m_aIdents.resize( m_aPath.size() );
423cdf0e10cSrcweir 
424cdf0e10cSrcweir     Command aCommand;
425cdf0e10cSrcweir     aCommand.Name = rtl::OUString::createFromAscii( "getPropertyValues" );
426cdf0e10cSrcweir     aCommand.Argument <<= m_sProperty;
427cdf0e10cSrcweir 
428cdf0e10cSrcweir     for( m_nRow = 0; sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aPath.size(); ++m_nRow )
429cdf0e10cSrcweir     {
430cdf0e10cSrcweir         m_aPath[m_nRow] =
431cdf0e10cSrcweir             m_aPath[m_nRow]                                          +
432cdf0e10cSrcweir             rtl::OUString::createFromAscii( "?Language=" )           +
433cdf0e10cSrcweir             m_aURLParameter.get_language()                           +
434cdf0e10cSrcweir             rtl::OUString::createFromAscii( "&System=" )             +
435cdf0e10cSrcweir             m_aURLParameter.get_system();
436cdf0e10cSrcweir 
437cdf0e10cSrcweir         uno::Reference< XContent > content = queryContent();
438cdf0e10cSrcweir         if( content.is() )
439cdf0e10cSrcweir         {
440cdf0e10cSrcweir             uno::Reference< XCommandProcessor > cmd( content,uno::UNO_QUERY );
441cdf0e10cSrcweir             cmd->execute( aCommand,0,uno::Reference< XCommandEnvironment >( 0 ) ) >>= m_aItems[m_nRow]; //TODO: check return value of operator >>=
442cdf0e10cSrcweir         }
443cdf0e10cSrcweir     }
444cdf0e10cSrcweir     m_nRow = 0xffffffff;
445cdf0e10cSrcweir }
446