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