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