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