1*2722ceddSAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3*2722ceddSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4*2722ceddSAndrew Rist * or more contributor license agreements. See the NOTICE file
5*2722ceddSAndrew Rist * distributed with this work for additional information
6*2722ceddSAndrew Rist * regarding copyright ownership. The ASF licenses this file
7*2722ceddSAndrew Rist * to you under the Apache License, Version 2.0 (the
8*2722ceddSAndrew Rist * "License"); you may not use this file except in compliance
9*2722ceddSAndrew Rist * with the License. You may obtain a copy of the License at
10*2722ceddSAndrew Rist *
11*2722ceddSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12*2722ceddSAndrew Rist *
13*2722ceddSAndrew Rist * Unless required by applicable law or agreed to in writing,
14*2722ceddSAndrew Rist * software distributed under the License is distributed on an
15*2722ceddSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*2722ceddSAndrew Rist * KIND, either express or implied. See the License for the
17*2722ceddSAndrew Rist * specific language governing permissions and limitations
18*2722ceddSAndrew Rist * under the License.
19*2722ceddSAndrew Rist *
20*2722ceddSAndrew Rist *************************************************************/
21*2722ceddSAndrew Rist
22*2722ceddSAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_desktop.hxx"
26cdf0e10cSrcweir
27cdf0e10cSrcweir #include "dp_package.hrc"
28cdf0e10cSrcweir #include "dp_backend.h"
29cdf0e10cSrcweir #include "dp_ucb.h"
30cdf0e10cSrcweir #include "dp_interact.h"
31cdf0e10cSrcweir #include "dp_dependencies.hxx"
32cdf0e10cSrcweir #include "dp_platform.hxx"
33cdf0e10cSrcweir #include "dp_descriptioninfoset.hxx"
34cdf0e10cSrcweir #include "dp_identifier.hxx"
35cdf0e10cSrcweir #include "rtl/uri.hxx"
36cdf0e10cSrcweir #include "cppuhelper/exc_hlp.hxx"
37cdf0e10cSrcweir #include "cppuhelper/implbase1.hxx"
38cdf0e10cSrcweir #include "ucbhelper/content.hxx"
39cdf0e10cSrcweir #include "svl/inettype.hxx"
40cdf0e10cSrcweir #include "comphelper/anytostring.hxx"
41cdf0e10cSrcweir #include "comphelper/makesequence.hxx"
42cdf0e10cSrcweir #include "comphelper/sequence.hxx"
43cdf0e10cSrcweir #include "com/sun/star/lang/WrappedTargetException.hpp"
44cdf0e10cSrcweir #include "com/sun/star/lang/XServiceInfo.hpp"
45cdf0e10cSrcweir #include "com/sun/star/beans/UnknownPropertyException.hpp"
46cdf0e10cSrcweir #include "com/sun/star/graphic/XGraphic.hpp"
47cdf0e10cSrcweir #include "com/sun/star/graphic/XGraphicProvider.hpp"
48cdf0e10cSrcweir #include "com/sun/star/io/XOutputStream.hpp"
49cdf0e10cSrcweir #include "com/sun/star/io/XInputStream.hpp"
50cdf0e10cSrcweir #include "com/sun/star/task/InteractionClassification.hpp"
51cdf0e10cSrcweir #include "com/sun/star/task/XInteractionApprove.hpp"
52cdf0e10cSrcweir #include "com/sun/star/ucb/XInteractionReplaceExistingData.hpp"
53cdf0e10cSrcweir #include "com/sun/star/ucb/NameClashResolveRequest.hpp"
54cdf0e10cSrcweir #include "com/sun/star/ucb/XContentAccess.hpp"
55cdf0e10cSrcweir #include "com/sun/star/ucb/NameClash.hpp"
56cdf0e10cSrcweir #include "com/sun/star/ucb/UnsupportedCommandException.hpp"
57cdf0e10cSrcweir #include "com/sun/star/sdbc/XResultSet.hpp"
58cdf0e10cSrcweir #include "com/sun/star/sdbc/XRow.hpp"
59cdf0e10cSrcweir #include "com/sun/star/packages/manifest/XManifestReader.hpp"
60cdf0e10cSrcweir #include "com/sun/star/packages/manifest/XManifestWriter.hpp"
61cdf0e10cSrcweir #include "com/sun/star/deployment/DependencyException.hpp"
62cdf0e10cSrcweir #include "com/sun/star/deployment/LicenseException.hpp"
63cdf0e10cSrcweir #include "com/sun/star/deployment/PlatformException.hpp"
64cdf0e10cSrcweir #include "com/sun/star/deployment/Prerequisites.hpp"
65cdf0e10cSrcweir #include "com/sun/star/xml/dom/XDocumentBuilder.hpp"
66cdf0e10cSrcweir #include "com/sun/star/xml/xpath/XXPathAPI.hpp"
67cdf0e10cSrcweir #include "com/sun/star/deployment/XPackageManager.hpp"
68cdf0e10cSrcweir #include "boost/optional.hpp"
69cdf0e10cSrcweir #include <vector>
70cdf0e10cSrcweir #include <stdio.h>
71cdf0e10cSrcweir
72cdf0e10cSrcweir #include "dp_extbackenddb.hxx"
73cdf0e10cSrcweir using namespace ::dp_misc;
74cdf0e10cSrcweir using namespace ::com::sun::star;
75cdf0e10cSrcweir using namespace ::com::sun::star::uno;
76cdf0e10cSrcweir
77cdf0e10cSrcweir namespace css = ::com::sun::star;
78cdf0e10cSrcweir
79cdf0e10cSrcweir using ::rtl::OUString;
80cdf0e10cSrcweir
81cdf0e10cSrcweir namespace dp_registry {
82cdf0e10cSrcweir namespace backend {
83cdf0e10cSrcweir namespace bundle {
84cdf0e10cSrcweir namespace {
85cdf0e10cSrcweir
86cdf0e10cSrcweir typedef cppu::ImplInheritanceHelper1<PackageRegistryBackend,
87cdf0e10cSrcweir lang::XServiceInfo> ImplBaseT;
88cdf0e10cSrcweir
89cdf0e10cSrcweir //==============================================================================
90cdf0e10cSrcweir class BackendImpl : public ImplBaseT
91cdf0e10cSrcweir {
92cdf0e10cSrcweir class PackageImpl : public ::dp_registry::backend::Package
93cdf0e10cSrcweir {
94cdf0e10cSrcweir BackendImpl * getMyBackend() const;
95cdf0e10cSrcweir /** constains the old tooltip description for the Extension Manager GUI in OOo v.2.x
96cdf0e10cSrcweir We keep it for backward compatibility.
97cdf0e10cSrcweir */
98cdf0e10cSrcweir OUString m_oldDescription;
99cdf0e10cSrcweir OUString m_url_expanded;
100cdf0e10cSrcweir const bool m_legacyBundle;
101cdf0e10cSrcweir Sequence< Reference<deployment::XPackage> > m_bundle;
102cdf0e10cSrcweir Sequence< Reference<deployment::XPackage> > * m_pBundle;
103cdf0e10cSrcweir
104cdf0e10cSrcweir ExtensionBackendDb::Data m_dbData;
105cdf0e10cSrcweir
106cdf0e10cSrcweir Reference<deployment::XPackage> bindBundleItem(
107cdf0e10cSrcweir OUString const & url, OUString const & mediaType,
108cdf0e10cSrcweir sal_Bool bRemoved, //that is, useing data base information
109cdf0e10cSrcweir OUString const & identifier,
110cdf0e10cSrcweir Reference<ucb::XCommandEnvironment> const & xCmdEnv,
111cdf0e10cSrcweir bool notifyDetectionError = true );
112cdf0e10cSrcweir
113cdf0e10cSrcweir typedef ::std::vector< Reference<deployment::XPackage> > t_packagevec;
114cdf0e10cSrcweir void scanBundle(
115cdf0e10cSrcweir t_packagevec & bundle,
116cdf0e10cSrcweir ::rtl::Reference<AbortChannel> const & abortChannel,
117cdf0e10cSrcweir Reference<ucb::XCommandEnvironment> const & xCmdEnv );
118cdf0e10cSrcweir void scanLegacyBundle(
119cdf0e10cSrcweir t_packagevec & bundle,
120cdf0e10cSrcweir OUString const & url,
121cdf0e10cSrcweir ::rtl::Reference<AbortChannel> const & abortChannel,
122cdf0e10cSrcweir Reference<ucb::XCommandEnvironment> const & xCmdEnv,
123cdf0e10cSrcweir bool skip_registration = false );
124cdf0e10cSrcweir ::std::vector<Reference<deployment::XPackage> > getPackagesFromDb(
125cdf0e10cSrcweir Reference<ucb::XCommandEnvironment> const & xCmdEnv);
126cdf0e10cSrcweir bool checkPlatform(
127cdf0e10cSrcweir Reference<ucb::XCommandEnvironment > const & environment);
128cdf0e10cSrcweir
129cdf0e10cSrcweir bool checkDependencies(
130cdf0e10cSrcweir Reference<ucb::XCommandEnvironment > const &
131cdf0e10cSrcweir environment,
132cdf0e10cSrcweir DescriptionInfoset const & description);
133cdf0e10cSrcweir // throws css::uno::RuntimeException,
134cdf0e10cSrcweir // css::deployment::DeploymentException
135cdf0e10cSrcweir
136cdf0e10cSrcweir ::sal_Bool checkLicense(
137cdf0e10cSrcweir Reference< ucb::XCommandEnvironment > const & xCmdEnv,
138cdf0e10cSrcweir DescriptionInfoset const & description, bool bNoLicenseChecking)
139cdf0e10cSrcweir throw (deployment::DeploymentException,
140cdf0e10cSrcweir ucb::CommandFailedException,
141cdf0e10cSrcweir ucb::CommandAbortedException,
142cdf0e10cSrcweir RuntimeException);
143cdf0e10cSrcweir // @throws DeploymentException
144cdf0e10cSrcweir OUString getTextFromURL(
145cdf0e10cSrcweir const Reference< ucb::XCommandEnvironment >& xCmdEnv,
146cdf0e10cSrcweir const OUString& licenseUrl);
147cdf0e10cSrcweir
148cdf0e10cSrcweir DescriptionInfoset getDescriptionInfoset();
149cdf0e10cSrcweir
150cdf0e10cSrcweir // Package
151cdf0e10cSrcweir virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
152cdf0e10cSrcweir ::osl::ResettableMutexGuard & guard,
153cdf0e10cSrcweir ::rtl::Reference<AbortChannel> const & abortChannel,
154cdf0e10cSrcweir Reference<ucb::XCommandEnvironment> const & xCmdEnv );
155cdf0e10cSrcweir virtual void processPackage_(
156cdf0e10cSrcweir ::osl::ResettableMutexGuard & guard,
157cdf0e10cSrcweir bool registerPackage,
158cdf0e10cSrcweir bool startup,
159cdf0e10cSrcweir ::rtl::Reference<AbortChannel> const & abortChannel,
160cdf0e10cSrcweir Reference<ucb::XCommandEnvironment> const & xCmdEnv );
161cdf0e10cSrcweir
162cdf0e10cSrcweir virtual void SAL_CALL disposing();
163cdf0e10cSrcweir
164cdf0e10cSrcweir
165cdf0e10cSrcweir
166cdf0e10cSrcweir public:
167cdf0e10cSrcweir PackageImpl(
168cdf0e10cSrcweir ::rtl::Reference<PackageRegistryBackend> const & myBackend,
169cdf0e10cSrcweir OUString const & url,
170cdf0e10cSrcweir OUString const & name,
171cdf0e10cSrcweir Reference<deployment::XPackageTypeInfo> const & xPackageType,
172cdf0e10cSrcweir bool legacyBundle,
173cdf0e10cSrcweir bool bRemoved,
174cdf0e10cSrcweir OUString const & identifier);
175cdf0e10cSrcweir
176cdf0e10cSrcweir // XPackage
177cdf0e10cSrcweir virtual sal_Bool SAL_CALL isBundle() throw (RuntimeException);
178cdf0e10cSrcweir
179cdf0e10cSrcweir virtual Sequence< Reference<deployment::XPackage> > SAL_CALL getBundle(
180cdf0e10cSrcweir Reference<task::XAbortChannel> const & xAbortChannel,
181cdf0e10cSrcweir Reference<ucb::XCommandEnvironment> const & xCmdEnv )
182cdf0e10cSrcweir throw (deployment::DeploymentException,
183cdf0e10cSrcweir ucb::CommandFailedException,
184cdf0e10cSrcweir ucb::CommandAbortedException,
185cdf0e10cSrcweir lang::IllegalArgumentException, RuntimeException);
186cdf0e10cSrcweir virtual OUString SAL_CALL getDescription()
187cdf0e10cSrcweir throw (deployment::ExtensionRemovedException, RuntimeException);
188cdf0e10cSrcweir
189cdf0e10cSrcweir virtual OUString SAL_CALL getLicenseText()
190cdf0e10cSrcweir throw (deployment::ExtensionRemovedException, RuntimeException);
191cdf0e10cSrcweir
192cdf0e10cSrcweir virtual void SAL_CALL exportTo(
193cdf0e10cSrcweir OUString const & destFolderURL, OUString const & newTitle,
194cdf0e10cSrcweir sal_Int32 nameClashAction,
195cdf0e10cSrcweir Reference<ucb::XCommandEnvironment> const & xCmdEnv )
196cdf0e10cSrcweir throw (deployment::ExtensionRemovedException,
197cdf0e10cSrcweir ucb::CommandFailedException,
198cdf0e10cSrcweir ucb::CommandAbortedException,
199cdf0e10cSrcweir RuntimeException);
200cdf0e10cSrcweir
201cdf0e10cSrcweir virtual ::sal_Int32 SAL_CALL checkPrerequisites(
202cdf0e10cSrcweir const Reference< task::XAbortChannel >& xAbortChannel,
203cdf0e10cSrcweir const Reference< ucb::XCommandEnvironment >& xCmdEnv,
204cdf0e10cSrcweir ::sal_Bool noLicenseChecking)
205cdf0e10cSrcweir throw (deployment::ExtensionRemovedException,
206cdf0e10cSrcweir deployment::DeploymentException,
207cdf0e10cSrcweir ucb::CommandFailedException,
208cdf0e10cSrcweir ucb::CommandAbortedException,
209cdf0e10cSrcweir RuntimeException);
210cdf0e10cSrcweir
211cdf0e10cSrcweir virtual ::sal_Bool SAL_CALL checkDependencies(
212cdf0e10cSrcweir const Reference< ucb::XCommandEnvironment >& xCmdEnv )
213cdf0e10cSrcweir throw (deployment::DeploymentException,
214cdf0e10cSrcweir deployment::ExtensionRemovedException,
215cdf0e10cSrcweir ucb::CommandFailedException,
216cdf0e10cSrcweir RuntimeException);
217cdf0e10cSrcweir
218cdf0e10cSrcweir virtual beans::Optional<OUString> SAL_CALL getIdentifier()
219cdf0e10cSrcweir throw (RuntimeException);
220cdf0e10cSrcweir
221cdf0e10cSrcweir virtual OUString SAL_CALL getVersion()
222cdf0e10cSrcweir throw (deployment::ExtensionRemovedException, RuntimeException);
223cdf0e10cSrcweir
224cdf0e10cSrcweir virtual Sequence<OUString> SAL_CALL getUpdateInformationURLs()
225cdf0e10cSrcweir throw (deployment::ExtensionRemovedException, RuntimeException);
226cdf0e10cSrcweir
227cdf0e10cSrcweir virtual beans::StringPair SAL_CALL getPublisherInfo()
228cdf0e10cSrcweir throw (deployment::ExtensionRemovedException, RuntimeException);
229cdf0e10cSrcweir
230cdf0e10cSrcweir virtual OUString SAL_CALL getDisplayName()
231cdf0e10cSrcweir throw (deployment::ExtensionRemovedException, RuntimeException);
232cdf0e10cSrcweir
233cdf0e10cSrcweir virtual Reference< graphic::XGraphic > SAL_CALL
234cdf0e10cSrcweir getIcon( ::sal_Bool bHighContrast )
235cdf0e10cSrcweir throw (deployment::ExtensionRemovedException,
236cdf0e10cSrcweir RuntimeException);
237cdf0e10cSrcweir };
238cdf0e10cSrcweir friend class PackageImpl;
239cdf0e10cSrcweir
240cdf0e10cSrcweir Reference<deployment::XPackageRegistry> m_xRootRegistry;
241cdf0e10cSrcweir const Reference<deployment::XPackageTypeInfo> m_xBundleTypeInfo;
242cdf0e10cSrcweir const Reference<deployment::XPackageTypeInfo> m_xLegacyBundleTypeInfo;
243cdf0e10cSrcweir Sequence< Reference<deployment::XPackageTypeInfo> > m_typeInfos;
244cdf0e10cSrcweir
245cdf0e10cSrcweir std::auto_ptr<ExtensionBackendDb> m_backendDb;
246cdf0e10cSrcweir
247cdf0e10cSrcweir void addDataToDb(OUString const & url, ExtensionBackendDb::Data const & data);
248cdf0e10cSrcweir ExtensionBackendDb::Data readDataFromDb(OUString const & url);
249cdf0e10cSrcweir void revokeEntryFromDb(OUString const & url);
250cdf0e10cSrcweir
251cdf0e10cSrcweir // PackageRegistryBackend
252cdf0e10cSrcweir virtual Reference<deployment::XPackage> bindPackage_(
253cdf0e10cSrcweir OUString const & url, OUString const & mediaType,
254cdf0e10cSrcweir sal_Bool bRemoved, OUString const & identifier,
255cdf0e10cSrcweir Reference<ucb::XCommandEnvironment> const & xCmdEnv );
256cdf0e10cSrcweir
257cdf0e10cSrcweir virtual void SAL_CALL disposing();
258cdf0e10cSrcweir
259cdf0e10cSrcweir public:
260cdf0e10cSrcweir BackendImpl(
261cdf0e10cSrcweir Sequence<Any> const & args,
262cdf0e10cSrcweir Reference<XComponentContext> const & xComponentContext,
263cdf0e10cSrcweir Reference<deployment::XPackageRegistry> const & xRootRegistry );
264cdf0e10cSrcweir
265cdf0e10cSrcweir // XServiceInfo
266cdf0e10cSrcweir virtual OUString SAL_CALL getImplementationName() throw (RuntimeException);
267cdf0e10cSrcweir virtual sal_Bool SAL_CALL supportsService( OUString const& name )
268cdf0e10cSrcweir throw (RuntimeException);
269cdf0e10cSrcweir virtual Sequence<OUString> SAL_CALL getSupportedServiceNames()
270cdf0e10cSrcweir throw (RuntimeException);
271cdf0e10cSrcweir
272cdf0e10cSrcweir // XPackageRegistry
273cdf0e10cSrcweir virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
274cdf0e10cSrcweir getSupportedPackageTypes() throw (RuntimeException);
275cdf0e10cSrcweir virtual void SAL_CALL packageRemoved(OUString const & url, OUString const & mediaType)
276cdf0e10cSrcweir throw (deployment::DeploymentException,
277cdf0e10cSrcweir uno::RuntimeException);
278cdf0e10cSrcweir
279cdf0e10cSrcweir using ImplBaseT::disposing;
280cdf0e10cSrcweir };
281cdf0e10cSrcweir
282cdf0e10cSrcweir //Used to find a XPackage with a particular URL
283cdf0e10cSrcweir class XPackage_eq : public std::unary_function<Reference<deployment::XPackage>, bool>
284cdf0e10cSrcweir {
285cdf0e10cSrcweir OUString m_URL;
286cdf0e10cSrcweir public:
XPackage_eq(const OUString & s)287cdf0e10cSrcweir explicit XPackage_eq(const OUString & s) : m_URL(s) {}
operator ()(const Reference<deployment::XPackage> & p) const288cdf0e10cSrcweir bool operator() (const Reference<deployment::XPackage> & p) const
289cdf0e10cSrcweir {
290cdf0e10cSrcweir return m_URL.equals(p->getURL());
291cdf0e10cSrcweir }
292cdf0e10cSrcweir };
293cdf0e10cSrcweir
294cdf0e10cSrcweir //______________________________________________________________________________
BackendImpl(Sequence<Any> const & args,Reference<XComponentContext> const & xComponentContext,Reference<deployment::XPackageRegistry> const & xRootRegistry)295cdf0e10cSrcweir BackendImpl::BackendImpl(
296cdf0e10cSrcweir Sequence<Any> const & args,
297cdf0e10cSrcweir Reference<XComponentContext> const & xComponentContext,
298cdf0e10cSrcweir Reference<deployment::XPackageRegistry> const & xRootRegistry )
299cdf0e10cSrcweir : ImplBaseT( args, xComponentContext ),
300cdf0e10cSrcweir m_xRootRegistry( xRootRegistry ),
301cdf0e10cSrcweir m_xBundleTypeInfo( new Package::TypeInfo(
302cdf0e10cSrcweir OUSTR("application/vnd.sun.star.package-bundle"),
303cdf0e10cSrcweir OUSTR("*.oxt;*.uno.pkg"),
304cdf0e10cSrcweir getResourceString(RID_STR_PACKAGE_BUNDLE),
305cdf0e10cSrcweir RID_IMG_DEF_PACKAGE_BUNDLE,
306cdf0e10cSrcweir RID_IMG_DEF_PACKAGE_BUNDLE_HC ) ),
307cdf0e10cSrcweir m_xLegacyBundleTypeInfo( new Package::TypeInfo(
308cdf0e10cSrcweir OUSTR("application/"
309cdf0e10cSrcweir "vnd.sun.star.legacy-package-bundle"),
310cdf0e10cSrcweir OUSTR("*.zip"),
311cdf0e10cSrcweir m_xBundleTypeInfo->getShortDescription(),
312cdf0e10cSrcweir RID_IMG_DEF_PACKAGE_BUNDLE,
313cdf0e10cSrcweir RID_IMG_DEF_PACKAGE_BUNDLE_HC ) ),
314cdf0e10cSrcweir m_typeInfos(2)
315cdf0e10cSrcweir {
316cdf0e10cSrcweir m_typeInfos[ 0 ] = m_xBundleTypeInfo;
317cdf0e10cSrcweir m_typeInfos[ 1 ] = m_xLegacyBundleTypeInfo;
318cdf0e10cSrcweir
319cdf0e10cSrcweir if (!transientMode())
320cdf0e10cSrcweir {
321cdf0e10cSrcweir OUString dbFile = makeURL(getCachePath(), getImplementationName());
322cdf0e10cSrcweir dbFile = makeURL(dbFile, OUSTR("backenddb.xml"));
323cdf0e10cSrcweir m_backendDb.reset(
324cdf0e10cSrcweir new ExtensionBackendDb(getComponentContext(), dbFile));
325cdf0e10cSrcweir }
326cdf0e10cSrcweir }
327cdf0e10cSrcweir
328cdf0e10cSrcweir //______________________________________________________________________________
disposing()329cdf0e10cSrcweir void BackendImpl::disposing()
330cdf0e10cSrcweir {
331cdf0e10cSrcweir m_xRootRegistry.clear();
332cdf0e10cSrcweir PackageRegistryBackend::disposing();
333cdf0e10cSrcweir }
334cdf0e10cSrcweir
335cdf0e10cSrcweir // XServiceInfo
getImplementationName()336cdf0e10cSrcweir OUString BackendImpl::getImplementationName() throw (RuntimeException)
337cdf0e10cSrcweir {
338cdf0e10cSrcweir return OUSTR("com.sun.star.comp.deployment.bundle.PackageRegistryBackend");
339cdf0e10cSrcweir }
340cdf0e10cSrcweir
supportsService(OUString const & name)341cdf0e10cSrcweir sal_Bool BackendImpl::supportsService( OUString const& name )
342cdf0e10cSrcweir throw (RuntimeException)
343cdf0e10cSrcweir {
344cdf0e10cSrcweir return getSupportedServiceNames()[0].equals(name);
345cdf0e10cSrcweir }
346cdf0e10cSrcweir
getSupportedServiceNames()347cdf0e10cSrcweir Sequence<OUString> BackendImpl::getSupportedServiceNames()
348cdf0e10cSrcweir throw (RuntimeException)
349cdf0e10cSrcweir {
350cdf0e10cSrcweir return comphelper::makeSequence(
351cdf0e10cSrcweir OUString::createFromAscii(BACKEND_SERVICE_NAME) );
352cdf0e10cSrcweir }
353cdf0e10cSrcweir
354cdf0e10cSrcweir // XPackageRegistry
355cdf0e10cSrcweir //______________________________________________________________________________
356cdf0e10cSrcweir Sequence< Reference<deployment::XPackageTypeInfo> >
getSupportedPackageTypes()357cdf0e10cSrcweir BackendImpl::getSupportedPackageTypes() throw (RuntimeException)
358cdf0e10cSrcweir {
359cdf0e10cSrcweir return m_typeInfos;
360cdf0e10cSrcweir }
361cdf0e10cSrcweir
packageRemoved(OUString const & url,OUString const &)362cdf0e10cSrcweir void BackendImpl::packageRemoved(OUString const & url, OUString const & /*mediaType*/)
363cdf0e10cSrcweir throw (deployment::DeploymentException,
364cdf0e10cSrcweir uno::RuntimeException)
365cdf0e10cSrcweir {
366cdf0e10cSrcweir //Notify the backend responsible for processing the different media
367cdf0e10cSrcweir //types that this extension was removed.
368cdf0e10cSrcweir ExtensionBackendDb::Data data = readDataFromDb(url);
369cdf0e10cSrcweir for (ExtensionBackendDb::Data::ITC_ITEMS i = data.items.begin(); i != data.items.end(); i++)
370cdf0e10cSrcweir {
371cdf0e10cSrcweir m_xRootRegistry->packageRemoved(i->first, i->second);
372cdf0e10cSrcweir }
373cdf0e10cSrcweir
374cdf0e10cSrcweir if (m_backendDb.get())
375cdf0e10cSrcweir m_backendDb->removeEntry(url);
376cdf0e10cSrcweir }
377cdf0e10cSrcweir
378cdf0e10cSrcweir
379cdf0e10cSrcweir // PackageRegistryBackend
380cdf0e10cSrcweir //______________________________________________________________________________
bindPackage_(OUString const & url,OUString const & mediaType_,sal_Bool bRemoved,OUString const & identifier,Reference<ucb::XCommandEnvironment> const & xCmdEnv)381cdf0e10cSrcweir Reference<deployment::XPackage> BackendImpl::bindPackage_(
382cdf0e10cSrcweir OUString const & url, OUString const & mediaType_,
383cdf0e10cSrcweir sal_Bool bRemoved, OUString const & identifier,
384cdf0e10cSrcweir Reference<ucb::XCommandEnvironment> const & xCmdEnv )
385cdf0e10cSrcweir {
386cdf0e10cSrcweir OUString mediaType( mediaType_ );
387cdf0e10cSrcweir if (mediaType.getLength() == 0)
388cdf0e10cSrcweir {
389cdf0e10cSrcweir // detect media-type:
390cdf0e10cSrcweir ::ucbhelper::Content ucbContent;
391cdf0e10cSrcweir if (create_ucb_content( &ucbContent, url, xCmdEnv ))
392cdf0e10cSrcweir {
393cdf0e10cSrcweir if (ucbContent.isFolder())
394cdf0e10cSrcweir {
395cdf0e10cSrcweir //Every .oxt, uno.pkg file must contain a META-INF folder
396cdf0e10cSrcweir ::ucbhelper::Content metaInfContent;
397cdf0e10cSrcweir if (create_ucb_content(
398cdf0e10cSrcweir &metaInfContent, makeURL( url, OUSTR("META-INF") ),
399cdf0e10cSrcweir xCmdEnv, false /* no throw */ ))
400cdf0e10cSrcweir {
401cdf0e10cSrcweir mediaType = OUSTR("application/vnd.sun.star.package-bundle");
402cdf0e10cSrcweir }
403cdf0e10cSrcweir //No support of legacy bundles, because every folder could be one.
404cdf0e10cSrcweir }
405cdf0e10cSrcweir else
406cdf0e10cSrcweir {
407cdf0e10cSrcweir const OUString title( ucbContent.getPropertyValue(
408cdf0e10cSrcweir StrTitle::get() ).get<OUString>() );
409cdf0e10cSrcweir if (title.endsWithIgnoreAsciiCaseAsciiL(
410cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM(".oxt") ) ||
411cdf0e10cSrcweir title.endsWithIgnoreAsciiCaseAsciiL(
412cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM(".uno.pkg") ))
413cdf0e10cSrcweir mediaType = OUSTR("application/vnd.sun.star.package-bundle");
414cdf0e10cSrcweir else if (title.endsWithIgnoreAsciiCaseAsciiL(
415cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM(".zip") ))
416cdf0e10cSrcweir mediaType =
417cdf0e10cSrcweir OUSTR("application/vnd.sun.star.legacy-package-bundle");
418cdf0e10cSrcweir }
419cdf0e10cSrcweir }
420cdf0e10cSrcweir if (mediaType.getLength() == 0)
421cdf0e10cSrcweir throw lang::IllegalArgumentException(
422cdf0e10cSrcweir StrCannotDetectMediaType::get() + url,
423cdf0e10cSrcweir static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
424cdf0e10cSrcweir }
425cdf0e10cSrcweir
426cdf0e10cSrcweir String type, subType;
427cdf0e10cSrcweir INetContentTypeParameterList params;
428cdf0e10cSrcweir if (INetContentTypes::parse( mediaType, type, subType, ¶ms ))
429cdf0e10cSrcweir {
430cdf0e10cSrcweir if (type.EqualsIgnoreCaseAscii("application"))
431cdf0e10cSrcweir {
432cdf0e10cSrcweir
433cdf0e10cSrcweir //In case a XPackage is created for a removed extension, we cannot
434cdf0e10cSrcweir //obtain the name
435cdf0e10cSrcweir OUString name;
436cdf0e10cSrcweir if (!bRemoved)
437cdf0e10cSrcweir {
438cdf0e10cSrcweir ::ucbhelper::Content ucbContent( url, xCmdEnv );
439cdf0e10cSrcweir name = ucbContent.getPropertyValue(
440cdf0e10cSrcweir StrTitle::get() ).get<OUString>();
441cdf0e10cSrcweir }
442cdf0e10cSrcweir if (subType.EqualsIgnoreCaseAscii("vnd.sun.star.package-bundle")) {
443cdf0e10cSrcweir return new PackageImpl(
444cdf0e10cSrcweir this, url, name, m_xBundleTypeInfo, false, bRemoved,
445cdf0e10cSrcweir identifier);
446cdf0e10cSrcweir }
447cdf0e10cSrcweir else if (subType.EqualsIgnoreCaseAscii(
448cdf0e10cSrcweir "vnd.sun.star.legacy-package-bundle")) {
449cdf0e10cSrcweir return new PackageImpl(
450cdf0e10cSrcweir this, url, name, m_xLegacyBundleTypeInfo, true, bRemoved,
451cdf0e10cSrcweir identifier);
452cdf0e10cSrcweir }
453cdf0e10cSrcweir }
454cdf0e10cSrcweir }
455cdf0e10cSrcweir throw lang::IllegalArgumentException(
456cdf0e10cSrcweir StrUnsupportedMediaType::get() + mediaType,
457cdf0e10cSrcweir static_cast<OWeakObject *>(this),
458cdf0e10cSrcweir static_cast<sal_Int16>(-1) );
459cdf0e10cSrcweir }
460cdf0e10cSrcweir
addDataToDb(OUString const & url,ExtensionBackendDb::Data const & data)461cdf0e10cSrcweir void BackendImpl::addDataToDb(
462cdf0e10cSrcweir OUString const & url, ExtensionBackendDb::Data const & data)
463cdf0e10cSrcweir {
464cdf0e10cSrcweir if (m_backendDb.get())
465cdf0e10cSrcweir m_backendDb->addEntry(url, data);
466cdf0e10cSrcweir }
467cdf0e10cSrcweir
readDataFromDb(OUString const & url)468cdf0e10cSrcweir ExtensionBackendDb::Data BackendImpl::readDataFromDb(
469cdf0e10cSrcweir OUString const & url)
470cdf0e10cSrcweir {
471cdf0e10cSrcweir ExtensionBackendDb::Data data;
472cdf0e10cSrcweir if (m_backendDb.get())
473cdf0e10cSrcweir data = m_backendDb->getEntry(url);
474cdf0e10cSrcweir return data;
475cdf0e10cSrcweir }
476cdf0e10cSrcweir
revokeEntryFromDb(OUString const & url)477cdf0e10cSrcweir void BackendImpl::revokeEntryFromDb(OUString const & url)
478cdf0e10cSrcweir {
479cdf0e10cSrcweir if (m_backendDb.get())
480cdf0e10cSrcweir m_backendDb->revokeEntry(url);
481cdf0e10cSrcweir }
482cdf0e10cSrcweir
483cdf0e10cSrcweir
484cdf0e10cSrcweir //##############################################################################
485cdf0e10cSrcweir
PackageImpl(::rtl::Reference<PackageRegistryBackend> const & myBackend,OUString const & url,OUString const & name,Reference<deployment::XPackageTypeInfo> const & xPackageType,bool legacyBundle,bool bRemoved,OUString const & identifier)486cdf0e10cSrcweir BackendImpl::PackageImpl::PackageImpl(
487cdf0e10cSrcweir ::rtl::Reference<PackageRegistryBackend> const & myBackend,
488cdf0e10cSrcweir OUString const & url,
489cdf0e10cSrcweir OUString const & name,
490cdf0e10cSrcweir Reference<deployment::XPackageTypeInfo> const & xPackageType,
491cdf0e10cSrcweir bool legacyBundle, bool bRemoved, OUString const & identifier)
492cdf0e10cSrcweir : Package( myBackend, url, name, name /* display-name */,
493cdf0e10cSrcweir xPackageType, bRemoved, identifier),
494cdf0e10cSrcweir m_url_expanded( expandUnoRcUrl( url ) ),
495cdf0e10cSrcweir m_legacyBundle( legacyBundle ),
496cdf0e10cSrcweir m_pBundle( 0 )
497cdf0e10cSrcweir {
498cdf0e10cSrcweir if (bRemoved)
499cdf0e10cSrcweir m_dbData = getMyBackend()->readDataFromDb(url);
500cdf0e10cSrcweir }
501cdf0e10cSrcweir
getMyBackend() const502cdf0e10cSrcweir BackendImpl * BackendImpl::PackageImpl::getMyBackend() const
503cdf0e10cSrcweir {
504cdf0e10cSrcweir BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
505cdf0e10cSrcweir if (NULL == pBackend)
506cdf0e10cSrcweir {
507cdf0e10cSrcweir //May throw a DisposedException
508cdf0e10cSrcweir check();
509cdf0e10cSrcweir //We should never get here...
510cdf0e10cSrcweir throw RuntimeException(
511cdf0e10cSrcweir OUSTR("Failed to get the BackendImpl"),
512cdf0e10cSrcweir static_cast<OWeakObject*>(const_cast<PackageImpl *>(this)));
513cdf0e10cSrcweir }
514cdf0e10cSrcweir return pBackend;
515cdf0e10cSrcweir }
516cdf0e10cSrcweir //______________________________________________________________________________
disposing()517cdf0e10cSrcweir void BackendImpl::PackageImpl::disposing()
518cdf0e10cSrcweir {
519cdf0e10cSrcweir sal_Int32 len = m_bundle.getLength();
520cdf0e10cSrcweir Reference<deployment::XPackage> const * p = m_bundle.getConstArray();
521cdf0e10cSrcweir for ( sal_Int32 pos = 0; pos < len; ++pos )
522cdf0e10cSrcweir try_dispose( p[ pos ] );
523cdf0e10cSrcweir m_bundle.realloc( 0 );
524cdf0e10cSrcweir
525cdf0e10cSrcweir Package::disposing();
526cdf0e10cSrcweir }
527cdf0e10cSrcweir
528cdf0e10cSrcweir // Package
529cdf0e10cSrcweir //______________________________________________________________________________
530cdf0e10cSrcweir beans::Optional< beans::Ambiguous<sal_Bool> >
isRegistered_(::osl::ResettableMutexGuard &,::rtl::Reference<AbortChannel> const & abortChannel,Reference<ucb::XCommandEnvironment> const & xCmdEnv)531cdf0e10cSrcweir BackendImpl::PackageImpl::isRegistered_(
532cdf0e10cSrcweir ::osl::ResettableMutexGuard &,
533cdf0e10cSrcweir ::rtl::Reference<AbortChannel> const & abortChannel,
534cdf0e10cSrcweir Reference<ucb::XCommandEnvironment> const & xCmdEnv )
535cdf0e10cSrcweir {
536cdf0e10cSrcweir //In case the object was created for a removed extension (m_bRemoved = true)
537cdf0e10cSrcweir //but the extension is not registered, then bundle will be empty. Then
538cdf0e10cSrcweir //the return value will be Optional<...>.IsPresent= false. Althoug this is
539cdf0e10cSrcweir //not true, this does not matter. Then registerPackage or revokePackage
540cdf0e10cSrcweir //would never be called for the items. But since the extension is removed
541cdf0e10cSrcweir //and not registered anyway, this does not matter.
542cdf0e10cSrcweir const Sequence< Reference<deployment::XPackage> > bundle(
543cdf0e10cSrcweir getBundle( abortChannel.get(), xCmdEnv ) );
544cdf0e10cSrcweir
545cdf0e10cSrcweir bool reg = false;
546cdf0e10cSrcweir bool present = false;
547cdf0e10cSrcweir bool ambig = false;
548cdf0e10cSrcweir for ( sal_Int32 pos = bundle.getLength(); pos--; )
549cdf0e10cSrcweir {
550cdf0e10cSrcweir Reference<deployment::XPackage> const & xPackage = bundle[ pos ];
551cdf0e10cSrcweir Reference<task::XAbortChannel> xSubAbortChannel(
552cdf0e10cSrcweir xPackage->createAbortChannel() );
553cdf0e10cSrcweir AbortChannel::Chain chain( abortChannel, xSubAbortChannel );
554cdf0e10cSrcweir beans::Optional< beans::Ambiguous<sal_Bool> > option(
555cdf0e10cSrcweir xPackage->isRegistered( xSubAbortChannel, xCmdEnv ) );
556cdf0e10cSrcweir
557cdf0e10cSrcweir //present = true if at least one bundle item has this value.
558cdf0e10cSrcweir //reg = true if all bundle items have an option value (option.IsPresent == 1)
559cdf0e10cSrcweir //and all have value of true (option.Value.Value == true)
560cdf0e10cSrcweir //If not, then the bundle has the status of not registered and ambiguous.
561cdf0e10cSrcweir if (option.IsPresent)
562cdf0e10cSrcweir {
563cdf0e10cSrcweir beans::Ambiguous<sal_Bool> const & status = option.Value;
564cdf0e10cSrcweir if (present)
565cdf0e10cSrcweir {
566cdf0e10cSrcweir //we never come here in the first iteration
567cdf0e10cSrcweir if (reg != (status.Value != sal_False)) {
568cdf0e10cSrcweir
569cdf0e10cSrcweir ambig = true;
570cdf0e10cSrcweir reg = false;
571cdf0e10cSrcweir break;
572cdf0e10cSrcweir }
573cdf0e10cSrcweir }
574cdf0e10cSrcweir else
575cdf0e10cSrcweir {
576cdf0e10cSrcweir //we always come here in the first iteration
577cdf0e10cSrcweir reg = status.Value;
578cdf0e10cSrcweir present = true;
579cdf0e10cSrcweir }
580cdf0e10cSrcweir }
581cdf0e10cSrcweir }
582cdf0e10cSrcweir return beans::Optional< beans::Ambiguous<sal_Bool> >(
583cdf0e10cSrcweir present, beans::Ambiguous<sal_Bool>(reg, ambig) );
584cdf0e10cSrcweir }
585cdf0e10cSrcweir
getTextFromURL(const css::uno::Reference<css::ucb::XCommandEnvironment> & xCmdEnv,const OUString & licenseUrl)586cdf0e10cSrcweir OUString BackendImpl::PackageImpl::getTextFromURL(
587cdf0e10cSrcweir const css::uno::Reference< css::ucb::XCommandEnvironment >& xCmdEnv,
588cdf0e10cSrcweir const OUString& licenseUrl)
589cdf0e10cSrcweir {
590cdf0e10cSrcweir try
591cdf0e10cSrcweir {
592cdf0e10cSrcweir ::ucbhelper::Content descContent(licenseUrl, xCmdEnv);
593cdf0e10cSrcweir ::rtl::ByteSequence seq = dp_misc::readFile(descContent);
594cdf0e10cSrcweir return OUString( reinterpret_cast<sal_Char const *>(
595cdf0e10cSrcweir seq.getConstArray()), seq.getLength(), RTL_TEXTENCODING_UTF8);
596cdf0e10cSrcweir }
597cdf0e10cSrcweir catch (css::uno::Exception&)
598cdf0e10cSrcweir {
599cdf0e10cSrcweir Any exc( ::cppu::getCaughtException() );
600cdf0e10cSrcweir throw css::deployment::DeploymentException(
601cdf0e10cSrcweir OUSTR("Could not read file ") + licenseUrl, 0, exc);
602cdf0e10cSrcweir }
603cdf0e10cSrcweir
604cdf0e10cSrcweir }
605cdf0e10cSrcweir
getDescriptionInfoset()606cdf0e10cSrcweir DescriptionInfoset BackendImpl::PackageImpl::getDescriptionInfoset()
607cdf0e10cSrcweir {
608cdf0e10cSrcweir return dp_misc::getDescriptionInfoset(m_url_expanded);
609cdf0e10cSrcweir }
610cdf0e10cSrcweir
checkPlatform(css::uno::Reference<css::ucb::XCommandEnvironment> const & environment)611cdf0e10cSrcweir bool BackendImpl::PackageImpl::checkPlatform(
612cdf0e10cSrcweir css::uno::Reference< css::ucb::XCommandEnvironment > const & environment)
613cdf0e10cSrcweir {
614cdf0e10cSrcweir bool ret = false;
615cdf0e10cSrcweir DescriptionInfoset info(getDescriptionInfoset());
616cdf0e10cSrcweir Sequence<OUString> platforms(info.getSupportedPlaforms());
617cdf0e10cSrcweir if (hasValidPlatform(platforms))
618cdf0e10cSrcweir {
619cdf0e10cSrcweir ret = true;
620cdf0e10cSrcweir }
621cdf0e10cSrcweir else
622cdf0e10cSrcweir {
623cdf0e10cSrcweir ret = false;
624cdf0e10cSrcweir rtl::OUString msg(
625cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("unsupported platform"));
626cdf0e10cSrcweir Any e(
627cdf0e10cSrcweir css::deployment::PlatformException(
628cdf0e10cSrcweir msg, static_cast<OWeakObject *>(this), this));
629cdf0e10cSrcweir if (!interactContinuation(
630cdf0e10cSrcweir e, cppu::UnoType< css::task::XInteractionApprove >::get(),
631cdf0e10cSrcweir environment, NULL, NULL))
632cdf0e10cSrcweir {
633cdf0e10cSrcweir throw css::deployment::DeploymentException(
634cdf0e10cSrcweir msg, static_cast<OWeakObject *>(this), e);
635cdf0e10cSrcweir }
636cdf0e10cSrcweir }
637cdf0e10cSrcweir return ret;
638cdf0e10cSrcweir }
639cdf0e10cSrcweir
640cdf0e10cSrcweir
checkDependencies(css::uno::Reference<css::ucb::XCommandEnvironment> const & environment,DescriptionInfoset const & description)641cdf0e10cSrcweir bool BackendImpl::PackageImpl::checkDependencies(
642cdf0e10cSrcweir css::uno::Reference< css::ucb::XCommandEnvironment > const & environment,
643cdf0e10cSrcweir DescriptionInfoset const & description)
644cdf0e10cSrcweir {
645cdf0e10cSrcweir css::uno::Sequence< css::uno::Reference< css::xml::dom::XElement > >
646cdf0e10cSrcweir unsatisfied(dp_misc::Dependencies::check(description));
647cdf0e10cSrcweir
648cdf0e10cSrcweir if (unsatisfied.getLength() == 0) {
649cdf0e10cSrcweir return true;
650cdf0e10cSrcweir } else {
651cdf0e10cSrcweir rtl::OUString msg(
652cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("unsatisfied dependencies"));
653cdf0e10cSrcweir Any e(
654cdf0e10cSrcweir css::deployment::DependencyException(
655cdf0e10cSrcweir msg, static_cast<OWeakObject *>(this), unsatisfied));
656cdf0e10cSrcweir if (!interactContinuation(
657cdf0e10cSrcweir e, cppu::UnoType< css::task::XInteractionApprove >::get(),
658cdf0e10cSrcweir environment, NULL, NULL))
659cdf0e10cSrcweir {
660cdf0e10cSrcweir throw css::deployment::DeploymentException(
661cdf0e10cSrcweir msg, static_cast<OWeakObject *>(this), e);
662cdf0e10cSrcweir }
663cdf0e10cSrcweir return false;
664cdf0e10cSrcweir }
665cdf0e10cSrcweir }
666cdf0e10cSrcweir
checkLicense(css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv,DescriptionInfoset const & info,bool alreadyInstalled)667cdf0e10cSrcweir ::sal_Bool BackendImpl::PackageImpl::checkLicense(
668cdf0e10cSrcweir css::uno::Reference< css::ucb::XCommandEnvironment > const & xCmdEnv,
669cdf0e10cSrcweir DescriptionInfoset const & info, bool alreadyInstalled)
670cdf0e10cSrcweir throw (css::deployment::DeploymentException,
671cdf0e10cSrcweir css::ucb::CommandFailedException,
672cdf0e10cSrcweir css::ucb::CommandAbortedException,
673cdf0e10cSrcweir css::uno::RuntimeException)
674cdf0e10cSrcweir {
675cdf0e10cSrcweir try
676cdf0e10cSrcweir {
677cdf0e10cSrcweir ::boost::optional<SimpleLicenseAttributes> simplLicAttr
678cdf0e10cSrcweir = info.getSimpleLicenseAttributes();
679cdf0e10cSrcweir if (! simplLicAttr)
680cdf0e10cSrcweir return true;
681cdf0e10cSrcweir OUString sLic = info.getLocalizedLicenseURL();
682cdf0e10cSrcweir //If we do not get a localized licence then there is an error in the description.xml
683cdf0e10cSrcweir //This should be handled by using a validating parser. Therefore we assume that no
684cdf0e10cSrcweir //license is available.
685cdf0e10cSrcweir if (sLic.getLength() == 0)
686cdf0e10cSrcweir throw css::deployment::DeploymentException(
687cdf0e10cSrcweir OUSTR("Could not obtain path to license. Possible error in description.xml"), 0, Any());
688cdf0e10cSrcweir OUString sHref = m_url_expanded + OUSTR("/") + sLic;
689cdf0e10cSrcweir OUString sLicense = getTextFromURL(xCmdEnv, sHref);
690cdf0e10cSrcweir ////determine who has to agree to the license
691cdf0e10cSrcweir //check correct value for attribute
692cdf0e10cSrcweir if ( ! (simplLicAttr->acceptBy.equals(OUSTR("user")) || simplLicAttr->acceptBy.equals(OUSTR("admin"))))
693cdf0e10cSrcweir throw css::deployment::DeploymentException(
694cdf0e10cSrcweir OUSTR("Could not obtain attribute simple-lincense@accept-by or it has no valid value"), 0, Any());
695cdf0e10cSrcweir
696cdf0e10cSrcweir
697cdf0e10cSrcweir //Only use interaction if there is no version of this extension already installed
698cdf0e10cSrcweir //and the suppress-on-update flag is not set for the new extension
699cdf0e10cSrcweir // alreadyInstalled | bSuppressOnUpdate | show license
700cdf0e10cSrcweir //----------------------------------------
701cdf0e10cSrcweir // 0 | 0 | 1
702cdf0e10cSrcweir // 0 | 1 | 1
703cdf0e10cSrcweir // 1 | 0 | 1
704cdf0e10cSrcweir // 1 | 1 | 0
705cdf0e10cSrcweir
706cdf0e10cSrcweir if ( !(alreadyInstalled && simplLicAttr->suppressOnUpdate))
707cdf0e10cSrcweir {
708cdf0e10cSrcweir css::deployment::LicenseException licExc(
709cdf0e10cSrcweir OUString(), 0, getDisplayName(), sLicense,
710cdf0e10cSrcweir simplLicAttr->acceptBy);
711cdf0e10cSrcweir bool approve = false;
712cdf0e10cSrcweir bool abort = false;
713cdf0e10cSrcweir if (! interactContinuation(
714cdf0e10cSrcweir Any(licExc), task::XInteractionApprove::static_type(), xCmdEnv, &approve, &abort ))
715cdf0e10cSrcweir throw css::deployment::DeploymentException(
716cdf0e10cSrcweir OUSTR("Could not interact with user."), 0, Any());
717cdf0e10cSrcweir
718cdf0e10cSrcweir if (approve == true)
719cdf0e10cSrcweir return true;
720cdf0e10cSrcweir else
721cdf0e10cSrcweir return false;
722cdf0e10cSrcweir //throw css::deployment::DeploymentException(
723cdf0e10cSrcweir // OUSTR("Extension Manager: User declined the license."),
724cdf0e10cSrcweir // static_cast<OWeakObject*>(this),
725cdf0e10cSrcweir // Any( css::deployment::LicenseException(OUSTR("User declined the license."), 0, m_name, sLicense)));
726cdf0e10cSrcweir }
727cdf0e10cSrcweir return true;
728cdf0e10cSrcweir } catch (css::ucb::CommandFailedException&) {
729cdf0e10cSrcweir throw;
730cdf0e10cSrcweir } catch (css::ucb::CommandAbortedException&) {
731cdf0e10cSrcweir throw;
732cdf0e10cSrcweir } catch (css::deployment::DeploymentException&) {
733cdf0e10cSrcweir throw;
734cdf0e10cSrcweir } catch (css::uno::RuntimeException&) {
735cdf0e10cSrcweir throw;
736cdf0e10cSrcweir } catch (css::uno::Exception&) {
737cdf0e10cSrcweir Any anyExc = cppu::getCaughtException();
738cdf0e10cSrcweir throw css::deployment::DeploymentException(OUSTR("Unexpected exception"), 0, anyExc);
739cdf0e10cSrcweir }
740cdf0e10cSrcweir }
741cdf0e10cSrcweir
checkPrerequisites(const css::uno::Reference<css::task::XAbortChannel> &,const css::uno::Reference<css::ucb::XCommandEnvironment> & xCmdEnv,sal_Bool alreadyInstalled)742cdf0e10cSrcweir ::sal_Int32 BackendImpl::PackageImpl::checkPrerequisites(
743cdf0e10cSrcweir const css::uno::Reference< css::task::XAbortChannel >&,
744cdf0e10cSrcweir const css::uno::Reference< css::ucb::XCommandEnvironment >& xCmdEnv,
745cdf0e10cSrcweir sal_Bool alreadyInstalled)
746cdf0e10cSrcweir throw (css::deployment::DeploymentException,
747cdf0e10cSrcweir css::deployment::ExtensionRemovedException,
748cdf0e10cSrcweir css::ucb::CommandFailedException,
749cdf0e10cSrcweir css::ucb::CommandAbortedException,
750cdf0e10cSrcweir css::uno::RuntimeException)
751cdf0e10cSrcweir {
752cdf0e10cSrcweir if (m_bRemoved)
753cdf0e10cSrcweir throw deployment::ExtensionRemovedException();
754cdf0e10cSrcweir DescriptionInfoset info = getDescriptionInfoset();
755cdf0e10cSrcweir if (!info.hasDescription())
756cdf0e10cSrcweir return 0;
757cdf0e10cSrcweir
758cdf0e10cSrcweir //always return LICENSE as long as the user did not accept the license
759cdf0e10cSrcweir //so that XExtensonManager::checkPrerequisitesAndEnable will again
760cdf0e10cSrcweir //check the license
761cdf0e10cSrcweir if (!checkPlatform(xCmdEnv))
762cdf0e10cSrcweir return deployment::Prerequisites::PLATFORM |
763cdf0e10cSrcweir deployment::Prerequisites::LICENSE;
764cdf0e10cSrcweir else if(!checkDependencies(xCmdEnv, info))
765cdf0e10cSrcweir return deployment::Prerequisites::DEPENDENCIES |
766cdf0e10cSrcweir deployment::Prerequisites::LICENSE;
767cdf0e10cSrcweir else if(!checkLicense(xCmdEnv, info, alreadyInstalled))
768cdf0e10cSrcweir return deployment::Prerequisites::LICENSE;
769cdf0e10cSrcweir else
770cdf0e10cSrcweir return 0;
771cdf0e10cSrcweir }
772cdf0e10cSrcweir
checkDependencies(const css::uno::Reference<css::ucb::XCommandEnvironment> & xCmdEnv)773cdf0e10cSrcweir ::sal_Bool BackendImpl::PackageImpl::checkDependencies(
774cdf0e10cSrcweir const css::uno::Reference< css::ucb::XCommandEnvironment >& xCmdEnv )
775cdf0e10cSrcweir throw (deployment::DeploymentException,
776cdf0e10cSrcweir deployment::ExtensionRemovedException,
777cdf0e10cSrcweir ucb::CommandFailedException,
778cdf0e10cSrcweir RuntimeException)
779cdf0e10cSrcweir {
780cdf0e10cSrcweir if (m_bRemoved)
781cdf0e10cSrcweir throw deployment::ExtensionRemovedException();
782cdf0e10cSrcweir DescriptionInfoset info = getDescriptionInfoset();
783cdf0e10cSrcweir if (!info.hasDescription())
784cdf0e10cSrcweir return sal_True;
785cdf0e10cSrcweir
786cdf0e10cSrcweir return checkDependencies(xCmdEnv, info);
787cdf0e10cSrcweir }
788cdf0e10cSrcweir
getIdentifier()789cdf0e10cSrcweir beans::Optional<OUString> BackendImpl::PackageImpl::getIdentifier()
790cdf0e10cSrcweir throw (RuntimeException)
791cdf0e10cSrcweir {
792cdf0e10cSrcweir OUString identifier;
793cdf0e10cSrcweir if (m_bRemoved)
794cdf0e10cSrcweir identifier = m_identifier;
795cdf0e10cSrcweir else
796cdf0e10cSrcweir identifier = dp_misc::generateIdentifier(
797cdf0e10cSrcweir getDescriptionInfoset().getIdentifier(), m_name);
798cdf0e10cSrcweir
799cdf0e10cSrcweir return beans::Optional<OUString>(
800cdf0e10cSrcweir true, identifier);
801cdf0e10cSrcweir }
802cdf0e10cSrcweir
getVersion()803cdf0e10cSrcweir OUString BackendImpl::PackageImpl::getVersion()
804cdf0e10cSrcweir throw (deployment::ExtensionRemovedException, RuntimeException)
805cdf0e10cSrcweir {
806cdf0e10cSrcweir if (m_bRemoved)
807cdf0e10cSrcweir throw deployment::ExtensionRemovedException();
808cdf0e10cSrcweir return getDescriptionInfoset().getVersion();
809cdf0e10cSrcweir }
810cdf0e10cSrcweir
getUpdateInformationURLs()811cdf0e10cSrcweir Sequence<OUString> BackendImpl::PackageImpl::getUpdateInformationURLs()
812cdf0e10cSrcweir throw (deployment::ExtensionRemovedException, RuntimeException)
813cdf0e10cSrcweir {
814cdf0e10cSrcweir if (m_bRemoved)
815cdf0e10cSrcweir throw deployment::ExtensionRemovedException();
816cdf0e10cSrcweir return getDescriptionInfoset().getUpdateInformationUrls();
817cdf0e10cSrcweir }
818cdf0e10cSrcweir
getPublisherInfo()819cdf0e10cSrcweir beans::StringPair BackendImpl::PackageImpl::getPublisherInfo()
820cdf0e10cSrcweir throw (deployment::ExtensionRemovedException, RuntimeException)
821cdf0e10cSrcweir {
822cdf0e10cSrcweir if (m_bRemoved)
823cdf0e10cSrcweir throw deployment::ExtensionRemovedException();
824cdf0e10cSrcweir ::std::pair< OUString, OUString > aInfo = getDescriptionInfoset().getLocalizedPublisherNameAndURL();
825cdf0e10cSrcweir beans::StringPair aStrPair( aInfo.first, aInfo.second );
826cdf0e10cSrcweir return aStrPair;
827cdf0e10cSrcweir }
828cdf0e10cSrcweir
829cdf0e10cSrcweir //______________________________________________________________________________
getIcon(sal_Bool bHighContrast)830cdf0e10cSrcweir uno::Reference< graphic::XGraphic > BackendImpl::PackageImpl::getIcon( sal_Bool bHighContrast )
831cdf0e10cSrcweir throw (deployment::ExtensionRemovedException, RuntimeException )
832cdf0e10cSrcweir {
833cdf0e10cSrcweir if (m_bRemoved)
834cdf0e10cSrcweir throw deployment::ExtensionRemovedException();
835cdf0e10cSrcweir
836cdf0e10cSrcweir uno::Reference< graphic::XGraphic > xGraphic;
837cdf0e10cSrcweir
838cdf0e10cSrcweir OUString aIconURL = getDescriptionInfoset().getIconURL( bHighContrast );
839cdf0e10cSrcweir if ( aIconURL.getLength() )
840cdf0e10cSrcweir {
841cdf0e10cSrcweir OUString aFullIconURL = m_url_expanded + OUSTR("/") + aIconURL;
842cdf0e10cSrcweir
843cdf0e10cSrcweir uno::Reference< XComponentContext > xContext( getMyBackend()->getComponentContext() );
844cdf0e10cSrcweir uno::Reference< graphic::XGraphicProvider > xGraphProvider(
845cdf0e10cSrcweir xContext->getServiceManager()->createInstanceWithContext( OUSTR( "com.sun.star.graphic.GraphicProvider" ), xContext ),
846cdf0e10cSrcweir uno::UNO_QUERY );
847cdf0e10cSrcweir
848cdf0e10cSrcweir if ( xGraphProvider.is() )
849cdf0e10cSrcweir {
850cdf0e10cSrcweir uno::Sequence< beans::PropertyValue > aMediaProps( 1 );
851cdf0e10cSrcweir aMediaProps[0].Name = OUSTR( "URL" );
852cdf0e10cSrcweir aMediaProps[0].Value <<= aFullIconURL;
853cdf0e10cSrcweir
854cdf0e10cSrcweir xGraphic = xGraphProvider->queryGraphic( aMediaProps );
855cdf0e10cSrcweir }
856cdf0e10cSrcweir }
857cdf0e10cSrcweir
858cdf0e10cSrcweir return xGraphic;
859cdf0e10cSrcweir }
860cdf0e10cSrcweir
861cdf0e10cSrcweir //______________________________________________________________________________
processPackage_(::osl::ResettableMutexGuard &,bool doRegisterPackage,bool startup,::rtl::Reference<AbortChannel> const & abortChannel,Reference<ucb::XCommandEnvironment> const & xCmdEnv)862cdf0e10cSrcweir void BackendImpl::PackageImpl::processPackage_(
863cdf0e10cSrcweir ::osl::ResettableMutexGuard &,
864cdf0e10cSrcweir bool doRegisterPackage,
865cdf0e10cSrcweir bool startup,
866cdf0e10cSrcweir ::rtl::Reference<AbortChannel> const & abortChannel,
867cdf0e10cSrcweir Reference<ucb::XCommandEnvironment> const & xCmdEnv )
868cdf0e10cSrcweir {
869cdf0e10cSrcweir const Sequence< Reference<deployment::XPackage> > bundle(
870cdf0e10cSrcweir getBundle( abortChannel.get(), xCmdEnv ) );
871cdf0e10cSrcweir
872cdf0e10cSrcweir if (doRegisterPackage)
873cdf0e10cSrcweir {
874cdf0e10cSrcweir ExtensionBackendDb::Data data;
875cdf0e10cSrcweir const sal_Int32 len = bundle.getLength();
876cdf0e10cSrcweir for ( sal_Int32 pos = 0; pos < len; ++pos )
877cdf0e10cSrcweir {
878cdf0e10cSrcweir checkAborted(abortChannel);
879cdf0e10cSrcweir Reference<deployment::XPackage> const & xPackage = bundle[ pos ];
880cdf0e10cSrcweir Reference<task::XAbortChannel> xSubAbortChannel(
881cdf0e10cSrcweir xPackage->createAbortChannel() );
882cdf0e10cSrcweir AbortChannel::Chain chain( abortChannel, xSubAbortChannel );
883cdf0e10cSrcweir try {
884cdf0e10cSrcweir xPackage->registerPackage( startup, xSubAbortChannel, xCmdEnv );
885cdf0e10cSrcweir }
886cdf0e10cSrcweir catch (Exception &)
887cdf0e10cSrcweir {
888cdf0e10cSrcweir //We even try a rollback if the user cancelled the action (CommandAbortedException)
889cdf0e10cSrcweir //in order to prevent invalid database entries.
890cdf0e10cSrcweir Any exc( ::cppu::getCaughtException() );
891cdf0e10cSrcweir // try to handle exception, notify:
892cdf0e10cSrcweir bool approve = false, abort = false;
893cdf0e10cSrcweir if (! interactContinuation(
894cdf0e10cSrcweir Any( lang::WrappedTargetException(
895cdf0e10cSrcweir OUSTR("bundle item registration error!"),
896cdf0e10cSrcweir static_cast<OWeakObject *>(this), exc ) ),
897cdf0e10cSrcweir task::XInteractionApprove::static_type(), xCmdEnv,
898cdf0e10cSrcweir &approve, &abort )) {
899cdf0e10cSrcweir OSL_ASSERT( !approve && !abort );
900cdf0e10cSrcweir if (m_legacyBundle) // default for legacy packages: ignore
901cdf0e10cSrcweir continue;
902cdf0e10cSrcweir // no selection at all, so rethrow;
903cdf0e10cSrcweir // no C++ rethrow after getCaughtException(),
904cdf0e10cSrcweir // see cppuhelper/exc_hlp.hxx:
905cdf0e10cSrcweir ::cppu::throwException(exc);
906cdf0e10cSrcweir }
907cdf0e10cSrcweir if (approve && !abort) // ignore error, just continue
908cdf0e10cSrcweir continue;
909cdf0e10cSrcweir
910cdf0e10cSrcweir {
911cdf0e10cSrcweir ProgressLevel progress(
912cdf0e10cSrcweir xCmdEnv, OUSTR("rollback...") );
913cdf0e10cSrcweir // try rollback
914cdf0e10cSrcweir for ( ; pos--; )
915cdf0e10cSrcweir {
916cdf0e10cSrcweir try {
917cdf0e10cSrcweir bundle[ pos ]->revokePackage(
918cdf0e10cSrcweir xSubAbortChannel, xCmdEnv );
919cdf0e10cSrcweir }
920cdf0e10cSrcweir catch (Exception &)
921cdf0e10cSrcweir {
922cdf0e10cSrcweir OSL_ENSURE( 0, ::rtl::OUStringToOString(
923cdf0e10cSrcweir ::comphelper::anyToString(
924cdf0e10cSrcweir ::cppu::getCaughtException() ),
925cdf0e10cSrcweir RTL_TEXTENCODING_UTF8 ).getStr() );
926cdf0e10cSrcweir // ignore any errors of rollback
927cdf0e10cSrcweir }
928cdf0e10cSrcweir }
929cdf0e10cSrcweir progress.update( OUSTR("rollback finished.") );
930cdf0e10cSrcweir }
931cdf0e10cSrcweir
932cdf0e10cSrcweir deployment::DeploymentException dpExc;
933cdf0e10cSrcweir if (exc >>= dpExc) {
934cdf0e10cSrcweir throw ucb::CommandFailedException(
935cdf0e10cSrcweir dpExc.Message, dpExc.Context, dpExc.Cause );
936cdf0e10cSrcweir }
937cdf0e10cSrcweir else {
938cdf0e10cSrcweir // rethrow CommandFailedException
939cdf0e10cSrcweir ::cppu::throwException(exc);
940cdf0e10cSrcweir }
941cdf0e10cSrcweir }
942cdf0e10cSrcweir data.items.push_back(
943cdf0e10cSrcweir ::std::make_pair(xPackage->getURL(),
944cdf0e10cSrcweir xPackage->getPackageType()->getMediaType()));
945cdf0e10cSrcweir }
946cdf0e10cSrcweir getMyBackend()->addDataToDb(getURL(), data);
947cdf0e10cSrcweir }
948cdf0e10cSrcweir else
949cdf0e10cSrcweir {
950cdf0e10cSrcweir // revoke in reverse order:
951cdf0e10cSrcweir for ( sal_Int32 pos = bundle.getLength(); pos--; )
952cdf0e10cSrcweir {
953cdf0e10cSrcweir checkAborted(abortChannel);
954cdf0e10cSrcweir Reference<deployment::XPackage> const & xPackage = bundle[ pos ];
955cdf0e10cSrcweir Reference<task::XAbortChannel> xSubAbortChannel(
956cdf0e10cSrcweir xPackage->createAbortChannel() );
957cdf0e10cSrcweir AbortChannel::Chain chain( abortChannel, xSubAbortChannel );
958cdf0e10cSrcweir try {
959cdf0e10cSrcweir bundle[ pos ]->revokePackage( xSubAbortChannel, xCmdEnv );
960cdf0e10cSrcweir }
961cdf0e10cSrcweir catch (RuntimeException &) {
962cdf0e10cSrcweir throw;
963cdf0e10cSrcweir }
964cdf0e10cSrcweir catch (ucb::CommandAbortedException &) {
965cdf0e10cSrcweir throw;
966cdf0e10cSrcweir }
967cdf0e10cSrcweir catch (Exception &) {
968cdf0e10cSrcweir // CommandFailedException, DeploymentException:
969cdf0e10cSrcweir Any exc( ::cppu::getCaughtException() );
970cdf0e10cSrcweir // try to handle exception, notify:
971cdf0e10cSrcweir bool approve = false, abort = false;
972cdf0e10cSrcweir if (! interactContinuation(
973cdf0e10cSrcweir Any( lang::WrappedTargetException(
974cdf0e10cSrcweir OUSTR("bundle item revocation error!"),
975cdf0e10cSrcweir static_cast<OWeakObject *>(this), exc ) ),
976cdf0e10cSrcweir task::XInteractionApprove::static_type(), xCmdEnv,
977cdf0e10cSrcweir &approve, &abort )) {
978cdf0e10cSrcweir OSL_ASSERT( !approve && !abort );
979cdf0e10cSrcweir if (m_legacyBundle) // default for legacy packages: ignore
980cdf0e10cSrcweir continue;
981cdf0e10cSrcweir // no selection at all, so rethrow
982cdf0e10cSrcweir // no C++ rethrow after getCaughtException(),
983cdf0e10cSrcweir // see cppuhelper/exc_hlp.hxx:
984cdf0e10cSrcweir ::cppu::throwException(exc);
985cdf0e10cSrcweir }
986cdf0e10cSrcweir // ignore errors when revoking, although abort may have been
987cdf0e10cSrcweir // selected
988cdf0e10cSrcweir }
989cdf0e10cSrcweir }
990cdf0e10cSrcweir getMyBackend()->revokeEntryFromDb(getURL());
991cdf0e10cSrcweir }
992cdf0e10cSrcweir }
993cdf0e10cSrcweir
994cdf0e10cSrcweir //______________________________________________________________________________
getDescription()995cdf0e10cSrcweir OUString BackendImpl::PackageImpl::getDescription()
996cdf0e10cSrcweir throw (deployment::ExtensionRemovedException, RuntimeException)
997cdf0e10cSrcweir {
998cdf0e10cSrcweir if (m_bRemoved)
999cdf0e10cSrcweir throw deployment::ExtensionRemovedException();
1000cdf0e10cSrcweir
1001cdf0e10cSrcweir const OUString sRelativeURL(getDescriptionInfoset().getLocalizedDescriptionURL());
1002cdf0e10cSrcweir OUString sDescription;
1003cdf0e10cSrcweir if (sRelativeURL.getLength())
1004cdf0e10cSrcweir {
1005cdf0e10cSrcweir OUString sURL = m_url_expanded + OUSTR("/") + sRelativeURL;
1006cdf0e10cSrcweir
1007cdf0e10cSrcweir try
1008cdf0e10cSrcweir {
1009cdf0e10cSrcweir sDescription = getTextFromURL( css::uno::Reference< css::ucb::XCommandEnvironment >(), sURL );
1010cdf0e10cSrcweir }
1011cdf0e10cSrcweir catch ( css::deployment::DeploymentException& )
1012cdf0e10cSrcweir {
1013cdf0e10cSrcweir OSL_ENSURE( 0, ::rtl::OUStringToOString( ::comphelper::anyToString( ::cppu::getCaughtException() ), RTL_TEXTENCODING_UTF8 ).getStr() );
1014cdf0e10cSrcweir }
1015cdf0e10cSrcweir }
1016cdf0e10cSrcweir
1017cdf0e10cSrcweir if (sDescription.getLength())
1018cdf0e10cSrcweir return sDescription;
1019cdf0e10cSrcweir return m_oldDescription;
1020cdf0e10cSrcweir }
1021cdf0e10cSrcweir
1022cdf0e10cSrcweir //______________________________________________________________________________
getLicenseText()1023cdf0e10cSrcweir OUString BackendImpl::PackageImpl::getLicenseText()
1024cdf0e10cSrcweir throw (deployment::ExtensionRemovedException, RuntimeException)
1025cdf0e10cSrcweir {
1026cdf0e10cSrcweir if (m_bRemoved)
1027cdf0e10cSrcweir throw deployment::ExtensionRemovedException();
1028cdf0e10cSrcweir
1029cdf0e10cSrcweir OUString sLicense;
1030cdf0e10cSrcweir DescriptionInfoset aInfo = getDescriptionInfoset();
1031cdf0e10cSrcweir
1032cdf0e10cSrcweir ::boost::optional< SimpleLicenseAttributes > aSimplLicAttr = aInfo.getSimpleLicenseAttributes();
1033cdf0e10cSrcweir if ( aSimplLicAttr )
1034cdf0e10cSrcweir {
1035cdf0e10cSrcweir OUString aLicenseURL = aInfo.getLocalizedLicenseURL();
1036cdf0e10cSrcweir
1037cdf0e10cSrcweir if ( aLicenseURL.getLength() )
1038cdf0e10cSrcweir {
1039cdf0e10cSrcweir OUString aFullURL = m_url_expanded + OUSTR("/") + aLicenseURL;
1040cdf0e10cSrcweir sLicense = getTextFromURL( Reference< ucb::XCommandEnvironment >(), aFullURL);
1041cdf0e10cSrcweir }
1042cdf0e10cSrcweir }
1043cdf0e10cSrcweir
1044cdf0e10cSrcweir return sLicense;
1045cdf0e10cSrcweir }
1046cdf0e10cSrcweir
1047cdf0e10cSrcweir //______________________________________________________________________________
exportTo(OUString const & destFolderURL,OUString const & newTitle,sal_Int32 nameClashAction,Reference<ucb::XCommandEnvironment> const & xCmdEnv)1048cdf0e10cSrcweir void BackendImpl::PackageImpl::exportTo(
1049cdf0e10cSrcweir OUString const & destFolderURL, OUString const & newTitle,
1050cdf0e10cSrcweir sal_Int32 nameClashAction, Reference<ucb::XCommandEnvironment> const & xCmdEnv )
1051cdf0e10cSrcweir throw (ucb::CommandFailedException,
1052cdf0e10cSrcweir deployment::ExtensionRemovedException,
1053cdf0e10cSrcweir ucb::CommandAbortedException, RuntimeException)
1054cdf0e10cSrcweir {
1055cdf0e10cSrcweir if (m_bRemoved)
1056cdf0e10cSrcweir throw deployment::ExtensionRemovedException();
1057cdf0e10cSrcweir
1058cdf0e10cSrcweir ::ucbhelper::Content sourceContent( m_url_expanded, xCmdEnv );
1059cdf0e10cSrcweir OUString title(newTitle);
1060cdf0e10cSrcweir if (title.getLength() == 0)
1061cdf0e10cSrcweir sourceContent.getPropertyValue( StrTitle::get() ) >>= title;
1062cdf0e10cSrcweir OUString destURL( makeURL( destFolderURL, ::rtl::Uri::encode(
1063cdf0e10cSrcweir title, rtl_UriCharClassPchar,
1064cdf0e10cSrcweir rtl_UriEncodeIgnoreEscapes,
1065cdf0e10cSrcweir RTL_TEXTENCODING_UTF8 ) ) );
1066cdf0e10cSrcweir
1067cdf0e10cSrcweir if (nameClashAction == ucb::NameClash::ASK)
1068cdf0e10cSrcweir {
1069cdf0e10cSrcweir if (create_ucb_content(
1070cdf0e10cSrcweir 0, destURL, xCmdEnv, false /* no throw */ )) {
1071cdf0e10cSrcweir bool replace = false, abort = false;
1072cdf0e10cSrcweir if (! interactContinuation(
1073cdf0e10cSrcweir Any( ucb::NameClashResolveRequest(
1074cdf0e10cSrcweir OUSTR("file already exists: ") + title,
1075cdf0e10cSrcweir static_cast<OWeakObject *>(this),
1076cdf0e10cSrcweir task::InteractionClassification_QUERY,
1077cdf0e10cSrcweir destFolderURL, title, OUString() ) ),
1078cdf0e10cSrcweir ucb::XInteractionReplaceExistingData::static_type(), xCmdEnv,
1079cdf0e10cSrcweir &replace, &abort ) || !replace) {
1080cdf0e10cSrcweir return;
1081cdf0e10cSrcweir }
1082cdf0e10cSrcweir }
1083cdf0e10cSrcweir }
1084cdf0e10cSrcweir else if (nameClashAction != ucb::NameClash::OVERWRITE) {
1085cdf0e10cSrcweir throw ucb::CommandFailedException(
1086cdf0e10cSrcweir OUSTR("unsupported nameClashAction!"),
1087cdf0e10cSrcweir static_cast<OWeakObject *>(this), Any() );
1088cdf0e10cSrcweir }
1089cdf0e10cSrcweir erase_path( destURL, xCmdEnv );
1090cdf0e10cSrcweir
1091cdf0e10cSrcweir ::rtl::OUStringBuffer buf;
1092cdf0e10cSrcweir buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.zip://") );
1093cdf0e10cSrcweir buf.append( ::rtl::Uri::encode( destURL,
1094cdf0e10cSrcweir rtl_UriCharClassRegName,
1095cdf0e10cSrcweir rtl_UriEncodeIgnoreEscapes,
1096cdf0e10cSrcweir RTL_TEXTENCODING_UTF8 ) );
1097cdf0e10cSrcweir buf.append( static_cast<sal_Unicode>('/') );
1098cdf0e10cSrcweir OUString destFolder( buf.makeStringAndClear() );
1099cdf0e10cSrcweir
1100cdf0e10cSrcweir ::ucbhelper::Content destFolderContent( destFolder, xCmdEnv );
1101cdf0e10cSrcweir {
1102cdf0e10cSrcweir // transfer every item of folder into zip:
1103cdf0e10cSrcweir Reference<sdbc::XResultSet> xResultSet(
1104cdf0e10cSrcweir sourceContent.createCursor(
1105cdf0e10cSrcweir Sequence<OUString>(),
1106cdf0e10cSrcweir ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS ) );
1107cdf0e10cSrcweir ProgressLevel progress( xCmdEnv, OUString() );
1108cdf0e10cSrcweir while (xResultSet->next())
1109cdf0e10cSrcweir {
1110cdf0e10cSrcweir ::ucbhelper::Content subContent(
1111cdf0e10cSrcweir Reference<ucb::XContentAccess>(
1112cdf0e10cSrcweir xResultSet, UNO_QUERY_THROW )->queryContent(), xCmdEnv );
1113cdf0e10cSrcweir if (! destFolderContent.transferContent(
1114cdf0e10cSrcweir subContent, ::ucbhelper::InsertOperation_COPY,
1115cdf0e10cSrcweir OUString(), ucb::NameClash::OVERWRITE ))
1116cdf0e10cSrcweir throw RuntimeException( OUSTR("UCB transferContent() failed!"),
1117cdf0e10cSrcweir static_cast<OWeakObject *>(this) );
1118cdf0e10cSrcweir progress.update( Any() ); // animating progress bar
1119cdf0e10cSrcweir }
1120cdf0e10cSrcweir }
1121cdf0e10cSrcweir
1122cdf0e10cSrcweir // assure META-INF folder:
1123cdf0e10cSrcweir ::ucbhelper::Content metainfFolderContent;
1124cdf0e10cSrcweir create_folder( &metainfFolderContent,
1125cdf0e10cSrcweir makeURL( destFolderContent.getURL(), OUSTR("META-INF") ),
1126cdf0e10cSrcweir xCmdEnv );
1127cdf0e10cSrcweir
1128cdf0e10cSrcweir if (m_legacyBundle)
1129cdf0e10cSrcweir {
1130cdf0e10cSrcweir // easy to migrate legacy bundles to new format:
1131cdf0e10cSrcweir // just export them once using a .oxt name!
1132cdf0e10cSrcweir // set detected media-types of any bundle item:
1133cdf0e10cSrcweir
1134cdf0e10cSrcweir // collect all manifest entries:
1135cdf0e10cSrcweir Sequence< Reference<deployment::XPackage> > bundle;
1136cdf0e10cSrcweir try {
1137cdf0e10cSrcweir bundle = getBundle( Reference<task::XAbortChannel>(), xCmdEnv );
1138cdf0e10cSrcweir }
1139cdf0e10cSrcweir // xxx todo: think about exception specs:
1140cdf0e10cSrcweir catch (deployment::DeploymentException &) {
1141cdf0e10cSrcweir OSL_ENSURE( 0, ::rtl::OUStringToOString(
1142cdf0e10cSrcweir ::comphelper::anyToString(
1143cdf0e10cSrcweir ::cppu::getCaughtException() ),
1144cdf0e10cSrcweir RTL_TEXTENCODING_UTF8 ).getStr() );
1145cdf0e10cSrcweir }
1146cdf0e10cSrcweir catch (lang::IllegalArgumentException & exc) {
1147cdf0e10cSrcweir (void) exc;
1148cdf0e10cSrcweir OSL_ENSURE( 0, ::rtl::OUStringToOString(
1149cdf0e10cSrcweir exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
1150cdf0e10cSrcweir }
1151cdf0e10cSrcweir
1152cdf0e10cSrcweir ::std::vector< Sequence<beans::PropertyValue> > manifest;
1153cdf0e10cSrcweir manifest.reserve( bundle.getLength() );
1154cdf0e10cSrcweir sal_Int32 baseURLlen = m_url_expanded.getLength();
1155cdf0e10cSrcweir Reference<deployment::XPackage> const *pbundle = bundle.getConstArray();
1156cdf0e10cSrcweir const OUString strMediaType = OUSTR("MediaType");
1157cdf0e10cSrcweir const OUString strFullPath = OUSTR("FullPath");
1158cdf0e10cSrcweir const OUString strIsFolder = OUSTR("IsFolder");
1159cdf0e10cSrcweir for ( sal_Int32 pos = bundle.getLength(); pos--; )
1160cdf0e10cSrcweir {
1161cdf0e10cSrcweir Reference<deployment::XPackage> const & xPackage = pbundle[ pos ];
1162cdf0e10cSrcweir OUString url_( expandUnoRcUrl( xPackage->getURL() ) );
1163cdf0e10cSrcweir OSL_ASSERT( url_.getLength() >= baseURLlen );
1164cdf0e10cSrcweir OUString fullPath;
1165cdf0e10cSrcweir if (url_.getLength() > baseURLlen)
1166cdf0e10cSrcweir fullPath = url_.copy( baseURLlen + 1 );
1167cdf0e10cSrcweir ::ucbhelper::Content ucbContent( url_, xCmdEnv );
1168cdf0e10cSrcweir if (ucbContent.getPropertyValue(strIsFolder).get<bool>())
1169cdf0e10cSrcweir fullPath += OUSTR("/");
1170cdf0e10cSrcweir Sequence<beans::PropertyValue> attribs( 2 );
1171cdf0e10cSrcweir beans::PropertyValue * pattribs = attribs.getArray();
1172cdf0e10cSrcweir pattribs[ 0 ].Name = strFullPath;
1173cdf0e10cSrcweir pattribs[ 0 ].Value <<= fullPath;
1174cdf0e10cSrcweir pattribs[ 1 ].Name = strMediaType;
1175cdf0e10cSrcweir const Reference<deployment::XPackageTypeInfo> xPackageType(
1176cdf0e10cSrcweir xPackage->getPackageType() );
1177cdf0e10cSrcweir OUString mediaType;
1178cdf0e10cSrcweir OSL_ASSERT( xPackageType.is() );
1179cdf0e10cSrcweir if (xPackageType.is())
1180cdf0e10cSrcweir mediaType = xPackageType->getMediaType();
1181cdf0e10cSrcweir else
1182cdf0e10cSrcweir mediaType = OUSTR("unknown");
1183cdf0e10cSrcweir pattribs[ 1 ].Value <<= mediaType;
1184cdf0e10cSrcweir manifest.push_back( attribs );
1185cdf0e10cSrcweir }
1186cdf0e10cSrcweir
1187cdf0e10cSrcweir // write into pipe:
1188cdf0e10cSrcweir Reference<XComponentContext> xContext(
1189cdf0e10cSrcweir getMyBackend()->getComponentContext() );
1190cdf0e10cSrcweir Reference<packages::manifest::XManifestWriter> xManifestWriter(
1191cdf0e10cSrcweir xContext->getServiceManager()->createInstanceWithContext(
1192cdf0e10cSrcweir OUSTR("com.sun.star.packages.manifest.ManifestWriter"),
1193cdf0e10cSrcweir xContext ), UNO_QUERY_THROW );
1194cdf0e10cSrcweir Reference<io::XOutputStream> xPipe(
1195cdf0e10cSrcweir xContext->getServiceManager()->createInstanceWithContext(
1196cdf0e10cSrcweir OUSTR("com.sun.star.io.Pipe"), xContext ), UNO_QUERY_THROW );
1197cdf0e10cSrcweir xManifestWriter->writeManifestSequence(
1198cdf0e10cSrcweir xPipe, comphelper::containerToSequence(manifest) );
1199cdf0e10cSrcweir
1200cdf0e10cSrcweir // write buffered pipe data to content:
1201cdf0e10cSrcweir ::ucbhelper::Content manifestContent(
1202cdf0e10cSrcweir makeURL( metainfFolderContent.getURL(), OUSTR("manifest.xml") ),
1203cdf0e10cSrcweir xCmdEnv );
1204cdf0e10cSrcweir manifestContent.writeStream(
1205cdf0e10cSrcweir Reference<io::XInputStream>( xPipe, UNO_QUERY_THROW ),
1206cdf0e10cSrcweir true /* replace existing */ );
1207cdf0e10cSrcweir }
1208cdf0e10cSrcweir else
1209cdf0e10cSrcweir {
1210cdf0e10cSrcweir // overwrite manifest.xml:
1211cdf0e10cSrcweir ::ucbhelper::Content manifestContent;
1212cdf0e10cSrcweir if ( ! create_ucb_content(
1213cdf0e10cSrcweir &manifestContent,
1214cdf0e10cSrcweir makeURL( m_url_expanded, OUSTR("META-INF/manifest.xml") ),
1215cdf0e10cSrcweir xCmdEnv, false ) )
1216cdf0e10cSrcweir {
1217cdf0e10cSrcweir OSL_ENSURE( 0, "### missing META-INF/manifest.xml file!" );
1218cdf0e10cSrcweir return;
1219cdf0e10cSrcweir }
1220cdf0e10cSrcweir
1221cdf0e10cSrcweir if (! metainfFolderContent.transferContent(
1222cdf0e10cSrcweir manifestContent, ::ucbhelper::InsertOperation_COPY,
1223cdf0e10cSrcweir OUString(), ucb::NameClash::OVERWRITE ))
1224cdf0e10cSrcweir throw RuntimeException( OUSTR("UCB transferContent() failed!"),
1225cdf0e10cSrcweir static_cast<OWeakObject *>(this) );
1226cdf0e10cSrcweir }
1227cdf0e10cSrcweir
1228cdf0e10cSrcweir // xxx todo: maybe obsolete in the future
1229cdf0e10cSrcweir try {
1230cdf0e10cSrcweir destFolderContent.executeCommand( OUSTR("flush"), Any() );
1231cdf0e10cSrcweir }
1232cdf0e10cSrcweir catch (ucb::UnsupportedCommandException &) {
1233cdf0e10cSrcweir }
1234cdf0e10cSrcweir }
1235cdf0e10cSrcweir
1236cdf0e10cSrcweir //______________________________________________________________________________
isBundle()1237cdf0e10cSrcweir sal_Bool BackendImpl::PackageImpl::isBundle() throw (RuntimeException)
1238cdf0e10cSrcweir {
1239cdf0e10cSrcweir return true;
1240cdf0e10cSrcweir }
1241cdf0e10cSrcweir
1242cdf0e10cSrcweir //______________________________________________________________________________
getBundle(Reference<task::XAbortChannel> const & xAbortChannel,Reference<ucb::XCommandEnvironment> const & xCmdEnv)1243cdf0e10cSrcweir Sequence< Reference<deployment::XPackage> > BackendImpl::PackageImpl::getBundle(
1244cdf0e10cSrcweir Reference<task::XAbortChannel> const & xAbortChannel,
1245cdf0e10cSrcweir Reference<ucb::XCommandEnvironment> const & xCmdEnv )
1246cdf0e10cSrcweir throw (deployment::DeploymentException,
1247cdf0e10cSrcweir ucb::CommandFailedException, ucb::CommandAbortedException,
1248cdf0e10cSrcweir lang::IllegalArgumentException, RuntimeException)
1249cdf0e10cSrcweir {
1250cdf0e10cSrcweir Sequence< Reference<deployment::XPackage> > * pBundle = m_pBundle;
1251cdf0e10cSrcweir if (pBundle == 0)
1252cdf0e10cSrcweir {
1253cdf0e10cSrcweir t_packagevec bundle;
1254cdf0e10cSrcweir if (m_bRemoved)
1255cdf0e10cSrcweir {
1256cdf0e10cSrcweir bundle = getPackagesFromDb(xCmdEnv);
1257cdf0e10cSrcweir }
1258cdf0e10cSrcweir else
1259cdf0e10cSrcweir {
1260cdf0e10cSrcweir try {
1261cdf0e10cSrcweir if (m_legacyBundle)
1262cdf0e10cSrcweir {
1263cdf0e10cSrcweir // .zip legacy packages allow script.xlb, dialog.xlb in bundle
1264cdf0e10cSrcweir // root folder:
1265cdf0e10cSrcweir OUString mediaType;
1266cdf0e10cSrcweir // probe for script.xlb:
1267cdf0e10cSrcweir if (create_ucb_content(
1268cdf0e10cSrcweir 0, makeURL( m_url_expanded, OUSTR("script.xlb") ),
1269cdf0e10cSrcweir xCmdEnv, false /* no throw */ )) {
1270cdf0e10cSrcweir mediaType = OUSTR("application/vnd.sun.star.basic-library");
1271cdf0e10cSrcweir }
1272cdf0e10cSrcweir // probe for dialog.xlb:
1273cdf0e10cSrcweir else if (create_ucb_content(
1274cdf0e10cSrcweir 0, makeURL( m_url_expanded, OUSTR("dialog.xlb") ),
1275cdf0e10cSrcweir xCmdEnv, false /* no throw */ ))
1276cdf0e10cSrcweir mediaType = OUSTR("application/vnd.sun.star."
1277cdf0e10cSrcweir "dialog-library");
1278cdf0e10cSrcweir
1279cdf0e10cSrcweir if (mediaType.getLength() > 0) {
1280cdf0e10cSrcweir const Reference<deployment::XPackage> xPackage(
1281cdf0e10cSrcweir bindBundleItem( getURL(), mediaType, false, OUString(),
1282cdf0e10cSrcweir xCmdEnv ) );
1283cdf0e10cSrcweir if (xPackage.is())
1284cdf0e10cSrcweir bundle.push_back( xPackage );
1285cdf0e10cSrcweir // continue scanning:
1286cdf0e10cSrcweir }
1287cdf0e10cSrcweir scanLegacyBundle( bundle, getURL(),
1288cdf0e10cSrcweir AbortChannel::get(xAbortChannel), xCmdEnv );
1289cdf0e10cSrcweir }
1290cdf0e10cSrcweir else
1291cdf0e10cSrcweir {
1292cdf0e10cSrcweir // .oxt:
1293cdf0e10cSrcweir scanBundle( bundle, AbortChannel::get(xAbortChannel), xCmdEnv );
1294cdf0e10cSrcweir }
1295cdf0e10cSrcweir
1296cdf0e10cSrcweir }
1297cdf0e10cSrcweir catch (RuntimeException &) {
1298cdf0e10cSrcweir throw;
1299cdf0e10cSrcweir }
1300cdf0e10cSrcweir catch (ucb::CommandFailedException &) {
1301cdf0e10cSrcweir throw;
1302cdf0e10cSrcweir }
1303cdf0e10cSrcweir catch (ucb::CommandAbortedException &) {
1304cdf0e10cSrcweir throw;
1305cdf0e10cSrcweir }
1306cdf0e10cSrcweir catch (deployment::DeploymentException &) {
1307cdf0e10cSrcweir throw;
1308cdf0e10cSrcweir }
1309cdf0e10cSrcweir catch (Exception &) {
1310cdf0e10cSrcweir Any exc( ::cppu::getCaughtException() );
1311cdf0e10cSrcweir throw deployment::DeploymentException(
1312cdf0e10cSrcweir OUSTR("error scanning bundle: ") + getURL(),
1313cdf0e10cSrcweir static_cast<OWeakObject *>(this), exc );
1314cdf0e10cSrcweir }
1315cdf0e10cSrcweir }
1316cdf0e10cSrcweir
1317cdf0e10cSrcweir // sort: schema before config data, typelibs before components:
1318cdf0e10cSrcweir Sequence< Reference<deployment::XPackage> > ret( bundle.size() );
1319cdf0e10cSrcweir Reference<deployment::XPackage> * pret = ret.getArray();
1320cdf0e10cSrcweir sal_Int32 lower_end = 0;
1321cdf0e10cSrcweir sal_Int32 upper_end = ret.getLength();
1322cdf0e10cSrcweir t_packagevec::const_iterator iPos( bundle.begin() );
1323cdf0e10cSrcweir t_packagevec::const_iterator const iEnd( bundle.end() );
1324cdf0e10cSrcweir for ( ; iPos != iEnd; ++iPos )
1325cdf0e10cSrcweir {
1326cdf0e10cSrcweir const Reference<deployment::XPackageTypeInfo> xPackageType(
1327cdf0e10cSrcweir (*iPos)->getPackageType() );
1328cdf0e10cSrcweir OSL_ASSERT( xPackageType.is() );
1329cdf0e10cSrcweir if (xPackageType.is()) {
1330cdf0e10cSrcweir const OUString mediaType( xPackageType->getMediaType() );
1331cdf0e10cSrcweir String type, subType;
1332cdf0e10cSrcweir INetContentTypeParameterList params;
1333cdf0e10cSrcweir if (INetContentTypes::parse(
1334cdf0e10cSrcweir mediaType, type, subType, ¶ms ) &&
1335cdf0e10cSrcweir type.EqualsIgnoreCaseAscii("application") &&
1336cdf0e10cSrcweir (subType.EqualsIgnoreCaseAscii(
1337cdf0e10cSrcweir "vnd.sun.star.uno-component") ||
1338cdf0e10cSrcweir subType.EqualsIgnoreCaseAscii(
1339cdf0e10cSrcweir "vnd.sun.star.configuration-data")))
1340cdf0e10cSrcweir {
1341cdf0e10cSrcweir --upper_end;
1342cdf0e10cSrcweir pret[ upper_end ] = *iPos;
1343cdf0e10cSrcweir continue;
1344cdf0e10cSrcweir }
1345cdf0e10cSrcweir }
1346cdf0e10cSrcweir pret[ lower_end ] = *iPos;
1347cdf0e10cSrcweir ++lower_end;
1348cdf0e10cSrcweir }
1349cdf0e10cSrcweir OSL_ASSERT( lower_end == upper_end );
1350cdf0e10cSrcweir
1351cdf0e10cSrcweir const ::osl::MutexGuard guard( getMutex() );
1352cdf0e10cSrcweir pBundle = m_pBundle;
1353cdf0e10cSrcweir if (pBundle == 0) {
1354cdf0e10cSrcweir m_bundle = ret;
1355cdf0e10cSrcweir pBundle = &m_bundle;
1356cdf0e10cSrcweir OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
1357cdf0e10cSrcweir m_pBundle = pBundle;
1358cdf0e10cSrcweir }
1359cdf0e10cSrcweir }
1360cdf0e10cSrcweir else {
1361cdf0e10cSrcweir OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
1362cdf0e10cSrcweir }
1363cdf0e10cSrcweir return *pBundle;
1364cdf0e10cSrcweir }
1365cdf0e10cSrcweir
isBundle_(OUString const & mediaType)1366cdf0e10cSrcweir inline bool isBundle_( OUString const & mediaType )
1367cdf0e10cSrcweir {
1368cdf0e10cSrcweir // xxx todo: additional parsing?
1369cdf0e10cSrcweir return mediaType.getLength() > 0 &&
1370cdf0e10cSrcweir (mediaType.matchIgnoreAsciiCaseAsciiL(
1371cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM(
1372cdf0e10cSrcweir "application/vnd.sun.star.package-bundle") ) ||
1373cdf0e10cSrcweir mediaType.matchIgnoreAsciiCaseAsciiL(
1374cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM(
1375cdf0e10cSrcweir "application/vnd.sun.star.legacy-package-bundle") ));
1376cdf0e10cSrcweir }
1377cdf0e10cSrcweir
1378cdf0e10cSrcweir //______________________________________________________________________________
bindBundleItem(OUString const & url,OUString const & mediaType,sal_Bool bRemoved,OUString const & identifier,Reference<ucb::XCommandEnvironment> const & xCmdEnv,bool notifyDetectionError)1379cdf0e10cSrcweir Reference<deployment::XPackage> BackendImpl::PackageImpl::bindBundleItem(
1380cdf0e10cSrcweir OUString const & url, OUString const & mediaType,
1381cdf0e10cSrcweir sal_Bool bRemoved, OUString const & identifier,
1382cdf0e10cSrcweir Reference<ucb::XCommandEnvironment> const & xCmdEnv,
1383cdf0e10cSrcweir bool notifyDetectionError )
1384cdf0e10cSrcweir {
1385cdf0e10cSrcweir // ignore any nested bundles:
1386cdf0e10cSrcweir if (isBundle_(mediaType))
1387cdf0e10cSrcweir return Reference<deployment::XPackage>();
1388cdf0e10cSrcweir
1389cdf0e10cSrcweir Reference<deployment::XPackage>xPackage;
1390cdf0e10cSrcweir try {
1391cdf0e10cSrcweir xPackage.set( getMyBackend()->m_xRootRegistry->bindPackage(
1392cdf0e10cSrcweir url, mediaType, bRemoved, identifier, xCmdEnv ) );
1393cdf0e10cSrcweir OSL_ASSERT( xPackage.is() );
1394cdf0e10cSrcweir }
1395cdf0e10cSrcweir catch (RuntimeException &) {
1396cdf0e10cSrcweir throw;
1397cdf0e10cSrcweir }
1398cdf0e10cSrcweir catch (ucb::CommandFailedException &) {
1399cdf0e10cSrcweir // ignore already handled error
1400cdf0e10cSrcweir }
1401cdf0e10cSrcweir catch (Exception &) {
1402cdf0e10cSrcweir const Any exc( ::cppu::getCaughtException() );
1403cdf0e10cSrcweir if (notifyDetectionError ||
1404cdf0e10cSrcweir !exc.isExtractableTo(
1405cdf0e10cSrcweir ::getCppuType( reinterpret_cast<
1406cdf0e10cSrcweir lang::IllegalArgumentException const *>(0) ) ))
1407cdf0e10cSrcweir {
1408cdf0e10cSrcweir interactContinuation(
1409cdf0e10cSrcweir Any( lang::WrappedTargetException(
1410cdf0e10cSrcweir OUSTR("bundle item error!"),
1411cdf0e10cSrcweir static_cast<OWeakObject *>(this), exc ) ),
1412cdf0e10cSrcweir task::XInteractionApprove::static_type(), xCmdEnv, 0, 0 );
1413cdf0e10cSrcweir }
1414cdf0e10cSrcweir }
1415cdf0e10cSrcweir
1416cdf0e10cSrcweir if (xPackage.is()) {
1417cdf0e10cSrcweir const Reference<deployment::XPackageTypeInfo> xPackageType(
1418cdf0e10cSrcweir xPackage->getPackageType() );
1419cdf0e10cSrcweir OSL_ASSERT( xPackageType.is() );
1420cdf0e10cSrcweir // ignore any nested bundles:
1421cdf0e10cSrcweir if (xPackageType.is() && isBundle_( xPackageType->getMediaType() ))
1422cdf0e10cSrcweir xPackage.clear();
1423cdf0e10cSrcweir }
1424cdf0e10cSrcweir return xPackage;
1425cdf0e10cSrcweir }
1426cdf0e10cSrcweir
1427cdf0e10cSrcweir //______________________________________________________________________________
scanBundle(t_packagevec & bundle,::rtl::Reference<AbortChannel> const & abortChannel,Reference<ucb::XCommandEnvironment> const & xCmdEnv)1428cdf0e10cSrcweir void BackendImpl::PackageImpl::scanBundle(
1429cdf0e10cSrcweir t_packagevec & bundle,
1430cdf0e10cSrcweir ::rtl::Reference<AbortChannel> const & abortChannel,
1431cdf0e10cSrcweir Reference<ucb::XCommandEnvironment> const & xCmdEnv )
1432cdf0e10cSrcweir {
1433cdf0e10cSrcweir OSL_ASSERT( !m_legacyBundle );
1434cdf0e10cSrcweir
1435cdf0e10cSrcweir ::ucbhelper::Content manifestContent;
1436cdf0e10cSrcweir if (! create_ucb_content(
1437cdf0e10cSrcweir &manifestContent,
1438cdf0e10cSrcweir makeURL( m_url_expanded, OUSTR("META-INF/manifest.xml") ),
1439cdf0e10cSrcweir xCmdEnv, false /* no throw */ ))
1440cdf0e10cSrcweir {
1441cdf0e10cSrcweir OSL_ENSURE( 0, "### missing META-INF/manifest.xml file!" );
1442cdf0e10cSrcweir return;
1443cdf0e10cSrcweir }
1444cdf0e10cSrcweir
1445cdf0e10cSrcweir
1446cdf0e10cSrcweir const lang::Locale officeLocale = getOfficeLocale();
1447cdf0e10cSrcweir OUString descrFile;
1448cdf0e10cSrcweir lang::Locale descrFileLocale;
1449cdf0e10cSrcweir
1450cdf0e10cSrcweir const Reference<XComponentContext> xContext(
1451cdf0e10cSrcweir getMyBackend()->getComponentContext() );
1452cdf0e10cSrcweir Reference<packages::manifest::XManifestReader> xManifestReader(
1453cdf0e10cSrcweir xContext->getServiceManager()->createInstanceWithContext(
1454cdf0e10cSrcweir OUSTR("com.sun.star.packages.manifest.ManifestReader"),
1455cdf0e10cSrcweir xContext ), UNO_QUERY_THROW );
1456cdf0e10cSrcweir const Sequence< Sequence<beans::PropertyValue> > manifestSeq(
1457cdf0e10cSrcweir xManifestReader->readManifestSequence( manifestContent.openStream() ) );
1458cdf0e10cSrcweir const OUString packageRootURL( getURL() );
1459cdf0e10cSrcweir for ( sal_Int32 pos = manifestSeq.getLength(); pos--; )
1460cdf0e10cSrcweir {
1461cdf0e10cSrcweir OUString fullPath, mediaType;
1462cdf0e10cSrcweir Sequence<beans::PropertyValue> const & attribs = manifestSeq[ pos ];
1463cdf0e10cSrcweir for ( sal_Int32 i = attribs.getLength(); i--; )
1464cdf0e10cSrcweir {
1465cdf0e10cSrcweir if (fullPath.getLength() > 0 && mediaType.getLength() > 0)
1466cdf0e10cSrcweir break;
1467cdf0e10cSrcweir if (attribs[i].Name.equalsAsciiL(
1468cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM("FullPath") ))
1469cdf0e10cSrcweir attribs[i].Value >>= fullPath;
1470cdf0e10cSrcweir else if (attribs[i].Name.equalsAsciiL(
1471cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM("MediaType") ))
1472cdf0e10cSrcweir attribs[i].Value >>= mediaType;
1473cdf0e10cSrcweir }
1474cdf0e10cSrcweir
1475cdf0e10cSrcweir if (fullPath.getLength() == 0 || mediaType.getLength() == 0 ||
1476cdf0e10cSrcweir mediaType.equalsAsciiL( // opt: exclude common text/xml
1477cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM("text/xml") ))
1478cdf0e10cSrcweir continue;
1479cdf0e10cSrcweir
1480cdf0e10cSrcweir String type, subType;
1481cdf0e10cSrcweir INetContentTypeParameterList params;
1482cdf0e10cSrcweir if (! INetContentTypes::parse( mediaType, type, subType, ¶ms ))
1483cdf0e10cSrcweir continue;
1484cdf0e10cSrcweir
1485cdf0e10cSrcweir INetContentTypeParameter const * param = params.find(
1486cdf0e10cSrcweir ByteString("platform") );
1487cdf0e10cSrcweir if (param != 0 && !platform_fits( param->m_sValue ))
1488cdf0e10cSrcweir continue;
1489cdf0e10cSrcweir const OUString url( makeURL( packageRootURL, fullPath ) );
1490cdf0e10cSrcweir
1491cdf0e10cSrcweir // check for bundle description:
1492cdf0e10cSrcweir if (type.EqualsIgnoreCaseAscii("application") &&
1493cdf0e10cSrcweir subType.EqualsIgnoreCaseAscii(
1494cdf0e10cSrcweir "vnd.sun.star.package-bundle-description"))
1495cdf0e10cSrcweir {
1496cdf0e10cSrcweir // check locale:
1497cdf0e10cSrcweir param = params.find( ByteString("locale") );
1498cdf0e10cSrcweir if (param == 0) {
1499cdf0e10cSrcweir if (descrFile.getLength() == 0)
1500cdf0e10cSrcweir descrFile = url;
1501cdf0e10cSrcweir }
1502cdf0e10cSrcweir else {
1503cdf0e10cSrcweir // match best locale:
1504cdf0e10cSrcweir lang::Locale locale( toLocale(param->m_sValue) );
1505cdf0e10cSrcweir if (locale.Language == officeLocale.Language)
1506cdf0e10cSrcweir {
1507cdf0e10cSrcweir if (descrFileLocale.Country == officeLocale.Country
1508cdf0e10cSrcweir && locale.Country != officeLocale.Country)
1509cdf0e10cSrcweir continue;
1510cdf0e10cSrcweir if (descrFileLocale.Variant == officeLocale.Variant
1511cdf0e10cSrcweir && locale.Variant != officeLocale.Variant)
1512cdf0e10cSrcweir continue;
1513cdf0e10cSrcweir descrFile = url;
1514cdf0e10cSrcweir descrFileLocale = locale;
1515cdf0e10cSrcweir }
1516cdf0e10cSrcweir }
1517cdf0e10cSrcweir continue;
1518cdf0e10cSrcweir }
1519cdf0e10cSrcweir
1520cdf0e10cSrcweir checkAborted( abortChannel );
1521cdf0e10cSrcweir
1522cdf0e10cSrcweir //We make sure that we only create one XPackage for a particular URL.
1523cdf0e10cSrcweir //Sometime programmers insert the same URL several times in the manifest
1524cdf0e10cSrcweir //which may lead to DisposedExceptions.
1525cdf0e10cSrcweir if (bundle.end() == std::find_if(bundle.begin(), bundle.end(), XPackage_eq(url)))
1526cdf0e10cSrcweir {
1527cdf0e10cSrcweir const Reference<deployment::XPackage> xPackage(
1528cdf0e10cSrcweir bindBundleItem( url, mediaType, false, OUString(), xCmdEnv ) );
1529cdf0e10cSrcweir if (xPackage.is())
1530cdf0e10cSrcweir bundle.push_back( xPackage );
1531cdf0e10cSrcweir }
1532cdf0e10cSrcweir else
1533cdf0e10cSrcweir {
1534cdf0e10cSrcweir fprintf(stderr, "manifest.xml contains a duplicate entry!\n");
1535cdf0e10cSrcweir }
1536cdf0e10cSrcweir }
1537cdf0e10cSrcweir
1538cdf0e10cSrcweir if (descrFile.getLength() > 0)
1539cdf0e10cSrcweir {
1540cdf0e10cSrcweir ::ucbhelper::Content descrFileContent;
1541cdf0e10cSrcweir if (create_ucb_content( &descrFileContent, descrFile,
1542cdf0e10cSrcweir xCmdEnv, false /* no throw */ ))
1543cdf0e10cSrcweir {
1544cdf0e10cSrcweir // patch description:
1545cdf0e10cSrcweir ::rtl::ByteSequence bytes( readFile( descrFileContent ) );
1546cdf0e10cSrcweir ::rtl::OUStringBuffer buf;
1547cdf0e10cSrcweir if ( bytes.getLength() )
1548cdf0e10cSrcweir {
1549cdf0e10cSrcweir buf.append( OUString( reinterpret_cast<sal_Char const *>(
1550cdf0e10cSrcweir bytes.getConstArray() ),
1551cdf0e10cSrcweir bytes.getLength(), RTL_TEXTENCODING_UTF8 ) );
1552cdf0e10cSrcweir }
1553cdf0e10cSrcweir else
1554cdf0e10cSrcweir {
1555cdf0e10cSrcweir buf.append( Package::getDescription() );
1556cdf0e10cSrcweir }
1557cdf0e10cSrcweir m_oldDescription = buf.makeStringAndClear();
1558cdf0e10cSrcweir }
1559cdf0e10cSrcweir }
1560cdf0e10cSrcweir }
1561cdf0e10cSrcweir
1562cdf0e10cSrcweir //______________________________________________________________________________
scanLegacyBundle(t_packagevec & bundle,OUString const & url,::rtl::Reference<AbortChannel> const & abortChannel,Reference<ucb::XCommandEnvironment> const & xCmdEnv,bool skip_registration)1563cdf0e10cSrcweir void BackendImpl::PackageImpl::scanLegacyBundle(
1564cdf0e10cSrcweir t_packagevec & bundle,
1565cdf0e10cSrcweir OUString const & url,
1566cdf0e10cSrcweir ::rtl::Reference<AbortChannel> const & abortChannel,
1567cdf0e10cSrcweir Reference<ucb::XCommandEnvironment> const & xCmdEnv,
1568cdf0e10cSrcweir bool skip_registration )
1569cdf0e10cSrcweir {
1570cdf0e10cSrcweir ::ucbhelper::Content ucbContent( url, xCmdEnv );
1571cdf0e10cSrcweir
1572cdf0e10cSrcweir // check for platform pathes:
1573cdf0e10cSrcweir const OUString title( ucbContent.getPropertyValue(
1574cdf0e10cSrcweir StrTitle::get() ).get<OUString>() );
1575cdf0e10cSrcweir if (title.endsWithIgnoreAsciiCaseAsciiL(
1576cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM(".plt") ) &&
1577cdf0e10cSrcweir !platform_fits( title.copy( 0, title.getLength() - 4 ) )) {
1578cdf0e10cSrcweir return;
1579cdf0e10cSrcweir }
1580cdf0e10cSrcweir if (title.endsWithIgnoreAsciiCaseAsciiL(
1581cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM("skip_registration") ))
1582cdf0e10cSrcweir skip_registration = true;
1583cdf0e10cSrcweir
1584cdf0e10cSrcweir OUString ar [] = { StrTitle::get(), OUSTR("IsFolder") };
1585cdf0e10cSrcweir Reference<sdbc::XResultSet> xResultSet(
1586cdf0e10cSrcweir ucbContent.createCursor(
1587cdf0e10cSrcweir Sequence<OUString>( ar, ARLEN(ar) ),
1588cdf0e10cSrcweir ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS ) );
1589cdf0e10cSrcweir while (xResultSet->next())
1590cdf0e10cSrcweir {
1591cdf0e10cSrcweir checkAborted( abortChannel );
1592cdf0e10cSrcweir
1593cdf0e10cSrcweir const Reference<sdbc::XRow> xRow( xResultSet, UNO_QUERY_THROW );
1594cdf0e10cSrcweir const OUString title_enc( ::rtl::Uri::encode(
1595cdf0e10cSrcweir xRow->getString( 1 /* Title */ ),
1596cdf0e10cSrcweir rtl_UriCharClassPchar,
1597cdf0e10cSrcweir rtl_UriEncodeIgnoreEscapes,
1598cdf0e10cSrcweir RTL_TEXTENCODING_UTF8 ) );
1599cdf0e10cSrcweir const OUString path( makeURL( url, title_enc ) );
1600cdf0e10cSrcweir
1601cdf0e10cSrcweir OUString mediaType;
1602cdf0e10cSrcweir const Reference<deployment::XPackage> xPackage(
1603cdf0e10cSrcweir bindBundleItem( path, OUString() /* detect */, false, OUString(),
1604cdf0e10cSrcweir xCmdEnv, false /* ignore detection errors */ ) );
1605cdf0e10cSrcweir if (xPackage.is()) {
1606cdf0e10cSrcweir const Reference<deployment::XPackageTypeInfo> xPackageType(
1607cdf0e10cSrcweir xPackage->getPackageType() );
1608cdf0e10cSrcweir OSL_ASSERT( xPackageType.is() );
1609cdf0e10cSrcweir if (xPackageType.is())
1610cdf0e10cSrcweir mediaType = xPackageType->getMediaType();
1611cdf0e10cSrcweir
1612cdf0e10cSrcweir if (skip_registration &&
1613cdf0e10cSrcweir // xxx todo: additional parsing?
1614cdf0e10cSrcweir mediaType.matchIgnoreAsciiCaseAsciiL(
1615cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM(
1616cdf0e10cSrcweir "application/vnd.sun.star.uno-component") ))
1617cdf0e10cSrcweir continue;
1618cdf0e10cSrcweir
1619cdf0e10cSrcweir bundle.push_back( xPackage );
1620cdf0e10cSrcweir }
1621cdf0e10cSrcweir
1622cdf0e10cSrcweir if (mediaType.getLength() == 0 ||
1623cdf0e10cSrcweir // script.xlb, dialog.xlb can be met everywhere:
1624cdf0e10cSrcweir mediaType.matchIgnoreAsciiCaseAsciiL(
1625cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM(
1626cdf0e10cSrcweir "application/vnd.sun.star.basic-library") ) ||
1627cdf0e10cSrcweir mediaType.matchIgnoreAsciiCaseAsciiL(
1628cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM(
1629cdf0e10cSrcweir "application/vnd.sun.star.dialog-library") ))
1630cdf0e10cSrcweir {
1631cdf0e10cSrcweir if (xRow->getBoolean( 2 /* IsFolder */ )) { // recurse into folder:
1632cdf0e10cSrcweir scanLegacyBundle(
1633cdf0e10cSrcweir bundle, path, abortChannel, xCmdEnv, skip_registration );
1634cdf0e10cSrcweir }
1635cdf0e10cSrcweir }
1636cdf0e10cSrcweir }
1637cdf0e10cSrcweir }
1638cdf0e10cSrcweir
getDisplayName()1639cdf0e10cSrcweir OUString BackendImpl::PackageImpl::getDisplayName()
1640cdf0e10cSrcweir throw (deployment::ExtensionRemovedException, RuntimeException)
1641cdf0e10cSrcweir {
1642cdf0e10cSrcweir if (m_bRemoved)
1643cdf0e10cSrcweir throw deployment::ExtensionRemovedException();
1644cdf0e10cSrcweir
1645cdf0e10cSrcweir OUString sName = getDescriptionInfoset().getLocalizedDisplayName();
1646cdf0e10cSrcweir if (sName.getLength() == 0)
1647cdf0e10cSrcweir return m_displayName;
1648cdf0e10cSrcweir else
1649cdf0e10cSrcweir return sName;
1650cdf0e10cSrcweir }
1651cdf0e10cSrcweir
1652cdf0e10cSrcweir ::std::vector<Reference<deployment::XPackage> >
getPackagesFromDb(Reference<ucb::XCommandEnvironment> const & xCmdEnv)1653cdf0e10cSrcweir BackendImpl::PackageImpl::getPackagesFromDb(
1654cdf0e10cSrcweir Reference<ucb::XCommandEnvironment> const & xCmdEnv)
1655cdf0e10cSrcweir {
1656cdf0e10cSrcweir ::std::vector<Reference<deployment::XPackage> > retVector;
1657cdf0e10cSrcweir
1658cdf0e10cSrcweir typedef ::std::vector< ::std::pair<OUString, OUString> >::const_iterator ITC;
1659cdf0e10cSrcweir for (ITC i = m_dbData.items.begin(); i != m_dbData.items.end(); i++)
1660cdf0e10cSrcweir {
1661cdf0e10cSrcweir Reference<deployment::XPackage> xExtension =
1662cdf0e10cSrcweir bindBundleItem(i->first, i->second, true, m_identifier, xCmdEnv);
1663cdf0e10cSrcweir OSL_ASSERT(xExtension.is());
1664cdf0e10cSrcweir retVector.push_back(xExtension);
1665cdf0e10cSrcweir }
1666cdf0e10cSrcweir
1667cdf0e10cSrcweir return retVector;
1668cdf0e10cSrcweir }
1669cdf0e10cSrcweir
1670cdf0e10cSrcweir } // anon namespace
1671cdf0e10cSrcweir
1672cdf0e10cSrcweir //==============================================================================
create(Reference<deployment::XPackageRegistry> const & xRootRegistry,OUString const & context,OUString const & cachePath,bool readOnly,Reference<XComponentContext> const & xComponentContext)1673cdf0e10cSrcweir Reference<deployment::XPackageRegistry> create(
1674cdf0e10cSrcweir Reference<deployment::XPackageRegistry> const & xRootRegistry,
1675cdf0e10cSrcweir OUString const & context, OUString const & cachePath, bool readOnly,
1676cdf0e10cSrcweir Reference<XComponentContext> const & xComponentContext )
1677cdf0e10cSrcweir {
1678cdf0e10cSrcweir Sequence<Any> args(
1679cdf0e10cSrcweir cachePath.getLength() == 0 ? 1 : 3 );
1680cdf0e10cSrcweir args[ 0 ] <<= context;
1681cdf0e10cSrcweir if (cachePath.getLength() > 0) {
1682cdf0e10cSrcweir args[ 1 ] <<= cachePath;
1683cdf0e10cSrcweir args[ 2 ] <<= readOnly;
1684cdf0e10cSrcweir }
1685cdf0e10cSrcweir return new BackendImpl( args, xComponentContext, xRootRegistry );
1686cdf0e10cSrcweir }
1687cdf0e10cSrcweir
1688cdf0e10cSrcweir } // namespace bundle
1689cdf0e10cSrcweir } // namespace backend
1690cdf0e10cSrcweir } // namespace dp_registry
1691cdf0e10cSrcweir
1692