[Libreoffice-commits] core.git: Branch 'distro/lhm/libreoffice-6-1+backports' - include/sfx2 offapi/com offapi/UnoApi_offapi.mk sc/source sfx2/source sw/source ucb/source writerfilter/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Wed Mar 13 15:58:19 UTC 2019


 include/sfx2/DocumentMetadataAccess.hxx                                           |    9 +
 offapi/UnoApi_offapi.mk                                                           |    1 
 offapi/com/sun/star/frame/XTransientDocumentsDocumentContentIdentifierFactory.idl |   59 ++++++++++
 sc/source/filter/xml/xmlwrap.cxx                                                  |    4 
 sfx2/source/doc/DocumentMetadataAccess.cxx                                        |   39 +++++-
 sw/source/filter/ww8/ww8par.cxx                                                   |    5 
 sw/source/filter/xml/swxml.cxx                                                    |    4 
 ucb/source/ucp/tdoc/tdoc_provider.cxx                                             |   27 +++-
 ucb/source/ucp/tdoc/tdoc_provider.hxx                                             |   13 +-
 writerfilter/source/dmapper/DomainMapper.cxx                                      |    4 
 10 files changed, 141 insertions(+), 24 deletions(-)

New commits:
commit fa268c3ca8a746b9a10e64f592eae866e4b81ba3
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Fri Feb 15 17:50:38 2019 +0100
Commit:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Wed Mar 13 16:57:57 2019 +0100

    tdf#123293 sfx2: fix metadata loss when loading from stream
    
    The problem is that when loading from a stream, there is no BaseURL and
    also no storage for the document.
    
    Due to the lack of BaseURL, the sfx2::createBaseURI() throws and loading
    RDF metadata fails, which also pops up an annoying warning dialog.
    
    Try to handle this in a similar way than a newly created document (see
    GetDMA()), by using the vnd.sun.star.tdoc scheme URL for the document;
    this however currently requires that the document has a XStorage, which
    is also not the case here.
    
    So add another UNO method to tdoc UCP's tdoc_ucp::ContentProvider,
    to split out the creation of the tdoc schema URL from the creation of
    the ucb Content, to get rid of the XStorage requirement.
    
    Change-Id: Ica62743f9d21db0b1464b70db1a62ebc61989ef8
    Reviewed-on: https://gerrit.libreoffice.org/67882
    Tested-by: Jenkins
    Reviewed-by: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
    (cherry picked from commit 0a5ca5768f56db481dd3b947b3dddaab7ed96450)
    Reviewed-on: https://gerrit.libreoffice.org/69174
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    Tested-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>

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 93a76c5908a2..f95f390777d2 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 2217a4a07838..ce5d7f360b55 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>
@@ -74,6 +75,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),
@@ -393,7 +395,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 ff6ad06ea6a7..9e8c2a2bf601 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>
@@ -114,16 +115,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)
@@ -1234,11 +1263,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 f03b8eff30f3..bf30029f5884 100644
--- a/sw/source/filter/ww8/ww8par.cxx
+++ b/sw/source/filter/ww8/ww8par.cxx
@@ -4926,10 +4926,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 4fcfae82fdfe..0bf39a274f63 100644
--- a/sw/source/filter/xml/swxml.cxx
+++ b/sw/source/filter/xml/swxml.cxx
@@ -793,8 +793,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 58f2652a4dc0..08590131231a 100644
--- a/ucb/source/ucp/tdoc/tdoc_provider.cxx
+++ b/ucb/source/ucp/tdoc/tdoc_provider.cxx
@@ -85,6 +85,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 );
@@ -93,10 +94,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 );
 
 
@@ -161,13 +163,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() )
@@ -178,7 +178,7 @@ ContentProvider::createDocumentContent(
             1 );
      }
 
-    OUString aDocId = tdoc_ucp::OfficeDocumentsManager::queryDocumentId( Model );
+    OUString aDocId = tdoc_ucp::OfficeDocumentsManager::queryDocumentId(xModel);
     if ( aDocId.isEmpty() )
     {
         throw lang::IllegalArgumentException(
@@ -193,6 +193,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 3501bd4d8ec9..f8c2fb701e83 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 <ucbhelper/providerhelper.hxx>
 #include "tdoc_uri.hxx"
@@ -51,9 +52,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 );
@@ -86,6 +88,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 459d67954793..01cace05488b 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -126,7 +126,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);
     }


More information about the Libreoffice-commits mailing list