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