1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dp_package.cxx,v $
10 * $Revision: 1.34.16.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_desktop.hxx"
34 #include "dp_package.hrc"
35 #include "dp_backend.h"
37 #include "dp_interact.h"
38 #include "dp_dependencies.hxx"
39 #include "dp_platform.hxx"
40 #include "dp_description.hxx"
41 #include "dp_descriptioninfoset.hxx"
42 #include "dp_identifier.hxx"
43 #include "rtl/uri.hxx"
44 #include "cppuhelper/exc_hlp.hxx"
45 #include "cppuhelper/implbase1.hxx"
46 #include "ucbhelper/content.hxx"
47 #include "svtools/inettype.hxx"
48 #include "comphelper/anytostring.hxx"
49 #include "comphelper/makesequence.hxx"
50 #include "comphelper/sequence.hxx"
51 #include "com/sun/star/lang/WrappedTargetException.hpp"
52 #include "com/sun/star/lang/XServiceInfo.hpp"
53 #include "com/sun/star/beans/UnknownPropertyException.hpp"
54 #include "com/sun/star/graphic/XGraphic.hpp"
55 #include "com/sun/star/graphic/XGraphicProvider.hpp"
56 #include "com/sun/star/io/XOutputStream.hpp"
57 #include "com/sun/star/io/XInputStream.hpp"
58 #include "com/sun/star/task/InteractionClassification.hpp"
59 #include "com/sun/star/task/XInteractionApprove.hpp"
60 #include "com/sun/star/ucb/XInteractionReplaceExistingData.hpp"
61 #include "com/sun/star/ucb/NameClashResolveRequest.hpp"
62 #include "com/sun/star/ucb/XContentAccess.hpp"
63 #include "com/sun/star/ucb/NameClash.hpp"
64 #include "com/sun/star/ucb/UnsupportedCommandException.hpp"
65 #include "com/sun/star/sdbc/XResultSet.hpp"
66 #include "com/sun/star/sdbc/XRow.hpp"
67 #include "com/sun/star/packages/manifest/XManifestReader.hpp"
68 #include "com/sun/star/packages/manifest/XManifestWriter.hpp"
69 #include "com/sun/star/deployment/DependencyException.hpp"
70 #include "com/sun/star/deployment/LicenseException.hpp"
71 #include "com/sun/star/deployment/LicenseIndividualAgreementException.hpp"
72 #include "com/sun/star/deployment/PlatformException.hpp"
73 #include "com/sun/star/xml/dom/XDocumentBuilder.hpp"
74 #include "com/sun/star/xml/xpath/XXPathAPI.hpp"
75 #include "com/sun/star/deployment/XPackageManager.hpp"
81 using namespace ::dp_misc
;
82 using namespace ::com::sun::star
;
83 using namespace ::com::sun::star::uno
;
84 using namespace ::com::sun::star::ucb
;
85 namespace css
= ::com::sun::star
;
86 namespace cssu
= ::com::sun::star::uno
;
87 using ::rtl::OUString
;
89 namespace dp_registry
{
94 typedef cppu::ImplInheritanceHelper1
<PackageRegistryBackend
,
95 lang::XServiceInfo
> ImplBaseT
;
97 //==============================================================================
98 class BackendImpl
: public ImplBaseT
100 class PackageImpl
: public ::dp_registry::backend::Package
102 BackendImpl
* getMyBackend() const;
103 /** constains the old tooltip description for the Extension Manager GUI in OOo v.2.x
104 We keep it for backward compatibility.
106 OUString m_oldDescription
;
107 OUString m_url_expanded
;
108 const bool m_legacyBundle
;
109 Sequence
< Reference
<deployment::XPackage
> > m_bundle
;
110 Sequence
< Reference
<deployment::XPackage
> > * m_pBundle
;
112 Reference
<deployment::XPackage
> bindBundleItem(
113 OUString
const & url
, OUString
const & mediaType
,
114 Reference
<XCommandEnvironment
> const & xCmdEnv
,
115 bool notifyDetectionError
= true );
117 typedef ::std::vector
< Reference
<deployment::XPackage
> > t_packagevec
;
119 t_packagevec
& bundle
,
120 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
121 Reference
<XCommandEnvironment
> const & xCmdEnv
);
122 void scanLegacyBundle(
123 t_packagevec
& bundle
,
124 OUString
const & url
,
125 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
126 Reference
<XCommandEnvironment
> const & xCmdEnv
,
127 bool skip_registration
= false );
130 css::uno::Reference
< css::ucb::XCommandEnvironment
> const & environment
);
132 bool checkDependencies(
133 css::uno::Reference
< css::ucb::XCommandEnvironment
> const &
135 ExtensionDescription
const & description
);
136 // throws css::uno::RuntimeException,
137 // css::deployment::DeploymentException
139 ::sal_Bool
checkLicense(
140 css::uno::Reference
< css::ucb::XCommandEnvironment
> const & xCmdEnv
,
141 ExtensionDescription
const& description
, bool bInstalled
,
142 OUString
const & aContextName
)
143 throw (css::deployment::DeploymentException
,
144 css::ucb::CommandFailedException
,
145 css::ucb::CommandAbortedException
,
146 css::uno::RuntimeException
);
147 // @throws DeploymentException
148 OUString
getTextFromURL(
149 const css::uno::Reference
< css::ucb::XCommandEnvironment
>& xCmdEnv
,
150 const OUString
& licenseUrl
);
152 DescriptionInfoset
getDescriptionInfoset();
155 virtual beans::Optional
< beans::Ambiguous
<sal_Bool
> > isRegistered_(
156 ::osl::ResettableMutexGuard
& guard
,
157 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
158 Reference
<XCommandEnvironment
> const & xCmdEnv
);
159 virtual void processPackage_(
160 ::osl::ResettableMutexGuard
& guard
,
161 bool registerPackage
,
162 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
163 Reference
<XCommandEnvironment
> const & xCmdEnv
);
165 virtual void SAL_CALL
disposing();
171 ::rtl::Reference
<PackageRegistryBackend
> const & myBackend
,
172 OUString
const & url
,
173 OUString
const & name
,
174 Reference
<deployment::XPackageTypeInfo
> const & xPackageType
,
176 : Package( myBackend
, url
, name
, name
/* display-name */,
178 m_url_expanded( expandUnoRcUrl( url
) ),
179 m_legacyBundle( legacyBundle
),
184 virtual sal_Bool SAL_CALL
isBundle() throw (RuntimeException
);
185 virtual Sequence
< Reference
<deployment::XPackage
> > SAL_CALL
getBundle(
186 Reference
<task::XAbortChannel
> const & xAbortChannel
,
187 Reference
<XCommandEnvironment
> const & xCmdEnv
)
188 throw (deployment::DeploymentException
,
189 CommandFailedException
, CommandAbortedException
,
190 lang::IllegalArgumentException
, RuntimeException
);
191 virtual OUString SAL_CALL
getDescription() throw (RuntimeException
);
192 virtual void SAL_CALL
exportTo(
193 OUString
const & destFolderURL
, OUString
const & newTitle
,
194 sal_Int32 nameClashAction
,
195 Reference
<XCommandEnvironment
> const & xCmdEnv
)
196 throw (CommandFailedException
, CommandAbortedException
,
199 virtual ::sal_Bool SAL_CALL
checkPrerequisites(
200 const css::uno::Reference
< css::task::XAbortChannel
>& xAbortChannel
,
201 const css::uno::Reference
< css::ucb::XCommandEnvironment
>& xCmdEnv
,
202 ::sal_Bool bInstalled
, OUString
const & aContextName
)
203 throw (css::deployment::DeploymentException
,
204 css::ucb::CommandFailedException
,
205 css::ucb::CommandAbortedException
,
206 css::uno::RuntimeException
);
208 virtual ::sal_Bool SAL_CALL
checkDependencies(
209 const css::uno::Reference
< css::ucb::XCommandEnvironment
>& xCmdEnv
)
210 throw (css::deployment::DeploymentException
,
211 css::ucb::CommandFailedException
,
212 css::uno::RuntimeException
);
214 virtual beans::Optional
<OUString
> SAL_CALL
getIdentifier()
215 throw (RuntimeException
);
217 virtual OUString SAL_CALL
getVersion() throw (RuntimeException
);
219 virtual Sequence
<OUString
> SAL_CALL
getUpdateInformationURLs()
220 throw (RuntimeException
);
222 virtual css::beans::StringPair SAL_CALL
getPublisherInfo() throw (css::uno::RuntimeException
);
224 virtual OUString SAL_CALL
getDisplayName() throw (RuntimeException
);
225 virtual css::uno::Reference
< css::graphic::XGraphic
> SAL_CALL
getIcon( ::sal_Bool bHighContrast
) throw (css::uno::RuntimeException
);
227 friend class PackageImpl
;
229 Reference
<deployment::XPackageRegistry
> m_xRootRegistry
;
230 const Reference
<deployment::XPackageTypeInfo
> m_xBundleTypeInfo
;
231 const Reference
<deployment::XPackageTypeInfo
> m_xLegacyBundleTypeInfo
;
232 Sequence
< Reference
<deployment::XPackageTypeInfo
> > m_typeInfos
;
234 // PackageRegistryBackend
235 virtual Reference
<deployment::XPackage
> bindPackage_(
236 OUString
const & url
, OUString
const & mediaType
,
237 Reference
<XCommandEnvironment
> const & xCmdEnv
);
239 virtual void SAL_CALL
disposing();
243 Sequence
<Any
> const & args
,
244 Reference
<XComponentContext
> const & xComponentContext
,
245 Reference
<deployment::XPackageRegistry
> const & xRootRegistry
);
248 virtual OUString SAL_CALL
getImplementationName() throw (RuntimeException
);
249 virtual sal_Bool SAL_CALL
supportsService( OUString
const& name
)
250 throw (RuntimeException
);
251 virtual Sequence
<OUString
> SAL_CALL
getSupportedServiceNames()
252 throw (RuntimeException
);
255 virtual Sequence
< Reference
<deployment::XPackageTypeInfo
> > SAL_CALL
256 getSupportedPackageTypes() throw (RuntimeException
);
258 using ImplBaseT::disposing
;
261 //Used to find a XPackage with a particular URL
262 class XPackage_eq
: public std::unary_function
<Reference
<deployment::XPackage
>, bool>
266 explicit XPackage_eq(const OUString
& s
) : m_URL(s
) {}
267 bool operator() (const Reference
<deployment::XPackage
> & p
) const
269 return m_URL
.equals(p
->getURL());
273 //______________________________________________________________________________
274 BackendImpl::BackendImpl(
275 Sequence
<Any
> const & args
,
276 Reference
<XComponentContext
> const & xComponentContext
,
277 Reference
<deployment::XPackageRegistry
> const & xRootRegistry
)
278 : ImplBaseT( args
, xComponentContext
),
279 m_xRootRegistry( xRootRegistry
),
280 m_xBundleTypeInfo( new Package::TypeInfo(
281 OUSTR("application/vnd.sun.star.package-bundle"),
282 OUSTR("*.oxt;*.uno.pkg"),
283 getResourceString(RID_STR_PACKAGE_BUNDLE
),
284 RID_IMG_DEF_PACKAGE_BUNDLE
,
285 RID_IMG_DEF_PACKAGE_BUNDLE_HC
) ),
286 m_xLegacyBundleTypeInfo( new Package::TypeInfo(
288 "vnd.sun.star.legacy-package-bundle"),
290 m_xBundleTypeInfo
->getShortDescription(),
291 RID_IMG_DEF_PACKAGE_BUNDLE
,
292 RID_IMG_DEF_PACKAGE_BUNDLE_HC
) ),
295 m_typeInfos
[ 0 ] = m_xBundleTypeInfo
;
296 m_typeInfos
[ 1 ] = m_xLegacyBundleTypeInfo
;
299 //______________________________________________________________________________
300 void BackendImpl::disposing()
302 m_xRootRegistry
.clear();
303 PackageRegistryBackend::disposing();
307 OUString
BackendImpl::getImplementationName() throw (RuntimeException
)
309 return OUSTR("com.sun.star.comp.deployment.bundle.PackageRegistryBackend");
312 sal_Bool
BackendImpl::supportsService( OUString
const& name
)
313 throw (RuntimeException
)
315 return getSupportedServiceNames()[0].equals(name
);
318 Sequence
<OUString
> BackendImpl::getSupportedServiceNames()
319 throw (RuntimeException
)
321 return comphelper::makeSequence(
322 OUString::createFromAscii(BACKEND_SERVICE_NAME
) );
326 //______________________________________________________________________________
327 Sequence
< Reference
<deployment::XPackageTypeInfo
> >
328 BackendImpl::getSupportedPackageTypes() throw (RuntimeException
)
335 // PackageRegistryBackend
336 //______________________________________________________________________________
337 Reference
<deployment::XPackage
> BackendImpl::bindPackage_(
338 OUString
const & url
, OUString
const & mediaType_
,
339 Reference
<XCommandEnvironment
> const & xCmdEnv
)
341 OUString
mediaType( mediaType_
);
342 if (mediaType
.getLength() == 0)
344 // detect media-type:
345 ::ucbhelper::Content ucbContent
;
346 if (create_ucb_content( &ucbContent
, url
, xCmdEnv
))
348 const OUString
title( ucbContent
.getPropertyValue(
349 StrTitle::get() ).get
<OUString
>() );
350 if (title
.endsWithIgnoreAsciiCaseAsciiL(
351 RTL_CONSTASCII_STRINGPARAM(".oxt") ) ||
352 title
.endsWithIgnoreAsciiCaseAsciiL(
353 RTL_CONSTASCII_STRINGPARAM(".uno.pkg") ))
354 mediaType
= OUSTR("application/vnd.sun.star.package-bundle");
355 else if (title
.endsWithIgnoreAsciiCaseAsciiL(
356 RTL_CONSTASCII_STRINGPARAM(".zip") ))
358 OUSTR("application/vnd.sun.star.legacy-package-bundle");
360 if (mediaType
.getLength() == 0)
361 throw lang::IllegalArgumentException(
362 StrCannotDetectMediaType::get() + url
,
363 static_cast<OWeakObject
*>(this), static_cast<sal_Int16
>(-1) );
366 String type
, subType
;
367 INetContentTypeParameterList params
;
368 if (INetContentTypes::parse( mediaType
, type
, subType
, ¶ms
))
370 if (type
.EqualsIgnoreCaseAscii("application"))
372 ::ucbhelper::Content
ucbContent( url
, xCmdEnv
);
373 if (subType
.EqualsIgnoreCaseAscii("vnd.sun.star.package-bundle")) {
374 return new PackageImpl(
375 this, url
, ucbContent
.getPropertyValue(
376 StrTitle::get() ).get
<OUString
>(),
377 m_xBundleTypeInfo
, false );
379 else if (subType
.EqualsIgnoreCaseAscii(
380 "vnd.sun.star.legacy-package-bundle")) {
381 return new PackageImpl(
382 this, url
, ucbContent
.getPropertyValue(
383 StrTitle::get() ).get
<OUString
>(),
384 m_xLegacyBundleTypeInfo
, true );
388 throw lang::IllegalArgumentException(
389 StrUnsupportedMediaType::get() + mediaType
,
390 static_cast<OWeakObject
*>(this),
391 static_cast<sal_Int16
>(-1) );
394 //##############################################################################
396 BackendImpl
* BackendImpl::PackageImpl::getMyBackend() const
398 BackendImpl
* pBackend
= static_cast<BackendImpl
*>(m_myBackend
.get());
399 if (NULL
== pBackend
)
401 //May throw a DisposedException
403 //We should never get here...
404 throw RuntimeException(
405 OUSTR("Failed to get the BackendImpl"),
406 static_cast<OWeakObject
*>(const_cast<PackageImpl
*>(this)));
410 //______________________________________________________________________________
411 void BackendImpl::PackageImpl::disposing()
413 sal_Int32 len
= m_bundle
.getLength();
414 Reference
<deployment::XPackage
> const * p
= m_bundle
.getConstArray();
415 for ( sal_Int32 pos
= 0; pos
< len
; ++pos
)
416 try_dispose( p
[ pos
] );
417 m_bundle
.realloc( 0 );
419 Package::disposing();
423 //______________________________________________________________________________
424 beans::Optional
< beans::Ambiguous
<sal_Bool
> >
425 BackendImpl::PackageImpl::isRegistered_(
426 ::osl::ResettableMutexGuard
&,
427 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
428 Reference
<XCommandEnvironment
> const & xCmdEnv
)
430 const Sequence
< Reference
<deployment::XPackage
> > bundle(
431 getBundle( abortChannel
.get(), xCmdEnv
) );
433 bool present
= false;
435 for ( sal_Int32 pos
= bundle
.getLength(); pos
--; )
437 Reference
<deployment::XPackage
> const & xPackage
= bundle
[ pos
];
438 //disregard executable (application/vnd.sun.star.executable)
439 //it will not be disabled/enabled.
440 OUString sType
= xPackage
->getPackageType()->getMediaType();
441 if (sType
.equals(OUSTR("application/vnd.sun.star.executable")))
444 Reference
<task::XAbortChannel
> xSubAbortChannel(
445 xPackage
->createAbortChannel() );
446 AbortChannel::Chain
chain( abortChannel
, xSubAbortChannel
);
447 beans::Optional
< beans::Ambiguous
<sal_Bool
> > option(
448 xPackage
->isRegistered( xSubAbortChannel
, xCmdEnv
) );
449 if (option
.IsPresent
)
451 beans::Ambiguous
<sal_Bool
> const & status
= option
.Value
;
454 if (reg
!= (status
.Value
!= sal_False
)) {
467 return beans::Optional
< beans::Ambiguous
<sal_Bool
> >(
468 present
, beans::Ambiguous
<sal_Bool
>(reg
, ambig
) );
471 OUString
BackendImpl::PackageImpl::getTextFromURL(
472 const css::uno::Reference
< css::ucb::XCommandEnvironment
>& xCmdEnv
,
473 const OUString
& licenseUrl
)
477 ::ucbhelper::Content
descContent(licenseUrl
, xCmdEnv
);
478 ::rtl::ByteSequence seq
= dp_misc::readFile(descContent
);
479 return OUString( reinterpret_cast<sal_Char
const *>(
480 seq
.getConstArray()), seq
.getLength(), RTL_TEXTENCODING_UTF8
);
482 catch (css::uno::Exception
&)
484 Any
exc( ::cppu::getCaughtException() );
485 throw css::deployment::DeploymentException(
486 OUSTR("Could not read file ") + licenseUrl
, 0, exc
);
491 DescriptionInfoset
BackendImpl::PackageImpl::getDescriptionInfoset()
493 css::uno::Reference
< css::xml::dom::XNode
> root
;
496 ExtensionDescription(
497 getMyBackend()->getComponentContext(), m_url_expanded
,
498 css::uno::Reference
< css::ucb::XCommandEnvironment
>()).
500 } catch (NoDescriptionException
&) {
501 } catch (css::deployment::DeploymentException
& e
) {
502 throw RuntimeException(
504 RTL_CONSTASCII_USTRINGPARAM(
505 "com.sun.star.deployment.DeploymentException: ")) +
507 static_cast< OWeakObject
* >(this));
509 return DescriptionInfoset(getMyBackend()->getComponentContext(), root
);
512 bool BackendImpl::PackageImpl::checkPlatform(
513 css::uno::Reference
< css::ucb::XCommandEnvironment
> const & environment
)
516 DescriptionInfoset
info(getDescriptionInfoset());
517 Sequence
<OUString
> platforms(info
.getSupportedPlaforms());
518 if (hasValidPlatform(platforms
))
526 RTL_CONSTASCII_USTRINGPARAM("unsupported platform"));
528 css::deployment::PlatformException(
529 msg
, static_cast<OWeakObject
*>(this), this));
530 if (!interactContinuation(
531 e
, cppu::UnoType
< css::task::XInteractionApprove
>::get(),
532 environment
, NULL
, NULL
))
534 throw css::deployment::DeploymentException(
535 msg
, static_cast<OWeakObject
*>(this), e
);
542 bool BackendImpl::PackageImpl::checkDependencies(
543 css::uno::Reference
< css::ucb::XCommandEnvironment
> const & environment
,
544 ExtensionDescription
const & description
)
546 css::uno::Sequence
< css::uno::Reference
< css::xml::dom::XElement
> >
548 dp_misc::Dependencies::check(
550 getMyBackend()->getComponentContext(),
551 description
.getRootElement())));
552 if (unsatisfied
.getLength() == 0) {
556 RTL_CONSTASCII_USTRINGPARAM("unsatisfied dependencies"));
558 css::deployment::DependencyException(
559 msg
, static_cast<OWeakObject
*>(this), unsatisfied
));
560 if (!interactContinuation(
561 e
, cppu::UnoType
< css::task::XInteractionApprove
>::get(),
562 environment
, NULL
, NULL
))
564 throw css::deployment::DeploymentException(
565 msg
, static_cast<OWeakObject
*>(this), e
);
571 ::sal_Bool
BackendImpl::PackageImpl::checkLicense(
572 css::uno::Reference
< css::ucb::XCommandEnvironment
> const & xCmdEnv
,
573 ExtensionDescription
const & desc
, bool bInstalled
, OUString
const & aContextName
)
574 throw (css::deployment::DeploymentException
,
575 css::ucb::CommandFailedException
,
576 css::ucb::CommandAbortedException
,
577 css::uno::RuntimeException
)
581 css::uno::Reference
<css::xml::dom::XNode
> xRoot
= desc
.getRootElement();
582 css::uno::Reference
<css::xml::xpath::XXPathAPI
> xPath
=
583 getDescriptionInfoset().getXpath();
585 css::uno::Reference
<css::xml::dom::XNode
> nodeSimpleLic
;
587 nodeSimpleLic
= xPath
->selectSingleNode(xRoot
,
588 OUSTR("/desc:description/desc:registration/desc:simple-license"));
589 } catch (css::xml::xpath::XPathException
&) {
593 if (!nodeSimpleLic
.is())
595 OUString sLic
= getDescriptionInfoset().getLocalizedLicenseURL();
596 //If we do not get a localized licence then there is an error in the description.xml
597 //This should be handled by using a validating parser. Therefore we assume that no
598 //license is available.
599 if (sLic
.getLength() == 0)
600 throw css::deployment::DeploymentException(
601 OUSTR("Could not obtain path to license. Possible error in description.xml"), 0, Any());
602 OUString sHref
= desc
.getExtensionRootUrl() + OUSTR("/") + sLic
;
603 OUString sLicense
= getTextFromURL(xCmdEnv
, sHref
);
604 //determine who has to agree to the license
605 css::uno::Reference
<css::xml::xpath::XXPathObject
> nodeAttribWho3
=
606 xPath
->eval(nodeSimpleLic
,
607 OUSTR("@accept-by"));
608 OUString sAccept
= nodeAttribWho3
->getString().trim();
609 //check correct value for attribute
610 if ( ! (sAccept
.equals(OUSTR("user")) || sAccept
.equals(OUSTR("admin"))))
611 throw css::deployment::DeploymentException(
612 OUSTR("Could not obtain attribute simple-lincense@accept-by or it has no valid value"), 0, Any());
614 //If if @accept-by="user" then every user needs to accept the license before it can be installed.
615 //Therefore we must prevent the installation as shared extension.
616 OSL_ASSERT(aContextName
.getLength());
617 if (sAccept
.equals(OUSTR("user")) && aContextName
.equals(OUSTR("shared")))
619 css::deployment::LicenseIndividualAgreementException exc
=
620 css::deployment::LicenseIndividualAgreementException(OUString(), 0, m_name
);
622 bool approve
= false;
624 if (! interactContinuation(
625 Any(exc
), task::XInteractionApprove::static_type(), xCmdEnv
, &approve
, &abort
))
626 throw css::deployment::DeploymentException(
627 OUSTR("Could not interact with user."), 0, Any());
630 //We should always prevent installation
634 //determine optional attribute simple-license@suppressOnUpdate
635 css::uno::Reference
<css::xml::dom::XElement
> elemSimpleLic(nodeSimpleLic
, css::uno::UNO_QUERY_THROW
);
636 sal_Bool bSuppress
= sal_False
;
637 if (elemSimpleLic
->hasAttribute(OUSTR("suppress-on-update")))
639 if (elemSimpleLic
->getAttribute(OUSTR("suppress-on-update")).equals(OUSTR("true")))
640 bSuppress
= sal_True
;
643 //Only use interaction if there is no version of this extension already installed
644 //and the suppress-on-update flag is not set for the new extension
645 // bInstalled | bSuppress | show license
646 //----------------------------------------
652 if ( !(bInstalled
&& bSuppress
))
654 css::deployment::LicenseException licExc
=
655 css::deployment::LicenseException(OUString(), 0, m_name
, sLicense
);
656 bool approve
= false;
658 if (! interactContinuation(
659 Any(licExc
), task::XInteractionApprove::static_type(), xCmdEnv
, &approve
, &abort
))
660 throw css::deployment::DeploymentException(
661 OUSTR("Could not interact with user."), 0, Any());
667 //throw css::deployment::DeploymentException(
668 // OUSTR("Extension Manager: User declined the license."),
669 // static_cast<OWeakObject*>(this),
670 // Any( css::deployment::LicenseException(OUSTR("User declined the license."), 0, m_name, sLicense)));
673 } catch (css::ucb::CommandFailedException
&) {
675 } catch (css::ucb::CommandAbortedException
&) {
677 } catch (css::deployment::DeploymentException
&) {
679 } catch (css::uno::RuntimeException
&) {
681 } catch (css::uno::Exception
&) {
682 Any anyExc
= cppu::getCaughtException();
683 throw css::deployment::DeploymentException(OUSTR("Unexpected exception"), 0, anyExc
);
687 ::sal_Bool
BackendImpl::PackageImpl::checkPrerequisites(
688 const css::uno::Reference
< css::task::XAbortChannel
>&,
689 const css::uno::Reference
< css::ucb::XCommandEnvironment
>& xCmdEnv
,
690 sal_Bool bInstalled
, OUString
const & aContextName
)
691 throw (css::deployment::DeploymentException
,
692 css::ucb::CommandFailedException
,
693 css::ucb::CommandAbortedException
,
694 css::uno::RuntimeException
)
696 std::auto_ptr
<ExtensionDescription
> spDescription
;
699 new ExtensionDescription(
700 getMyBackend()->getComponentContext(),
703 } catch (NoDescriptionException
& ) {
706 return checkPlatform(xCmdEnv
)
707 && checkDependencies(xCmdEnv
, *spDescription
)
708 && checkLicense(xCmdEnv
, *spDescription
, bInstalled
, aContextName
);
711 ::sal_Bool
BackendImpl::PackageImpl::checkDependencies(
712 const css::uno::Reference
< css::ucb::XCommandEnvironment
>& xCmdEnv
)
713 throw (css::deployment::DeploymentException
,
714 css::ucb::CommandFailedException
,
715 css::uno::RuntimeException
)
717 std::auto_ptr
<ExtensionDescription
> spDescription
;
720 new ExtensionDescription( getMyBackend()->getComponentContext(), m_url_expanded
, xCmdEnv
));
721 } catch (NoDescriptionException
& ) {
724 return checkDependencies(xCmdEnv
, *spDescription
);
727 beans::Optional
<OUString
> BackendImpl::PackageImpl::getIdentifier()
728 throw (RuntimeException
)
730 return beans::Optional
<OUString
>(
732 dp_misc::generateIdentifier(
733 getDescriptionInfoset().getIdentifier(), m_name
));
736 OUString
BackendImpl::PackageImpl::getVersion() throw (RuntimeException
)
738 return getDescriptionInfoset().getVersion();
741 Sequence
<OUString
> BackendImpl::PackageImpl::getUpdateInformationURLs()
742 throw (RuntimeException
)
744 return getDescriptionInfoset().getUpdateInformationUrls();
747 beans::StringPair
BackendImpl::PackageImpl::getPublisherInfo()
748 throw (RuntimeException
)
750 ::std::pair
< OUString
, OUString
> aInfo
= getDescriptionInfoset().getLocalizedPublisherNameAndURL();
751 beans::StringPair
aStrPair( aInfo
.first
, aInfo
.second
);
755 //______________________________________________________________________________
756 uno::Reference
< graphic::XGraphic
> BackendImpl::PackageImpl::getIcon( sal_Bool bHighContrast
)
757 throw ( RuntimeException
)
759 uno::Reference
< graphic::XGraphic
> xGraphic
;
761 OUString aIconURL
= getDescriptionInfoset().getIconURL( bHighContrast
);
762 if ( aIconURL
.getLength() )
764 OUString aFullIconURL
= m_url_expanded
+ OUSTR("/") + aIconURL
;
766 uno::Reference
< XComponentContext
> xContext( getMyBackend()->getComponentContext() );
767 uno::Reference
< graphic::XGraphicProvider
> xGraphProvider(
768 xContext
->getServiceManager()->createInstanceWithContext( OUSTR( "com.sun.star.graphic.GraphicProvider" ), xContext
),
771 if ( xGraphProvider
.is() )
773 uno::Sequence
< beans::PropertyValue
> aMediaProps( 1 );
774 aMediaProps
[0].Name
= OUSTR( "URL" );
775 aMediaProps
[0].Value
<<= aFullIconURL
;
777 xGraphic
= xGraphProvider
->queryGraphic( aMediaProps
);
784 //______________________________________________________________________________
785 void BackendImpl::PackageImpl::processPackage_(
786 ::osl::ResettableMutexGuard
&,
787 bool doRegisterPackage
,
788 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
789 Reference
<XCommandEnvironment
> const & xCmdEnv
)
791 const Sequence
< Reference
<deployment::XPackage
> > bundle(
792 getBundle( abortChannel
.get(), xCmdEnv
) );
794 if (doRegisterPackage
)
796 const sal_Int32 len
= bundle
.getLength();
797 for ( sal_Int32 pos
= 0; pos
< len
; ++pos
)
799 checkAborted(abortChannel
);
800 Reference
<deployment::XPackage
> const & xPackage
= bundle
[ pos
];
801 Reference
<task::XAbortChannel
> xSubAbortChannel(
802 xPackage
->createAbortChannel() );
803 AbortChannel::Chain
chain( abortChannel
, xSubAbortChannel
);
805 xPackage
->registerPackage( xSubAbortChannel
, xCmdEnv
);
807 catch (RuntimeException
&) {
810 catch (CommandAbortedException
&) {
813 catch (Exception
&) {
814 // CommandFailedException, DeploymentException:
815 Any
exc( ::cppu::getCaughtException() );
816 // try to handle exception, notify:
817 bool approve
= false, abort
= false;
818 if (! interactContinuation(
819 Any( lang::WrappedTargetException(
820 OUSTR("bundle item registration error!"),
821 static_cast<OWeakObject
*>(this), exc
) ),
822 task::XInteractionApprove::static_type(), xCmdEnv
,
823 &approve
, &abort
)) {
824 OSL_ASSERT( !approve
&& !abort
);
825 if (m_legacyBundle
) // default for legacy packages: ignore
827 // no selection at all, so rethrow;
828 // no C++ rethrow after getCaughtException(),
829 // see cppuhelper/exc_hlp.hxx:
830 ::cppu::throwException(exc
);
832 if (approve
&& !abort
) // ignore error, just continue
836 ProgressLevel
progress(
837 xCmdEnv
, OUSTR("rollback...") );
842 bundle
[ pos
]->revokePackage(
843 xSubAbortChannel
, xCmdEnv
);
845 catch (RuntimeException
&) {
848 catch (CommandAbortedException
&) {
851 catch (Exception
&) {
852 // bundle rollback error:
853 OSL_ENSURE( 0, ::rtl::OUStringToOString(
854 ::comphelper::anyToString(
855 ::cppu::getCaughtException() ),
856 RTL_TEXTENCODING_UTF8
).getStr() );
857 // ignore any errors of rollback
860 progress
.update( OUSTR("rollback finished.") );
863 deployment::DeploymentException dpExc
;
865 throw CommandFailedException(
866 dpExc
.Message
, dpExc
.Context
, dpExc
.Cause
);
869 // rethrow CommandFailedException
870 ::cppu::throwException(exc
);
877 // revoke in reverse order:
878 for ( sal_Int32 pos
= bundle
.getLength(); pos
--; )
880 checkAborted(abortChannel
);
881 Reference
<deployment::XPackage
> const & xPackage
= bundle
[ pos
];
882 Reference
<task::XAbortChannel
> xSubAbortChannel(
883 xPackage
->createAbortChannel() );
884 AbortChannel::Chain
chain( abortChannel
, xSubAbortChannel
);
886 bundle
[ pos
]->revokePackage( xSubAbortChannel
, xCmdEnv
);
888 catch (RuntimeException
&) {
891 catch (CommandAbortedException
&) {
894 catch (Exception
&) {
895 // CommandFailedException, DeploymentException:
896 Any
exc( ::cppu::getCaughtException() );
897 // try to handle exception, notify:
898 bool approve
= false, abort
= false;
899 if (! interactContinuation(
900 Any( lang::WrappedTargetException(
901 OUSTR("bundle item revocation error!"),
902 static_cast<OWeakObject
*>(this), exc
) ),
903 task::XInteractionApprove::static_type(), xCmdEnv
,
904 &approve
, &abort
)) {
905 OSL_ASSERT( !approve
&& !abort
);
906 if (m_legacyBundle
) // default for legacy packages: ignore
908 // no selection at all, so rethrow
909 // no C++ rethrow after getCaughtException(),
910 // see cppuhelper/exc_hlp.hxx:
911 ::cppu::throwException(exc
);
913 // ignore errors when revoking, although abort may have been
920 //______________________________________________________________________________
921 OUString
BackendImpl::PackageImpl::getDescription() throw (RuntimeException
)
923 const OUString
sRelativeURL(getDescriptionInfoset().getLocalizedDescriptionURL());
924 OUString sDescription
;
925 if (sRelativeURL
.getLength())
927 OUString sURL
= m_url_expanded
+ OUSTR("/") + sRelativeURL
;
928 sDescription
= getTextFromURL(
929 css::uno::Reference
< css::ucb::XCommandEnvironment
>(), sURL
);
932 if (sDescription
.getLength())
934 else if(m_oldDescription
.getLength())
935 return m_oldDescription
;
940 //______________________________________________________________________________
941 void BackendImpl::PackageImpl::exportTo(
942 OUString
const & destFolderURL
, OUString
const & newTitle
,
943 sal_Int32 nameClashAction
, Reference
<XCommandEnvironment
> const & xCmdEnv
)
944 throw (CommandFailedException
, CommandAbortedException
, RuntimeException
)
946 ::ucbhelper::Content
sourceContent( m_url_expanded
, xCmdEnv
);
947 OUString
title(newTitle
);
948 if (title
.getLength() == 0)
949 sourceContent
.getPropertyValue( StrTitle::get() ) >>= title
;
950 OUString
destURL( makeURL( destFolderURL
, ::rtl::Uri::encode(
951 title
, rtl_UriCharClassPchar
,
952 rtl_UriEncodeIgnoreEscapes
,
953 RTL_TEXTENCODING_UTF8
) ) );
955 if (nameClashAction
== NameClash::ASK
)
957 if (create_ucb_content(
958 0, destURL
, xCmdEnv
, false /* no throw */ )) {
959 bool replace
= false, abort
= false;
960 if (! interactContinuation(
961 Any( NameClashResolveRequest(
962 OUSTR("file already exists: ") + title
,
963 static_cast<OWeakObject
*>(this),
964 task::InteractionClassification_QUERY
,
965 destFolderURL
, title
, OUString() ) ),
966 XInteractionReplaceExistingData::static_type(), xCmdEnv
,
967 &replace
, &abort
) || !replace
) {
972 else if (nameClashAction
!= NameClash::OVERWRITE
) {
973 throw CommandFailedException(
974 OUSTR("unsupported nameClashAction!"),
975 static_cast<OWeakObject
*>(this), Any() );
977 erase_path( destURL
, xCmdEnv
);
979 ::rtl::OUStringBuffer buf
;
980 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.zip://") );
981 buf
.append( ::rtl::Uri::encode( destURL
,
982 rtl_UriCharClassRegName
,
983 rtl_UriEncodeIgnoreEscapes
,
984 RTL_TEXTENCODING_UTF8
) );
985 buf
.append( static_cast<sal_Unicode
>('/') );
986 OUString
destFolder( buf
.makeStringAndClear() );
988 ::ucbhelper::Content
destFolderContent( destFolder
, xCmdEnv
);
990 // transfer every item of folder into zip:
991 Reference
<sdbc::XResultSet
> xResultSet(
992 sourceContent
.createCursor(
993 Sequence
<OUString
>(),
994 ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS
) );
995 ProgressLevel
progress( xCmdEnv
, OUString() );
996 while (xResultSet
->next())
998 ::ucbhelper::Content
subContent(
999 Reference
<XContentAccess
>(
1000 xResultSet
, UNO_QUERY_THROW
)->queryContent(), xCmdEnv
);
1001 if (! destFolderContent
.transferContent(
1002 subContent
, ::ucbhelper::InsertOperation_COPY
,
1003 OUString(), NameClash::OVERWRITE
))
1004 throw RuntimeException( OUSTR("UCB transferContent() failed!"),
1005 static_cast<OWeakObject
*>(this) );
1006 progress
.update( Any() ); // animating progress bar
1010 // assure META-INF folder:
1011 ::ucbhelper::Content metainfFolderContent
;
1012 create_folder( &metainfFolderContent
,
1013 makeURL( destFolderContent
.getURL(), OUSTR("META-INF") ),
1018 // easy to migrate legacy bundles to new format:
1019 // just export them once using a .oxt name!
1020 // set detected media-types of any bundle item:
1022 // collect all manifest entries:
1023 Sequence
< Reference
<deployment::XPackage
> > bundle
;
1025 bundle
= getBundle( Reference
<task::XAbortChannel
>(), xCmdEnv
);
1027 // xxx todo: think about exception specs:
1028 catch (deployment::DeploymentException
&) {
1029 OSL_ENSURE( 0, ::rtl::OUStringToOString(
1030 ::comphelper::anyToString(
1031 ::cppu::getCaughtException() ),
1032 RTL_TEXTENCODING_UTF8
).getStr() );
1034 catch (lang::IllegalArgumentException
& exc
) {
1036 OSL_ENSURE( 0, ::rtl::OUStringToOString(
1037 exc
.Message
, RTL_TEXTENCODING_UTF8
).getStr() );
1040 ::std::vector
< Sequence
<beans::PropertyValue
> > manifest
;
1041 manifest
.reserve( bundle
.getLength() );
1042 sal_Int32 baseURLlen
= m_url_expanded
.getLength();
1043 Reference
<deployment::XPackage
> const *pbundle
= bundle
.getConstArray();
1044 const OUString strMediaType
= OUSTR("MediaType");
1045 const OUString strFullPath
= OUSTR("FullPath");
1046 const OUString strIsFolder
= OUSTR("IsFolder");
1047 for ( sal_Int32 pos
= bundle
.getLength(); pos
--; )
1049 Reference
<deployment::XPackage
> const & xPackage
= pbundle
[ pos
];
1050 OUString
url_( expandUnoRcUrl( xPackage
->getURL() ) );
1051 OSL_ASSERT( url_
.getLength() >= baseURLlen
);
1053 if (url_
.getLength() > baseURLlen
)
1054 fullPath
= url_
.copy( baseURLlen
+ 1 );
1055 ::ucbhelper::Content
ucbContent( url_
, xCmdEnv
);
1056 if (ucbContent
.getPropertyValue(strIsFolder
).get
<bool>())
1057 fullPath
+= OUSTR("/");
1058 Sequence
<beans::PropertyValue
> attribs( 2 );
1059 beans::PropertyValue
* pattribs
= attribs
.getArray();
1060 pattribs
[ 0 ].Name
= strFullPath
;
1061 pattribs
[ 0 ].Value
<<= fullPath
;
1062 pattribs
[ 1 ].Name
= strMediaType
;
1063 const Reference
<deployment::XPackageTypeInfo
> xPackageType(
1064 xPackage
->getPackageType() );
1066 OSL_ASSERT( xPackageType
.is() );
1067 if (xPackageType
.is())
1068 mediaType
= xPackageType
->getMediaType();
1070 mediaType
= OUSTR("unknown");
1071 pattribs
[ 1 ].Value
<<= mediaType
;
1072 manifest
.push_back( attribs
);
1076 Reference
<XComponentContext
> xContext(
1077 getMyBackend()->getComponentContext() );
1078 Reference
<packages::manifest::XManifestWriter
> xManifestWriter(
1079 xContext
->getServiceManager()->createInstanceWithContext(
1080 OUSTR("com.sun.star.packages.manifest.ManifestWriter"),
1081 xContext
), UNO_QUERY_THROW
);
1082 Reference
<io::XOutputStream
> xPipe(
1083 xContext
->getServiceManager()->createInstanceWithContext(
1084 OUSTR("com.sun.star.io.Pipe"), xContext
), UNO_QUERY_THROW
);
1085 xManifestWriter
->writeManifestSequence(
1086 xPipe
, comphelper::containerToSequence(manifest
) );
1088 // write buffered pipe data to content:
1089 ::ucbhelper::Content
manifestContent(
1090 makeURL( metainfFolderContent
.getURL(), OUSTR("manifest.xml") ),
1092 manifestContent
.writeStream(
1093 Reference
<io::XInputStream
>( xPipe
, UNO_QUERY_THROW
),
1094 true /* replace existing */ );
1098 // overwrite manifest.xml:
1099 ::ucbhelper::Content manifestContent
;
1100 if ( ! create_ucb_content(
1102 makeURL( m_url_expanded
, OUSTR("META-INF/manifest.xml") ),
1105 OSL_ENSURE( 0, "### missing META-INF/manifest.xml file!" );
1109 if (! metainfFolderContent
.transferContent(
1110 manifestContent
, ::ucbhelper::InsertOperation_COPY
,
1111 OUString(), NameClash::OVERWRITE
))
1112 throw RuntimeException( OUSTR("UCB transferContent() failed!"),
1113 static_cast<OWeakObject
*>(this) );
1116 // xxx todo: maybe obsolete in the future
1118 destFolderContent
.executeCommand( OUSTR("flush"), Any() );
1120 catch (UnsupportedCommandException
&) {
1124 //______________________________________________________________________________
1125 sal_Bool
BackendImpl::PackageImpl::isBundle() throw (RuntimeException
)
1130 //______________________________________________________________________________
1131 Sequence
< Reference
<deployment::XPackage
> > BackendImpl::PackageImpl::getBundle(
1132 Reference
<task::XAbortChannel
> const & xAbortChannel
,
1133 Reference
<XCommandEnvironment
> const & xCmdEnv
)
1134 throw (deployment::DeploymentException
,
1135 CommandFailedException
, CommandAbortedException
,
1136 lang::IllegalArgumentException
, RuntimeException
)
1138 Sequence
< Reference
<deployment::XPackage
> > * pBundle
= m_pBundle
;
1141 t_packagevec bundle
;
1145 // .zip legacy packages allow script.xlb, dialog.xlb in bundle
1148 // probe for script.xlb:
1149 if (create_ucb_content(
1150 0, makeURL( m_url_expanded
, OUSTR("script.xlb") ),
1151 xCmdEnv
, false /* no throw */ )) {
1152 mediaType
= OUSTR("application/vnd.sun.star.basic-library");
1154 // probe for dialog.xlb:
1155 else if (create_ucb_content(
1156 0, makeURL( m_url_expanded
, OUSTR("dialog.xlb") ),
1157 xCmdEnv
, false /* no throw */ ))
1158 mediaType
= OUSTR("application/vnd.sun.star."
1161 if (mediaType
.getLength() > 0) {
1162 const Reference
<deployment::XPackage
> xPackage(
1163 bindBundleItem( getURL(), mediaType
, xCmdEnv
) );
1165 bundle
.push_back( xPackage
);
1166 // continue scanning:
1168 scanLegacyBundle( bundle
, getURL(),
1169 AbortChannel::get(xAbortChannel
), xCmdEnv
);
1174 scanBundle( bundle
, AbortChannel::get(xAbortChannel
), xCmdEnv
);
1177 catch (RuntimeException
&) {
1180 catch (CommandFailedException
&) {
1183 catch (CommandAbortedException
&) {
1186 catch (deployment::DeploymentException
&) {
1189 catch (Exception
&) {
1190 Any
exc( ::cppu::getCaughtException() );
1191 throw deployment::DeploymentException(
1192 OUSTR("error scanning bundle: ") + getURL(),
1193 static_cast<OWeakObject
*>(this), exc
);
1196 // sort: schema before config data, typelibs before components:
1197 Sequence
< Reference
<deployment::XPackage
> > ret( bundle
.size() );
1198 Reference
<deployment::XPackage
> * pret
= ret
.getArray();
1199 sal_Int32 lower_end
= 0;
1200 sal_Int32 upper_end
= ret
.getLength();
1201 t_packagevec::const_iterator
iPos( bundle
.begin() );
1202 t_packagevec::const_iterator
const iEnd( bundle
.end() );
1203 for ( ; iPos
!= iEnd
; ++iPos
)
1205 const Reference
<deployment::XPackageTypeInfo
> xPackageType(
1206 (*iPos
)->getPackageType() );
1207 OSL_ASSERT( xPackageType
.is() );
1208 if (xPackageType
.is()) {
1209 const OUString
mediaType( xPackageType
->getMediaType() );
1210 String type
, subType
;
1211 INetContentTypeParameterList params
;
1212 if (INetContentTypes::parse(
1213 mediaType
, type
, subType
, ¶ms
) &&
1214 type
.EqualsIgnoreCaseAscii("application") &&
1215 (subType
.EqualsIgnoreCaseAscii(
1216 "vnd.sun.star.uno-component") ||
1217 subType
.EqualsIgnoreCaseAscii(
1218 "vnd.sun.star.configuration-data")))
1221 pret
[ upper_end
] = *iPos
;
1225 pret
[ lower_end
] = *iPos
;
1228 OSL_ASSERT( lower_end
== upper_end
);
1230 const ::osl::MutexGuard
guard( getMutex() );
1231 pBundle
= m_pBundle
;
1234 pBundle
= &m_bundle
;
1235 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
1236 m_pBundle
= pBundle
;
1240 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
1245 inline bool isBundle_( OUString
const & mediaType
)
1247 // xxx todo: additional parsing?
1248 return mediaType
.getLength() > 0 &&
1249 (mediaType
.matchIgnoreAsciiCaseAsciiL(
1250 RTL_CONSTASCII_STRINGPARAM(
1251 "application/vnd.sun.star.package-bundle") ) ||
1252 mediaType
.matchIgnoreAsciiCaseAsciiL(
1253 RTL_CONSTASCII_STRINGPARAM(
1254 "application/vnd.sun.star.legacy-package-bundle") ));
1257 //______________________________________________________________________________
1258 Reference
<deployment::XPackage
> BackendImpl::PackageImpl::bindBundleItem(
1259 OUString
const & url
, OUString
const & mediaType
,
1260 Reference
<XCommandEnvironment
> const & xCmdEnv
,
1261 bool notifyDetectionError
)
1263 // ignore any nested bundles:
1264 if (isBundle_(mediaType
))
1265 return Reference
<deployment::XPackage
>();
1267 Reference
<deployment::XPackage
>xPackage
;
1269 xPackage
.set( getMyBackend()->m_xRootRegistry
->bindPackage(
1270 url
, mediaType
, xCmdEnv
) );
1271 OSL_ASSERT( xPackage
.is() );
1273 catch (RuntimeException
&) {
1276 catch (CommandFailedException
&) {
1277 // ignore already handled error
1279 catch (Exception
&) {
1280 const Any
exc( ::cppu::getCaughtException() );
1281 if (notifyDetectionError
||
1282 !exc
.isExtractableTo(
1283 ::getCppuType( reinterpret_cast<
1284 lang::IllegalArgumentException
const *>(0) ) ))
1286 interactContinuation(
1287 Any( lang::WrappedTargetException(
1288 OUSTR("bundle item error!"),
1289 static_cast<OWeakObject
*>(this), exc
) ),
1290 task::XInteractionApprove::static_type(), xCmdEnv
, 0, 0 );
1294 if (xPackage
.is()) {
1295 const Reference
<deployment::XPackageTypeInfo
> xPackageType(
1296 xPackage
->getPackageType() );
1297 OSL_ASSERT( xPackageType
.is() );
1298 // ignore any nested bundles:
1299 if (xPackageType
.is() && isBundle_( xPackageType
->getMediaType() ))
1305 //______________________________________________________________________________
1306 void BackendImpl::PackageImpl::scanBundle(
1307 t_packagevec
& bundle
,
1308 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
1309 Reference
<XCommandEnvironment
> const & xCmdEnv
)
1311 OSL_ASSERT( !m_legacyBundle
);
1313 ::ucbhelper::Content manifestContent
;
1314 if (! create_ucb_content(
1316 makeURL( m_url_expanded
, OUSTR("META-INF/manifest.xml") ),
1317 xCmdEnv
, false /* no throw */ ))
1319 OSL_ENSURE( 0, "### missing META-INF/manifest.xml file!" );
1324 const lang::Locale officeLocale
= getOfficeLocale();
1326 lang::Locale descrFileLocale
;
1328 const Reference
<XComponentContext
> xContext(
1329 getMyBackend()->getComponentContext() );
1330 Reference
<packages::manifest::XManifestReader
> xManifestReader(
1331 xContext
->getServiceManager()->createInstanceWithContext(
1332 OUSTR("com.sun.star.packages.manifest.ManifestReader"),
1333 xContext
), UNO_QUERY_THROW
);
1334 const Sequence
< Sequence
<beans::PropertyValue
> > manifestSeq(
1335 xManifestReader
->readManifestSequence( manifestContent
.openStream() ) );
1336 const OUString
packageRootURL( getURL() );
1337 for ( sal_Int32 pos
= manifestSeq
.getLength(); pos
--; )
1339 OUString fullPath
, mediaType
;
1340 Sequence
<beans::PropertyValue
> const & attribs
= manifestSeq
[ pos
];
1341 for ( sal_Int32 i
= attribs
.getLength(); i
--; )
1343 if (fullPath
.getLength() > 0 && mediaType
.getLength() > 0)
1345 if (attribs
[i
].Name
.equalsAsciiL(
1346 RTL_CONSTASCII_STRINGPARAM("FullPath") ))
1347 attribs
[i
].Value
>>= fullPath
;
1348 else if (attribs
[i
].Name
.equalsAsciiL(
1349 RTL_CONSTASCII_STRINGPARAM("MediaType") ))
1350 attribs
[i
].Value
>>= mediaType
;
1353 if (fullPath
.getLength() == 0 || mediaType
.getLength() == 0 ||
1354 mediaType
.equalsAsciiL( // opt: exclude common text/xml
1355 RTL_CONSTASCII_STRINGPARAM("text/xml") ))
1358 String type
, subType
;
1359 INetContentTypeParameterList params
;
1360 if (! INetContentTypes::parse( mediaType
, type
, subType
, ¶ms
))
1363 INetContentTypeParameter
const * param
= params
.find(
1364 ByteString("platform") );
1365 if (param
!= 0 && !platform_fits( param
->m_sValue
))
1367 const OUString
url( makeURL( packageRootURL
, fullPath
) );
1369 INetContentTypeParameter
const * execParam
= params
.find(
1370 ByteString("executable") );
1371 if (execParam
!=0 && execParam
->m_sValue
.CompareIgnoreCaseToAscii("true")==COMPARE_EQUAL
) {
1372 ::rtl::OUString expandedUrl
=expandUnoRcUrl(url
);
1373 oslFileError err
=osl_setFileAttributes( expandedUrl
.pData
, osl_File_Attribute_OwnRead
| osl_File_Attribute_OwnExe
);
1376 if (type
.EqualsIgnoreCaseAscii("application") &&
1377 subType
.EqualsIgnoreCaseAscii(
1383 // check for bundle description:
1384 if (type
.EqualsIgnoreCaseAscii("application") &&
1385 subType
.EqualsIgnoreCaseAscii(
1386 "vnd.sun.star.package-bundle-description"))
1389 param
= params
.find( ByteString("locale") );
1391 if (descrFile
.getLength() == 0)
1395 // match best locale:
1396 lang::Locale
locale( toLocale(param
->m_sValue
) );
1397 if (locale
.Language
== officeLocale
.Language
)
1399 if (descrFileLocale
.Country
== officeLocale
.Country
1400 && locale
.Country
!= officeLocale
.Country
)
1402 if (descrFileLocale
.Variant
== officeLocale
.Variant
1403 && locale
.Variant
!= officeLocale
.Variant
)
1406 descrFileLocale
= locale
;
1412 checkAborted( abortChannel
);
1414 //We make sure that we only create one XPackage for a particular URL.
1415 //Sometime programmers insert the same URL several times in the manifest
1416 //which may lead to DisposedExceptions.
1417 if (bundle
.end() == std::find_if(bundle
.begin(), bundle
.end(), XPackage_eq(url
)))
1419 const Reference
<deployment::XPackage
> xPackage(
1420 bindBundleItem( url
, mediaType
, xCmdEnv
) );
1422 bundle
.push_back( xPackage
);
1426 fprintf(stderr
, "manifest.xml contains a duplicate entry!\n");
1430 if (descrFile
.getLength() > 0)
1432 ::ucbhelper::Content descrFileContent
;
1433 if (create_ucb_content( &descrFileContent
, descrFile
,
1434 xCmdEnv
, false /* no throw */ ))
1436 // patch description:
1437 ::rtl::ByteSequence
bytes( readFile( descrFileContent
) );
1438 ::rtl::OUStringBuffer buf
;
1439 if ( bytes
.getLength() )
1441 buf
.append( OUString( reinterpret_cast<sal_Char
const *>(
1442 bytes
.getConstArray() ),
1443 bytes
.getLength(), RTL_TEXTENCODING_UTF8
) );
1447 buf
.append( Package::getDescription() );
1449 m_oldDescription
= buf
.makeStringAndClear();
1454 //______________________________________________________________________________
1455 void BackendImpl::PackageImpl::scanLegacyBundle(
1456 t_packagevec
& bundle
,
1457 OUString
const & url
,
1458 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
1459 Reference
<XCommandEnvironment
> const & xCmdEnv
,
1460 bool skip_registration
)
1462 ::ucbhelper::Content
ucbContent( url
, xCmdEnv
);
1464 // check for platform pathes:
1465 const OUString
title( ucbContent
.getPropertyValue(
1466 StrTitle::get() ).get
<OUString
>() );
1467 if (title
.endsWithIgnoreAsciiCaseAsciiL(
1468 RTL_CONSTASCII_STRINGPARAM(".plt") ) &&
1469 !platform_fits( title
.copy( 0, title
.getLength() - 4 ) )) {
1472 if (title
.endsWithIgnoreAsciiCaseAsciiL(
1473 RTL_CONSTASCII_STRINGPARAM("skip_registration") ))
1474 skip_registration
= true;
1476 OUString ar
[] = { StrTitle::get(), OUSTR("IsFolder") };
1477 Reference
<sdbc::XResultSet
> xResultSet(
1478 ucbContent
.createCursor(
1479 Sequence
<OUString
>( ar
, ARLEN(ar
) ),
1480 ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS
) );
1481 while (xResultSet
->next())
1483 checkAborted( abortChannel
);
1485 const Reference
<sdbc::XRow
> xRow( xResultSet
, UNO_QUERY_THROW
);
1486 const OUString
title_enc( ::rtl::Uri::encode(
1487 xRow
->getString( 1 /* Title */ ),
1488 rtl_UriCharClassPchar
,
1489 rtl_UriEncodeIgnoreEscapes
,
1490 RTL_TEXTENCODING_UTF8
) );
1491 const OUString
path( makeURL( url
, title_enc
) );
1494 const Reference
<deployment::XPackage
> xPackage(
1495 bindBundleItem( path
, OUString() /* detect */, xCmdEnv
,
1496 false /* ignore detection errors */ ) );
1497 if (xPackage
.is()) {
1498 const Reference
<deployment::XPackageTypeInfo
> xPackageType(
1499 xPackage
->getPackageType() );
1500 OSL_ASSERT( xPackageType
.is() );
1501 if (xPackageType
.is())
1502 mediaType
= xPackageType
->getMediaType();
1504 if (skip_registration
&&
1505 // xxx todo: additional parsing?
1506 mediaType
.matchIgnoreAsciiCaseAsciiL(
1507 RTL_CONSTASCII_STRINGPARAM(
1508 "application/vnd.sun.star.uno-component") ))
1511 bundle
.push_back( xPackage
);
1514 if (mediaType
.getLength() == 0 ||
1515 // script.xlb, dialog.xlb can be met everywhere:
1516 mediaType
.matchIgnoreAsciiCaseAsciiL(
1517 RTL_CONSTASCII_STRINGPARAM(
1518 "application/vnd.sun.star.basic-library") ) ||
1519 mediaType
.matchIgnoreAsciiCaseAsciiL(
1520 RTL_CONSTASCII_STRINGPARAM(
1521 "application/vnd.sun.star.dialog-library") ))
1523 if (xRow
->getBoolean( 2 /* IsFolder */ )) { // recurse into folder:
1525 bundle
, path
, abortChannel
, xCmdEnv
, skip_registration
);
1531 OUString
BackendImpl::PackageImpl::getDisplayName() throw (RuntimeException
)
1533 OUString sName
= getDescriptionInfoset().getLocalizedDisplayName();
1534 if (sName
.getLength() == 0)
1535 return m_displayName
;
1542 //==============================================================================
1543 Reference
<deployment::XPackageRegistry
> create(
1544 Reference
<deployment::XPackageRegistry
> const & xRootRegistry
,
1545 OUString
const & context
, OUString
const & cachePath
, bool readOnly
,
1546 Reference
<XComponentContext
> const & xComponentContext
)
1549 cachePath
.getLength() == 0 ? 1 : 3 );
1550 args
[ 0 ] <<= context
;
1551 if (cachePath
.getLength() > 0) {
1552 args
[ 1 ] <<= cachePath
;
1553 args
[ 2 ] <<= readOnly
;
1555 return new BackendImpl( args
, xComponentContext
, xRootRegistry
);
1558 } // namespace bundle
1559 } // namespace backend
1560 } // namespace dp_registry