LCOV - code coverage report
Current view: top level - libreoffice/desktop/source/deployment/registry/package - dp_package.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 644 0.0 %
Date: 2012-12-27 Functions: 0 48 0.0 %
Legend: Lines: hit not hit

          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, &params ))
     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, &params ) &&
    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, &params ))
    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: */

Generated by: LCOV version 1.10