diff options
author | Oliver Bolte <obo@openoffice.org> | 2004-08-12 11:10:51 +0000 |
---|---|---|
committer | Oliver Bolte <obo@openoffice.org> | 2004-08-12 11:10:51 +0000 |
commit | 3c0ac1b9a06cf68a954d6e69fcefbe825ebea6ce (patch) | |
tree | 8b00bbd2e5982dae08015b3c0bdfc9896449cc73 /desktop | |
parent | e3a25e2c91e9150bdaa4b9e05aecb6eb552b84d5 (diff) |
INTEGRATION: CWS unotlc (1.3.18); FILE MERGED
2004/08/05 12:03:05 dbo 1.3.18.7: #i31111# fixing interaction
2004/08/04 15:25:37 dbo 1.3.18.6: #i31111#
2004/08/04 11:58:05 dbo 1.3.18.5: #i31111# switching to vnd.sun.star.zip
Issue number:
Submitted by:
Reviewed by:
2004/08/03 09:14:05 dbo 1.3.18.4: #31111#
Issue number:
Submitted by:
Reviewed by:
2004/08/02 15:18:46 dbo 1.3.18.3: #i31111#
2004/07/30 13:21:50 dbo 1.3.18.2: #i31111# API revision, manager operates on inflated content
Issue number:
Submitted by:
Reviewed by:
2004/07/14 14:21:29 dbo 1.3.18.1: #i20304# new factory helper, config refresh, singleton live deployment, minor string review, modified isRegistered()
Issue number:
Submitted by:
Reviewed by:
Diffstat (limited to 'desktop')
-rw-r--r-- | desktop/source/deployment/registry/package/dp_package.cxx | 689 |
1 files changed, 478 insertions, 211 deletions
diff --git a/desktop/source/deployment/registry/package/dp_package.cxx b/desktop/source/deployment/registry/package/dp_package.cxx index e93faad07cee..0d4f22792e64 100644 --- a/desktop/source/deployment/registry/package/dp_package.cxx +++ b/desktop/source/deployment/registry/package/dp_package.cxx @@ -2,9 +2,9 @@ * * $RCSfile: dp_package.cxx,v $ * - * $Revision: 1.3 $ + * $Revision: 1.4 $ * - * last change: $Author: kz $ $Date: 2004-06-11 12:16:29 $ + * last change: $Author: obo $ $Date: 2004-08-12 12:10:51 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -62,14 +62,26 @@ #include "dp_package.hrc" #include "dp_backend.h" #include "dp_ucb.h" +#include "dp_interact.h" #include "rtl/uri.hxx" #include "cppuhelper/exc_hlp.hxx" #include "ucbhelper/content.hxx" #include "svtools/inettype.hxx" #include "comphelper/anytostring.hxx" +#include "com/sun/star/beans/UnknownPropertyException.hpp" +#include "com/sun/star/io/XOutputStream.hpp" +#include "com/sun/star/io/XInputStream.hpp" +#include "com/sun/star/task/InteractionClassification.hpp" +#include "com/sun/star/ucb/XInteractionReplaceExistingData.hpp" +#include "com/sun/star/ucb/NameClashResolveRequest.hpp" #include "com/sun/star/ucb/XContentAccess.hpp" +#include "com/sun/star/ucb/NameClash.hpp" +#include "com/sun/star/ucb/UnsupportedCommandException.hpp" #include "com/sun/star/sdbc/XResultSet.hpp" #include "com/sun/star/sdbc/XRow.hpp" +#include "com/sun/star/packages/manifest/XManifestReader.hpp" +#include "com/sun/star/packages/manifest/XManifestWriter.hpp" +#include <list> #include <vector> @@ -79,12 +91,9 @@ using namespace ::com::sun::star::uno; using namespace ::com::sun::star::ucb; using ::rtl::OUString; -namespace dp_registry -{ -namespace backend -{ -namespace package -{ +namespace dp_registry { +namespace backend { +namespace bundle { //============================================================================== class BackendImpl : public PackageRegistryBackend @@ -97,28 +106,44 @@ protected: OUString const & url, OUString const & mediaType, Reference<XCommandEnvironment> const & xCmdEnv ); + virtual void SAL_CALL disposing(); + public: - inline BackendImpl( Reference<XComponentContext> const & xComponentContext, + inline BackendImpl( Sequence<Any> const & args, + Reference<XComponentContext> const & xComponentContext, OUString const & implName, - Sequence<OUString> const & supportedMediaTypes ) + Sequence<OUString> const & supportedMediaTypes, + Reference<deployment::XPackageRegistry> + const & xRootRegistry ) : PackageRegistryBackend( - xComponentContext, implName, supportedMediaTypes ), - m_strPackageBundle( getResourceString(RID_STR_PACKAGE_BUNDLE) ) + args, xComponentContext, implName, supportedMediaTypes ), + m_strPackageBundle( getResourceString(RID_STR_PACKAGE_BUNDLE) ), + m_xRootRegistry( xRootRegistry ) {} + + Reference<deployment::XPackageRegistry> m_xRootRegistry; }; +//______________________________________________________________________________ +void BackendImpl::disposing() +{ + m_xRootRegistry.clear(); + PackageRegistryBackend::disposing(); +} + //============================================================================== class PackageImpl : public ::dp_registry::backend::Package { protected: - OUString m_scanURL; - bool m_legacyPackage; - + OUString m_url_expanded; + bool m_legacyBundle; + typedef ::std::list< ::std::pair<OUString, OUString> > t_bundleInfos; + t_bundleInfos m_bundleInfos; Sequence< Reference<deployment::XPackage> > m_bundle; bool m_bundleInit; typedef ::std::vector< Reference<deployment::XPackage> > t_packagevec; - void scanBundle( + void scanLegacyBundle( t_packagevec & bundle, OUString const & url, ::rtl::Reference<AbortChannel> const & abortChannel, @@ -126,7 +151,7 @@ protected: bool skip_registration = false ); // Package - virtual bool isRegistered_( + virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_( ::osl::ResettableMutexGuard & guard, ::rtl::Reference<AbortChannel> const & abortChannel, Reference<XCommandEnvironment> const & xCmdEnv ); @@ -147,7 +172,8 @@ public: OUString const & mediaType, OUString const & name, OUString const & description, - bool legacyPackage ); + bool legacyBundle, + Reference<XCommandEnvironment> const & xCmdEnv ); // XPackage virtual sal_Bool SAL_CALL isBundle() throw (RuntimeException); @@ -159,28 +185,39 @@ public: lang::IllegalArgumentException, RuntimeException); virtual Any SAL_CALL getIcon( sal_Bool highContrast, sal_Bool smallIcon ) throw (RuntimeException); + virtual void SAL_CALL exportTo( + OUString const & destFolderURL, OUString const & newTitle, + sal_Int32 nameClashAction, + Reference<XCommandEnvironment> const & xCmdEnv ) + throw (CommandFailedException, CommandAbortedException, + RuntimeException); }; //============================================================================== -OUString SAL_CALL getImplementationName() -{ - return OUSTR( - "com.sun.star.comp.deployment.package.PackageRegistryBackend"); -} - -//============================================================================== -Reference<XInterface> SAL_CALL create( +Reference<deployment::XPackageRegistry> create( + Reference<deployment::XPackageRegistry> const & xRootRegistry, + OUString const & context, OUString const & cachePath, bool readOnly, Reference<XComponentContext> const & xComponentContext ) - SAL_THROW( (Exception) ) { + Sequence<Any> args( + cachePath.getLength() == 0 ? 1 : 3 ); + args[ 0 ] <<= context; + if (cachePath.getLength() > 0) { + args[ 1 ] <<= cachePath; + args[ 2 ] <<= readOnly; + } + OUString const mediaTypes [] = { - OUSTR("application/vnd.sun.star.uno-package"), - OUSTR("application/vnd.sun.star.uno-legacy-package") + OUSTR("application/vnd.sun.star.package-bundle"), + OUSTR("application/vnd.sun.star.legacy-package-bundle") }; - return static_cast< ::cppu::OWeakObject * >( - new BackendImpl( xComponentContext, getImplementationName(), - Sequence<OUString>( - mediaTypes, ARLEN(mediaTypes) ) ) ); + + return new BackendImpl( args, xComponentContext, + OUSTR("com.sun.star.comp.deployment." + "bundle.PackageRegistryBackend"), + Sequence<OUString>( + mediaTypes, ARLEN(mediaTypes) ), + xRootRegistry ); } // PackageRegistryBackend @@ -201,11 +238,11 @@ Reference<deployment::XPackage> BackendImpl::bindPackage_( OUSTR("Title") ) ) ); if (title.endsWithIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM(".uno.pkg") )) - mediaType = OUSTR("application/vnd.sun.star.uno-package"); + mediaType = OUSTR("application/vnd.sun.star.package-bundle"); else if (title.endsWithIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM(".zip") )) mediaType = - OUSTR("application/vnd.sun.star.uno-legacy-package"); + OUSTR("application/vnd.sun.star.legacy-package-bundle"); } if (mediaType.getLength() == 0) throw lang::IllegalArgumentException( @@ -220,23 +257,19 @@ Reference<deployment::XPackage> BackendImpl::bindPackage_( if (type.EqualsIgnoreCaseAscii("application")) { ::ucb::Content ucbContent( url, xCmdEnv ); - if (subType.EqualsIgnoreCaseAscii("vnd.sun.star.uno-package")) - { + if (subType.EqualsIgnoreCaseAscii("vnd.sun.star.package-bundle")) return new PackageImpl( this, url, mediaType, extract_throw<OUString>( ucbContent.getPropertyValue( OUSTR("Title") ) ), - m_strPackageBundle, false ); - } + m_strPackageBundle, false, xCmdEnv ); else if (subType.EqualsIgnoreCaseAscii( - "vnd.sun.star.uno-legacy-package")) - { + "vnd.sun.star.legacy-package-bundle")) return new PackageImpl( this, url, mediaType, extract_throw<OUString>( ucbContent.getPropertyValue( OUSTR("Title") ) ), - m_strPackageBundle, true ); - } + m_strPackageBundle, true, xCmdEnv ); } } throw lang::IllegalArgumentException( @@ -254,19 +287,139 @@ PackageImpl::PackageImpl( OUString const & mediaType, OUString const & name, OUString const & description, - bool legacyPackage ) + bool legacyBundle, + Reference<XCommandEnvironment> const & xCmdEnv ) : Package( myBackend, url, mediaType, name, name /* display-name */, description ), - m_legacyPackage( legacyPackage ), + m_url_expanded( expand_url( url ) ), + m_legacyBundle( legacyBundle ), m_bundleInit( false ) { - ::rtl::OUStringBuffer buf; - buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.pkg://") ); - buf.append( ::rtl::Uri::encode( url, rtl_UriCharClassRegName, - rtl_UriEncodeIgnoreEscapes, - RTL_TEXTENCODING_UTF8 ) ); - buf.append( static_cast<sal_Unicode>('/') ); - m_scanURL = buf.makeStringAndClear(); + if (! legacyBundle) + { + ::ucb::Content manifestContent; + if (create_ucb_content( + &manifestContent, + make_url( m_url_expanded, OUSTR("META-INF/manifest.xml") ), + xCmdEnv, false /* no throw */ )) + { + bool baseIsExpandURL = url.matchAsciiL( + RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.expand:") ); + lang::Locale const & officeLocale = getOfficeLocale(); + OUString descrFile; + lang::Locale descrFileLocale; + + Reference<XComponentContext> xContext( + myBackend->getComponentContext() ); + Reference<packages::manifest::XManifestReader> xManifestReader( + xContext->getServiceManager()->createInstanceWithContext( + OUSTR("com.sun.star.packages.manifest.ManifestReader"), + xContext ), UNO_QUERY_THROW ); + Sequence< Sequence<beans::PropertyValue> > manifestSeq( + xManifestReader->readManifestSequence( + manifestContent.openStream() ) ); + Sequence<beans::PropertyValue> const * pmanifestSeq = + manifestSeq.getConstArray(); + for ( sal_Int32 pos = manifestSeq.getLength(); pos--; ) + { + OUString path, mediaType; + beans::PropertyValue const * pattribs = + pmanifestSeq[ pos ].getConstArray(); + for ( sal_Int32 i = pmanifestSeq[ pos ].getLength(); i--; ) + { + if (path.getLength() > 0 && mediaType.getLength() > 0) + break; + if (pattribs[i].Name.equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM("FullPath") )) + pattribs[i].Value >>= path; + else if (pattribs[i].Name.equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM("MediaType") )) + pattribs[i].Value >>= mediaType; + } + + if (path.getLength() == 0 || mediaType.getLength() == 0 || + mediaType.equalsAsciiL( // opt: exclude common text/xml + RTL_CONSTASCII_STRINGPARAM("text/xml") )) + continue; + + String type, subType; + INetContentTypeParameterList params; + if (! INetContentTypes::parse( + mediaType, type, subType, ¶ms )) + continue; + + INetContentTypeParameter const * param = params.find( + ByteString("platform") ); + if (param != 0 && !platform_fits( param->m_sValue )) + continue; + if (path.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("/") )) + continue; // exclude root folder + + if (type.EqualsIgnoreCaseAscii("application") && + subType.EqualsIgnoreCaseAscii( + "vnd.sun.star.package-bundle-description")) + { + // check locale: + INetContentTypeParameter const * param = + params.find( ByteString("locale") ); + if (param == 0) { + if (descrFile.getLength() == 0) + descrFile = path; + } + else + { + // match best locale: + lang::Locale locale( toLocale(param->m_sValue) ); + if (locale.Language == officeLocale.Language) + { + if (descrFileLocale.Country == officeLocale.Country + && locale.Country != officeLocale.Country) + continue; + if (descrFileLocale.Variant == officeLocale.Variant + && locale.Variant != officeLocale.Variant) + continue; + descrFile = path; + descrFileLocale = locale; + } + } + } + + if (baseIsExpandURL) { + // encode once more for vnd.sun.star.expand schema: + // vnd.sun.star.expand:$UNO_... + // will expand to file-url + path = ::rtl::Uri::encode( + path, rtl_UriCharClassUric, + rtl_UriEncodeIgnoreEscapes, + RTL_TEXTENCODING_UTF8 ); + } + path = make_url( url, path ); + m_bundleInfos.push_back( + ::std::pair<OUString, OUString>(path, mediaType) ); + } + + if (descrFile.getLength() > 0) + { + ::ucb::Content descrFileContent; + if (create_ucb_content( &descrFileContent, + make_url( + m_url_expanded, descrFile ), + xCmdEnv, false /* no throw */ )) + { + // patch description: + ::rtl::ByteSequence bytes( readFile( descrFileContent ) ); + ::rtl::OUStringBuffer buf; + buf.append( OUString( reinterpret_cast<sal_Char const *>( + bytes.getConstArray() ), + bytes.getLength(), + RTL_TEXTENCODING_UTF8 ) ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\n") ); + buf.append( getDescription() ); + m_description = buf.makeStringAndClear(); + } + } + } + } } //______________________________________________________________________________ @@ -283,42 +436,45 @@ void PackageImpl::disposing() // Package //______________________________________________________________________________ -bool PackageImpl::isRegistered_( +beans::Optional< beans::Ambiguous<sal_Bool> > PackageImpl::isRegistered_( ::osl::ResettableMutexGuard & guard, ::rtl::Reference<AbortChannel> const & abortChannel, Reference<XCommandEnvironment> const & xCmdEnv ) { Sequence< Reference<deployment::XPackage> > bundle( getBundle( abortChannel.get(), xCmdEnv ) ); - if (bundle.getLength() == 0) - throw beans::UnknownPropertyException( - OUSTR("registration cannot bet determined: ") + m_url, - static_cast<OWeakObject *>(this) ); - Reference<deployment::XPackage> const * pbundle = bundle.getConstArray(); - bool ret = true; - bool init = false; + bool reg = false; + bool present = false; + bool ambig = false; for ( sal_Int32 pos = bundle.getLength(); pos--; ) { Reference<deployment::XPackage> const & xPackage = pbundle[ pos ]; Reference<task::XAbortChannel> xSubAbortChannel( xPackage->createAbortChannel() ); AbortChannel::Chain chain( abortChannel, xSubAbortChannel ); - bool b = xPackage->isRegistered( xSubAbortChannel, xCmdEnv ); - if (init) + beans::Optional< beans::Ambiguous<sal_Bool> > option( + xPackage->isRegistered( xSubAbortChannel, xCmdEnv ) ); + if (option.IsPresent) { - if (ret != b) - throw beans::UnknownPropertyException( - OUSTR("registration status is ambiguous: ") + m_url, - static_cast<OWeakObject *>(this) ); - } - else - { - ret = b; - init = true; + beans::Ambiguous<sal_Bool> const & status = option.Value; + if (present) + { + if (reg != (status.Value != sal_False)) { + ambig = true; + reg = false; + break; + } + } + else + { + reg = status.Value; + present = true; + } } } - return ret; + return beans::Optional< beans::Ambiguous<sal_Bool> >( + present, beans::Ambiguous<sal_Bool>(reg, ambig) ); } //______________________________________________________________________________ @@ -335,8 +491,7 @@ void PackageImpl::processPackage_( if (registerPackage) { sal_Int32 len = bundle.getLength(); - for ( sal_Int32 pos = 0; pos < len; ++pos ) - { + for ( sal_Int32 pos = 0; pos < len; ++pos ) { Reference<deployment::XPackage> const & xPackage = pbundle[ pos ]; Reference<task::XAbortChannel> xSubAbortChannel( xPackage->createAbortChannel() ); @@ -347,8 +502,7 @@ void PackageImpl::processPackage_( else { // revoke in reverse order: - for ( sal_Int32 pos = bundle.getLength(); pos--; ) - { + for ( sal_Int32 pos = bundle.getLength(); pos--; ) { Reference<deployment::XPackage> const & xPackage = pbundle[ pos ]; Reference<task::XAbortChannel> xSubAbortChannel( xPackage->createAbortChannel() ); @@ -364,8 +518,7 @@ Any PackageImpl::getIcon( sal_Bool highContrast, sal_Bool smallIcon ) throw (RuntimeException) { OSL_ASSERT( smallIcon ); - if (smallIcon) - { + if (smallIcon) { sal_uInt16 ret = highContrast ? RID_IMG_DEF_PACKAGE_BUNDLE_HC : RID_IMG_DEF_PACKAGE_BUNDLE; return makeAny(ret); @@ -374,6 +527,157 @@ Any PackageImpl::getIcon( sal_Bool highContrast, sal_Bool smallIcon ) } //______________________________________________________________________________ +void PackageImpl::exportTo( + OUString const & destFolderURL, OUString const & newTitle, + sal_Int32 nameClashAction, Reference<XCommandEnvironment> const & xCmdEnv ) + throw (CommandFailedException, CommandAbortedException, RuntimeException) +{ + ::ucb::Content sourceContent( m_url_expanded, xCmdEnv ); + OUString title(newTitle); + if (title.getLength() == 0) + sourceContent.getPropertyValue( OUSTR("Title") ) >>= title; + OUString destURL( make_url( destFolderURL, ::rtl::Uri::encode( + title, rtl_UriCharClassPchar, + rtl_UriEncodeIgnoreEscapes, + RTL_TEXTENCODING_UTF8 ) ) ); + + if (nameClashAction == NameClash::ASK) + { + if (create_ucb_content( + 0, destURL, xCmdEnv, false /* no throw */ ) && + !interactContinuation( + makeAny( NameClashResolveRequest( + OUSTR("file already exists: ") + title, + static_cast<OWeakObject *>(this), + task::InteractionClassification_QUERY, + destFolderURL, title, OUString() ) ), + XInteractionReplaceExistingData::static_type(), xCmdEnv )) { + return; + } + } + else if (nameClashAction != NameClash::OVERWRITE) { + throw CommandFailedException( + OUSTR("unsupported nameClashAction!"), + static_cast<OWeakObject *>(this), Any() ); + } + erase_path( destURL, xCmdEnv ); + + ::rtl::OUStringBuffer buf; + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.zip://") ); + buf.append( ::rtl::Uri::encode( destURL, + rtl_UriCharClassRegName, + rtl_UriEncodeIgnoreEscapes, + RTL_TEXTENCODING_UTF8 ) ); + buf.append( static_cast<sal_Unicode>('/') ); + OUString destFolder( buf.makeStringAndClear() ); + + ProgressLevel progress( xCmdEnv ); + ::ucb::Content destFolderContent( destFolder, xCmdEnv ); + // transfer every item of folder into zip: + Reference<sdbc::XResultSet> xResultSet( + sourceContent.createCursor( Sequence<OUString>(), + ::ucb::INCLUDE_FOLDERS_AND_DOCUMENTS ) ); + while (xResultSet->next()) { + ::ucb::Content subContent( + Reference<XContentAccess>( + xResultSet, UNO_QUERY_THROW )->queryContent(), xCmdEnv ); + if (! destFolderContent.transferContent( + subContent, ::ucb::InsertOperation_COPY, + OUString(), NameClash::OVERWRITE )) + throw RuntimeException( OUSTR("UCB transferContent() failed!"), + static_cast<OWeakObject *>(this) ); + progress.update(); + } + + // assure META-INF folder: + ::ucb::Content metainfFolderContent; + create_folder( &metainfFolderContent, + make_url( destFolderContent.getURL(), OUSTR("META-INF") ), + xCmdEnv ); + + if (m_legacyBundle) + { + // easy to migrate legacy bundles to new format: + // just export them once using a .uno.pkg name! + // set detected media-types of any bundle item: + + // collect all manifest entries: + Sequence< Reference<deployment::XPackage> > bundle; + try { + bundle = getBundle( Reference<task::XAbortChannel>(), xCmdEnv ); + } + // xxx todo: think about exception specs: + catch (deployment::DeploymentException &) { + OSL_ASSERT( 0 ); + } + catch (lang::IllegalArgumentException &) { + OSL_ASSERT( 0 ); + } + + ::std::vector< Sequence<beans::PropertyValue> > manifest; + manifest.reserve( bundle.getLength() ); + sal_Int32 baseURLlen = m_url_expanded.getLength(); + Reference<deployment::XPackage> const *pbundle = bundle.getConstArray(); + OUString strMediaType = OUSTR("MediaType"); + OUString strFullPath = OUSTR("FullPath"); + for ( sal_Int32 pos = bundle.getLength(); pos--; ) + { + Reference<deployment::XPackage> const & xPackage = pbundle[ pos ]; + OUString url_( expand_url( xPackage->getURL() ) ); + OSL_ASSERT( url_.getLength() > baseURLlen ); + Sequence<beans::PropertyValue> attribs( 2 ); + beans::PropertyValue * pattribs = attribs.getArray(); + pattribs[ 0 ].Name = strFullPath; + pattribs[ 0 ].Value <<= url_.copy( baseURLlen + 1 ); + pattribs[ 1 ].Name = strMediaType; + pattribs[ 1 ].Value <<= xPackage->getMediaType(); + manifest.push_back( attribs ); + } + + // write into pipe: + Reference<XComponentContext> xContext( + getMyBackend()->getComponentContext() ); + Reference<packages::manifest::XManifestWriter> xManifestWriter( + xContext->getServiceManager()->createInstanceWithContext( + OUSTR("com.sun.star.packages.manifest.ManifestWriter"), + xContext ), UNO_QUERY_THROW ); + Reference<io::XOutputStream> xPipe( + xContext->getServiceManager()->createInstanceWithContext( + OUSTR("com.sun.star.io.Pipe"), xContext ), UNO_QUERY_THROW ); + xManifestWriter->writeManifestSequence( + xPipe, Sequence< Sequence<beans::PropertyValue> >( + &manifest[ 0 ], manifest.size() ) ); + + // write buffered pipe data to content: + ::ucb::Content manifestContent( + make_url( metainfFolderContent.getURL(), OUSTR("manifest.xml") ), + xCmdEnv ); + manifestContent.writeStream( + Reference<io::XInputStream>( xPipe, UNO_QUERY_THROW ), + true /* replace existing */ ); + } + else + { + // overwrite manifest.xml: + ::ucb::Content manifestContent( + make_url( m_url_expanded, OUSTR("META-INF/manifest.xml") ), + xCmdEnv ); + if (! metainfFolderContent.transferContent( + manifestContent, ::ucb::InsertOperation_COPY, + OUString(), NameClash::OVERWRITE )) + throw RuntimeException( OUSTR("UCB transferContent() failed!"), + static_cast<OWeakObject *>(this) ); + } + + // xxx todo: obsolete in the future + try { + destFolderContent.executeCommand( OUSTR("flush"), Any() ); + } + catch (UnsupportedCommandException &) { + } +} + +//______________________________________________________________________________ sal_Bool PackageImpl::isBundle() throw (RuntimeException) { return true; @@ -390,58 +694,75 @@ Sequence< Reference<deployment::XPackage> > PackageImpl::getBundle( if (! m_bundleInit) { t_packagevec bundle; - try - { - if (m_legacyPackage) + try { + if (m_legacyBundle) { // legacy packages allow script.xlb, dialog.xlb in bundle // root folder: OUString mediaType; // probe for script.xlb: if (create_ucb_content( - 0, make_url( m_scanURL, OUSTR("script.xlb") ), - xCmdEnv, false /* no throw */ )) - mediaType = OUSTR("application/vnd.sun.star." - "basic-script"); + 0, make_url( m_url_expanded, OUSTR("script.xlb") ), + xCmdEnv, false /* no throw */ )) { + mediaType = OUSTR("application/vnd.sun.star.basic-library"); + } // probe for dialog.xlb: else if (create_ucb_content( - 0, make_url( m_scanURL, OUSTR("dialog.xlb") ), + 0, make_url( m_url_expanded, OUSTR("dialog.xlb") ), xCmdEnv, false /* no throw */ )) mediaType = OUSTR("application/vnd.sun.star." "dialog-library"); + if (mediaType.getLength() > 0) { Reference<deployment::XPackage> xPackage( - getMyBackend()->getRootRegistry()->bindPackage( - m_scanURL, mediaType, xCmdEnv ) ); + getMyBackend()->m_xRootRegistry->bindPackage( + getURL(), + mediaType, xCmdEnv ) ); OSL_ASSERT( xPackage.is() ); bundle.push_back( xPackage ); + // continue scanning: + } + scanLegacyBundle( bundle, getURL(), + AbortChannel::get(xAbortChannel), xCmdEnv ); + } + else + { + // .uno.pkg: + ::rtl::Reference<AbortChannel> abortChannel( + AbortChannel::get(xAbortChannel) ); + t_bundleInfos::const_iterator iPos( m_bundleInfos.begin() ); + t_bundleInfos::const_iterator const iEnd( m_bundleInfos.end() ); + for ( ; iPos != iEnd; ++iPos ) { + checkAborted( abortChannel ); + try { + Reference<deployment::XPackage> xPackage( + getMyBackend()->m_xRootRegistry->bindPackage( + iPos->first, iPos->second, xCmdEnv ) ); + OSL_ASSERT( xPackage.is() ); + bundle.push_back( xPackage ); + } + catch (lang::IllegalArgumentException &) { + } } } - scanBundle( bundle, m_scanURL, - AbortChannel::get(xAbortChannel), xCmdEnv ); } - catch (RuntimeException &) - { + catch (RuntimeException &) { throw; } - catch (CommandFailedException &) - { + catch (CommandFailedException &) { throw; } - catch (CommandAbortedException &) - { + catch (CommandAbortedException &) { throw; } - catch (deployment::DeploymentException &) - { + catch (deployment::DeploymentException &) { throw; } - catch (Exception &) - { + catch (Exception &) { Any exc( ::cppu::getCaughtException() ); throw deployment::DeploymentException( - OUSTR("error scanning bundle: ") + m_url, + OUSTR("error scanning bundle: ") + getURL(), static_cast<OWeakObject *>(this), exc ); } @@ -467,8 +788,7 @@ Sequence< Reference<deployment::XPackage> > PackageImpl::getBundle( --upper_end; pret[ upper_end ] = *iPos; } - else - { + else { pret[ lower_end ] = *iPos; ++lower_end; } @@ -476,8 +796,7 @@ Sequence< Reference<deployment::XPackage> > PackageImpl::getBundle( OSL_ASSERT( lower_end == upper_end ); ::osl::MutexGuard guard( getMutex() ); - if (! m_bundleInit) - { + if (! m_bundleInit) { m_bundle = ret; m_bundleInit = true; } @@ -486,7 +805,7 @@ Sequence< Reference<deployment::XPackage> > PackageImpl::getBundle( } //______________________________________________________________________________ -void PackageImpl::scanBundle( +void PackageImpl::scanLegacyBundle( t_packagevec & bundle, OUString const & url, ::rtl::Reference<AbortChannel> const & abortChannel, @@ -495,129 +814,77 @@ void PackageImpl::scanBundle( { ::ucb::Content ucbContent( url, xCmdEnv ); - if (m_legacyPackage) - { - // check for platform pathes: - OUString title( extract_throw<OUString>( - ucbContent.getPropertyValue( OUSTR("Title") ) ) ); - if (title.endsWithIgnoreAsciiCaseAsciiL( - RTL_CONSTASCII_STRINGPARAM(".plt") )) - { - if (! platform_fits( title.copy( 0, title.getLength() - 4 ) )) - return; - } - - if (title.endsWithIgnoreAsciiCaseAsciiL( - RTL_CONSTASCII_STRINGPARAM("skip_registration") )) - skip_registration = true; - } + // check for platform pathes: + OUString title( extract_throw<OUString>( + ucbContent.getPropertyValue( OUSTR("Title") ) ) ); + if (title.endsWithIgnoreAsciiCaseAsciiL( + RTL_CONSTASCII_STRINGPARAM(".plt") ) && + !platform_fits( title.copy( 0, title.getLength() - 4 ) )) + return; + if (title.endsWithIgnoreAsciiCaseAsciiL( + RTL_CONSTASCII_STRINGPARAM("skip_registration") )) + skip_registration = true; OUString ar [] = { OUSTR("Title"), OUSTR("IsFolder") }; Reference<sdbc::XResultSet> xResultSet( ucbContent.createCursor( Sequence<OUString>( ar, ARLEN(ar) ), - ::ucb::INCLUDE_FOLDERS_AND_DOCUMENTS ) ); + ::ucb::INCLUDE_FOLDERS_AND_DOCUMENTS ) ); while (xResultSet->next()) { checkAborted( abortChannel ); Reference<sdbc::XRow> xRow( xResultSet, UNO_QUERY_THROW ); OUString title( xRow->getString( 1 /* Title */ ) ); - OUString path( make_url( url, ::rtl::Uri::encode( - title, rtl_UriCharClassPchar, - rtl_UriEncodeIgnoreEscapes, - RTL_TEXTENCODING_UTF8 ) ) ); - if (m_legacyPackage) - { - OUString mediaType; - try - { - Reference<deployment::XPackage> xPackage( - getMyBackend()->getRootRegistry()->bindPackage( - path, OUString(), xCmdEnv ) ); - OSL_ASSERT( xPackage.is() ); - mediaType = xPackage->getMediaType(); - - if (skip_registration && - // xxx todo: additional media-type parsing? - mediaType.matchIgnoreAsciiCaseAsciiL( - RTL_CONSTASCII_STRINGPARAM( - "application/vnd.sun.star.uno-component") )) - continue; - - bundle.push_back( xPackage ); - } - catch (lang::IllegalArgumentException &) - { - } - if (mediaType.getLength() == 0 || - // script.xlb, dialog.xlb can be met everywhere: - mediaType.matchIgnoreAsciiCaseAsciiL( - RTL_CONSTASCII_STRINGPARAM( - "application/vnd.sun.star.basic-script") ) || + OUString title_enc( ::rtl::Uri::encode( title, rtl_UriCharClassPchar, + rtl_UriEncodeIgnoreEscapes, + RTL_TEXTENCODING_UTF8 ) ); + if (url.matchAsciiL( + RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.expand:") )) { + // encode once more for vnd.sun.star.expand schema: + // vnd.sun.star.expand:$UNO_... will expand to file-url + title_enc = ::rtl::Uri::encode( title_enc, rtl_UriCharClassUric, + rtl_UriEncodeIgnoreEscapes, + RTL_TEXTENCODING_UTF8 ); + } + OUString path( make_url( url, title_enc ) ); + + OUString mediaType; + try { + Reference<deployment::XPackage> xPackage( + getMyBackend()->m_xRootRegistry->bindPackage( + path, OUString(), xCmdEnv ) ); + OSL_ASSERT( xPackage.is() ); + mediaType = xPackage->getMediaType(); + + if (skip_registration && + // xxx todo: additional media-type parsing? mediaType.matchIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM( - "application/vnd.sun.star.dialog-library") )) - { - if (xRow->getBoolean( 2 /* IsFolder */ )) - { - // recurse into folder: - scanBundle( bundle, path, - abortChannel, xCmdEnv, skip_registration ); - } - } + "application/vnd.sun.star.uno-component") )) + continue; + + bundle.push_back( xPackage ); + } + catch (lang::IllegalArgumentException &) { } - else - { - OUString mediaType; - Reference<XContentAccess> xContentAccess( xRow, UNO_QUERY_THROW ); - ::ucb::Content item( xContentAccess->queryContent(), xCmdEnv ); - try - { - item.getPropertyValue( OUSTR("MediaType") ) >>= mediaType; - } - catch (beans::UnknownPropertyException &) - { - } - if (mediaType.getLength() > 0) - { - String type, subType; - INetContentTypeParameterList params; - if (INetContentTypes::parse( - mediaType, type, subType, ¶ms )) - { - INetContentTypeParameter const * param = params.find( - ByteString("platform") ); - if (param != 0 && !platform_fits( param->m_sValue )) - continue; - } - Reference<deployment::XPackage> xPackage( - getMyBackend()->getRootRegistry()->bindPackage( - path, mediaType, xCmdEnv ) ); - OSL_ASSERT( xPackage.is() ); - bundle.push_back( xPackage ); - } - else - { - if (xRow->getBoolean( 2 /* IsFolder */ )) - { - // recurse into folder: - scanBundle( bundle, path, - abortChannel, xCmdEnv, skip_registration ); - } - else - { - // ignore this item: - // xxx todo: discuss whether it is sensible to ignore files - // within .uno.pkg packages that don't have a media-type - // entry - } - } + if (mediaType.getLength() == 0 || + // script.xlb, dialog.xlb can be met everywhere: + mediaType.matchIgnoreAsciiCaseAsciiL( + RTL_CONSTASCII_STRINGPARAM( + "application/vnd.sun.star.basic-library") ) || + mediaType.matchIgnoreAsciiCaseAsciiL( + RTL_CONSTASCII_STRINGPARAM( + "application/vnd.sun.star.dialog-library") )) + { + if (xRow->getBoolean( 2 /* IsFolder */ )) // recurse into folder: + scanLegacyBundle( + bundle, path, abortChannel, xCmdEnv, skip_registration ); } } } -} // namespace package +} // namespace bundle } // namespace backend } // namespace dp_registry |