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