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