Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "db.hxx"
30 : : #include <osl/diagnose.h>
31 : : #include <osl/thread.h>
32 : : #include <osl/process.h>
33 : : #include <rtl/uri.hxx>
34 : : #include <osl/file.hxx>
35 : : #include <com/sun/star/lang/Locale.hpp>
36 : : #include <rtl/ustrbuf.hxx>
37 : : #include "inputstream.hxx"
38 : : #include <algorithm>
39 : : #include <string.h>
40 : :
41 : : #include <l10ntools/HelpIndexer.hxx>
42 : :
43 : : // Extensible help
44 : : #include "com/sun/star/deployment/ExtensionManager.hpp"
45 : : #include "com/sun/star/deployment/thePackageManagerFactory.hpp"
46 : : #include <comphelper/processfactory.hxx>
47 : : #include <com/sun/star/beans/XPropertySet.hpp>
48 : : #include <com/sun/star/uno/XComponentContext.hpp>
49 : : #include <com/sun/star/ucb/XCommandEnvironment.hpp>
50 : : #include <com/sun/star/beans/Optional.hpp>
51 : : #include <com/sun/star/beans/PropertyValue.hpp>
52 : : #include <com/sun/star/beans/NamedValue.hpp>
53 : : #include <com/sun/star/frame/XConfigManager.hpp>
54 : : #include <com/sun/star/ucb/SimpleFileAccess.hpp>
55 : : #include <com/sun/star/util/XMacroExpander.hpp>
56 : : #include <com/sun/star/uri/XUriReferenceFactory.hpp>
57 : : #include <com/sun/star/uri/XVndSunStarExpandUrl.hpp>
58 : : #include <com/sun/star/script/XInvocation.hpp>
59 : : #include <comphelper/locale.hxx>
60 : :
61 : : #include <com/sun/star/awt/XToolkit.hpp>
62 : : #include <com/sun/star/awt/XExtendedToolkit.hpp>
63 : : #include <com/sun/star/awt/XWindowPeer.hpp>
64 : : #include <com/sun/star/awt/XVclWindowPeer.hpp>
65 : : #include <com/sun/star/awt/XTopWindow.hpp>
66 : :
67 : : #include <comphelper/storagehelper.hxx>
68 : : #include <comphelper/string.hxx>
69 : :
70 : : #include "databases.hxx"
71 : : #include "urlparameter.hxx"
72 : :
73 : : using namespace chelp;
74 : : using namespace berkeleydbproxy;
75 : : using namespace com::sun::star;
76 : : using namespace com::sun::star::uno;
77 : : using namespace com::sun::star::io;
78 : : using namespace com::sun::star::container;
79 : : using namespace com::sun::star::i18n;
80 : : using namespace com::sun::star::lang;
81 : : using namespace com::sun::star::deployment;
82 : : using namespace com::sun::star::beans;
83 : :
84 : :
85 : 4 : rtl::OUString Databases::expandURL( const rtl::OUString& aURL )
86 : : {
87 [ + - ]: 4 : osl::MutexGuard aGuard( m_aMutex );
88 [ + - ]: 4 : rtl::OUString aRetURL = expandURL( aURL, m_xContext );
89 [ + - ]: 4 : return aRetURL;
90 : : }
91 : :
92 : 4 : rtl::OUString Databases::expandURL( const rtl::OUString& aURL, Reference< uno::XComponentContext > xContext )
93 : : {
94 [ + + ][ + - ]: 4 : static Reference< util::XMacroExpander > xMacroExpander;
95 [ + + ][ + - ]: 4 : static Reference< uri::XUriReferenceFactory > xFac;
96 : :
97 [ - + ]: 4 : if( !xContext.is() )
98 : 0 : return rtl::OUString();
99 : :
100 [ + + ][ - + ]: 4 : if( !xMacroExpander.is() || !xFac.is() )
[ + + ]
101 : : {
102 [ + - ][ + - ]: 2 : Reference< XMultiComponentFactory > xSMgr( xContext->getServiceManager(), UNO_QUERY );
[ + - ]
103 : :
104 : : xFac = Reference< uri::XUriReferenceFactory >(
105 [ + - ]: 2 : xSMgr->createInstanceWithContext( rtl::OUString(
106 [ + - ][ + - ]: 2 : "com.sun.star.uri.UriReferenceFactory"), xContext ) , UNO_QUERY );
[ + - ]
107 [ - + ]: 2 : if( !xFac.is() )
108 : : {
109 : : throw RuntimeException(
110 : : ::rtl::OUString( "Databases::expand(), could not instatiate UriReferenceFactory." ),
111 [ # # ]: 0 : Reference< XInterface >() );
112 : : }
113 : :
114 : : xMacroExpander = Reference< util::XMacroExpander >(
115 [ + - ]: 2 : xContext->getValueByName(
116 : 2 : ::rtl::OUString( "/singletons/com.sun.star.util.theMacroExpander" ) ),
117 [ + - ][ + - ]: 2 : UNO_QUERY_THROW );
[ + - ]
118 : : }
119 : :
120 : 4 : rtl::OUString aRetURL = aURL;
121 [ + - ]: 4 : if( xMacroExpander.is() )
122 : : {
123 : 4 : Reference< uri::XUriReference > uriRef;
124 : 4 : for (;;)
125 : : {
126 [ + - ][ + - ]: 8 : uriRef = Reference< uri::XUriReference >( xFac->parse( aRetURL ), UNO_QUERY );
[ + - ][ + - ]
127 [ + - ]: 8 : if ( uriRef.is() )
128 : : {
129 [ + - ]: 8 : Reference < uri::XVndSunStarExpandUrl > sxUri( uriRef, UNO_QUERY );
130 [ + + ]: 8 : if( !sxUri.is() )
131 : : break;
132 : :
133 [ + - ][ + - ]: 8 : aRetURL = sxUri->expand( xMacroExpander );
[ + + ]
134 : : }
135 : 4 : }
136 : : }
137 : 4 : return aRetURL;
138 : : }
139 : :
140 : 21 : Databases::Databases( sal_Bool showBasic,
141 : : const rtl::OUString& instPath,
142 : : const com::sun::star::uno::Sequence< rtl::OUString >& imagesZipPaths,
143 : : const rtl::OUString& productName,
144 : : const rtl::OUString& productVersion,
145 : : const rtl::OUString& styleSheet,
146 : : Reference< uno::XComponentContext > xContext )
147 : : : m_xContext( xContext ),
148 : : m_bShowBasic(showBasic),
149 : : m_pErrorDoc( 0 ),
150 : : m_nCustomCSSDocLength( 0 ),
151 : : m_pCustomCSSDoc( 0 ),
152 : : m_aCSS(styleSheet.toAsciiLowerCase()),
153 : : newProdName(rtl::OUString( "$[officename]" ) ),
154 : : newProdVersion(rtl::OUString( "$[officeversion]" ) ),
155 : : prodName( rtl::OUString( "%PRODUCTNAME" ) ),
156 : : prodVersion( rtl::OUString( "%PRODUCTVERSION" ) ),
157 : : vendName( rtl::OUString( "%VENDORNAME" ) ),
158 : : vendVersion( rtl::OUString( "%VENDORVERSION" ) ),
159 : : vendShort( rtl::OUString( "%VENDORSHORT" ) ),
160 : : m_aImagesZipPaths( imagesZipPaths ),
161 [ + + ][ + - ]: 168 : m_nSymbolsStyle( 0 )
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
162 : : {
163 [ + - ][ + - ]: 21 : m_xSMgr = Reference< XMultiComponentFactory >( m_xContext->getServiceManager(), UNO_QUERY );
[ + - ][ + - ]
164 : :
165 : 21 : m_vAdd[0] = 12;
166 : 21 : m_vAdd[1] = 15;
167 : 21 : m_vAdd[2] = 11;
168 : 21 : m_vAdd[3] = 14;
169 : 21 : m_vAdd[4] = 12;
170 : 21 : m_vAdd[5] = 13;
171 : 21 : m_vAdd[6] = 16;
172 : :
173 : 21 : m_vReplacement[0] = productName;
174 : 21 : m_vReplacement[1] = productVersion;
175 : : // m_vReplacement[2...4] (vendorName/-Version/-Short) are empty strings
176 : 21 : m_vReplacement[5] = productName;
177 : 21 : m_vReplacement[6] = productVersion;
178 : :
179 [ + - ]: 21 : setInstallPath( instPath );
180 : :
181 [ + - ][ + - ]: 21 : m_xSFA = ucb::SimpleFileAccess::create(m_xContext);
182 [ # # # # ]: 21 : }
183 : :
184 [ + - ][ + - ]: 189 : Databases::~Databases()
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
185 : : {
186 : : // release stylesheet
187 : :
188 [ - + ]: 21 : delete[] m_pCustomCSSDoc;
189 : :
190 : : // release errorDocument
191 : :
192 [ - + ]: 21 : delete[] m_pErrorDoc;
193 : :
194 : : // unload the databases
195 : :
196 : : {
197 : : // DatabasesTable
198 [ + - ]: 21 : DatabasesTable::iterator it = m_aDatabases.begin();
199 [ + - ][ + + ]: 33 : while( it != m_aDatabases.end() )
200 : : {
201 [ + - ][ + - ]: 12 : if( it->second )
202 [ + - ][ + - ]: 12 : it->second->close( 0 );
203 [ + - ][ + - ]: 12 : delete it->second;
[ + - ]
204 : 12 : ++it;
205 : : }
206 : : }
207 : :
208 : : {
209 : : // ModInfoTable
210 : :
211 [ + - ]: 21 : ModInfoTable::iterator it = m_aModInfo.begin();
212 [ + - ][ + + ]: 23 : while( it != m_aModInfo.end() )
213 : : {
214 [ + - ][ + - ]: 2 : delete it->second;
215 : 2 : ++it;
216 : : }
217 : : }
218 : :
219 : : {
220 : : // KeywordInfoTable
221 : :
222 [ + - ]: 21 : KeywordInfoTable::iterator it = m_aKeywordInfo.begin();
223 [ + - ][ - + ]: 21 : while( it != m_aKeywordInfo.end() )
224 : : {
225 [ # # ][ # # ]: 0 : delete it->second;
[ # # ]
226 : 0 : ++it;
227 : : }
228 : : }
229 [ + + # # : 189 : }
# # ][ + - ]
230 : :
231 : 0 : static bool impl_getZipFile(
232 : : Sequence< rtl::OUString > & rImagesZipPaths,
233 : : const rtl::OUString & rZipName,
234 : : rtl::OUString & rFileName )
235 : : {
236 : 0 : rtl::OUString aWorkingDir;
237 [ # # ]: 0 : osl_getProcessWorkingDir( &aWorkingDir.pData );
238 [ # # ]: 0 : const rtl::OUString *pPathArray = rImagesZipPaths.getArray();
239 [ # # ]: 0 : for ( int i = 0; i < rImagesZipPaths.getLength(); ++i )
240 : : {
241 : 0 : rtl::OUString aFileName = pPathArray[ i ];
242 [ # # ]: 0 : if ( !aFileName.isEmpty() )
243 : : {
244 [ # # ]: 0 : if ( 1 + aFileName.lastIndexOf( '/' ) != aFileName.getLength() )
245 : : {
246 : 0 : aFileName += rtl::OUString( "/" );
247 : : }
248 : 0 : aFileName += rZipName;
249 : : // the icons are not read when the URL is a symlink
250 [ # # ]: 0 : osl::File::getAbsoluteFileURL( aWorkingDir, aFileName, rFileName );
251 : :
252 : : // test existence
253 : 0 : osl::DirectoryItem aDirItem;
254 [ # # ][ # # ]: 0 : if ( osl::DirectoryItem::get( rFileName, aDirItem ) == osl::FileBase::E_None )
255 [ # # ][ # # ]: 0 : return true;
256 : : }
257 [ # # ]: 0 : }
258 : 0 : return false;
259 : : }
260 : :
261 : 0 : rtl::OString Databases::getImagesZipFileURL()
262 : : {
263 : : //sal_Int16 nSymbolsStyle = SvtMiscOptions().GetCurrentSymbolsStyle();
264 : 0 : sal_Int16 nSymbolsStyle = 0;
265 : : try
266 : : {
267 : : uno::Reference< lang::XMultiServiceFactory > xConfigProvider(
268 [ # # ][ # # ]: 0 : m_xSMgr ->createInstanceWithContext(::rtl::OUString("com.sun.star.configuration.ConfigurationProvider"), m_xContext), uno::UNO_QUERY_THROW);
[ # # ]
269 : :
270 : : // set root path
271 [ # # ]: 0 : uno::Sequence < uno::Any > lParams(1);
272 : 0 : beans::PropertyValue aParam ;
273 : 0 : aParam.Name = ::rtl::OUString("nodepath");
274 [ # # ]: 0 : aParam.Value <<= ::rtl::OUString("org.openoffice.Office.Common");
275 [ # # ][ # # ]: 0 : lParams[0] = uno::makeAny(aParam);
276 : :
277 : : // open it
278 [ # # ]: 0 : uno::Reference< uno::XInterface > xCFG( xConfigProvider->createInstanceWithArguments(
279 : : ::rtl::OUString("com.sun.star.configuration.ConfigurationAccess"),
280 [ # # ]: 0 : lParams) );
281 : :
282 : 0 : bool bChanged = false;
283 [ # # ]: 0 : uno::Reference< container::XHierarchicalNameAccess > xAccess(xCFG, uno::UNO_QUERY_THROW);
284 [ # # ][ # # ]: 0 : uno::Any aResult = xAccess->getByHierarchicalName(::rtl::OUString("Misc/SymbolSet"));
285 [ # # ][ # # ]: 0 : if ( (aResult >>= nSymbolsStyle) && m_nSymbolsStyle != nSymbolsStyle )
[ # # ]
286 : : {
287 : 0 : m_nSymbolsStyle = nSymbolsStyle;
288 : 0 : bChanged = true;
289 : : }
290 : :
291 [ # # ][ # # ]: 0 : if ( m_aImagesZipFileURL.isEmpty() || bChanged )
[ # # ]
292 : : {
293 : 0 : rtl::OUString aImageZip, aSymbolsStyleName;
294 [ # # ][ # # ]: 0 : aResult = xAccess->getByHierarchicalName(::rtl::OUString("Misc/SymbolStyle"));
295 : 0 : aResult >>= aSymbolsStyleName;
296 : :
297 : 0 : bool bFound = false;
298 [ # # ]: 0 : if ( !aSymbolsStyleName.isEmpty() )
299 : : {
300 : 0 : rtl::OUString aZipName = rtl::OUString( "images_" );
301 : 0 : aZipName += aSymbolsStyleName;
302 : 0 : aZipName += rtl::OUString( ".zip" );
303 : :
304 [ # # ]: 0 : bFound = impl_getZipFile( m_aImagesZipPaths, aZipName, aImageZip );
305 : : }
306 : :
307 [ # # ]: 0 : if ( ! bFound )
308 [ # # ]: 0 : bFound = impl_getZipFile( m_aImagesZipPaths, rtl::OUString( "images.zip" ), aImageZip );
309 : :
310 [ # # ]: 0 : if ( ! bFound )
311 : 0 : aImageZip = rtl::OUString();
312 : :
313 : : m_aImagesZipFileURL = rtl::OUStringToOString(
314 : : rtl::Uri::encode(
315 : : aImageZip,
316 : : rtl_UriCharClassPchar,
317 : : rtl_UriEncodeIgnoreEscapes,
318 [ # # ]: 0 : RTL_TEXTENCODING_UTF8 ), RTL_TEXTENCODING_UTF8 );
319 [ # # ][ # # ]: 0 : }
320 : : }
321 [ # # ]: 0 : catch ( NoSuchElementException const & )
322 : : {
323 : : }
324 : :
325 : 0 : return m_aImagesZipFileURL;
326 : : }
327 : :
328 : 106 : void Databases::replaceName( rtl::OUString& oustring ) const
329 : : {
330 : 106 : sal_Int32 idx = -1,idx1 = -1,idx2 = -1,k = 0,off;
331 : 106 : bool cap = false;
332 : 106 : rtl::OUStringBuffer aStrBuf( 0 );
333 : :
334 : 12 : while( true )
335 : : {
336 : 118 : ++idx;
337 : 118 : idx1 = oustring.indexOf( sal_Unicode('%'),idx);
338 : 118 : idx2 = oustring.indexOf( sal_Unicode('$'),idx);
339 : :
340 [ + + ][ + + ]: 118 : if(idx1 == -1 && idx2 == -1)
341 : 106 : break;
342 : :
343 [ + + ]: 12 : if(idx1 == -1)
344 : 2 : idx = idx2;
345 [ + - ]: 10 : else if(idx2 == -1)
346 : 10 : idx = idx1;
347 : : else {
348 : : // no index is zero
349 [ # # ]: 0 : if(idx1 < idx2)
350 : 0 : idx = idx1;
351 [ # # ]: 0 : else if(idx2 < idx1 )
352 : 0 : idx = idx2;
353 : : }
354 : :
355 [ + + ]: 12 : if( oustring.indexOf( prodName,idx ) == idx )
356 : 10 : off = PRODUCTNAME;
357 [ - + ]: 2 : else if( oustring.indexOf( prodVersion,idx ) == idx )
358 : 0 : off = PRODUCTVERSION;
359 [ - + ]: 2 : else if( oustring.indexOf( vendName,idx ) == idx )
360 : 0 : off = VENDORNAME;
361 [ - + ]: 2 : else if( oustring.indexOf( vendVersion,idx ) == idx )
362 : 0 : off = VENDORVERSION;
363 [ - + ]: 2 : else if( oustring.indexOf( vendShort,idx ) == idx )
364 : 0 : off = VENDORSHORT;
365 [ + - ]: 2 : else if( oustring.indexOf( newProdName,idx ) == idx )
366 : 2 : off = NEWPRODUCTNAME;
367 [ # # ]: 0 : else if( oustring.indexOf( newProdVersion,idx ) == idx )
368 : 0 : off = NEWPRODUCTVERSION;
369 : : else
370 : 0 : off = -1;
371 : :
372 [ + - ]: 12 : if( off != -1 )
373 : : {
374 [ + - ]: 12 : if( ! cap )
375 : : {
376 : 12 : cap = true;
377 [ + - ]: 12 : aStrBuf.ensureCapacity( 256 );
378 : : }
379 : :
380 [ + - ]: 12 : aStrBuf.append( &oustring.getStr()[k],idx - k );
381 [ + - ]: 12 : aStrBuf.append( m_vReplacement[off] );
382 : 12 : k = idx + m_vAdd[off];
383 : : }
384 : : }
385 : :
386 [ + + ]: 106 : if( cap )
387 : : {
388 [ + - ]: 12 : if( k < oustring.getLength() )
389 [ + - ]: 12 : aStrBuf.append( &oustring.getStr()[k],oustring.getLength()-k );
390 [ + - ]: 12 : oustring = aStrBuf.makeStringAndClear();
391 : 106 : }
392 : 106 : }
393 : :
394 : 635 : rtl::OUString Databases::getInstallPathAsURL()
395 : : {
396 [ + - ]: 635 : osl::MutexGuard aGuard( m_aMutex );
397 : :
398 [ + - ]: 635 : return m_aInstallDirectory;
399 : : }
400 : :
401 : 12 : const std::vector< rtl::OUString >& Databases::getModuleList( const rtl::OUString& Language )
402 : : {
403 [ + - ]: 12 : if( m_avModules.empty() )
404 : : {
405 [ + - ][ + - ]: 12 : rtl::OUString fileName,dirName = getInstallPathAsURL() + processLang( Language );
406 : 12 : osl::Directory dirFile( dirName );
407 : :
408 : 12 : osl::DirectoryItem aDirItem;
409 : 12 : osl::FileStatus aStatus( osl_FileStatus_Mask_FileName );
410 : :
411 : : sal_Int32 idx;
412 : :
413 [ + - ][ + - ]: 12 : if( osl::FileBase::E_None != dirFile.open() )
414 : 12 : return m_avModules;
415 : :
416 [ # # ][ # # ]: 0 : while( dirFile.getNextItem( aDirItem ) == osl::FileBase::E_None &&
[ # # ][ # # ]
417 [ # # ]: 0 : aDirItem.getFileStatus( aStatus ) == osl::FileBase::E_None )
418 : : {
419 [ # # ]: 0 : if( ! aStatus.isValid( osl_FileStatus_Mask_FileName ) )
420 : 0 : continue;
421 : :
422 [ # # ]: 0 : fileName = aStatus.getFileName();
423 : :
424 : : // Check, whether fileName is of the form *.cfg
425 : 0 : idx = fileName.lastIndexOf( sal_Unicode( '.' ) );
426 : :
427 [ # # ]: 0 : if( idx == -1 )
428 : 0 : continue;
429 : :
430 : 0 : const sal_Unicode* str = fileName.getStr();
431 : :
432 [ # # ][ # # ]: 0 : if( fileName.getLength() == idx + 4 &&
[ # # ][ # # ]
[ # # ]
[ # # # # ]
[ # # ][ # # ]
433 : 0 : ( str[idx + 1] == 'c' || str[idx + 1] == 'C' ) &&
434 : 0 : ( str[idx + 2] == 'f' || str[idx + 2] == 'F' ) &&
435 : 0 : ( str[idx + 3] == 'g' || str[idx + 3] == 'G' ) &&
436 [ # # ][ # # ]: 0 : ( fileName = fileName.copy(0,idx).toAsciiLowerCase() ).compareToAscii( "picture" ) != 0 ) {
437 [ # # ][ # # ]: 0 : if(! m_bShowBasic && fileName.compareToAscii("sbasic") == 0 )
[ # # ]
438 : 0 : continue;
439 [ # # ]: 0 : m_avModules.push_back( fileName );
440 : : }
441 [ + - ][ + - ]: 12 : }
[ + - ][ + - ]
[ + - ][ + - ]
[ - + ]
442 : : }
443 : 12 : return m_avModules;
444 : : }
445 : :
446 : :
447 : :
448 : 196 : StaticModuleInformation* Databases::getStaticInformationForModule( const rtl::OUString& Module,
449 : : const rtl::OUString& Language )
450 : : {
451 [ + - ]: 196 : osl::MutexGuard aGuard( m_aMutex );
452 : :
453 [ + - ]: 196 : rtl::OUString key = processLang(Language) + rtl::OUString( "/" ) + Module;
454 : :
455 : : std::pair< ModInfoTable::iterator,bool > aPair =
456 [ + - ]: 196 : m_aModInfo.insert( ModInfoTable::value_type( key,0 ) );
457 : :
458 : 196 : ModInfoTable::iterator it = aPair.first;
459 : :
460 [ + - ][ + - ]: 196 : if( aPair.second && ! it->second )
[ + + ][ + + ]
461 : : {
462 : : osl::File cfgFile( getInstallPathAsURL() +
463 : : key +
464 [ + - ]: 2 : rtl::OUString( ".cfg" ) );
465 : :
466 [ - + ][ + - ]: 2 : if( osl::FileBase::E_None != cfgFile.open( osl_File_OpenFlag_Read ) )
467 [ # # ]: 0 : it->second = 0;
468 : : else
469 : : {
470 : 2 : sal_uInt32 pos = 0;
471 : : sal_uInt64 nRead;
472 : : sal_Char buffer[2048];
473 : : sal_Unicode lineBuffer[1028];
474 : 2 : rtl::OUString fileContent;
475 : :
476 [ + - ][ + - ]: 4 : while( osl::FileBase::E_None == cfgFile.read( &buffer,2048,nRead ) && nRead )
[ + + ][ + + ]
477 [ + - ]: 2 : fileContent += rtl::OUString( buffer,sal_Int32( nRead ),RTL_TEXTENCODING_UTF8 );
478 : :
479 [ + - ]: 2 : cfgFile.close();
480 : :
481 : 2 : const sal_Unicode* str = fileContent.getStr();
482 : 2 : rtl::OUString current,lang_,program,startid,title,heading,fulltext;
483 : 2 : rtl::OUString order( "1" );
484 : :
485 [ + + ]: 252 : for( sal_Int32 i = 0;i < fileContent.getLength();i++ )
486 : : {
487 : 250 : sal_Unicode ch = str[ i ];
488 [ + + ][ - + ]: 250 : if( ch == sal_Unicode( '\n' ) || ch == sal_Unicode( '\r' ) )
489 : : {
490 [ + + ]: 16 : if( pos )
491 : : {
492 : 12 : current = rtl::OUString( lineBuffer,pos );
493 : :
494 [ + + ]: 12 : if( current.compareToAscii( "Title",5 ) == 0 )
495 : : {
496 : 2 : title = current.copy( current.indexOf(sal_Unicode( '=' ) ) + 1 );
497 : : }
498 [ + + ]: 10 : else if( current.compareToAscii( "Start",5 ) == 0 )
499 : : {
500 : 2 : startid = current.copy( current.indexOf('=') + 1 );
501 : : }
502 [ + + ]: 8 : else if( current.compareToAscii( "Language",8 ) == 0 )
503 : : {
504 : 2 : lang_ = current.copy( current.indexOf('=') + 1 );
505 : : }
506 [ + + ]: 6 : else if( current.compareToAscii( "Program",7 ) == 0 )
507 : : {
508 : 2 : program = current.copy( current.indexOf('=') + 1 );
509 : : }
510 [ + + ]: 4 : else if( current.compareToAscii( "Heading",7 ) == 0 )
511 : : {
512 : 2 : heading = current.copy( current.indexOf('=') + 1 );
513 : : }
514 [ - + ]: 2 : else if( current.compareToAscii( "FullText",8 ) == 0 )
515 : : {
516 : 0 : fulltext = current.copy( current.indexOf('=') + 1 );
517 : : }
518 [ + - ]: 2 : else if( current.compareToAscii( "Order",5 ) == 0 )
519 : : {
520 : 2 : order = current.copy( current.indexOf('=') + 1 );
521 : : }
522 : : }
523 : 16 : pos = 0;
524 : : }
525 : : else
526 : 234 : lineBuffer[ pos++ ] = ch;
527 : : }
528 [ + - ]: 2 : replaceName( title );
529 [ + - ]: 2 : it->second = new StaticModuleInformation( title,
530 : : startid,
531 : : program,
532 : : heading,
533 : : fulltext,
534 [ + - ]: 4 : order );
535 [ + - ]: 2 : }
536 : : }
537 : :
538 [ + - ][ + - ]: 196 : return it->second;
539 : : }
540 : :
541 : :
542 : :
543 : :
544 : 504 : rtl::OUString Databases::processLang( const rtl::OUString& Language )
545 : : {
546 [ + - ]: 504 : osl::MutexGuard aGuard( m_aMutex );
547 : :
548 : 504 : rtl::OUString ret;
549 [ + - ]: 504 : LangSetTable::iterator it = m_aLangSet.find( Language );
550 : :
551 [ + - ][ + + ]: 504 : if( it == m_aLangSet.end() )
552 : : {
553 : : sal_Int32 idx;
554 : 16 : osl::DirectoryItem aDirItem;
555 : :
556 [ + - ][ - + ]: 16 : if( osl::FileBase::E_None == osl::DirectoryItem::get( getInstallPathAsURL() + Language,aDirItem ) )
[ + - ]
557 : : {
558 : 0 : ret = Language;
559 [ # # ]: 0 : m_aLangSet[ Language ] = ret;
560 : : }
561 [ + + ][ - + ]: 36 : else if( ( ( idx = Language.indexOf( '-' ) ) != -1 ||
[ + - ][ + + ]
562 : : ( idx = Language.indexOf( '_' ) ) != -1 ) &&
563 : : osl::FileBase::E_None == osl::DirectoryItem::get( getInstallPathAsURL() + Language.copy( 0,idx ),
564 [ + - ][ + - ]: 20 : aDirItem ) )
[ + + ][ + + ]
[ + + ][ # #
# # # # ]
565 : : {
566 : 4 : ret = Language.copy( 0,idx );
567 [ + - ]: 4 : m_aLangSet[ Language ] = ret;
568 [ + - ]: 16 : }
569 : : }
570 : : else
571 [ + - ]: 488 : ret = it->second;
572 : :
573 [ + - ]: 504 : return ret;
574 : : }
575 : :
576 : :
577 : 0 : rtl::OUString Databases::country( const rtl::OUString& Language )
578 : : {
579 : : sal_Int32 idx;
580 [ # # ][ # # ]: 0 : if( ( idx = Language.indexOf( '-' ) ) != -1 ||
[ # # ]
581 : : ( idx = Language.indexOf( '_' ) ) != -1 )
582 : 0 : return Language.copy( 1+idx );
583 : :
584 : 0 : return rtl::OUString();
585 : : }
586 : :
587 : :
588 : :
589 : 404 : Db* Databases::getBerkeley( const rtl::OUString& Database,
590 : : const rtl::OUString& Language, bool helpText,
591 : : const rtl::OUString* pExtensionPath )
592 : : {
593 [ + - ][ - + ]: 404 : if( Database.isEmpty() || Language.isEmpty() )
[ - + ]
594 : 0 : return 0;
595 : :
596 [ + - ]: 404 : osl::MutexGuard aGuard( m_aMutex );
597 : :
598 : :
599 [ + + ][ + + ]: 404 : rtl::OUString aFileExt( helpText ? rtl::OUString(".ht") : rtl::OUString(".db") );
[ + + ]
600 [ + - ][ + - ]: 404 : rtl::OUString dbFileName = rtl::OUStringBuffer().append('/').append(Database).append(aFileExt).makeStringAndClear();
[ + - ][ + - ]
601 : 404 : rtl::OUString key;
602 [ + + ]: 404 : if( pExtensionPath == NULL )
603 [ + - ]: 296 : key = processLang( Language ) + dbFileName;
604 : : else
605 : 108 : key = *pExtensionPath + Language + dbFileName; // make unique, don't change language
606 : :
607 : : std::pair< DatabasesTable::iterator,bool > aPair =
608 [ + - ]: 404 : m_aDatabases.insert( DatabasesTable::value_type( key,0 ) );
609 : :
610 : 404 : DatabasesTable::iterator it = aPair.first;
611 : :
612 [ + - ][ + - ]: 404 : if( aPair.second && ! it->second )
[ + + ][ + + ]
613 : : {
614 [ + - ][ + - ]: 12 : Db* table = new Db();
615 : :
616 : 12 : rtl::OUString fileURL;
617 [ + + ]: 12 : if( pExtensionPath )
618 [ + - ]: 4 : fileURL = expandURL(*pExtensionPath) + Language + dbFileName;
619 : : else
620 [ + - ]: 8 : fileURL = getInstallPathAsURL() + key;
621 : :
622 : 12 : rtl::OUString fileNameDBHelp( fileURL );
623 : : //Extensions always use the new format
624 [ + + ]: 12 : if( pExtensionPath != NULL )
625 : 4 : fileNameDBHelp += rtl::OUString( "_" );
626 : : //SimpleFileAccess takes file URLs as arguments!!! Using filenames works accidentally but
627 : : //fails for example when using long path names on Windows (starting with \\?\)
628 [ + - ][ + - ]: 12 : if( m_xSFA->exists( fileNameDBHelp ) )
[ + - ]
629 : : {
630 [ + - ][ + - ]: 12 : DBHelp* pDBHelp = new DBHelp( fileNameDBHelp, m_xSFA );
631 : 12 : table->setDBHelp( pDBHelp );
632 : : }
633 [ # # ][ # # ]: 0 : else if( table->open( 0,fileURL, DB_BTREE,DB_RDONLY,0644 ) )
634 : : {
635 [ # # ]: 0 : table->close( 0 );
636 [ # # ][ # # ]: 0 : delete table;
637 : 0 : table = 0;
638 : : }
639 : :
640 [ + - ]: 12 : it->second = table;
641 : : }
642 : :
643 [ + - ][ + - ]: 404 : return it->second;
644 : : }
645 : :
646 : : Reference< XCollator >
647 : 0 : Databases::getCollator( const rtl::OUString& Language,
648 : : const rtl::OUString& System )
649 : : {
650 : : (void)System;
651 : :
652 : 0 : rtl::OUString key = Language;
653 : :
654 [ # # ]: 0 : osl::MutexGuard aGuard( m_aMutex );
655 : :
656 : : CollatorTable::iterator it =
657 [ # # ][ # # ]: 0 : m_aCollatorTable.insert( CollatorTable::value_type( key,0 ) ).first;
[ # # ][ # # ]
658 : :
659 [ # # ][ # # ]: 0 : if( ! it->second.is() )
660 : : {
661 [ # # ]: 0 : it->second =
662 : : Reference< XCollator > (
663 [ # # ]: 0 : m_xSMgr->createInstanceWithContext( rtl::OUString( "com.sun.star.i18n.Collator" ),
664 [ # # ][ # # ]: 0 : m_xContext ), UNO_QUERY );
[ # # ]
665 [ # # ]: 0 : rtl::OUString langStr = processLang(Language);
666 : 0 : rtl::OUString countryStr = country(Language);
667 [ # # ]: 0 : if( countryStr.isEmpty() )
668 : : {
669 [ # # ]: 0 : if( langStr.compareToAscii("de") == 0 )
670 : 0 : countryStr = rtl::OUString("DE");
671 [ # # ]: 0 : else if( langStr.compareToAscii("en") == 0 )
672 : 0 : countryStr = rtl::OUString("US");
673 [ # # ]: 0 : else if( langStr.compareToAscii("es") == 0 )
674 : 0 : countryStr = rtl::OUString("ES");
675 [ # # ]: 0 : else if( langStr.compareToAscii("it") == 0 )
676 : 0 : countryStr = rtl::OUString("IT");
677 [ # # ]: 0 : else if( langStr.compareToAscii("fr") == 0 )
678 : 0 : countryStr = rtl::OUString("FR");
679 [ # # ]: 0 : else if( langStr.compareToAscii("sv") == 0 )
680 : 0 : countryStr = rtl::OUString("SE");
681 [ # # ]: 0 : else if( langStr.compareToAscii("ja") == 0 )
682 : 0 : countryStr = rtl::OUString("JP");
683 [ # # ]: 0 : else if( langStr.compareToAscii("ko") == 0 )
684 : 0 : countryStr = rtl::OUString("KR");
685 : : }
686 [ # # ][ # # ]: 0 : it->second->loadDefaultCollator( Locale( langStr,
687 : : countryStr,
688 : : rtl::OUString() ),
689 [ # # ]: 0 : 0 );
690 : : }
691 : :
692 [ # # ][ # # ]: 0 : return it->second;
693 : : }
694 : :
695 : :
696 : :
697 : : namespace chelp {
698 : :
699 : 0 : struct KeywordElementComparator
700 : : {
701 : 0 : KeywordElementComparator( const Reference< XCollator >& xCollator )
702 : 0 : : m_xCollator( xCollator )
703 : 0 : { }
704 : :
705 : 0 : bool operator()( const KeywordInfo::KeywordElement& la,
706 : : const KeywordInfo::KeywordElement& ra ) const
707 : : {
708 : 0 : const rtl::OUString& l = la.key;
709 : 0 : const rtl::OUString& r = ra.key;
710 : :
711 : : bool ret;
712 : :
713 [ # # ]: 0 : if( m_xCollator.is() )
714 : : {
715 : 0 : sal_Int32 l1 = l.indexOf( sal_Unicode( ';' ) );
716 [ # # ]: 0 : sal_Int32 l3 = ( l1 == -1 ? l.getLength() : l1 );
717 : :
718 : 0 : sal_Int32 r1 = r.indexOf( sal_Unicode( ';' ) );
719 [ # # ]: 0 : sal_Int32 r3 = ( r1 == -1 ? r.getLength() : r1 );
720 : :
721 : 0 : sal_Int32 c1 = m_xCollator->compareSubstring( l,0,l3,r,0,r3 );
722 : :
723 [ # # ]: 0 : if( c1 == +1 )
724 : 0 : ret = false;
725 [ # # ]: 0 : else if( c1 == 0 )
726 : : {
727 : 0 : sal_Int32 l2 = l.getLength() - l1 - 1;
728 : 0 : sal_Int32 r2 = r.getLength() - r1 - 1;
729 : 0 : ret = ( m_xCollator->compareSubstring( l,1+l1,l2,r,1+r1,r2 ) < 0 );
730 : : }
731 : : else
732 : 0 : ret = true;
733 : : }
734 : : else
735 : 0 : ret = bool( l < r );
736 : :
737 : 0 : return ret;
738 : : }
739 : :
740 : : Reference< XCollator > m_xCollator;
741 : : }; // end struct KeywordElementComparator
742 : :
743 : : }
744 : :
745 : :
746 : :
747 : 0 : KeywordInfo::KeywordElement::KeywordElement( Databases *pDatabases,
748 : : Db* pDb,
749 : : rtl::OUString& ky,
750 : : rtl::OUString& data )
751 [ # # ][ # # ]: 0 : : key( ky )
[ # # ]
752 : : {
753 [ # # ]: 0 : pDatabases->replaceName( key );
754 [ # # ]: 0 : init( pDatabases,pDb,data );
755 : 0 : }
756 : :
757 : :
758 : :
759 : 0 : void KeywordInfo::KeywordElement::init( Databases *pDatabases,Db* pDb,const rtl::OUString& ids )
760 : : {
761 : 0 : const sal_Unicode* idstr = ids.getStr();
762 [ # # ][ # # ]: 0 : std::vector< rtl::OUString > id,anchor;
763 : 0 : int idx = -1,k;
764 [ # # ]: 0 : while( ( idx = ids.indexOf( ';',k = ++idx ) ) != -1 )
765 : : {
766 : 0 : int h = ids.indexOf( sal_Unicode( '#' ),k );
767 [ # # ]: 0 : if( h < idx )
768 : : {
769 : : // found an anchor
770 [ # # ]: 0 : id.push_back( rtl::OUString( &idstr[k],h-k ) );
771 [ # # ]: 0 : anchor.push_back( rtl::OUString( &idstr[h+1],idx-h-1 ) );
772 : : }
773 : : else
774 : : {
775 [ # # ]: 0 : id.push_back( rtl::OUString( &idstr[k],idx-k ) );
776 [ # # ]: 0 : anchor.push_back( rtl::OUString() );
777 : : }
778 : : }
779 : :
780 [ # # ]: 0 : listId.realloc( id.size() );
781 [ # # ]: 0 : listAnchor.realloc( id.size() );
782 [ # # ]: 0 : listTitle.realloc( id.size() );
783 : :
784 [ # # ]: 0 : Dbt data;
785 : 0 : DBData aDBData;
786 : 0 : const sal_Char* pData = NULL;
787 : 0 : const sal_Char pEmpty[] = "";
788 : :
789 [ # # ]: 0 : for( sal_uInt32 i = 0; i < id.size(); ++i )
790 : : {
791 [ # # ]: 0 : listId[i] = id[i];
792 [ # # ]: 0 : listAnchor[i] = anchor[i];
793 : :
794 : 0 : pData = pEmpty;
795 [ # # ]: 0 : if( pDb )
796 : : {
797 [ # # ]: 0 : rtl::OString idi( id[i].getStr(),id[i].getLength(),RTL_TEXTENCODING_UTF8 );
798 : 0 : DBHelp* pDBHelp = pDb->getDBHelp();
799 [ # # ]: 0 : if( pDBHelp != NULL )
800 : : {
801 [ # # ]: 0 : bool bSuccess = pDBHelp->getValueForKey( idi, aDBData );
802 [ # # ]: 0 : if( bSuccess )
803 : : {
804 : 0 : pData = aDBData.getData();
805 : : }
806 : : }
807 : : else
808 : : {
809 : 0 : Dbt key_( static_cast< void* >( const_cast< sal_Char* >( idi.getStr() ) ),
810 [ # # ]: 0 : idi.getLength() );
811 [ # # ]: 0 : pDb->get( 0,&key_,&data,0 );
812 [ # # ][ # # ]: 0 : pData = static_cast<sal_Char*>( data.get_data() );
813 : 0 : }
814 : : }
815 : :
816 : 0 : DbtToStringConverter converter( pData );
817 : :
818 [ # # ]: 0 : rtl::OUString title = converter.getTitle();
819 [ # # ]: 0 : pDatabases->replaceName( title );
820 [ # # ]: 0 : listTitle[i] = title;
821 [ # # ]: 0 : }
822 : 0 : }
823 : :
824 : :
825 : :
826 : 0 : KeywordInfo::KeywordInfo( const std::vector< KeywordElement >& aVec )
827 : 0 : : listKey( aVec.size() ),
828 : 0 : listId( aVec.size() ),
829 : 0 : listAnchor( aVec.size() ),
830 [ # # ]: 0 : listTitle( aVec.size() )
[ # # # # ]
831 : : {
832 [ # # ]: 0 : for( unsigned int i = 0; i < aVec.size(); ++i )
833 : : {
834 [ # # ]: 0 : listKey[i] = aVec[i].key;
835 [ # # ][ # # ]: 0 : listId[i] = aVec[i].listId;
836 [ # # ][ # # ]: 0 : listAnchor[i] = aVec[i].listAnchor;
837 [ # # ][ # # ]: 0 : listTitle[i] = aVec[i].listTitle;
838 : : }
839 : 0 : }
840 : :
841 : 0 : bool Databases::checkModuleMatchForExtension
842 : : ( const rtl::OUString& Database, const rtl::OUString& doclist )
843 : : {
844 : 0 : bool bBelongsToDatabase = true;
845 : :
846 : : // Analyse doclist string to find module assignments
847 : 0 : bool bFoundAtLeastOneModule = false;
848 : 0 : bool bModuleMatch = false;
849 : 0 : sal_Int32 nLen = doclist.getLength();
850 : 0 : sal_Int32 nLastFound = doclist.lastIndexOf( sal_Unicode(';') );
851 [ # # ]: 0 : if( nLastFound == -1 )
852 : 0 : nLastFound = nLen;
853 : 0 : const sal_Unicode* pStr = doclist.getStr();
854 : 0 : sal_Int32 nFound = doclist.lastIndexOf( sal_Unicode('_') );
855 [ # # ]: 0 : while( nFound != -1 )
856 : : {
857 : : // Simple optimization, stop if '_' is followed by "id"
858 [ # # ]: 0 : if( nLen - nFound > 2 )
859 : : {
860 [ # # ][ # # ]: 0 : if( pStr[ nFound + 1 ] == sal_Unicode('i') &&
861 : 0 : pStr[ nFound + 2 ] == sal_Unicode('d') )
862 : : break;
863 : : }
864 : :
865 : 0 : rtl::OUString aModule = doclist.copy( nFound + 1, nLastFound - nFound - 1 );
866 [ # # ]: 0 : std::vector< rtl::OUString >::iterator result = std::find( m_avModules.begin(), m_avModules.end(), aModule );
867 [ # # ][ # # ]: 0 : if( result != m_avModules.end() )
868 : : {
869 : 0 : bFoundAtLeastOneModule = true;
870 [ # # ]: 0 : if( Database == aModule )
871 : : {
872 : 0 : bModuleMatch = true;
873 : : break;
874 : : }
875 : : }
876 : :
877 : 0 : nLastFound = nFound;
878 [ # # ]: 0 : if( nLastFound == 0 )
879 : : break;
880 [ # # ]: 0 : nFound = doclist.lastIndexOf( sal_Unicode('_'), nLastFound - 1 );
881 : 0 : }
882 : :
883 [ # # ][ # # ]: 0 : if( bFoundAtLeastOneModule && !bModuleMatch )
884 : 0 : bBelongsToDatabase = false;
885 : :
886 : 0 : return bBelongsToDatabase;
887 : : }
888 : :
889 : :
890 : 0 : KeywordInfo* Databases::getKeyword( const rtl::OUString& Database,
891 : : const rtl::OUString& Language )
892 : : {
893 [ # # ]: 0 : osl::MutexGuard aGuard( m_aMutex );
894 : :
895 [ # # ]: 0 : rtl::OUString key = processLang(Language) + rtl::OUString( "/" ) + Database;
896 : :
897 : : std::pair< KeywordInfoTable::iterator,bool > aPair =
898 [ # # ]: 0 : m_aKeywordInfo.insert( KeywordInfoTable::value_type( key,0 ) );
899 : :
900 : 0 : KeywordInfoTable::iterator it = aPair.first;
901 : :
902 [ # # ][ # # ]: 0 : if( aPair.second && ! it->second )
[ # # ][ # # ]
903 : : {
904 [ # # ]: 0 : std::vector<KeywordInfo::KeywordElement> aVector;
905 : :
906 [ # # ]: 0 : KeyDataBaseFileIterator aDbFileIt( m_xContext, *this, Database, Language );
907 : 0 : rtl::OUString fileURL;
908 : 0 : bool bExtension = false;
909 [ # # ][ # # ]: 0 : while( !(fileURL = aDbFileIt.nextDbFile( bExtension )).isEmpty() )
910 : : {
911 [ # # ]: 0 : Db table;
912 : :
913 : 0 : rtl::OUString fileNameDBHelp( fileURL );
914 [ # # ]: 0 : if( bExtension )
915 : 0 : fileNameDBHelp += rtl::OUString( "_" );
916 [ # # ][ # # ]: 0 : if( m_xSFA->exists( fileNameDBHelp ) )
[ # # ]
917 : : {
918 [ # # ]: 0 : DBHelp aDBHelp( fileNameDBHelp, m_xSFA );
919 : :
920 : 0 : DBData aKey;
921 : 0 : DBData aValue;
922 [ # # ][ # # ]: 0 : if( aDBHelp.startIteration() )
923 : : {
924 [ # # ]: 0 : Db* idmap = getBerkeley( Database,Language );
925 : :
926 : 0 : DBHelp* pDBHelp = idmap->getDBHelp();
927 [ # # ]: 0 : if( pDBHelp != NULL )
928 : : {
929 : 0 : bool bOptimizeForPerformance = true;
930 [ # # ]: 0 : pDBHelp->releaseHashMap();
931 [ # # ]: 0 : pDBHelp->createHashMap( bOptimizeForPerformance );
932 : : }
933 : :
934 [ # # ][ # # ]: 0 : while( aDBHelp.getNextKeyAndValue( aKey, aValue ) )
935 : : {
936 : 0 : rtl::OUString keyword( aKey.getData(), aKey.getSize(),
937 [ # # ]: 0 : RTL_TEXTENCODING_UTF8 );
938 : 0 : rtl::OUString doclist( aValue.getData(), aValue.getSize(),
939 [ # # ]: 0 : RTL_TEXTENCODING_UTF8 );
940 : :
941 : 0 : bool bBelongsToDatabase = true;
942 [ # # ]: 0 : if( bExtension )
943 [ # # ]: 0 : bBelongsToDatabase = checkModuleMatchForExtension( Database, doclist );
944 : :
945 [ # # ]: 0 : if( !bBelongsToDatabase )
946 : 0 : continue;
947 : :
948 : : aVector.push_back( KeywordInfo::KeywordElement( this,
949 : : idmap,
950 : : keyword,
951 [ # # ][ # # ]: 0 : doclist ) );
[ # # ][ # # ]
952 [ # # ]: 0 : }
953 [ # # ]: 0 : aDBHelp.stopIteration();
954 : :
955 [ # # ]: 0 : if( pDBHelp != NULL )
956 [ # # ]: 0 : pDBHelp->releaseHashMap();
957 [ # # ]: 0 : }
958 : : }
959 : :
960 [ # # ][ # # ]: 0 : else if( 0 == table.open( 0,fileURL,DB_BTREE,DB_RDONLY,0644 ) )
961 : : {
962 [ # # ]: 0 : Db* idmap = getBerkeley( Database,Language );
963 : :
964 : 0 : bool first = true;
965 : :
966 : 0 : Dbc* cursor = 0;
967 [ # # ]: 0 : table.cursor( 0,&cursor,0 );
968 [ # # ][ # # ]: 0 : Dbt key_,data;
969 [ # # ]: 0 : key_.set_flags( DB_DBT_MALLOC ); // Initially the cursor must allocate the necessary memory
970 [ # # ]: 0 : data.set_flags( DB_DBT_MALLOC );
971 [ # # ][ # # ]: 0 : while( cursor && DB_NOTFOUND != cursor->get( &key_,&data,DB_NEXT ) )
[ # # ][ # # ]
972 : : {
973 [ # # ]: 0 : rtl::OUString keyword( static_cast<sal_Char*>(key_.get_data()),
974 [ # # ]: 0 : key_.get_size(),
975 [ # # ]: 0 : RTL_TEXTENCODING_UTF8 );
976 [ # # ]: 0 : rtl::OUString doclist( static_cast<sal_Char*>(data.get_data()),
977 [ # # ]: 0 : data.get_size(),
978 [ # # ]: 0 : RTL_TEXTENCODING_UTF8 );
979 : :
980 : 0 : bool bBelongsToDatabase = true;
981 [ # # ]: 0 : if( bExtension )
982 [ # # ]: 0 : bBelongsToDatabase = checkModuleMatchForExtension( Database, doclist );
983 : :
984 [ # # ]: 0 : if( !bBelongsToDatabase )
985 : 0 : continue;
986 : :
987 : : aVector.push_back( KeywordInfo::KeywordElement( this,
988 : : idmap,
989 : : keyword,
990 [ # # ][ # # ]: 0 : doclist ) );
[ # # ]
991 [ # # ]: 0 : if( first )
992 : : {
993 [ # # ]: 0 : key_.set_flags( DB_DBT_REALLOC );
994 [ # # ]: 0 : data.set_flags( DB_DBT_REALLOC );
995 : 0 : first = false;
996 : : }
997 [ # # ][ # # ]: 0 : }
998 : :
999 [ # # ][ # # ]: 0 : if( cursor ) cursor->close();
[ # # ][ # # ]
1000 : : }
1001 [ # # ]: 0 : table.close( 0 );
1002 [ # # ]: 0 : }
1003 : :
1004 : : // sorting
1005 [ # # ]: 0 : Reference< XCollator > xCollator = getCollator( Language,rtl::OUString());
1006 [ # # ]: 0 : KeywordElementComparator aComparator( xCollator );
1007 [ # # ][ # # ]: 0 : std::sort(aVector.begin(),aVector.end(),aComparator);
[ # # ]
1008 : :
1009 [ # # ][ # # ]: 0 : KeywordInfo* pInfo = it->second = new KeywordInfo( aVector );
[ # # ]
1010 [ # # ][ # # ]: 0 : (void)pInfo;
1011 : : }
1012 : :
1013 [ # # ][ # # ]: 0 : return it->second;
1014 : : }
1015 : :
1016 : 0 : Reference< XHierarchicalNameAccess > Databases::jarFile( const rtl::OUString& jar,
1017 : : const rtl::OUString& Language )
1018 : : {
1019 [ # # ][ # # ]: 0 : if( jar.isEmpty() || Language.isEmpty() )
[ # # ]
1020 : : {
1021 [ # # ]: 0 : return Reference< XHierarchicalNameAccess >( 0 );
1022 : : }
1023 [ # # ][ # # ]: 0 : rtl::OUString key = rtl::OUStringBuffer(processLang(Language)).append('/').append(jar).makeStringAndClear();
[ # # ][ # # ]
[ # # ]
1024 : :
1025 [ # # ]: 0 : osl::MutexGuard aGuard( m_aMutex );
1026 : :
1027 : : ZipFileTable::iterator it =
1028 [ # # ][ # # ]: 0 : m_aZipFileTable.insert( ZipFileTable::value_type( key,Reference< XHierarchicalNameAccess >(0) ) ).first;
[ # # ][ # # ]
1029 : :
1030 [ # # ][ # # ]: 0 : if( ! it->second.is() )
1031 : : {
1032 : 0 : rtl::OUString zipFile;
1033 : : try
1034 : : {
1035 : : // Extension jar file? Search for ?
1036 : 0 : sal_Int32 nQuestionMark1 = jar.indexOf( sal_Unicode('?') );
1037 : 0 : sal_Int32 nQuestionMark2 = jar.lastIndexOf( sal_Unicode('?') );
1038 [ # # ][ # # ]: 0 : if( nQuestionMark1 != -1 && nQuestionMark2 != -1 && nQuestionMark1 != nQuestionMark2 )
[ # # ]
1039 : : {
1040 : 0 : ::rtl::OUString aExtensionPath = jar.copy( nQuestionMark1 + 1, nQuestionMark2 - nQuestionMark1 - 1 );
1041 : 0 : ::rtl::OUString aPureJar = jar.copy( nQuestionMark2 + 1 );
1042 : :
1043 : 0 : rtl::OUStringBuffer aStrBuf;
1044 [ # # ]: 0 : aStrBuf.append( aExtensionPath );
1045 [ # # ]: 0 : aStrBuf.append( '/' );
1046 [ # # ]: 0 : aStrBuf.append( aPureJar );
1047 : :
1048 [ # # ][ # # ]: 0 : zipFile = expandURL( aStrBuf.makeStringAndClear() );
1049 : : }
1050 : : else
1051 : : {
1052 [ # # ]: 0 : zipFile = getInstallPathAsURL() + key;
1053 : : }
1054 : :
1055 [ # # ]: 0 : Sequence< Any > aArguments( 2 );
1056 : :
1057 [ # # ]: 0 : XInputStream_impl* p = new XInputStream_impl( zipFile );
1058 [ # # ][ # # ]: 0 : if( p->CtorSuccess() )
1059 : : {
1060 [ # # ][ # # ]: 0 : Reference< XInputStream > xInputStream( p );
1061 [ # # ][ # # ]: 0 : aArguments[ 0 ] <<= xInputStream;
1062 : : }
1063 : : else
1064 : : {
1065 [ # # ][ # # ]: 0 : delete p;
1066 [ # # ][ # # ]: 0 : aArguments[ 0 ] <<= zipFile;
1067 : : }
1068 : :
1069 : : // let ZipPackage be used ( no manifest.xml is required )
1070 : 0 : beans::NamedValue aArg;
1071 : 0 : aArg.Name = ::rtl::OUString( "StorageFormat" );
1072 [ # # ][ # # ]: 0 : aArg.Value <<= ZIP_STORAGE_FORMAT_STRING;
1073 [ # # ][ # # ]: 0 : aArguments[ 1 ] <<= aArg;
1074 : :
1075 : : Reference< XInterface > xIfc
1076 [ # # ]: 0 : = m_xSMgr->createInstanceWithArgumentsAndContext(
1077 : : rtl::OUString(
1078 : : "com.sun.star.packages.comp.ZipPackage" ),
1079 [ # # ]: 0 : aArguments, m_xContext );
1080 : :
1081 [ # # ]: 0 : if ( xIfc.is() )
1082 : : {
1083 [ # # ][ # # ]: 0 : it->second = Reference< XHierarchicalNameAccess >( xIfc, UNO_QUERY );
[ # # ]
1084 : :
1085 : : OSL_ENSURE( it->second.is(),
1086 : : "ContentProvider::createPackage - "
1087 : : "Got no hierarchical name access!" );
1088 : :
1089 [ # # ]: 0 : }
[ # # # ]
1090 : : }
1091 [ # # ]: 0 : catch ( RuntimeException & )
1092 : : {
1093 : : }
1094 [ # # ]: 0 : catch ( Exception & )
1095 : : {
1096 : 0 : }
1097 : : }
1098 : :
1099 [ # # ][ # # ]: 0 : return it->second;
1100 : : }
1101 : :
1102 : 0 : Reference< XHierarchicalNameAccess > Databases::findJarFileForPath
1103 : : ( const rtl::OUString& jar, const rtl::OUString& Language,
1104 : : const rtl::OUString& path, rtl::OUString* o_pExtensionPath,
1105 : : rtl::OUString* o_pExtensionRegistryPath )
1106 : : {
1107 : 0 : Reference< XHierarchicalNameAccess > xNA;
1108 [ # # ][ # # ]: 0 : if( jar.isEmpty() || Language.isEmpty() )
[ # # ]
1109 : : {
1110 : : return xNA;
1111 : : }
1112 : :
1113 [ # # ]: 0 : JarFileIterator aJarFileIt( m_xContext, *this, jar, Language );
1114 : 0 : Reference< XHierarchicalNameAccess > xTestNA;
1115 : 0 : Reference< deployment::XPackage > xParentPackageBundle;
1116 [ # # ][ # # ]: 0 : while( (xTestNA = aJarFileIt.nextJarFile( xParentPackageBundle, o_pExtensionPath, o_pExtensionRegistryPath )).is() )
[ # # ]
1117 : : {
1118 [ # # ][ # # ]: 0 : if( xTestNA.is() && xTestNA->hasByHierarchicalName( path ) )
[ # # ][ # # ]
[ # # ]
1119 : : {
1120 : 0 : bool bSuccess = true;
1121 [ # # ]: 0 : if( xParentPackageBundle.is() )
1122 : : {
1123 : 0 : rtl::OUString aIdentifierInPath;
1124 : 0 : sal_Int32 nFindSlash = path.indexOf( '/' );
1125 [ # # ]: 0 : if( nFindSlash != -1 )
1126 : 0 : aIdentifierInPath = path.copy( 0, nFindSlash );
1127 : :
1128 [ # # ][ # # ]: 0 : beans::Optional<rtl::OUString> aIdentifierOptional = xParentPackageBundle->getIdentifier();
1129 [ # # ][ # # ]: 0 : if( !aIdentifierInPath.isEmpty() && aIdentifierOptional.IsPresent )
[ # # ]
1130 : : {
1131 : 0 : rtl::OUString aUnencodedIdentifier = aIdentifierOptional.Value;
1132 : : rtl::OUString aIdentifier = rtl::Uri::encode( aUnencodedIdentifier,
1133 : 0 : rtl_UriCharClassPchar, rtl_UriEncodeIgnoreEscapes, RTL_TEXTENCODING_UTF8 );
1134 : :
1135 [ # # ]: 0 : if( !aIdentifierInPath.equals( aIdentifier ) )
1136 : : {
1137 : : // path does not start with extension identifier -> ignore
1138 : 0 : bSuccess = false;
1139 : 0 : }
1140 : : }
1141 : : else
1142 : : {
1143 : : // No identifier -> ignore
1144 : 0 : bSuccess = false;
1145 : 0 : }
1146 : : }
1147 : :
1148 [ # # ]: 0 : if( bSuccess )
1149 : : {
1150 [ # # ]: 0 : xNA = xTestNA;
1151 : 0 : break;
1152 : : }
1153 : : }
1154 : : }
1155 : :
1156 [ # # ]: 0 : return xNA;
1157 : : }
1158 : :
1159 : 0 : void Databases::popupDocument( URLParameter* urlPar,char **buffer,int *byteCount )
1160 : : {
1161 : : const char* pop1 =
1162 : : " <html> "
1163 : : " <head> "
1164 : : " <help:css-file-link xmlns:help=\"http://openoffice.org/2000/help\"/> "
1165 : : " </head> "
1166 : : " <body> "
1167 : 0 : " <help:popup-cut Id=\"";
1168 : 0 : const sal_Int32 l1 = strlen( pop1 );
1169 : :
1170 : 0 : const char* pop3 = "\" Eid=\"";
1171 : 0 : const sal_Int32 l3 = strlen( pop3 );
1172 : :
1173 : : const char* pop5 =
1174 : : "\" xmlns:help=\"http://openoffice.org/2000/help\"></help:popup-cut> "
1175 : : " </body> "
1176 : 0 : " </html>";
1177 : 0 : const sal_Int32 l5 = strlen( pop5 );
1178 : : sal_Int32 l2,l4;
1179 : :
1180 [ # # ]: 0 : rtl::OUString val = urlPar->get_id();
1181 [ # # ]: 0 : rtl::OString pop2O( val.getStr(),l2 = val.getLength(),RTL_TEXTENCODING_UTF8 );
1182 : 0 : const char* pop2 = pop2O.getStr();
1183 : :
1184 : 0 : val = urlPar->get_eid();
1185 [ # # ]: 0 : rtl::OString pop4O( val.getStr(),l4 = val.getLength(),RTL_TEXTENCODING_UTF8 );
1186 : 0 : const char* pop4 = pop4O.getStr();
1187 : :
1188 : 0 : (*byteCount) = l1 + l2 + l3 + l4 + l5;
1189 : :
1190 [ # # ]: 0 : *buffer = new char[ 1+*byteCount ];
1191 : :
1192 : 0 : memcpy( *buffer,pop1,l1 );
1193 : 0 : memcpy( *buffer+l1,pop2,l2 );
1194 : 0 : memcpy( *buffer+(l1+l2),pop3,l3 );
1195 : 0 : memcpy( *buffer+(l1+l2+l3),pop4,l4 );
1196 : 0 : memcpy( *buffer+(l1+l2+l3+l4),pop5,l5 );
1197 : 0 : (*buffer)[*byteCount] = 0;
1198 : 0 : }
1199 : :
1200 : :
1201 : 0 : void Databases::changeCSS(const rtl::OUString& newStyleSheet)
1202 : : {
1203 : 0 : m_aCSS = newStyleSheet.toAsciiLowerCase();
1204 [ # # ]: 0 : delete[] m_pCustomCSSDoc, m_pCustomCSSDoc = 0,m_nCustomCSSDocLength = 0;
1205 : 0 : }
1206 : :
1207 : :
1208 : :
1209 : 0 : void Databases::cascadingStylesheet( const rtl::OUString& Language,
1210 : : char** buffer,
1211 : : int* byteCount )
1212 : : {
1213 [ # # ]: 0 : if( ! m_pCustomCSSDoc )
1214 : : {
1215 : 0 : int retry = 2;
1216 : 0 : bool error = true;
1217 : 0 : rtl::OUString fileURL;
1218 : :
1219 : 0 : sal_Bool bHighContrastMode = sal_False;
1220 : 0 : rtl::OUString aCSS( m_aCSS );
1221 [ # # ]: 0 : if ( aCSS.compareToAscii( "default" ) == 0 )
1222 : : {
1223 : : // #i50760: "default" needs to adapt HC mode
1224 : : uno::Reference< awt::XToolkit > xToolkit = uno::Reference< awt::XToolkit >(
1225 [ # # ][ # # ]: 0 : ::comphelper::getProcessServiceFactory()->createInstance( rtl::OUString( "com.sun.star.awt.Toolkit" ) ), uno::UNO_QUERY );
[ # # ][ # # ]
1226 [ # # ]: 0 : if ( xToolkit.is() )
1227 : : {
1228 [ # # ]: 0 : uno::Reference< awt::XExtendedToolkit > xExtToolkit( xToolkit, uno::UNO_QUERY );
1229 [ # # ]: 0 : if ( xExtToolkit.is() )
1230 : : {
1231 [ # # ][ # # ]: 0 : uno::Reference< awt::XTopWindow > xTopWindow = xExtToolkit->getActiveTopWindow();
1232 [ # # ]: 0 : if ( xTopWindow.is() )
1233 : : {
1234 [ # # ]: 0 : uno::Reference< awt::XVclWindowPeer > xVclWindowPeer( xTopWindow, uno::UNO_QUERY );
1235 [ # # ]: 0 : if ( xVclWindowPeer.is() )
1236 : : {
1237 [ # # ][ # # ]: 0 : uno::Any aHCMode = xVclWindowPeer->getProperty( rtl::OUString( "HighContrastMode" ) );
1238 [ # # ][ # # ]: 0 : if ( ( aHCMode >>= bHighContrastMode ) && bHighContrastMode )
[ # # ]
1239 : 0 : aCSS = rtl::OUString( "highcontrastblack" );
1240 : 0 : }
1241 : 0 : }
1242 : 0 : }
1243 : 0 : }
1244 : : }
1245 : :
1246 [ # # ][ # # ]: 0 : while( error && retry )
[ # # ]
1247 : : {
1248 : :
1249 [ # # ]: 0 : if( retry == 2 )
1250 : : fileURL =
1251 : : getInstallPathAsURL() +
1252 : : processLang( Language ) +
1253 : : rtl::OUString( "/" ) +
1254 : : aCSS +
1255 [ # # ][ # # ]: 0 : rtl::OUString( ".css" );
1256 [ # # ]: 0 : else if( retry == 1 )
1257 : : fileURL =
1258 : : getInstallPathAsURL() +
1259 : : aCSS +
1260 [ # # ]: 0 : rtl::OUString( ".css" );
1261 : :
1262 : 0 : osl::DirectoryItem aDirItem;
1263 : 0 : osl::File aFile( fileURL );
1264 : 0 : osl::FileStatus aStatus( osl_FileStatus_Mask_FileSize );
1265 : :
1266 [ # # ][ # # ]: 0 : if( osl::FileBase::E_None == osl::DirectoryItem::get( fileURL,aDirItem ) &&
[ # # ][ # # ]
[ # # ]
1267 [ # # ]: 0 : osl::FileBase::E_None == aFile.open( osl_File_OpenFlag_Read ) &&
1268 [ # # ]: 0 : osl::FileBase::E_None == aDirItem.getFileStatus( aStatus ) )
1269 : : {
1270 : : sal_uInt64 nSize;
1271 [ # # ]: 0 : aFile.getSize( nSize );
1272 : 0 : m_nCustomCSSDocLength = (int)nSize;
1273 [ # # ]: 0 : m_pCustomCSSDoc = new char[ 1 + m_nCustomCSSDocLength ];
1274 : 0 : m_pCustomCSSDoc[ m_nCustomCSSDocLength ] = 0;
1275 : 0 : sal_uInt64 a = m_nCustomCSSDocLength,b = m_nCustomCSSDocLength;
1276 [ # # ]: 0 : aFile.read( m_pCustomCSSDoc,a,b );
1277 [ # # ]: 0 : aFile.close();
1278 : 0 : error = false;
1279 : : }
1280 : :
1281 : 0 : --retry;
1282 [ # # ][ # # ]: 0 : if ( !retry && error && bHighContrastMode )
[ # # ]
1283 : : {
1284 : : // fall back to default css
1285 : 0 : aCSS = rtl::OUString( "default" );
1286 : 0 : retry = 2;
1287 : 0 : bHighContrastMode = sal_False;
1288 : : }
1289 [ # # ][ # # ]: 0 : }
1290 : :
1291 [ # # ]: 0 : if( error )
1292 : : {
1293 : 0 : m_nCustomCSSDocLength = 0;
1294 [ # # ]: 0 : m_pCustomCSSDoc = new char[ 1 ]; // Initialize with 1 to avoid gcc compiler warning
1295 : 0 : }
1296 : : }
1297 : :
1298 : 0 : *byteCount = m_nCustomCSSDocLength;
1299 : 0 : *buffer = new char[ 1 + *byteCount ];
1300 : 0 : (*buffer)[*byteCount] = 0;
1301 : 0 : memcpy( *buffer,m_pCustomCSSDoc,m_nCustomCSSDocLength );
1302 : :
1303 : 0 : }
1304 : :
1305 : :
1306 : 386 : void Databases::setActiveText( const rtl::OUString& Module,
1307 : : const rtl::OUString& Language,
1308 : : const rtl::OUString& Id,
1309 : : char** buffer,
1310 : : int* byteCount )
1311 : : {
1312 [ + - ]: 386 : DataBaseIterator aDbIt( m_xContext, *this, Module, Language, true );
1313 : :
1314 : : // #i84550 Cache information about failed ids
1315 [ + - ]: 386 : rtl::OString id( Id.getStr(),Id.getLength(),RTL_TEXTENCODING_UTF8 );
1316 [ + - ]: 386 : EmptyActiveTextSet::iterator it = m_aEmptyActiveTextSet.find( id );
1317 [ + - ]: 386 : bool bFoundAsEmpty = ( it != m_aEmptyActiveTextSet.end() );
1318 [ + - ]: 386 : Dbt data;
1319 : 386 : DBData aDBData;
1320 : :
1321 : 386 : int nSize = 0;
1322 : 386 : const sal_Char* pData = NULL;
1323 : :
1324 : 386 : bool bSuccess = false;
1325 [ + + ]: 386 : if( !bFoundAsEmpty )
1326 : : {
1327 : : Db* db;
1328 [ + - ]: 106 : Dbt key( static_cast< void* >( const_cast< sal_Char* >( id.getStr() ) ),id.getLength() );
1329 [ + + ][ + - ]: 224 : while( !bSuccess && (db = aDbIt.nextDb()) != NULL )
[ + + ][ + + ]
1330 : : {
1331 : 118 : DBHelp* pDBHelp = db->getDBHelp();
1332 [ + - ]: 118 : if( pDBHelp != NULL )
1333 : : {
1334 [ + - ]: 118 : bSuccess = pDBHelp->getValueForKey( id, aDBData );
1335 : 118 : nSize = aDBData.getSize();
1336 : 118 : pData = aDBData.getData();
1337 : : }
1338 : : else
1339 : : {
1340 [ # # ]: 0 : int err = db->get( 0, &key, &data, 0 );
1341 [ # # ]: 0 : if( err == 0 )
1342 : : {
1343 : 0 : bSuccess = true;
1344 [ # # ]: 0 : nSize = data.get_size();
1345 [ # # ]: 0 : pData = static_cast<sal_Char*>( data.get_data() );
1346 : : }
1347 : : }
1348 [ + - ]: 106 : }
1349 : : }
1350 : :
1351 [ + + ]: 386 : if( bSuccess )
1352 : : {
1353 : : // ensure existence of tmp after for
1354 : 94 : rtl::OString tmp;
1355 [ + + ]: 8096 : for( int i = 0; i < nSize; ++i )
1356 [ + + ][ + + ]: 8012 : if( pData[i] == '%' || pData[i] == '$' )
1357 : : {
1358 : : // need of replacement
1359 [ + - ]: 10 : rtl::OUString temp = rtl::OUString( pData, nSize, RTL_TEXTENCODING_UTF8 );
1360 [ + - ]: 10 : replaceName( temp );
1361 : : tmp = rtl::OString( temp.getStr(),
1362 : : temp.getLength(),
1363 [ + - ]: 10 : RTL_TEXTENCODING_UTF8 );
1364 : 10 : nSize = tmp.getLength();
1365 : 10 : pData = tmp.getStr();
1366 : 10 : break;
1367 : : }
1368 : :
1369 : 94 : *byteCount = nSize;
1370 [ + - ]: 94 : *buffer = new char[ 1 + nSize ];
1371 : 94 : (*buffer)[nSize] = 0;
1372 : 94 : memcpy( *buffer, pData, nSize );
1373 : : }
1374 : : else
1375 : : {
1376 : 292 : *byteCount = 0;
1377 [ + - ]: 292 : *buffer = new char[1]; // Initialize with 1 to avoid compiler warnings
1378 [ + + ]: 292 : if( !bFoundAsEmpty )
1379 [ + - ]: 12 : m_aEmptyActiveTextSet.insert( id );
1380 [ + - ][ + - ]: 386 : }
1381 : 386 : }
1382 : :
1383 : :
1384 : 21 : void Databases::setInstallPath( const rtl::OUString& aInstDir )
1385 : : {
1386 [ + - ]: 21 : osl::MutexGuard aGuard( m_aMutex );
1387 : :
1388 [ + - ]: 21 : osl::FileBase::getFileURLFromSystemPath( aInstDir,m_aInstallDirectory );
1389 : : //TODO: check returned error code
1390 : :
1391 [ + - ]: 21 : if( m_aInstallDirectory.lastIndexOf( sal_Unicode( '/' ) ) != m_aInstallDirectory.getLength() - 1 )
1392 [ + - ]: 21 : m_aInstallDirectory += rtl::OUString( "/" );
1393 : 21 : }
1394 : :
1395 : :
1396 : : //===================================================================
1397 : : // class ExtensionIteratorBase
1398 : :
1399 [ + - ]: 21 : ExtensionHelpExistanceMap ExtensionIteratorBase::aHelpExistanceMap;
1400 : :
1401 : 386 : ExtensionIteratorBase::ExtensionIteratorBase( Reference< XComponentContext > xContext,
1402 : : Databases& rDatabases, const rtl::OUString& aInitialModule, const rtl::OUString& aLanguage )
1403 : : : m_xContext( xContext )
1404 : : , m_rDatabases( rDatabases )
1405 : : , m_eState( INITIAL_MODULE )
1406 : : , m_aInitialModule( aInitialModule )
1407 [ + - ][ + - ]: 386 : , m_aLanguage( aLanguage )
[ + - ]
1408 : : {
1409 [ + - ]: 386 : init();
1410 : 386 : }
1411 : :
1412 : 190 : ExtensionIteratorBase::ExtensionIteratorBase( Databases& rDatabases,
1413 : : const rtl::OUString& aInitialModule, const rtl::OUString& aLanguage )
1414 : : : m_rDatabases( rDatabases )
1415 : : , m_eState( INITIAL_MODULE )
1416 : : , m_aInitialModule( aInitialModule )
1417 [ + - ][ + - ]: 190 : , m_aLanguage( aLanguage )
[ + - ]
1418 : : {
1419 [ + - ]: 190 : init();
1420 : 190 : }
1421 : :
1422 : 576 : void ExtensionIteratorBase::init()
1423 : : {
1424 [ + + ]: 576 : if( !m_xContext.is() )
1425 : : {
1426 [ + - ]: 190 : Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
1427 [ + - ]: 190 : Reference< XPropertySet > xProps( xFactory, UNO_QUERY );
1428 : : OSL_ASSERT( xProps.is() );
1429 [ + - ]: 190 : if (xProps.is())
1430 : : {
1431 [ + - ]: 190 : xProps->getPropertyValue(
1432 [ + - ][ + - ]: 190 : ::rtl::OUString( "DefaultContext" ) ) >>= m_xContext;
1433 : : OSL_ASSERT( m_xContext.is() );
1434 : 190 : }
1435 : : }
1436 [ - + ]: 576 : if( !m_xContext.is() )
1437 : : {
1438 : : throw RuntimeException(
1439 : : ::rtl::OUString( "ExtensionIteratorBase::init(), no XComponentContext" ),
1440 [ # # ]: 0 : Reference< XInterface >() );
1441 : : }
1442 : :
1443 [ + - ]: 576 : m_xSFA = ucb::SimpleFileAccess::create(m_xContext);
1444 : :
1445 : 576 : m_bUserPackagesLoaded = false;
1446 : 576 : m_bSharedPackagesLoaded = false;
1447 : 576 : m_bBundledPackagesLoaded = false;
1448 : 576 : m_iUserPackage = 0;
1449 : 576 : m_iSharedPackage = 0;
1450 : 576 : m_iBundledPackage = 0;
1451 : 576 : }
1452 : :
1453 : 864 : Reference< deployment::XPackage > ExtensionIteratorBase::implGetHelpPackageFromPackage
1454 : : ( Reference< deployment::XPackage > xPackage, Reference< deployment::XPackage >& o_xParentPackageBundle )
1455 : : {
1456 : 864 : o_xParentPackageBundle.clear();
1457 : :
1458 : 864 : Reference< deployment::XPackage > xHelpPackage;
1459 [ + - ]: 864 : if( !xPackage.is() )
1460 : : return xHelpPackage;
1461 : :
1462 : : // #i84550 Cache information about help content in extension
1463 [ + - ][ + - ]: 864 : rtl::OUString aExtensionPath = xPackage->getURL();
1464 [ + - ]: 864 : ExtensionHelpExistanceMap::iterator it = aHelpExistanceMap.find( aExtensionPath );
1465 [ + - ]: 864 : bool bFound = ( it != aHelpExistanceMap.end() );
1466 [ + - ][ + + ]: 864 : bool bHasHelp = bFound ? it->second : false;
1467 [ + + ][ + + ]: 864 : if( bFound && !bHasHelp )
1468 : : return xHelpPackage;
1469 : :
1470 : : // Check if parent package is registered
1471 [ + - ]: 122 : beans::Optional< beans::Ambiguous<sal_Bool> > option( xPackage->isRegistered
1472 [ + - ]: 122 : ( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() ) );
1473 : 122 : bool bRegistered = false;
1474 [ + - ]: 122 : if( option.IsPresent )
1475 : : {
1476 : 122 : beans::Ambiguous<sal_Bool> const & reg = option.Value;
1477 [ + - ][ + - ]: 122 : if( !reg.IsAmbiguous && reg.Value )
1478 : 122 : bRegistered = true;
1479 : : }
1480 [ + - ]: 122 : if( bRegistered )
1481 : : {
1482 : 122 : rtl::OUString aHelpMediaType( "application/vnd.sun.star.help" );
1483 [ + - ][ + - ]: 122 : if( xPackage->isBundle() )
[ + - ]
1484 : : {
1485 [ + - ]: 122 : Sequence< Reference< deployment::XPackage > > aPkgSeq = xPackage->getBundle
1486 [ + - ]: 122 : ( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() );
1487 : 122 : sal_Int32 nPkgCount = aPkgSeq.getLength();
1488 : 122 : const Reference< deployment::XPackage >* pSeq = aPkgSeq.getConstArray();
1489 [ + + ]: 298 : for( sal_Int32 iPkg = 0 ; iPkg < nPkgCount ; ++iPkg )
1490 : : {
1491 : 176 : const Reference< deployment::XPackage > xSubPkg = pSeq[ iPkg ];
1492 [ + - ][ + - ]: 176 : const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = xSubPkg->getPackageType();
1493 [ + - ][ + - ]: 176 : rtl::OUString aMediaType = xPackageTypeInfo->getMediaType();
1494 [ + + ]: 176 : if( aMediaType.equals( aHelpMediaType ) )
1495 : : {
1496 [ + - ]: 108 : xHelpPackage = xSubPkg;
1497 [ + - ]: 176 : o_xParentPackageBundle = xPackage;
1498 : : break;
1499 : : }
1500 [ + + ][ + + ]: 298 : }
[ + + ][ + - ]
1501 : : }
1502 : : else
1503 : : {
1504 [ # # ][ # # ]: 0 : const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = xPackage->getPackageType();
1505 [ # # ][ # # ]: 0 : rtl::OUString aMediaType = xPackageTypeInfo->getMediaType();
1506 [ # # ]: 0 : if( aMediaType.equals( aHelpMediaType ) )
1507 [ # # ]: 0 : xHelpPackage = xPackage;
1508 : 122 : }
1509 : : }
1510 : :
1511 [ + + ]: 122 : if( !bFound )
1512 [ + - ]: 16 : aHelpExistanceMap[ aExtensionPath ] = xHelpPackage.is();
1513 : :
1514 : 864 : return xHelpPackage;
1515 : : }
1516 : :
1517 : 108 : Reference< deployment::XPackage > ExtensionIteratorBase::implGetNextUserHelpPackage
1518 : : ( Reference< deployment::XPackage >& o_xParentPackageBundle )
1519 : : {
1520 : 108 : Reference< deployment::XPackage > xHelpPackage;
1521 : :
1522 [ + - ]: 108 : if( !m_bUserPackagesLoaded )
1523 : : {
1524 [ + - ]: 108 : Reference< XExtensionManager > xExtensionManager = ExtensionManager::get(m_xContext);
1525 [ + - ]: 108 : m_aUserPackagesSeq = xExtensionManager->getDeployedExtensions
1526 [ + - ][ + - ]: 108 : ( rtl::OUString("user"), Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() );
[ + - ]
1527 : 108 : m_bUserPackagesLoaded = true;
1528 : : }
1529 : :
1530 [ + - ]: 108 : if( m_iUserPackage == m_aUserPackagesSeq.getLength() )
1531 : : {
1532 : 108 : m_eState = SHARED_EXTENSIONS; // Later: SHARED_MODULE
1533 : : }
1534 : : else
1535 : : {
1536 : 0 : const Reference< deployment::XPackage >* pUserPackages = m_aUserPackagesSeq.getConstArray();
1537 : 0 : Reference< deployment::XPackage > xPackage = pUserPackages[ m_iUserPackage++ ];
1538 : : OSL_ENSURE( xPackage.is(), "ExtensionIteratorBase::implGetNextUserHelpPackage(): Invalid package" );
1539 [ # # ][ # # ]: 0 : xHelpPackage = implGetHelpPackageFromPackage( xPackage, o_xParentPackageBundle );
1540 : : }
1541 : :
1542 : 108 : return xHelpPackage;
1543 : : }
1544 : :
1545 : 108 : Reference< deployment::XPackage > ExtensionIteratorBase::implGetNextSharedHelpPackage
1546 : : ( Reference< deployment::XPackage >& o_xParentPackageBundle )
1547 : : {
1548 : 108 : Reference< deployment::XPackage > xHelpPackage;
1549 : :
1550 [ + - ]: 108 : if( !m_bSharedPackagesLoaded )
1551 : : {
1552 [ + - ]: 108 : Reference< XExtensionManager > xExtensionManager = ExtensionManager::get(m_xContext);
1553 [ + - ]: 108 : m_aSharedPackagesSeq = xExtensionManager->getDeployedExtensions
1554 [ + - ][ + - ]: 108 : ( rtl::OUString("shared"), Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() );
[ + - ]
1555 : 108 : m_bSharedPackagesLoaded = true;
1556 : : }
1557 : :
1558 [ + - ]: 108 : if( m_iSharedPackage == m_aSharedPackagesSeq.getLength() )
1559 : : {
1560 : 108 : m_eState = BUNDLED_EXTENSIONS;
1561 : : }
1562 : : else
1563 : : {
1564 : 0 : const Reference< deployment::XPackage >* pSharedPackages = m_aSharedPackagesSeq.getConstArray();
1565 : 0 : Reference< deployment::XPackage > xPackage = pSharedPackages[ m_iSharedPackage++ ];
1566 : : OSL_ENSURE( xPackage.is(), "ExtensionIteratorBase::implGetNextSharedHelpPackage(): Invalid package" );
1567 [ # # ][ # # ]: 0 : xHelpPackage = implGetHelpPackageFromPackage( xPackage, o_xParentPackageBundle );
1568 : : }
1569 : :
1570 : 108 : return xHelpPackage;
1571 : : }
1572 : :
1573 : 972 : Reference< deployment::XPackage > ExtensionIteratorBase::implGetNextBundledHelpPackage
1574 : : ( Reference< deployment::XPackage >& o_xParentPackageBundle )
1575 : : {
1576 : 972 : Reference< deployment::XPackage > xHelpPackage;
1577 : :
1578 [ + + ]: 972 : if( !m_bBundledPackagesLoaded )
1579 : : {
1580 [ + - ]: 108 : Reference< XExtensionManager > xExtensionManager = ExtensionManager::get(m_xContext);
1581 [ + - ]: 108 : m_aBundledPackagesSeq = xExtensionManager->getDeployedExtensions
1582 [ + - ][ + - ]: 108 : ( rtl::OUString("bundled"), Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() );
[ + - ]
1583 : 108 : m_bBundledPackagesLoaded = true;
1584 : : }
1585 : :
1586 [ + + ]: 972 : if( m_iBundledPackage == m_aBundledPackagesSeq.getLength() )
1587 : : {
1588 : 108 : m_eState = END_REACHED;
1589 : : }
1590 : : else
1591 : : {
1592 : : const Reference< deployment::XPackage >* pBundledPackages =
1593 : 864 : m_aBundledPackagesSeq.getConstArray();
1594 : 864 : Reference< deployment::XPackage > xPackage = pBundledPackages[ m_iBundledPackage++ ];
1595 : : OSL_ENSURE( xPackage.is(), "ExtensionIteratorBase::implGetNextBundledHelpPackage(): Invalid package" );
1596 [ + - ][ + - ]: 864 : xHelpPackage = implGetHelpPackageFromPackage( xPackage, o_xParentPackageBundle );
1597 : : }
1598 : :
1599 : 972 : return xHelpPackage;
1600 : : }
1601 : :
1602 : 0 : rtl::OUString ExtensionIteratorBase::implGetFileFromPackage(
1603 : : const rtl::OUString& rFileExtension, Reference< deployment::XPackage > xPackage )
1604 : : {
1605 : : // No extension -> search for pure language folder
1606 : 0 : bool bLangFolderOnly = rFileExtension.isEmpty();
1607 : :
1608 : 0 : rtl::OUString aFile;
1609 : 0 : rtl::OUString aLanguage = m_aLanguage;
1610 [ # # ]: 0 : for( sal_Int32 iPass = 0 ; iPass < 2 ; ++iPass )
1611 : : {
1612 : 0 : rtl::OUStringBuffer aStrBuf;
1613 [ # # ][ # # ]: 0 : aStrBuf.append( xPackage->getRegistrationDataURL().Value);
[ # # ]
1614 [ # # ]: 0 : aStrBuf.append( '/' );
1615 [ # # ]: 0 : aStrBuf.append( aLanguage );
1616 [ # # ]: 0 : if( !bLangFolderOnly )
1617 : : {
1618 [ # # ]: 0 : aStrBuf.append( '/' );
1619 [ # # ]: 0 : aStrBuf.append( "help" );
1620 [ # # ]: 0 : aStrBuf.append( rFileExtension );
1621 : : }
1622 : :
1623 [ # # ][ # # ]: 0 : aFile = m_rDatabases.expandURL( aStrBuf.makeStringAndClear() );
1624 [ # # ]: 0 : if( iPass == 0 )
1625 : : {
1626 [ # # ][ # # ]: 0 : if( m_xSFA->exists( aFile ) )
[ # # ]
1627 : : break;
1628 : :
1629 [ # # ]: 0 : ::std::vector< ::rtl::OUString > av;
1630 [ # # ]: 0 : implGetLanguageVectorFromPackage( av, xPackage );
1631 [ # # # # ]: 0 : ::std::vector< ::rtl::OUString >::const_iterator pFound = av.end();
1632 : : try
1633 : : {
1634 [ # # ]: 0 : pFound = ::comphelper::Locale::getFallback( av, m_aLanguage );
1635 : : }
1636 [ # # ]: 0 : catch( ::comphelper::Locale::MalFormedLocaleException& )
1637 : : {}
1638 [ # # ][ # # ]: 0 : if( pFound != av.end() )
1639 : 0 : aLanguage = *pFound;
1640 : : }
1641 [ # # ]: 0 : }
1642 : 0 : return aFile;
1643 : : }
1644 : :
1645 : 0 : inline bool isLetter( sal_Unicode c )
1646 : : {
1647 : 0 : return comphelper::string::isalphaAscii(c);
1648 : : }
1649 : :
1650 : 0 : void ExtensionIteratorBase::implGetLanguageVectorFromPackage( ::std::vector< ::rtl::OUString > &rv,
1651 : : com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage )
1652 : : {
1653 : 0 : rv.clear();
1654 [ # # ][ # # ]: 0 : rtl::OUString aExtensionPath = xPackage->getURL();
1655 [ # # ][ # # ]: 0 : Sequence< rtl::OUString > aEntrySeq = m_xSFA->getFolderContents( aExtensionPath, true );
1656 : :
1657 : 0 : const rtl::OUString* pSeq = aEntrySeq.getConstArray();
1658 : 0 : sal_Int32 nCount = aEntrySeq.getLength();
1659 [ # # ]: 0 : for( sal_Int32 i = 0 ; i < nCount ; ++i )
1660 : : {
1661 : 0 : rtl::OUString aEntry = pSeq[i];
1662 [ # # ][ # # ]: 0 : if( m_xSFA->isFolder( aEntry ) )
[ # # ]
1663 : : {
1664 : 0 : sal_Int32 nLastSlash = aEntry.lastIndexOf( '/' );
1665 [ # # ]: 0 : if( nLastSlash != -1 )
1666 : : {
1667 : 0 : rtl::OUString aPureEntry = aEntry.copy( nLastSlash + 1 );
1668 : :
1669 : : // Check language scheme
1670 : 0 : int nLen = aPureEntry.getLength();
1671 : 0 : const sal_Unicode* pc = aPureEntry.getStr();
1672 [ # # ][ # # ]: 0 : bool bStartCanBeLanguage = ( nLen >= 2 && isLetter( pc[0] ) && isLetter( pc[1] ) );
[ # # ][ # # ]
[ # # ]
1673 : : bool bIsLanguage = bStartCanBeLanguage &&
1674 [ # # ][ # # ]: 0 : ( nLen == 2 || (nLen == 5 && pc[2] == '-' && isLetter( pc[3] ) && isLetter( pc[4] )) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
1675 [ # # ]: 0 : if( bIsLanguage )
1676 [ # # ]: 0 : rv.push_back( aPureEntry );
1677 : : }
1678 : : }
1679 [ # # ]: 0 : }
1680 : 0 : }
1681 : :
1682 : :
1683 : : //===================================================================
1684 : : // class DataBaseIterator
1685 : :
1686 : 512 : Db* DataBaseIterator::nextDb( rtl::OUString* o_pExtensionPath, rtl::OUString* o_pExtensionRegistryPath )
1687 : : {
1688 : 512 : Db* pRetDb = NULL;
1689 : :
1690 [ + + ][ + + ]: 1996 : while( !pRetDb && m_eState != END_REACHED )
[ + + ]
1691 : : {
1692 [ + + + + : 1484 : switch( m_eState )
- - ]
1693 : : {
1694 : : case INITIAL_MODULE:
1695 : 296 : pRetDb = m_rDatabases.getBerkeley( m_aInitialModule, m_aLanguage, m_bHelpText );
1696 : 296 : m_eState = USER_EXTENSIONS; // Later: SHARED_MODULE
1697 : 296 : break;
1698 : :
1699 : : // Later:
1700 : : //case SHARED_MODULE
1701 : : //...
1702 : :
1703 : : case USER_EXTENSIONS:
1704 : : {
1705 : 108 : Reference< deployment::XPackage > xParentPackageBundle;
1706 [ + - ]: 108 : Reference< deployment::XPackage > xHelpPackage = implGetNextUserHelpPackage( xParentPackageBundle );
1707 [ - + ]: 108 : if( !xHelpPackage.is() )
1708 : : break;
1709 [ # # ]: 0 : pRetDb = implGetDbFromPackage( xHelpPackage, o_pExtensionPath, o_pExtensionRegistryPath );
1710 : 108 : break;
1711 : : }
1712 : :
1713 : : case SHARED_EXTENSIONS:
1714 : : {
1715 : 108 : Reference< deployment::XPackage > xParentPackageBundle;
1716 [ + - ]: 108 : Reference< deployment::XPackage > xHelpPackage = implGetNextSharedHelpPackage( xParentPackageBundle );
1717 [ - + ]: 108 : if( !xHelpPackage.is() )
1718 : : break;
1719 : :
1720 [ # # ]: 0 : pRetDb = implGetDbFromPackage( xHelpPackage, o_pExtensionPath, o_pExtensionRegistryPath );
1721 : 108 : break;
1722 : : }
1723 : :
1724 : : case BUNDLED_EXTENSIONS:
1725 : : {
1726 : 972 : Reference< deployment::XPackage > xParentPackageBundle;
1727 [ + - ]: 972 : Reference< deployment::XPackage > xHelpPackage = implGetNextBundledHelpPackage( xParentPackageBundle );
1728 [ + + ]: 972 : if( !xHelpPackage.is() )
1729 : : break;
1730 : :
1731 [ + - ]: 108 : pRetDb = implGetDbFromPackage( xHelpPackage, o_pExtensionPath, o_pExtensionRegistryPath );
1732 : 972 : break;
1733 : : }
1734 : :
1735 : : case END_REACHED:
1736 : : OSL_FAIL( "DataBaseIterator::nextDb(): Invalid case END_REACHED" );
1737 : 0 : break;
1738 : : }
1739 : : }
1740 : :
1741 : 512 : return pRetDb;
1742 : : }
1743 : :
1744 : 108 : Db* DataBaseIterator::implGetDbFromPackage( Reference< deployment::XPackage > xPackage,
1745 : : rtl::OUString* o_pExtensionPath, rtl::OUString* o_pExtensionRegistryPath )
1746 : : {
1747 : :
1748 : 108 : beans::Optional< ::rtl::OUString> optRegData;
1749 : : try
1750 : : {
1751 [ + - ][ + - ]: 108 : optRegData = xPackage->getRegistrationDataURL();
1752 : : }
1753 [ # # ]: 0 : catch ( deployment::ExtensionRemovedException&)
1754 : : {
1755 : 0 : return NULL;
1756 : : }
1757 : :
1758 : 108 : Db* pRetDb = NULL;
1759 [ + - ][ + - ]: 108 : if (optRegData.IsPresent && !optRegData.Value.isEmpty())
[ + - ]
1760 : : {
1761 [ + - ][ + - ]: 108 : rtl::OUString aRegDataUrl = rtl::OUStringBuffer(optRegData.Value).append('/').makeStringAndClear();
[ + - ]
1762 : :
1763 : 108 : rtl::OUString aHelpFilesBaseName("help");
1764 : :
1765 : 108 : rtl::OUString aUsedLanguage = m_aLanguage;
1766 : : pRetDb = m_rDatabases.getBerkeley(
1767 [ + - ]: 108 : aHelpFilesBaseName, aUsedLanguage, m_bHelpText, &aRegDataUrl);
1768 : :
1769 : : // Language fallback
1770 [ - + ]: 108 : if( !pRetDb )
1771 : : {
1772 [ # # ]: 0 : ::std::vector< ::rtl::OUString > av;
1773 [ # # ]: 0 : implGetLanguageVectorFromPackage( av, xPackage );
1774 [ # # # # ]: 0 : ::std::vector< ::rtl::OUString >::const_iterator pFound = av.end();
1775 : : try
1776 : : {
1777 [ # # ]: 0 : pFound = ::comphelper::Locale::getFallback( av, m_aLanguage );
1778 : : }
1779 [ # # ]: 0 : catch( ::comphelper::Locale::MalFormedLocaleException& )
1780 : : {}
1781 [ # # ][ # # ]: 0 : if( pFound != av.end() )
1782 : : {
1783 : 0 : aUsedLanguage = *pFound;
1784 : : pRetDb = m_rDatabases.getBerkeley(
1785 [ # # ]: 0 : aHelpFilesBaseName, aUsedLanguage, m_bHelpText, &aRegDataUrl);
1786 : 0 : }
1787 : : }
1788 : :
1789 [ + + ]: 108 : if( o_pExtensionPath )
1790 : 96 : *o_pExtensionPath = aRegDataUrl + aUsedLanguage;
1791 : :
1792 [ + + ]: 108 : if( o_pExtensionRegistryPath )
1793 [ + - ][ + - ]: 108 : *o_pExtensionRegistryPath = rtl::OUStringBuffer(xPackage->getURL()).append('/').append(aUsedLanguage).makeStringAndClear();
[ + - ][ + - ]
[ + - ][ + - ]
1794 : : }
1795 : :
1796 [ # # ]: 108 : return pRetDb;
1797 : : }
1798 : :
1799 : :
1800 : : //===================================================================
1801 : : // class KeyDataBaseFileIterator
1802 : :
1803 : : //returns a file URL
1804 : 0 : rtl::OUString KeyDataBaseFileIterator::nextDbFile( bool& o_rbExtension )
1805 : : {
1806 : 0 : rtl::OUString aRetFile;
1807 : :
1808 [ # # ][ # # ]: 0 : while( aRetFile.isEmpty() && m_eState != END_REACHED )
[ # # ]
1809 : : {
1810 [ # # # # : 0 : switch( m_eState )
# # ]
1811 : : {
1812 : : case INITIAL_MODULE:
1813 : : aRetFile = rtl::OUStringBuffer(m_rDatabases.getInstallPathAsURL()).
1814 [ # # ][ # # ]: 0 : append(m_rDatabases.processLang(m_aLanguage)).append('/').
[ # # ][ # # ]
[ # # ]
1815 [ # # ][ # # ]: 0 : append(m_aInitialModule).append(".key").makeStringAndClear();
[ # # ]
1816 : :
1817 : 0 : o_rbExtension = false;
1818 : :
1819 : 0 : m_eState = USER_EXTENSIONS; // Later: SHARED_MODULE
1820 : 0 : break;
1821 : :
1822 : : // Later:
1823 : : //case SHARED_MODULE
1824 : : //...
1825 : :
1826 : : case USER_EXTENSIONS:
1827 : : {
1828 : 0 : Reference< deployment::XPackage > xParentPackageBundle;
1829 [ # # ]: 0 : Reference< deployment::XPackage > xHelpPackage = implGetNextUserHelpPackage( xParentPackageBundle );
1830 [ # # ]: 0 : if( !xHelpPackage.is() )
1831 : : break;
1832 : :
1833 [ # # ]: 0 : aRetFile = implGetDbFileFromPackage( xHelpPackage );
1834 : 0 : o_rbExtension = true;
1835 : 0 : break;
1836 : : }
1837 : :
1838 : : case SHARED_EXTENSIONS:
1839 : : {
1840 : 0 : Reference< deployment::XPackage > xParentPackageBundle;
1841 [ # # ]: 0 : Reference< deployment::XPackage > xHelpPackage = implGetNextSharedHelpPackage( xParentPackageBundle );
1842 [ # # ]: 0 : if( !xHelpPackage.is() )
1843 : : break;
1844 : :
1845 [ # # ]: 0 : aRetFile = implGetDbFileFromPackage( xHelpPackage );
1846 : 0 : o_rbExtension = true;
1847 : 0 : break;
1848 : : }
1849 : :
1850 : : case BUNDLED_EXTENSIONS:
1851 : : {
1852 : 0 : Reference< deployment::XPackage > xParentPackageBundle;
1853 [ # # ]: 0 : Reference< deployment::XPackage > xHelpPackage = implGetNextBundledHelpPackage( xParentPackageBundle );
1854 [ # # ]: 0 : if( !xHelpPackage.is() )
1855 : : break;
1856 : :
1857 [ # # ]: 0 : aRetFile = implGetDbFileFromPackage( xHelpPackage );
1858 : 0 : o_rbExtension = true;
1859 : 0 : break;
1860 : : }
1861 : :
1862 : : case END_REACHED:
1863 : : OSL_FAIL( "DataBaseIterator::nextDbFile(): Invalid case END_REACHED" );
1864 : 0 : break;
1865 : : }
1866 : : }
1867 : :
1868 : 0 : return aRetFile;
1869 : : }
1870 : :
1871 : : //Returns a file URL, that does not contain macros
1872 : 0 : rtl::OUString KeyDataBaseFileIterator::implGetDbFileFromPackage
1873 : : ( Reference< deployment::XPackage > xPackage )
1874 : : {
1875 : : rtl::OUString aExpandedURL =
1876 [ # # ]: 0 : implGetFileFromPackage( rtl::OUString( ".key" ), xPackage );
1877 : :
1878 : 0 : return aExpandedURL;
1879 : : }
1880 : :
1881 : :
1882 : : //===================================================================
1883 : : // class JarFileIterator
1884 : :
1885 : 0 : Reference< XHierarchicalNameAccess > JarFileIterator::nextJarFile
1886 : : ( Reference< deployment::XPackage >& o_xParentPackageBundle,
1887 : : rtl::OUString* o_pExtensionPath, rtl::OUString* o_pExtensionRegistryPath )
1888 : : {
1889 : 0 : Reference< XHierarchicalNameAccess > xNA;
1890 : :
1891 [ # # ][ # # ]: 0 : while( !xNA.is() && m_eState != END_REACHED )
[ # # ]
1892 : : {
1893 [ # # # # : 0 : switch( m_eState )
# # ]
1894 : : {
1895 : : case INITIAL_MODULE:
1896 [ # # ][ # # ]: 0 : xNA = m_rDatabases.jarFile( m_aInitialModule, m_aLanguage );
1897 : 0 : m_eState = USER_EXTENSIONS; // Later: SHARED_MODULE
1898 : 0 : break;
1899 : :
1900 : : // Later:
1901 : : //case SHARED_MODULE
1902 : : //...
1903 : :
1904 : : case USER_EXTENSIONS:
1905 : : {
1906 [ # # ]: 0 : Reference< deployment::XPackage > xHelpPackage = implGetNextUserHelpPackage( o_xParentPackageBundle );
1907 [ # # ]: 0 : if( !xHelpPackage.is() )
1908 : : break;
1909 : :
1910 [ # # ][ # # ]: 0 : xNA = implGetJarFromPackage( xHelpPackage, o_pExtensionPath, o_pExtensionRegistryPath );
1911 : 0 : break;
1912 : : }
1913 : :
1914 : : case SHARED_EXTENSIONS:
1915 : : {
1916 [ # # ]: 0 : Reference< deployment::XPackage > xHelpPackage = implGetNextSharedHelpPackage( o_xParentPackageBundle );
1917 [ # # ]: 0 : if( !xHelpPackage.is() )
1918 : : break;
1919 : :
1920 [ # # ][ # # ]: 0 : xNA = implGetJarFromPackage( xHelpPackage, o_pExtensionPath, o_pExtensionRegistryPath );
1921 : 0 : break;
1922 : : }
1923 : :
1924 : : case BUNDLED_EXTENSIONS:
1925 : : {
1926 [ # # ]: 0 : Reference< deployment::XPackage > xHelpPackage = implGetNextBundledHelpPackage( o_xParentPackageBundle );
1927 [ # # ]: 0 : if( !xHelpPackage.is() )
1928 : : break;
1929 : :
1930 [ # # ][ # # ]: 0 : xNA = implGetJarFromPackage( xHelpPackage, o_pExtensionPath, o_pExtensionRegistryPath );
1931 : 0 : break;
1932 : : }
1933 : :
1934 : : case END_REACHED:
1935 : : OSL_FAIL( "JarFileIterator::nextJarFile(): Invalid case END_REACHED" );
1936 : 0 : break;
1937 : : }
1938 : : }
1939 : :
1940 : 0 : return xNA;
1941 : : }
1942 : :
1943 : 0 : Reference< XHierarchicalNameAccess > JarFileIterator::implGetJarFromPackage
1944 : : ( Reference< deployment::XPackage > xPackage, rtl::OUString* o_pExtensionPath, rtl::OUString* o_pExtensionRegistryPath )
1945 : : {
1946 : 0 : Reference< XHierarchicalNameAccess > xNA;
1947 : :
1948 : : rtl::OUString zipFile =
1949 [ # # ]: 0 : implGetFileFromPackage( rtl::OUString( ".jar" ), xPackage );
1950 : :
1951 : : try
1952 : : {
1953 [ # # ]: 0 : Sequence< Any > aArguments( 2 );
1954 [ # # ][ # # ]: 0 : aArguments[ 0 ] <<= zipFile;
1955 : :
1956 : : // let ZipPackage be used ( no manifest.xml is required )
1957 : 0 : beans::NamedValue aArg;
1958 : 0 : aArg.Name = ::rtl::OUString( "StorageFormat" );
1959 [ # # ][ # # ]: 0 : aArg.Value <<= ZIP_STORAGE_FORMAT_STRING;
1960 [ # # ][ # # ]: 0 : aArguments[ 1 ] <<= aArg;
1961 : :
1962 [ # # ][ # # ]: 0 : Reference< XMultiComponentFactory >xSMgr( m_xContext->getServiceManager(), UNO_QUERY );
[ # # ]
1963 : : Reference< XInterface > xIfc
1964 [ # # ]: 0 : = xSMgr->createInstanceWithArgumentsAndContext(
1965 : : rtl::OUString(
1966 : : "com.sun.star.packages.comp.ZipPackage" ),
1967 [ # # ]: 0 : aArguments, m_xContext );
1968 : :
1969 [ # # ]: 0 : if ( xIfc.is() )
1970 : : {
1971 [ # # ][ # # ]: 0 : xNA = Reference< XHierarchicalNameAccess >( xIfc, UNO_QUERY );
1972 : :
1973 : : OSL_ENSURE( xNA.is(),
1974 : : "JarFileIterator::implGetJarFromPackage() - "
1975 : : "Got no hierarchical name access!" );
1976 [ # # ]: 0 : }
[ # # # ]
1977 : : }
1978 [ # # ]: 0 : catch ( RuntimeException & )
1979 : : {}
1980 [ # # ]: 0 : catch ( Exception & )
1981 : : {}
1982 : :
1983 [ # # ][ # # ]: 0 : if( xNA.is() && o_pExtensionPath != NULL )
[ # # ]
1984 : : {
1985 : : // Extract path including language from file name
1986 : 0 : sal_Int32 nLastSlash = zipFile.lastIndexOf( '/' );
1987 [ # # ]: 0 : if( nLastSlash != -1 )
1988 : 0 : *o_pExtensionPath = zipFile.copy( 0, nLastSlash );
1989 : :
1990 [ # # ]: 0 : if( o_pExtensionRegistryPath != NULL )
1991 : : {
1992 : 0 : rtl::OUString& rPath = *o_pExtensionPath;
1993 : 0 : sal_Int32 nLastSlashInPath = rPath.lastIndexOf( '/', rPath.getLength() - 1 );
1994 : :
1995 [ # # ][ # # ]: 0 : *o_pExtensionRegistryPath = xPackage->getURL();
1996 : 0 : *o_pExtensionRegistryPath += rPath.copy( nLastSlashInPath);
1997 : : }
1998 : : }
1999 : :
2000 : 0 : return xNA;
2001 : : }
2002 : :
2003 : :
2004 : : //===================================================================
2005 : : // class IndexFolderIterator
2006 : :
2007 : 0 : rtl::OUString IndexFolderIterator::nextIndexFolder( bool& o_rbExtension, bool& o_rbTemporary )
2008 : : {
2009 : 0 : rtl::OUString aIndexFolder;
2010 : :
2011 [ # # ][ # # ]: 0 : while( aIndexFolder.isEmpty() && m_eState != END_REACHED )
[ # # ]
2012 : : {
2013 [ # # # # : 0 : switch( m_eState )
# # ]
2014 : : {
2015 : : case INITIAL_MODULE:
2016 : : aIndexFolder = rtl::OUStringBuffer(m_rDatabases.getInstallPathAsURL()).
2017 [ # # ][ # # ]: 0 : append(m_rDatabases.processLang(m_aLanguage)).append('/').
[ # # ][ # # ]
[ # # ]
2018 [ # # ][ # # ]: 0 : append(m_aInitialModule).append(".idxl").makeStringAndClear();
[ # # ]
2019 : :
2020 : 0 : o_rbTemporary = false;
2021 : 0 : o_rbExtension = false;
2022 : :
2023 : 0 : m_eState = USER_EXTENSIONS; // Later: SHARED_MODULE
2024 : 0 : break;
2025 : :
2026 : : // Later:
2027 : : //case SHARED_MODULE
2028 : : //...
2029 : :
2030 : : case USER_EXTENSIONS:
2031 : : {
2032 : 0 : Reference< deployment::XPackage > xParentPackageBundle;
2033 [ # # ]: 0 : Reference< deployment::XPackage > xHelpPackage = implGetNextUserHelpPackage( xParentPackageBundle );
2034 [ # # ]: 0 : if( !xHelpPackage.is() )
2035 : : break;
2036 : :
2037 [ # # ]: 0 : aIndexFolder = implGetIndexFolderFromPackage( o_rbTemporary, xHelpPackage );
2038 : 0 : o_rbExtension = true;
2039 : 0 : break;
2040 : : }
2041 : :
2042 : : case SHARED_EXTENSIONS:
2043 : : {
2044 : 0 : Reference< deployment::XPackage > xParentPackageBundle;
2045 [ # # ]: 0 : Reference< deployment::XPackage > xHelpPackage = implGetNextSharedHelpPackage( xParentPackageBundle );
2046 [ # # ]: 0 : if( !xHelpPackage.is() )
2047 : : break;
2048 : :
2049 [ # # ]: 0 : aIndexFolder = implGetIndexFolderFromPackage( o_rbTemporary, xHelpPackage );
2050 : 0 : o_rbExtension = true;
2051 : 0 : break;
2052 : : }
2053 : :
2054 : : case BUNDLED_EXTENSIONS:
2055 : : {
2056 : 0 : Reference< deployment::XPackage > xParentPackageBundle;
2057 [ # # ]: 0 : Reference< deployment::XPackage > xHelpPackage = implGetNextBundledHelpPackage( xParentPackageBundle );
2058 [ # # ]: 0 : if( !xHelpPackage.is() )
2059 : : break;
2060 : :
2061 [ # # ]: 0 : aIndexFolder = implGetIndexFolderFromPackage( o_rbTemporary, xHelpPackage );
2062 : 0 : o_rbExtension = true;
2063 : 0 : break;
2064 : : }
2065 : :
2066 : : case END_REACHED:
2067 : : OSL_FAIL( "IndexFolderIterator::nextIndexFolder(): Invalid case END_REACHED" );
2068 : 0 : break;
2069 : : }
2070 : : }
2071 : :
2072 : 0 : return aIndexFolder;
2073 : : }
2074 : :
2075 : 0 : rtl::OUString IndexFolderIterator::implGetIndexFolderFromPackage( bool& o_rbTemporary, Reference< deployment::XPackage > xPackage )
2076 : : {
2077 : : rtl::OUString aIndexFolder =
2078 [ # # ]: 0 : implGetFileFromPackage( rtl::OUString( ".idxl" ), xPackage );
2079 : :
2080 : 0 : o_rbTemporary = false;
2081 [ # # ][ # # ]: 0 : if( !m_xSFA->isFolder( aIndexFolder ) )
[ # # ]
2082 : : {
2083 : : // i98680: Missing index? Try to generate now
2084 [ # # ]: 0 : rtl::OUString aLangURL = implGetFileFromPackage( rtl::OUString(), xPackage );
2085 [ # # ][ # # ]: 0 : if( m_xSFA->isFolder( aLangURL ) )
[ # # ]
2086 : : {
2087 : : // Test write access (shared extension may be read only)
2088 : 0 : bool bIsWriteAccess = false;
2089 : : try
2090 : : {
2091 : 0 : rtl::OUString aCreateTestFolder = aLangURL + rtl::OUString( "CreateTestFolder" );
2092 [ # # ][ # # ]: 0 : m_xSFA->createFolder( aCreateTestFolder );
2093 [ # # ][ # # ]: 0 : if( m_xSFA->isFolder( aCreateTestFolder ) )
[ # # ]
2094 : 0 : bIsWriteAccess = true;
2095 : :
2096 [ # # ][ # # ]: 0 : m_xSFA->kill( aCreateTestFolder );
[ # # ]
2097 : : }
2098 [ # # # # ]: 0 : catch (const Exception &)
2099 : : {
2100 : : }
2101 : :
2102 : : // TEST
2103 : : //bIsWriteAccess = false;
2104 : :
2105 : : try
2106 : : {
2107 : 0 : rtl::OUString aLang;
2108 : 0 : sal_Int32 nLastSlash = aLangURL.lastIndexOf( '/' );
2109 [ # # ]: 0 : if( nLastSlash != -1 )
2110 : 0 : aLang = aLangURL.copy( nLastSlash + 1 );
2111 : : else
2112 : 0 : aLang = rtl::OUString( "en" );
2113 : :
2114 : 0 : rtl::OUString aMod("help");
2115 : :
2116 : 0 : rtl::OUString aZipDir = aLangURL;
2117 [ # # ]: 0 : if( !bIsWriteAccess )
2118 : : {
2119 : 0 : rtl::OUString aTempFileURL;
2120 [ # # ]: 0 : ::osl::FileBase::RC eErr = ::osl::File::createTempFile( 0, 0, &aTempFileURL );
2121 [ # # ]: 0 : if( eErr == ::osl::FileBase::E_None )
2122 : : {
2123 : 0 : rtl::OUString aTempDirURL = aTempFileURL;
2124 : : try
2125 : : {
2126 [ # # ][ # # ]: 0 : m_xSFA->kill( aTempDirURL );
2127 : : }
2128 [ # # ]: 0 : catch (const Exception &)
2129 : : {
2130 : : }
2131 [ # # ][ # # ]: 0 : m_xSFA->createFolder( aTempDirURL );
2132 : :
2133 : 0 : aZipDir = aTempDirURL;
2134 : 0 : o_rbTemporary = true;
2135 : 0 : }
2136 : : }
2137 : :
2138 [ # # ]: 0 : HelpIndexer aIndexer(aLang, aMod, aLangURL, aZipDir);
2139 [ # # ]: 0 : aIndexer.indexDocuments();
2140 : :
2141 [ # # ]: 0 : if( bIsWriteAccess )
2142 [ # # ]: 0 : aIndexFolder = implGetFileFromPackage( rtl::OUString( ".idxl" ), xPackage );
2143 : : else
2144 [ # # ][ # # ]: 0 : aIndexFolder = aZipDir + rtl::OUString( "/help.idxl" );
2145 : : }
2146 [ # # ]: 0 : catch (const Exception &)
2147 : : {
2148 : : }
2149 : 0 : }
2150 : : }
2151 : :
2152 : 0 : return aIndexFolder;
2153 : : }
2154 : :
2155 : 0 : void IndexFolderIterator::deleteTempIndexFolder( const rtl::OUString& aIndexFolder )
2156 : : {
2157 : 0 : sal_Int32 nLastSlash = aIndexFolder.lastIndexOf( '/' );
2158 [ # # ]: 0 : if( nLastSlash != -1 )
2159 : : {
2160 : 0 : rtl::OUString aTmpFolder = aIndexFolder.copy( 0, nLastSlash );
2161 : : try
2162 : : {
2163 [ # # ][ # # ]: 0 : m_xSFA->kill( aTmpFolder );
2164 : : }
2165 [ # # ]: 0 : catch (const Exception &)
2166 : : {
2167 : 0 : }
2168 : : }
2169 [ + - ][ + - ]: 63 : }
[ # # ]
2170 : :
2171 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|