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 : :
30 : : #include "dp_help.hrc"
31 : : #include "dp_backend.h"
32 : : #include "dp_helpbackenddb.hxx"
33 : : #include "dp_ucb.h"
34 : : #include "rtl/uri.hxx"
35 : : #include "osl/file.hxx"
36 : : #include "rtl/bootstrap.hxx"
37 : : #include "ucbhelper/content.hxx"
38 : : #include "comphelper/servicedecl.hxx"
39 : : #include "svl/inettype.hxx"
40 : : #include "svtools/javainteractionhandler.hxx"
41 : : #include "uno/current_context.hxx"
42 : : #include "unotools/pathoptions.hxx"
43 : :
44 : : #if !defined(ANDROID) && !defined(IOS)
45 : : #include <l10ntools/compilehelp.hxx>
46 : : #include <l10ntools/HelpIndexer.hxx>
47 : : #endif
48 : : #include <com/sun/star/ucb/SimpleFileAccess.hpp>
49 : : #include <com/sun/star/ucb/XSimpleFileAccess2.hpp>
50 : : #include <com/sun/star/util/XMacroExpander.hpp>
51 : : #include <com/sun/star/uri/XUriReferenceFactory.hpp>
52 : : #include <com/sun/star/uri/XVndSunStarExpandUrl.hpp>
53 : : #include <com/sun/star/script/XInvocation.hpp>
54 : : #include "boost/optional.hpp"
55 : :
56 : : using namespace ::dp_misc;
57 : : using namespace ::com::sun::star;
58 : : using namespace ::com::sun::star::uno;
59 : : using namespace ::com::sun::star::ucb;
60 : : using ::rtl::OUString;
61 : :
62 : : namespace dp_registry {
63 : : namespace backend {
64 : : namespace help {
65 : : namespace {
66 : :
67 : : //==============================================================================
68 [ + - ][ + - ]: 380 : class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend
[ - + ]
69 : : {
70 [ - + ]: 248 : class PackageImpl : public ::dp_registry::backend::Package
71 : : {
72 : : BackendImpl * getMyBackend() const;
73 : :
74 : : // Package
75 : : virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
76 : : ::osl::ResettableMutexGuard & guard,
77 : : ::rtl::Reference<AbortChannel> const & abortChannel,
78 : : Reference<XCommandEnvironment> const & xCmdEnv );
79 : : virtual void processPackage_(
80 : : ::osl::ResettableMutexGuard & guard,
81 : : bool registerPackage,
82 : : bool startup,
83 : : ::rtl::Reference<AbortChannel> const & abortChannel,
84 : : Reference<XCommandEnvironment> const & xCmdEnv );
85 : :
86 : :
87 : : public:
88 : : PackageImpl(
89 : : ::rtl::Reference<PackageRegistryBackend> const & myBackend,
90 : : OUString const & url, OUString const & name,
91 : : Reference<deployment::XPackageTypeInfo> const & xPackageType,
92 : : bool bRemoved, OUString const & identifier);
93 : :
94 : : bool extensionContainsCompiledHelp();
95 : :
96 : : //XPackage
97 : : virtual css::beans::Optional< ::rtl::OUString > SAL_CALL getRegistrationDataURL()
98 : : throw (deployment::ExtensionRemovedException, css::uno::RuntimeException);
99 : : };
100 : : friend class PackageImpl;
101 : :
102 : : // PackageRegistryBackend
103 : : virtual Reference<deployment::XPackage> bindPackage_(
104 : : OUString const & url, OUString const & mediaType,
105 : : sal_Bool bRemoved, OUString const & identifier,
106 : : Reference<XCommandEnvironment> const & xCmdEnv );
107 : :
108 : : void implProcessHelp( PackageImpl * package, bool doRegisterPackage,
109 : : Reference<ucb::XCommandEnvironment> const & xCmdEnv);
110 : : void implCollectXhpFiles( const rtl::OUString& aDir,
111 : : std::vector< rtl::OUString >& o_rXhpFileVector );
112 : :
113 : : void addDataToDb(OUString const & url, HelpBackendDb::Data const & data);
114 : : ::boost::optional<HelpBackendDb::Data> readDataFromDb(OUString const & url);
115 : : bool hasActiveEntry(OUString const & url);
116 : : void revokeEntryFromDb(OUString const & url);
117 : : bool activateEntry(OUString const & url);
118 : :
119 : : Reference< ucb::XSimpleFileAccess2 > getFileAccess( void );
120 : : Reference< ucb::XSimpleFileAccess2 > m_xSFA;
121 : :
122 : : const Reference<deployment::XPackageTypeInfo> m_xHelpTypeInfo;
123 : : Sequence< Reference<deployment::XPackageTypeInfo> > m_typeInfos;
124 : : std::auto_ptr<HelpBackendDb> m_backendDb;
125 : :
126 : : public:
127 : : BackendImpl( Sequence<Any> const & args,
128 : : Reference<XComponentContext> const & xComponentContext );
129 : :
130 : : // XPackageRegistry
131 : : virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
132 : : getSupportedPackageTypes() throw (RuntimeException);
133 : : virtual void SAL_CALL packageRemoved(OUString const & url, OUString const & mediaType)
134 : : throw (deployment::DeploymentException,
135 : : uno::RuntimeException);
136 : :
137 : : };
138 : :
139 : : //______________________________________________________________________________
140 : 380 : BackendImpl::BackendImpl(
141 : : Sequence<Any> const & args,
142 : : Reference<XComponentContext> const & xComponentContext )
143 : : : PackageRegistryBackend( args, xComponentContext ),
144 : : m_xHelpTypeInfo( new Package::TypeInfo(
145 : : OUSTR("application/vnd.sun.star.help"),
146 : : rtl::OUString(),
147 : : getResourceString(RID_STR_HELP),
148 [ + - ]: 380 : RID_IMG_HELP ) ),
149 [ + - ][ + - ]: 760 : m_typeInfos( 1 )
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
150 : : {
151 [ + - ][ + - ]: 380 : m_typeInfos[ 0 ] = m_xHelpTypeInfo;
152 [ + - ]: 380 : if (!transientMode())
153 : : {
154 [ + - ][ + - ]: 380 : OUString dbFile = makeURL(getCachePath(), OUSTR("backenddb.xml"));
155 : : m_backendDb.reset(
156 [ + - ][ + - ]: 380 : new HelpBackendDb(getComponentContext(), dbFile));
157 : :
158 : : //clean up data folders which are no longer used.
159 : : //This must not be done in the same process where the help files
160 : : //are still registers. Only after revoking and restarting OOo the folders
161 : : //can be removed. This works now, because the extension manager is a singleton
162 : : //and the backends are only create once per process.
163 [ + - ]: 380 : ::std::list<OUString> folders = m_backendDb->getAllDataUrls();
164 [ + - ]: 380 : deleteUnusedFolders(OUString(), folders);
165 : : }
166 : 380 : }
167 : :
168 : : // XPackageRegistry
169 : : //______________________________________________________________________________
170 : : Sequence< Reference<deployment::XPackageTypeInfo> >
171 : 380 : BackendImpl::getSupportedPackageTypes() throw (RuntimeException)
172 : : {
173 : 380 : return m_typeInfos;
174 : : }
175 : :
176 : 0 : void BackendImpl::packageRemoved(OUString const & url, OUString const & /*mediaType*/)
177 : : throw (deployment::DeploymentException,
178 : : uno::RuntimeException)
179 : : {
180 [ # # ]: 0 : if (m_backendDb.get())
181 : 0 : m_backendDb->removeEntry(url);
182 : 0 : }
183 : :
184 : : // PackageRegistryBackend
185 : : //______________________________________________________________________________
186 : 585 : Reference<deployment::XPackage> BackendImpl::bindPackage_(
187 : : OUString const & url, OUString const & mediaType_,
188 : : sal_Bool bRemoved, OUString const & identifier,
189 : : Reference<XCommandEnvironment> const & xCmdEnv )
190 : : {
191 : : // we don't support auto detection:
192 [ + + ]: 585 : if (mediaType_.isEmpty())
193 : : throw lang::IllegalArgumentException(
194 [ + - ]: 461 : StrCannotDetectMediaType::get() + url,
195 [ + - ][ + - ]: 922 : static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
196 : :
197 [ + - ][ + - ]: 124 : String type, subType;
198 [ + - ]: 124 : INetContentTypeParameterList params;
199 [ + - ][ + - ]: 124 : if (INetContentTypes::parse( mediaType_, type, subType, ¶ms ))
[ + - ][ + - ]
200 : : {
201 [ + - ][ + - ]: 124 : if (type.EqualsIgnoreCaseAscii("application"))
202 : : {
203 : 124 : OUString name;
204 [ + - ]: 124 : if (!bRemoved)
205 : : {
206 [ + - ]: 124 : ::ucbhelper::Content ucbContent( url, xCmdEnv );
207 [ + - ][ + - ]: 124 : name = StrTitle::getTitle( ucbContent );
208 : : }
209 : :
210 [ + - ]: 124 : if (subType.EqualsIgnoreCaseAscii(
211 [ + - ]: 124 : "vnd.sun.star.help"))
212 : : {
213 : : return new PackageImpl(
214 : : this, url, name, m_xHelpTypeInfo, bRemoved,
215 [ + - ][ + - ]: 248 : identifier);
[ + - ]
216 [ - + ]: 124 : }
217 : : }
218 : : }
219 : : throw lang::IllegalArgumentException(
220 [ # # ]: 0 : StrUnsupportedMediaType::get() + mediaType_,
221 : : static_cast<OWeakObject *>(this),
222 [ + - ][ # # ]: 585 : static_cast<sal_Int16>(-1) );
[ # # ][ + - ]
[ + - ]
223 : : }
224 : :
225 : 62 : void BackendImpl::addDataToDb(
226 : : OUString const & url, HelpBackendDb::Data const & data)
227 : : {
228 [ + - ]: 62 : if (m_backendDb.get())
229 : 62 : m_backendDb->addEntry(url, data);
230 : 62 : }
231 : :
232 : 108 : ::boost::optional<HelpBackendDb::Data> BackendImpl::readDataFromDb(
233 : : OUString const & url)
234 : : {
235 : 108 : ::boost::optional<HelpBackendDb::Data> data;
236 [ + - ]: 108 : if (m_backendDb.get())
237 [ + - ][ + - ]: 108 : data = m_backendDb->getEntry(url);
[ + - ]
238 : 108 : return data;
239 : : }
240 : :
241 : 526 : bool BackendImpl::hasActiveEntry(OUString const & url)
242 : : {
243 [ + - ]: 526 : if (m_backendDb.get())
244 : 526 : return m_backendDb->hasActiveEntry(url);
245 : 526 : return false;
246 : : }
247 : :
248 : 0 : void BackendImpl::revokeEntryFromDb(OUString const & url)
249 : : {
250 [ # # ]: 0 : if (m_backendDb.get())
251 : 0 : m_backendDb->revokeEntry(url);
252 : 0 : }
253 : :
254 : 62 : bool BackendImpl::activateEntry(OUString const & url)
255 : : {
256 [ + - ]: 62 : if (m_backendDb.get())
257 : 62 : return m_backendDb->activateEntry(url);
258 : 62 : return false;
259 : : }
260 : :
261 : :
262 : 124 : BackendImpl::PackageImpl::PackageImpl(
263 : : ::rtl::Reference<PackageRegistryBackend> const & myBackend,
264 : : OUString const & url, OUString const & name,
265 : : Reference<deployment::XPackageTypeInfo> const & xPackageType,
266 : : bool bRemoved, OUString const & identifier)
267 : : : Package( myBackend, url, name, name, xPackageType, bRemoved,
268 : 124 : identifier)
269 : : {
270 : 124 : }
271 : :
272 : : // Package
273 : 696 : BackendImpl * BackendImpl::PackageImpl::getMyBackend() const
274 : : {
275 : 696 : BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
276 [ - + ]: 696 : if (NULL == pBackend)
277 : : {
278 : : //May throw a DisposedException
279 : 0 : check();
280 : : //We should never get here...
281 : : throw RuntimeException(
282 : : OUSTR("Failed to get the BackendImpl"),
283 [ # # ][ # # ]: 0 : static_cast<OWeakObject*>(const_cast<PackageImpl *>(this)));
[ # # ]
284 : : }
285 : 696 : return pBackend;
286 : : }
287 : :
288 : 62 : bool BackendImpl::PackageImpl::extensionContainsCompiledHelp()
289 : : {
290 : 62 : bool bCompiled = true;
291 [ + - ][ + - ]: 62 : rtl::OUString aExpandedHelpURL = dp_misc::expandUnoRcUrl(getURL());
292 : :
293 : 62 : ::osl::Directory helpFolder(aExpandedHelpURL);
294 [ + - ][ + - ]: 62 : if ( helpFolder.open() == ::osl::File::E_None)
295 : : {
296 : : //iterate over the contents of the help folder
297 : : //We assume that all folders withing the help folder contain language specific
298 : : //help files. If just one of them does not contain compiled help then this
299 : : //function returns false.
300 : 62 : ::osl::DirectoryItem item;
301 : 62 : ::osl::File::RC errorNext = ::osl::File::E_None;
302 [ + - ][ + - ]: 62 : while ((errorNext = helpFolder.getNextItem(item)) == ::osl::File::E_None)
303 : : {
304 : : //No find the language folders
305 : 62 : ::osl::FileStatus stat(osl_FileStatus_Mask_Type | osl_FileStatus_Mask_FileName |osl_FileStatus_Mask_FileURL);
306 [ + - ][ + - ]: 62 : if (item.getFileStatus(stat) == ::osl::File::E_None)
307 : : {
308 [ + - ][ - + ]: 62 : if (stat.getFileType() != ::osl::FileStatus::Directory)
309 : 0 : continue;
310 : :
311 : : //look if there is the folder help.idxl in the language folder
312 [ + - ][ + - ]: 62 : OUString compUrl(stat.getFileURL() + OUSTR("/help.idxl"));
313 : 62 : ::osl::Directory compiledFolder(compUrl);
314 [ + - ][ + - ]: 62 : if (compiledFolder.open() != ::osl::File::E_None)
315 : : {
316 : 62 : bCompiled = false;
317 : : break;
318 [ + - ][ + - ]: 62 : }
[ - + ]
319 : : }
320 : : else
321 : : {
322 : : //Error
323 : : OSL_ASSERT(0);
324 : 0 : bCompiled = false;
325 : : break;
326 : : }
327 [ - - + ]: 62 : }
328 [ + - ][ - + ]: 62 : if (errorNext != ::osl::File::E_NOENT
329 : : && errorNext != ::osl::File::E_None)
330 : : {
331 : : //Error
332 : : OSL_ASSERT(0);
333 : 0 : bCompiled = false;
334 [ + - ]: 62 : }
335 : : }
336 [ + - ]: 62 : return bCompiled;
337 : : }
338 : :
339 : : //______________________________________________________________________________
340 : : beans::Optional< beans::Ambiguous<sal_Bool> >
341 : 418 : BackendImpl::PackageImpl::isRegistered_(
342 : : ::osl::ResettableMutexGuard &,
343 : : ::rtl::Reference<AbortChannel> const &,
344 : : Reference<XCommandEnvironment> const & )
345 : : {
346 : 418 : BackendImpl * that = getMyBackend();
347 : :
348 : 418 : bool bReg = false;
349 [ + + ][ + - ]: 418 : if (that->hasActiveEntry(getURL()))
350 : 232 : bReg = true;
351 : :
352 : 418 : return beans::Optional< beans::Ambiguous<sal_Bool> >( true, beans::Ambiguous<sal_Bool>( bReg, false ) );
353 : : }
354 : :
355 : : //______________________________________________________________________________
356 : 62 : void BackendImpl::PackageImpl::processPackage_(
357 : : ::osl::ResettableMutexGuard &,
358 : : bool doRegisterPackage,
359 : : bool /* startup */,
360 : : ::rtl::Reference<AbortChannel> const & abortChannel,
361 : : Reference<XCommandEnvironment> const & xCmdEnv )
362 : : {
363 : : (void)doRegisterPackage;
364 : : (void)abortChannel;
365 : : (void)xCmdEnv;
366 : :
367 : 62 : BackendImpl* that = getMyBackend();
368 : 62 : that->implProcessHelp( this, doRegisterPackage, xCmdEnv);
369 : 62 : }
370 : :
371 : 108 : beans::Optional< OUString > BackendImpl::PackageImpl::getRegistrationDataURL()
372 : : throw (deployment::ExtensionRemovedException,
373 : : css::uno::RuntimeException)
374 : : {
375 [ - + ]: 108 : if (m_bRemoved)
376 [ # # ]: 0 : throw deployment::ExtensionRemovedException();
377 : :
378 : : ::boost::optional<HelpBackendDb::Data> data =
379 [ + - ][ + - ]: 108 : getMyBackend()->readDataFromDb(getURL());
[ + - ]
380 : :
381 [ + - ][ + - ]: 108 : if (data && getMyBackend()->hasActiveEntry(getURL()))
[ + - ][ + - ]
[ + - ][ + - ]
[ + - # # ]
[ + - ]
382 [ + - ]: 108 : return beans::Optional<OUString>(true, data->dataUrl);
383 : :
384 [ + - ]: 108 : return beans::Optional<OUString>(true, OUString());
385 : : }
386 : :
387 : 62 : void BackendImpl::implProcessHelp(
388 : : PackageImpl * package, bool doRegisterPackage,
389 : : Reference<ucb::XCommandEnvironment> const & xCmdEnv)
390 : : {
391 [ + - ][ + - ]: 62 : Reference< deployment::XPackage > xPackage(package);
392 : : OSL_ASSERT(xPackage.is());
393 [ + - ]: 62 : if (doRegisterPackage)
394 : : {
395 : : //revive already processed help if possible
396 [ + - ][ + - ]: 62 : if ( !activateEntry(xPackage->getURL()))
[ + - ][ + - ]
397 : : {
398 : 62 : HelpBackendDb::Data data;
399 [ + - ][ + - ]: 62 : data.dataUrl = xPackage->getURL();
400 [ + - ][ + - ]: 62 : if (!package->extensionContainsCompiledHelp())
401 : : {
402 : : #if !defined(ANDROID) && !defined(IOS)
403 [ + - ]: 62 : const OUString sHelpFolder = createFolder(OUString(), xCmdEnv);
404 : 62 : data.dataUrl = sHelpFolder;
405 : :
406 [ + - ]: 62 : Reference< ucb::XSimpleFileAccess2 > xSFA = getFileAccess();
407 [ + - ][ + - ]: 62 : rtl::OUString aHelpURL = xPackage->getURL();
408 [ + - ]: 62 : rtl::OUString aExpandedHelpURL = dp_misc::expandUnoRcUrl( aHelpURL );
409 [ + - ][ + - ]: 62 : rtl::OUString aName = xPackage->getName();
410 [ + - ][ + - ]: 62 : if( !xSFA->isFolder( aExpandedHelpURL ) )
[ - + ]
411 : : {
412 [ # # ][ # # ]: 0 : rtl::OUString aErrStr = getResourceString( RID_STR_HELPPROCESSING_GENERAL_ERROR );
[ # # ]
413 : 0 : aErrStr += rtl::OUString("No help folder" );
414 : 0 : OWeakObject* oWeakThis = static_cast<OWeakObject *>(this);
415 : : throw deployment::DeploymentException( rtl::OUString(), oWeakThis,
416 [ # # ][ # # ]: 0 : makeAny( uno::Exception( aErrStr, oWeakThis ) ) );
[ # # ][ # # ]
[ # # ]
417 : : }
418 : :
419 : : // Scan languages
420 [ + - ][ + - ]: 62 : Sequence< rtl::OUString > aLanguageFolderSeq = xSFA->getFolderContents( aExpandedHelpURL, true );
421 : 62 : sal_Int32 nLangCount = aLanguageFolderSeq.getLength();
422 : 62 : const rtl::OUString* pSeq = aLanguageFolderSeq.getConstArray();
423 [ + + ]: 124 : for( sal_Int32 iLang = 0 ; iLang < nLangCount ; ++iLang )
424 : : {
425 : 62 : rtl::OUString aLangURL = pSeq[iLang];
426 [ + - ][ + - ]: 62 : if( xSFA->isFolder( aLangURL ) )
[ + - ]
427 : : {
428 [ + - ]: 62 : std::vector< rtl::OUString > aXhpFileVector;
429 : :
430 : : // calculate jar file URL
431 : 62 : sal_Int32 indexStartSegment = aLangURL.lastIndexOf('/');
432 : : // for example "/en"
433 : : OUString langFolderURLSegment(
434 : : aLangURL.copy(
435 : 62 : indexStartSegment + 1, aLangURL.getLength() - indexStartSegment - 1));
436 : :
437 : : //create the folder in the "temporary folder"
438 [ + - ]: 62 : ::ucbhelper::Content langFolderContent;
439 [ + - ]: 62 : const OUString langFolderDest = makeURL(sHelpFolder, langFolderURLSegment);
440 [ + - ]: 62 : const OUString langFolderDestExpanded = ::dp_misc::expandUnoRcUrl(langFolderDest);
441 : : ::dp_misc::create_folder(
442 : : &langFolderContent,
443 [ + - ]: 62 : langFolderDest, xCmdEnv);
444 : :
445 : 62 : const OUString aHelpStr("help");
446 : 62 : const OUString aSlash("/");
447 : :
448 : : rtl::OUString aJarFile(
449 : : makeURL(sHelpFolder, langFolderURLSegment + aSlash + aHelpStr +
450 [ + - ][ + - ]: 62 : OUSTR(".jar")));
451 [ + - ]: 62 : aJarFile = ::dp_misc::expandUnoRcUrl(aJarFile);
452 : :
453 : : rtl::OUString aEncodedJarFilePath = rtl::Uri::encode(
454 : : aJarFile, rtl_UriCharClassPchar,
455 : : rtl_UriEncodeIgnoreEscapes,
456 : 62 : RTL_TEXTENCODING_UTF8 );
457 : 62 : rtl::OUString aDestBasePath = rtl::OUString("vnd.sun.star.zip://" );
458 : 62 : aDestBasePath += aEncodedJarFilePath;
459 : 62 : aDestBasePath += rtl::OUString("/" );
460 : :
461 : 62 : sal_Int32 nLenLangFolderURL = aLangURL.getLength() + 1;
462 : :
463 [ + - ][ + - ]: 62 : Sequence< rtl::OUString > aSubLangSeq = xSFA->getFolderContents( aLangURL, true );
464 : 62 : sal_Int32 nSubLangCount = aSubLangSeq.getLength();
465 : 62 : const rtl::OUString* pSubLangSeq = aSubLangSeq.getConstArray();
466 [ + + ]: 124 : for( sal_Int32 iSubLang = 0 ; iSubLang < nSubLangCount ; ++iSubLang )
467 : : {
468 : 62 : rtl::OUString aSubFolderURL = pSubLangSeq[iSubLang];
469 [ + - ][ - + ]: 62 : if( !xSFA->isFolder( aSubFolderURL ) )
[ + - ]
470 : 0 : continue;
471 : :
472 [ + - ]: 62 : implCollectXhpFiles( aSubFolderURL, aXhpFileVector );
473 : :
474 : : // Copy to package (later: move?)
475 : 62 : rtl::OUString aDestPath = aDestBasePath;
476 : 62 : rtl::OUString aPureFolderName = aSubFolderURL.copy( nLenLangFolderURL );
477 : 62 : aDestPath += aPureFolderName;
478 [ + - ][ + - ]: 62 : xSFA->copy( aSubFolderURL, aDestPath );
479 [ + - ]: 62 : }
480 : :
481 : : // Call compiler
482 : 62 : sal_Int32 nXhpFileCount = aXhpFileVector.size();
483 [ + + ][ + - ]: 124 : rtl::OUString* pXhpFiles = new rtl::OUString[nXhpFileCount];
484 [ + + ]: 124 : for( sal_Int32 iXhp = 0 ; iXhp < nXhpFileCount ; ++iXhp )
485 : : {
486 : 62 : rtl::OUString aXhpFile = aXhpFileVector[iXhp];
487 : 62 : rtl::OUString aXhpRelFile = aXhpFile.copy( nLenLangFolderURL );
488 : 62 : pXhpFiles[iXhp] = aXhpRelFile;
489 : 62 : }
490 : :
491 [ + - ][ + - ]: 62 : rtl::OUString aOfficeHelpPath( SvtPathOptions().GetHelpPath() );
[ + - ][ + - ]
492 : 62 : rtl::OUString aOfficeHelpPathFileURL;
493 [ + - ]: 62 : ::osl::File::getFileURLFromSystemPath( aOfficeHelpPath, aOfficeHelpPathFileURL );
494 : :
495 : 62 : HelpProcessingErrorInfo aErrorInfo;
496 : : bool bSuccess = compileExtensionHelp(
497 : : aOfficeHelpPathFileURL, aHelpStr, aLangURL,
498 : : nXhpFileCount, pXhpFiles,
499 [ + - ]: 62 : langFolderDestExpanded, aErrorInfo );
500 : :
501 [ + - ]: 62 : if( bSuccess )
502 : : {
503 : 62 : rtl::OUString aLang;
504 : 62 : sal_Int32 nLastSlash = aLangURL.lastIndexOf( '/' );
505 [ + - ]: 62 : if( nLastSlash != -1 )
506 : 62 : aLang = aLangURL.copy( nLastSlash + 1 );
507 : : else
508 : 0 : aLang = rtl::OUString("en" );
509 : :
510 : 62 : rtl::OUString aMod("help");
511 : :
512 [ + - ]: 62 : HelpIndexer aIndexer(aLang, aMod, langFolderDestExpanded, langFolderDestExpanded);
513 [ + - ][ + - ]: 62 : aIndexer.indexDocuments();
514 : : }
515 : :
516 [ - + ]: 62 : if( !bSuccess )
517 : : {
518 : 0 : sal_uInt16 nErrStrId = 0;
519 [ # # # ]: 0 : switch( aErrorInfo.m_eErrorClass )
520 : : {
521 : : case HELPPROCESSING_GENERAL_ERROR:
522 : 0 : case HELPPROCESSING_INTERNAL_ERROR: nErrStrId = RID_STR_HELPPROCESSING_GENERAL_ERROR; break;
523 : 0 : case HELPPROCESSING_XMLPARSING_ERROR: nErrStrId = RID_STR_HELPPROCESSING_XMLPARSING_ERROR; break;
524 : : default: ;
525 : : };
526 : :
527 : 0 : rtl::OUString aErrStr;
528 [ # # ]: 0 : if( nErrStrId != 0 )
529 : : {
530 [ # # ][ # # ]: 0 : aErrStr = getResourceString( nErrStrId );
[ # # ]
531 : :
532 : : // Remoce CR/LF
533 : 0 : rtl::OUString aErrMsg( aErrorInfo.m_aErrorMsg );
534 : 0 : sal_Unicode nCR = 13, nLF = 10;
535 : 0 : sal_Int32 nSearchCR = aErrMsg.indexOf( nCR );
536 : 0 : sal_Int32 nSearchLF = aErrMsg.indexOf( nLF );
537 : : sal_Int32 nCopy;
538 [ # # ][ # # ]: 0 : if( nSearchCR != -1 || nSearchLF != -1 )
539 : : {
540 [ # # ]: 0 : if( nSearchCR == -1 )
541 : 0 : nCopy = nSearchLF;
542 [ # # ]: 0 : else if( nSearchLF == -1 )
543 : 0 : nCopy = nSearchCR;
544 : : else
545 [ # # ]: 0 : nCopy = ( nSearchCR < nSearchLF ) ? nSearchCR : nSearchLF;
546 : :
547 : 0 : aErrMsg = aErrMsg.copy( 0, nCopy );
548 : : }
549 : 0 : aErrStr += aErrMsg;
550 [ # # ][ # # ]: 0 : if( nErrStrId == RID_STR_HELPPROCESSING_XMLPARSING_ERROR && !aErrorInfo.m_aXMLParsingFile.isEmpty() )
[ # # ]
551 : : {
552 : 0 : aErrStr += rtl::OUString(" in " );
553 : :
554 : : rtl::OUString aDecodedFile = rtl::Uri::decode( aErrorInfo.m_aXMLParsingFile,
555 : 0 : rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
556 : 0 : aErrStr += aDecodedFile;
557 [ # # ]: 0 : if( aErrorInfo.m_nXMLParsingLine != -1 )
558 : : {
559 : 0 : aErrStr += rtl::OUString(", line " );
560 : 0 : aErrStr += ::rtl::OUString::valueOf( aErrorInfo.m_nXMLParsingLine );
561 : 0 : }
562 : 0 : }
563 : : }
564 : :
565 : 0 : OWeakObject* oWeakThis = static_cast<OWeakObject *>(this);
566 : : throw deployment::DeploymentException( rtl::OUString(), oWeakThis,
567 [ # # ][ # # ]: 0 : makeAny( uno::Exception( aErrStr, oWeakThis ) ) );
[ # # ][ # # ]
[ # # ]
568 [ + - ][ + - ]: 62 : }
569 : : }
570 [ + - ]: 124 : }
571 : : #else
572 : : (void) xCmdEnv;
573 : : #endif
574 : : }
575 : : //Writing the data entry replaces writing the flag file. If we got to this
576 : : //point the registration was successful.
577 [ + - ][ + - ]: 62 : addDataToDb(xPackage->getURL(), data);
[ + - ]
578 : : }
579 : : } //if (doRegisterPackage)
580 : : else
581 : : {
582 [ # # ][ # # ]: 0 : revokeEntryFromDb(xPackage->getURL());
[ # # ]
583 : 62 : }
584 : 62 : }
585 : :
586 : 62 : void BackendImpl::implCollectXhpFiles( const rtl::OUString& aDir,
587 : : std::vector< rtl::OUString >& o_rXhpFileVector )
588 : : {
589 [ + - ]: 62 : Reference< ucb::XSimpleFileAccess2 > xSFA = getFileAccess();
590 : :
591 : : // Scan xhp files recursively
592 [ + - ][ + - ]: 62 : Sequence< rtl::OUString > aSeq = xSFA->getFolderContents( aDir, true );
593 : 62 : sal_Int32 nCount = aSeq.getLength();
594 : 62 : const rtl::OUString* pSeq = aSeq.getConstArray();
595 [ + + ]: 124 : for( sal_Int32 i = 0 ; i < nCount ; ++i )
596 : : {
597 : 62 : rtl::OUString aURL = pSeq[i];
598 [ + - ][ - + ]: 62 : if( xSFA->isFolder( aURL ) )
[ + - ]
599 : : {
600 [ # # ]: 0 : implCollectXhpFiles( aURL, o_rXhpFileVector );
601 : : }
602 : : else
603 : : {
604 : 62 : sal_Int32 nLastDot = aURL.lastIndexOf( '.' );
605 [ + - ]: 62 : if( nLastDot != -1 )
606 : : {
607 : 62 : rtl::OUString aExt = aURL.copy( nLastDot + 1 );
608 [ + - ]: 62 : if( aExt.equalsIgnoreAsciiCase( rtl::OUString("xhp" ) ) )
609 [ + - ]: 62 : o_rXhpFileVector.push_back( aURL );
610 : : }
611 : : }
612 [ + - ]: 124 : }
613 : 62 : }
614 : :
615 : 124 : Reference< ucb::XSimpleFileAccess2 > BackendImpl::getFileAccess( void )
616 : : {
617 [ + + ]: 124 : if( !m_xSFA.is() )
618 : : {
619 : 62 : Reference<XComponentContext> const & xContext = getComponentContext();
620 [ + - ]: 62 : if( xContext.is() )
621 : : {
622 [ + - ]: 62 : m_xSFA = ucb::SimpleFileAccess::create(xContext);
623 : : }
624 [ - + ]: 62 : if( !m_xSFA.is() )
625 : : {
626 : : throw RuntimeException(
627 : : ::rtl::OUString(
628 : : "dp_registry::backend::help::BackendImpl::getFileAccess(), "
629 : : "could not instatiate SimpleFileAccess." ),
630 [ # # ]: 0 : Reference< XInterface >() );
631 : : }
632 : : }
633 : 124 : return m_xSFA;
634 : : }
635 : :
636 : : } // anon namespace
637 : :
638 : : namespace sdecl = comphelper::service_decl;
639 : 124 : sdecl::class_<BackendImpl, sdecl::with_args<true> > serviceBI;
640 : 124 : extern sdecl::ServiceDecl const serviceDecl(
641 : : serviceBI,
642 : : "com.sun.star.comp.deployment.help.PackageRegistryBackend",
643 : : BACKEND_SERVICE_NAME );
644 : :
645 : : } // namespace help
646 : : } // namespace backend
647 [ + - ][ + - ]: 372 : } // namespace dp_registry
648 : :
649 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|