diff options
-rw-r--r-- | include/sfx2/DocumentMetadataAccess.hxx | 9 | ||||
-rw-r--r-- | offapi/UnoApi_offapi.mk | 1 | ||||
-rw-r--r-- | offapi/com/sun/star/frame/XTransientDocumentsDocumentContentIdentifierFactory.idl | 59 | ||||
-rw-r--r-- | sc/source/filter/xml/xmlwrap.cxx | 4 | ||||
-rw-r--r-- | sfx2/source/doc/DocumentMetadataAccess.cxx | 39 | ||||
-rw-r--r-- | sw/source/filter/ww8/ww8par.cxx | 5 | ||||
-rw-r--r-- | sw/source/filter/xml/swxml.cxx | 4 | ||||
-rw-r--r-- | ucb/source/ucp/tdoc/tdoc_provider.cxx | 27 | ||||
-rw-r--r-- | ucb/source/ucp/tdoc/tdoc_provider.hxx | 13 | ||||
-rw-r--r-- | writerfilter/source/dmapper/DomainMapper.cxx | 4 |
10 files changed, 141 insertions, 24 deletions
diff --git a/include/sfx2/DocumentMetadataAccess.hxx b/include/sfx2/DocumentMetadataAccess.hxx index 31a61adebb01..cf5a2ddbcbac 100644 --- a/include/sfx2/DocumentMetadataAccess.hxx +++ b/include/sfx2/DocumentMetadataAccess.hxx @@ -44,6 +44,9 @@ namespace com { namespace sun { namespace star { namespace embed { class XStorage; } } } } +namespace com { namespace sun { namespace star { namespace frame { + class XModel; +} } } } class SfxObjectShell; namespace sfx2 { @@ -52,7 +55,7 @@ namespace sfx2 { /** create a base URI for loading metadata from an ODF (sub)document. @param i_xContext component context - @param i_xStorage storage for the document; FileSystemStorage is allowed + @param i_xModel model of the document (required if no URI is provided) @param i_rPkgURI the URI for the package @param i_rSubDocument (optional) path of the subdocument in package @@ -60,8 +63,8 @@ namespace sfx2 { */ css::uno::Reference< css::rdf::XURI> SFX2_DLLPUBLIC createBaseURI( - css::uno::Reference< css::uno::XComponentContext> const & i_xContext, - css::uno::Reference< css::embed::XStorage> const & i_xStorage, + css::uno::Reference<css::uno::XComponentContext> const & i_xContext, + css::uno::Reference<css::frame::XModel> const & i_xModel, OUString const & i_rPkgURI, OUString const & i_rSubDocument = OUString()); diff --git a/offapi/UnoApi_offapi.mk b/offapi/UnoApi_offapi.mk index 9934fff83b8c..13a00192bd8c 100644 --- a/offapi/UnoApi_offapi.mk +++ b/offapi/UnoApi_offapi.mk @@ -2656,6 +2656,7 @@ $(eval $(call gb_UnoApi_add_idlfiles,offapi,com/sun/star/frame,\ XToolbarController \ XToolbarControllerListener \ XTransientDocumentsDocumentContentFactory \ + XTransientDocumentsDocumentContentIdentifierFactory \ XUIControllerFactory \ XUIControllerRegistration \ XUntitledNumbers \ diff --git a/offapi/com/sun/star/frame/XTransientDocumentsDocumentContentIdentifierFactory.idl b/offapi/com/sun/star/frame/XTransientDocumentsDocumentContentIdentifierFactory.idl new file mode 100644 index 000000000000..26359db3eec5 --- /dev/null +++ b/offapi/com/sun/star/frame/XTransientDocumentsDocumentContentIdentifierFactory.idl @@ -0,0 +1,59 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + */ +#ifndef __com_sun_star_frame_XTransientDocumentsDocumentContentIdentifierFactory_idl__ +#define __com_sun_star_frame_XTransientDocumentsDocumentContentIdentifierFactory_idl__ + +#include <com/sun/star/uno/XInterface.idl> +#include <com/sun/star/ucb/XContentIdentifier.idl> +#include <com/sun/star/frame/XModel.idl> +#include <com/sun/star/lang/IllegalArgumentException.idl> + + +module com { module sun { module star { module frame { + +/** a factory for identifiers of + com::sun::star::ucb::TransientDocumentsDocumentContents. + + @see com::sun::star::document::OfficeDocument + @see com::sun::star::ucb::XContentIdentifier + + @since LibreOffice 6.3 +*/ +interface XTransientDocumentsDocumentContentIdentifierFactory + : com::sun::star::uno::XInterface +{ + /** creates a com::sun::star::ucb::XContentIdentifier + based on a given com::sun::star::document::OfficeDocument. + + @param Model + the document model for which a + com::sun::star::ucb::XContentIdentifier + is requested. The model must be an implementation of service + com::sun::star::document::OfficeDocument. + + @returns + a content identifier based on the given document model. + + @throws com::sun::star::lang::IllegalArgumentException + if the document model cannot be associated with content for any reason. + */ + com::sun::star::ucb::XContentIdentifier + createDocumentContentIdentifier( + [in] com::sun::star::frame::XModel Model ) + raises ( com::sun::star::lang::IllegalArgumentException ); + +}; + + +}; }; }; }; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/filter/xml/xmlwrap.cxx b/sc/source/filter/xml/xmlwrap.cxx index a81f7fb6475e..3120a999e811 100644 --- a/sc/source/filter/xml/xmlwrap.cxx +++ b/sc/source/filter/xml/xmlwrap.cxx @@ -37,6 +37,7 @@ #include <sfx2/sfxsids.hrc> #include <com/sun/star/container/XChild.hpp> #include <com/sun/star/beans/XPropertySetInfo.hpp> +#include <com/sun/star/frame/XTransientDocumentsDocumentContentFactory.hpp> #include <com/sun/star/xml/sax/InputSource.hpp> #include <com/sun/star/xml/sax/Parser.hpp> #include <com/sun/star/xml/sax/XFastParser.hpp> @@ -76,6 +77,7 @@ #include <unonames.hxx> using namespace com::sun::star; +using namespace css::uno; ScXMLImportWrapper::ScXMLImportWrapper( ScDocShell& rDocSh, SfxMedium* pM, const uno::Reference < embed::XStorage >& xStor ) : mrDocShell(rDocSh), @@ -395,7 +397,7 @@ bool ScXMLImportWrapper::Import( ImportFlags nMode, ErrCode& rError ) const uno::Reference< rdf::XDocumentMetadataAccess > xDMA( xModel, uno::UNO_QUERY_THROW ); const uno::Reference< rdf::XURI > xBaseURI( - ::sfx2::createBaseURI( xContext, xStorage, aBaseURL, aName ) ); + ::sfx2::createBaseURI( xContext, xModel, aBaseURL, aName ) ); uno::Reference<task::XInteractionHandler> xHandler = mrDocShell.GetMedium()->GetInteractionHandler(); xDMA->loadMetadataFromStorage( xStorage, xBaseURI, xHandler ); diff --git a/sfx2/source/doc/DocumentMetadataAccess.cxx b/sfx2/source/doc/DocumentMetadataAccess.cxx index 8d5c1a6bc1ad..be9a472014d0 100644 --- a/sfx2/source/doc/DocumentMetadataAccess.cxx +++ b/sfx2/source/doc/DocumentMetadataAccess.cxx @@ -25,6 +25,7 @@ #include <com/sun/star/embed/ElementModes.hpp> #include <com/sun/star/embed/XStorage.hpp> #include <com/sun/star/embed/XTransactedObject.hpp> +#include <com/sun/star/frame/XTransientDocumentsDocumentContentIdentifierFactory.hpp> #include <com/sun/star/task/ErrorCodeIOException.hpp> #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp> #include <com/sun/star/rdf/FileFormat.hpp> @@ -116,16 +117,44 @@ static bool isReservedFile(OUString const & i_rPath) uno::Reference<rdf::XURI> createBaseURI( uno::Reference<uno::XComponentContext> const & i_xContext, - uno::Reference<embed::XStorage> const & i_xStorage, + uno::Reference<frame::XModel> const & i_xModel, OUString const & i_rPkgURI, OUString const & i_rSubDocument) { - if (!i_xContext.is() || !i_xStorage.is() || i_rPkgURI.isEmpty()) { + if (!i_xContext.is() || (!i_xModel.is() && i_rPkgURI.isEmpty())) { throw uno::RuntimeException(); } + OUString pkgURI(i_rPkgURI); + + // tdf#123293 chicken/egg problem when loading from stream: there is no URI, + // and also the model doesn't have a storage yet, so we need to get the + // tdoc URI without a storage... + if (pkgURI.isEmpty()) + { + assert(i_xModel.is()); + uno::Reference<frame::XTransientDocumentsDocumentContentIdentifierFactory> + const xTDDCIF( + i_xContext->getServiceManager()->createInstanceWithContext( + "com.sun.star.ucb.TransientDocumentsContentProvider", + i_xContext), + uno::UNO_QUERY_THROW); + uno::Reference<ucb::XContentIdentifier> const xContentId( + xTDDCIF->createDocumentContentIdentifier(i_xModel)); + SAL_WARN_IF(!xContentId.is(), "sfx", "createBaseURI: cannot create ContentIdentifier"); + if (!xContentId.is()) + { + throw uno::RuntimeException("createBaseURI: cannot create ContentIdentifier"); + } + pkgURI = xContentId->getContentIdentifier(); + assert(!pkgURI.isEmpty()); + if (!pkgURI.isEmpty() && !pkgURI.endsWith("/")) + { + pkgURI = pkgURI + "/"; + } + } + // #i108078# workaround non-hierarchical vnd.sun.star.expand URIs // this really should be done somewhere else, not here. - OUString pkgURI(i_rPkgURI); if (pkgURI.matchIgnoreAsciiCase("vnd.sun.star.expand:")) { // expand it here (makeAbsolute requires hierarchical URI) @@ -1252,11 +1281,11 @@ DocumentMetadataAccess::loadMetadataFromMedium( } uno::Reference<rdf::XURI> xBaseURI; try { - xBaseURI = createBaseURI(m_pImpl->m_xContext, xStorage, BaseURL); + xBaseURI = createBaseURI(m_pImpl->m_xContext, nullptr, BaseURL); } catch (const uno::Exception &) { // fall back to URL try { - xBaseURI = createBaseURI(m_pImpl->m_xContext, xStorage, URL); + xBaseURI = createBaseURI(m_pImpl->m_xContext, nullptr, URL); } catch (const uno::Exception &) { OSL_FAIL("cannot create base URI"); } diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx index e59de82a5223..70a3e9b44977 100644 --- a/sw/source/filter/ww8/ww8par.cxx +++ b/sw/source/filter/ww8/ww8par.cxx @@ -4915,10 +4915,11 @@ ErrCode SwWW8ImplReader::CoreLoad(WW8Glossary const *pGloss) // Initialize RDF metadata, to be able to add statements during the import. try { - uno::Reference<rdf::XDocumentMetadataAccess> xDocumentMetadataAccess(m_rDoc.GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW); + uno::Reference<frame::XModel> const xModel(m_rDoc.GetDocShell()->GetBaseModel()); + uno::Reference<rdf::XDocumentMetadataAccess> xDocumentMetadataAccess(xModel, uno::UNO_QUERY_THROW); uno::Reference<uno::XComponentContext> xComponentContext(comphelper::getProcessComponentContext()); uno::Reference<embed::XStorage> xStorage = comphelper::OStorageHelper::GetTemporaryStorage(); - const uno::Reference<rdf::XURI> xBaseURI(sfx2::createBaseURI(xComponentContext, xStorage, m_sBaseURL)); + const uno::Reference<rdf::XURI> xBaseURI(sfx2::createBaseURI(xComponentContext, xModel, m_sBaseURL)); uno::Reference<task::XInteractionHandler> xHandler; xDocumentMetadataAccess->loadMetadataFromStorage(xStorage, xBaseURI, xHandler); } diff --git a/sw/source/filter/xml/swxml.cxx b/sw/source/filter/xml/swxml.cxx index 138dc19981c8..61eca98bf971 100644 --- a/sw/source/filter/xml/swxml.cxx +++ b/sw/source/filter/xml/swxml.cxx @@ -795,8 +795,10 @@ ErrCode XMLReader::Read( SwDoc &rDoc, const OUString& rBaseURL, SwPaM &rPaM, con { const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(xModelComp, uno::UNO_QUERY_THROW); + const uno::Reference<frame::XModel> xModel(xModelComp, + uno::UNO_QUERY_THROW); const uno::Reference<rdf::XURI> xBaseURI( ::sfx2::createBaseURI( - xContext, xStorage, rBaseURL, StreamPath) ); + xContext, xModel, rBaseURL, StreamPath) ); const uno::Reference<task::XInteractionHandler> xHandler( pDocSh->GetMedium()->GetInteractionHandler() ); xDMA->loadMetadataFromStorage(xStorage, xBaseURI, xHandler); diff --git a/ucb/source/ucp/tdoc/tdoc_provider.cxx b/ucb/source/ucp/tdoc/tdoc_provider.cxx index fef2f3145f5e..fdcfd241502c 100644 --- a/ucb/source/ucp/tdoc/tdoc_provider.cxx +++ b/ucb/source/ucp/tdoc/tdoc_provider.cxx @@ -88,6 +88,7 @@ css::uno::Any SAL_CALL ContentProvider::queryInterface( const css::uno::Type & r static_cast< lang::XTypeProvider* >(this), static_cast< lang::XServiceInfo* >(this), static_cast< ucb::XContentProvider* >(this), + static_cast< frame::XTransientDocumentsDocumentContentIdentifierFactory* >(this), static_cast< frame::XTransientDocumentsDocumentContentFactory* >(this) ); return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); @@ -96,10 +97,11 @@ css::uno::Any SAL_CALL ContentProvider::queryInterface( const css::uno::Type & r // XTypeProvider methods. -XTYPEPROVIDER_IMPL_4( ContentProvider, +XTYPEPROVIDER_IMPL_5( ContentProvider, lang::XTypeProvider, lang::XServiceInfo, ucb::XContentProvider, + frame::XTransientDocumentsDocumentContentIdentifierFactory, frame::XTransientDocumentsDocumentContentFactory ); @@ -164,13 +166,11 @@ ContentProvider::queryContent( } -// XTransientDocumentsDocumentContentFactory methods. - +// XTransientDocumentsDocumentContentIdentifierFactory methods. -// virtual -uno::Reference< ucb::XContent > SAL_CALL -ContentProvider::createDocumentContent( - const uno::Reference< frame::XModel >& Model ) +uno::Reference<ucb::XContentIdentifier> SAL_CALL +ContentProvider::createDocumentContentIdentifier( + uno::Reference<frame::XModel> const& xModel) { // model -> id -> content identifier -> queryContent if ( !m_xDocsMgr.is() ) @@ -181,7 +181,7 @@ ContentProvider::createDocumentContent( 1 ); } - OUString aDocId = tdoc_ucp::OfficeDocumentsManager::queryDocumentId( Model ); + OUString aDocId = tdoc_ucp::OfficeDocumentsManager::queryDocumentId(xModel); if ( aDocId.isEmpty() ) { throw lang::IllegalArgumentException( @@ -196,6 +196,17 @@ ContentProvider::createDocumentContent( uno::Reference< ucb::XContentIdentifier > xId = new ::ucbhelper::ContentIdentifier( aBuffer.makeStringAndClear() ); + return xId; +} + +// XTransientDocumentsDocumentContentFactory methods. + +uno::Reference< ucb::XContent > SAL_CALL +ContentProvider::createDocumentContent( + uno::Reference<frame::XModel> const& xModel) +{ + uno::Reference<ucb::XContentIdentifier> const xId( + createDocumentContentIdentifier(xModel)); osl::MutexGuard aGuard( m_aMutex ); diff --git a/ucb/source/ucp/tdoc/tdoc_provider.hxx b/ucb/source/ucp/tdoc/tdoc_provider.hxx index 2f308bf3ff5c..f1dc515b1b84 100644 --- a/ucb/source/ucp/tdoc/tdoc_provider.hxx +++ b/ucb/source/ucp/tdoc/tdoc_provider.hxx @@ -22,6 +22,7 @@ #include <rtl/ref.hxx> #include <com/sun/star/frame/XTransientDocumentsDocumentContentFactory.hpp> +#include <com/sun/star/frame/XTransientDocumentsDocumentContentIdentifierFactory.hpp> #include <com/sun/star/packages/WrongPasswordException.hpp> #include <com/sun/star/lang/XSingleServiceFactory.hpp> #include <com/sun/star/lang/XMultiServiceFactory.hpp> @@ -53,9 +54,10 @@ namespace tdoc_ucp { class StorageElementFactory; -class ContentProvider : - public ::ucbhelper::ContentProviderImplHelper, - public css::frame::XTransientDocumentsDocumentContentFactory +class ContentProvider + : public ::ucbhelper::ContentProviderImplHelper + , public css::frame::XTransientDocumentsDocumentContentIdentifierFactory + , public css::frame::XTransientDocumentsDocumentContentFactory { public: explicit ContentProvider( const css::uno::Reference< css::uno::XComponentContext >& rxContext ); @@ -88,6 +90,11 @@ public: virtual css::uno::Reference< css::ucb::XContent > SAL_CALL queryContent( const css::uno::Reference< css::ucb::XContentIdentifier >& Identifier ) override; + // XTransientDocumentsDocumentContentIdentifierFactory + virtual css::uno::Reference<css::ucb::XContentIdentifier> SAL_CALL + createDocumentContentIdentifier( + css::uno::Reference<css::frame::XModel> const& xModel) override; + // XTransientDocumentsDocumentContentFactory virtual css::uno::Reference< css::ucb::XContent > SAL_CALL createDocumentContent( const css::uno::Reference< diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx index a44771dbd8ab..9d2cbd7bfe81 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -128,7 +128,9 @@ DomainMapper::DomainMapper( const uno::Reference< uno::XComponentContext >& xCon uno::Reference<rdf::XDocumentMetadataAccess> xDocumentMetadataAccess(xModel, uno::UNO_QUERY_THROW); uno::Reference<embed::XStorage> xStorage = comphelper::OStorageHelper::GetTemporaryStorage(); OUString aBaseURL = rMediaDesc.getUnpackedValueOrDefault("URL", OUString()); - const uno::Reference<rdf::XURI> xBaseURI(sfx2::createBaseURI(xContext, xStorage, aBaseURL, OUString())); + const uno::Reference<frame::XModel> xModel_(xModel, + uno::UNO_QUERY_THROW); + const uno::Reference<rdf::XURI> xBaseURI(sfx2::createBaseURI(xContext, xModel_, aBaseURL, OUString())); const uno::Reference<task::XInteractionHandler> xHandler; xDocumentMetadataAccess->loadMetadataFromStorage(xStorage, xBaseURI, xHandler); } |