summaryrefslogtreecommitdiff
path: root/desktop
diff options
context:
space:
mode:
authorOliver Bolte <obo@openoffice.org>2004-08-12 11:10:51 +0000
committerOliver Bolte <obo@openoffice.org>2004-08-12 11:10:51 +0000
commit3c0ac1b9a06cf68a954d6e69fcefbe825ebea6ce (patch)
tree8b00bbd2e5982dae08015b3c0bdfc9896449cc73 /desktop
parente3a25e2c91e9150bdaa4b9e05aecb6eb552b84d5 (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.cxx689
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, &params ))
+ 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, &params ))
- {
- 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