[Libreoffice-commits] core.git: 2 commits - include/oox oox/source writerfilter/source
Ashod Nakashian
ashod.nakashian at collabora.co.uk
Wed Feb 14 00:03:44 UTC 2018
include/oox/core/xmlfilterbase.hxx | 5
oox/source/core/xmlfilterbase.cxx | 202 ++++++++++++++++++++++++++++
writerfilter/source/filter/WriterFilter.cxx | 36 ----
3 files changed, 209 insertions(+), 34 deletions(-)
New commits:
commit 335a2b80fa900848a8b60d8fd5db6656bc30a95a
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date: Tue Feb 6 17:49:23 2018 -0500
oox: preserve custom oox fragments and packages
Change-Id: Ic4c75d136601a9b7d772aab577c9fbebc7391eaf
Reviewed-on: https://gerrit.libreoffice.org/49236
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
diff --git a/include/oox/core/xmlfilterbase.hxx b/include/oox/core/xmlfilterbase.hxx
index 7621a0081a53..51e6e496ea6a 100644
--- a/include/oox/core/xmlfilterbase.hxx
+++ b/include/oox/core/xmlfilterbase.hxx
@@ -259,6 +259,9 @@ private:
virtual StorageRef implCreateStorage(
const css::uno::Reference< css::io::XStream >& rxOutStream ) const override;
+ void importCustomFragments(css::uno::Reference<css::embed::XStorage>& xDocumentStorage);
+ void exportCustomFragments();
+
private:
::std::unique_ptr< XmlFilterBaseImpl > mxImpl;
sal_Int32 mnRelId;
diff --git a/oox/source/core/xmlfilterbase.cxx b/oox/source/core/xmlfilterbase.cxx
index 15f253c734c7..d97aeab59a89 100644
--- a/oox/source/core/xmlfilterbase.cxx
+++ b/oox/source/core/xmlfilterbase.cxx
@@ -29,6 +29,9 @@
#include <com/sun/star/xml/sax/InputSource.hpp>
#include <com/sun/star/xml/sax/XFastParser.hpp>
#include <com/sun/star/xml/sax/XFastSAXSerializable.hpp>
+#include <com/sun/star/xml/dom/XDocument.hpp>
+#include <com/sun/star/xml/sax/XSAXSerializable.hpp>
+#include <com/sun/star/xml/sax/Writer.hpp>
#include <com/sun/star/document/XDocumentProperties.hpp>
#include <o3tl/any.hxx>
#include <unotools/mediadescriptor.hxx>
@@ -48,6 +51,7 @@
#include <oox/helper/zipstorage.hxx>
#include <oox/ole/olestorage.hxx>
#include <oox/token/namespaces.hxx>
+#include <oox/token/relationship.hxx>
#include <oox/token/properties.hxx>
#include <oox/token/tokens.hxx>
#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
@@ -57,6 +61,7 @@
#include <comphelper/processfactory.hxx>
#include <oox/core/filterdetect.hxx>
#include <comphelper/storagehelper.hxx>
+#include <comphelper/sequence.hxx>
#include <oox/crypto/DocumentEncryption.hxx>
#include <tools/date.hxx>
@@ -64,6 +69,7 @@
#include <com/sun/star/util/Duration.hpp>
#include <sax/tools/converter.hxx>
#include <oox/token/namespacemap.hxx>
+#include <editeng/unoprnms.hxx>
using ::com::sun::star::xml::dom::DocumentBuilder;
using ::com::sun::star::xml::dom::XDocument;
@@ -282,6 +288,8 @@ void XmlFilterBase::importDocumentProperties()
Reference< XDocumentProperties > xDocProps = xPropSupplier->getDocumentProperties();
xImporter->importProperties( xDocumentStorage, xDocProps );
checkDocumentProperties(xDocProps);
+
+ importCustomFragments(xDocumentStorage);
}
FastParser* XmlFilterBase::createParser()
@@ -833,6 +841,8 @@ void XmlFilterBase::exportDocumentProperties( const Reference< XDocumentProperti
writeAppProperties( *this, xProperties );
writeCustomProperties( *this, xProperties );
}
+
+ exportCustomFragments();
}
// protected ------------------------------------------------------------------
@@ -946,6 +956,168 @@ OUString XmlFilterBase::getNamespaceURL(sal_Int32 nNSID) const
return itr->second;
}
+void XmlFilterBase::importCustomFragments(css::uno::Reference<css::embed::XStorage>& xDocumentStorage)
+{
+ Reference<XRelationshipAccess> xRelations(xDocumentStorage, UNO_QUERY);
+ if (xRelations.is())
+ {
+ // These are all the custom types we recognize and can preserve.
+ static const std::set<OUString> sCustomTypes = {
+ "http://schemas.dell.com/ddp/2016/relationships/xenFile",
+ "http://schemas.dell.com/ddp/2016/relationships/hmacFile",
+ "http://schemas.dell.com/ddp/2016/relationships/metadataFile"
+ };
+
+ uno::Sequence<uno::Sequence<beans::StringPair>> aSeqs = xRelations->getAllRelationships();
+
+ std::vector<StreamDataSequence> aCustomFragments;
+ std::vector<OUString> aCustomFragmentTypes;
+ std::vector<OUString> aCustomFragmentTargets;
+ for (sal_Int32 j = 0; j < aSeqs.getLength(); j++)
+ {
+ OUString sType;
+ OUString sTarget;
+ const uno::Sequence<beans::StringPair>& aSeq = aSeqs[j];
+ for (sal_Int32 i = 0; i < aSeq.getLength(); i++)
+ {
+ const beans::StringPair& aPair = aSeq[i];
+ if (aPair.First == "Target")
+ sTarget = aPair.Second;
+ else if (aPair.First == "Type")
+ sType = aPair.Second;
+ }
+
+ if (sCustomTypes.find(sType) != sCustomTypes.end())
+ {
+ StreamDataSequence aDataSeq;
+ if (importBinaryData(aDataSeq, sTarget))
+ {
+ aCustomFragments.emplace_back(aDataSeq);
+ aCustomFragmentTypes.emplace_back(sType);
+ aCustomFragmentTargets.emplace_back(sTarget);
+ }
+ }
+ }
+
+ // Adding the saved custom xml DOM
+ comphelper::SequenceAsHashMap aGrabBagProperties;
+ aGrabBagProperties["OOXCustomFragments"] <<= comphelper::containerToSequence(aCustomFragments);
+ aGrabBagProperties["OOXCustomFragmentTypes"] <<= comphelper::containerToSequence(aCustomFragmentTypes);
+ aGrabBagProperties["OOXCustomFragmentTargets"] <<= comphelper::containerToSequence(aCustomFragmentTargets);
+
+ std::vector<uno::Reference<xml::dom::XDocument>> aCustomXmlDomList;
+ std::vector<uno::Reference<xml::dom::XDocument>> aCustomXmlDomPropsList;
+ //FIXME: Ideally, we should get these the relations, but it seems that is not consistently set.
+ // In some cases it's stored in the workbook relationships, which is unexpected. So we discover them directly.
+ for (int i = 1; i < 100; ++i)
+ {
+ Reference<XDocument> xCustDoc = importFragment("customXml/item" + OUString::number(i) + ".xml");
+ Reference<XDocument> xCustDocProps = importFragment("customXml/itemProps" + OUString::number(i) + ".xml");
+ if (xCustDoc && xCustDocProps)
+ {
+ aCustomXmlDomList.emplace_back(xCustDoc);
+ aCustomXmlDomPropsList.emplace_back(xCustDocProps);
+ }
+ else
+ break;
+ }
+
+ // Adding the saved custom xml DOM
+ aGrabBagProperties["OOXCustomXml"] <<= comphelper::containerToSequence(aCustomXmlDomList);
+ aGrabBagProperties["OOXCustomXmlProps"] <<= comphelper::containerToSequence(aCustomXmlDomPropsList);
+
+ Reference<XComponent> xModel(getModel(), UNO_QUERY);
+ oox::core::XmlFilterBase::putPropertiesToDocumentGrabBag(xModel, aGrabBagProperties);
+ }
+}
+
+void XmlFilterBase::exportCustomFragments()
+{
+ Reference<XComponent> xModel(getModel(), UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xPropSet(xModel, uno::UNO_QUERY_THROW);
+
+ uno::Reference<beans::XPropertySetInfo> xPropSetInfo = xPropSet->getPropertySetInfo();
+ static const OUString aName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
+ if (!xPropSetInfo->hasPropertyByName(aName))
+ return;
+
+ uno::Sequence<uno::Reference<xml::dom::XDocument>> customXmlDomlist;
+ uno::Sequence<uno::Reference<xml::dom::XDocument>> customXmlDomPropslist;
+ uno::Sequence<StreamDataSequence> customFragments;
+ uno::Sequence<OUString> customFragmentTypes;
+ uno::Sequence<OUString> customFragmentTargets;
+
+ uno::Sequence<beans::PropertyValue> propList;
+ xPropSet->getPropertyValue(aName) >>= propList;
+ for (sal_Int32 nProp = 0; nProp < propList.getLength(); ++nProp)
+ {
+ const OUString propName = propList[nProp].Name;
+ if (propName == "OOXCustomXml")
+ {
+ propList[nProp].Value >>= customXmlDomlist;
+ }
+ else if (propName == "OOXCustomXmlProps")
+ {
+ propList[nProp].Value >>= customXmlDomPropslist;
+ }
+ else if (propName == "OOXCustomFragments")
+ {
+ propList[nProp].Value >>= customFragments;
+ }
+ else if (propName == "OOXCustomFragmentTypes")
+ {
+ propList[nProp].Value >>= customFragmentTypes;
+ }
+ else if (propName == "OOXCustomFragmentTargets")
+ {
+ propList[nProp].Value >>= customFragmentTargets;
+ }
+ }
+
+ // Expect customXmlDomPropslist.getLength() == customXmlDomlist.getLength().
+ for (sal_Int32 j = 0; j < customXmlDomlist.getLength(); j++)
+ {
+ uno::Reference<xml::dom::XDocument> customXmlDom = customXmlDomlist[j];
+ uno::Reference<xml::dom::XDocument> customXmlDomProps = customXmlDomPropslist[j];
+ const OUString fragmentPath = "customXml/item" + OUString::number((j+1)) + ".xml";
+ if (customXmlDom.is())
+ {
+ addRelation(oox::getRelationship(Relationship::CUSTOMXML), "../" + fragmentPath);
+
+ uno::Reference<xml::sax::XSAXSerializable> serializer(customXmlDom, uno::UNO_QUERY);
+ uno::Reference<xml::sax::XWriter> writer = xml::sax::Writer::create(comphelper::getProcessComponentContext());
+ writer->setOutputStream(openFragmentStream(fragmentPath, "application/xml"));
+ serializer->serialize(uno::Reference<xml::sax::XDocumentHandler>(writer, uno::UNO_QUERY_THROW),
+ uno::Sequence<beans::StringPair>());
+ }
+
+ if (customXmlDomProps.is())
+ {
+ uno::Reference<xml::sax::XSAXSerializable> serializer(customXmlDomProps, uno::UNO_QUERY);
+ uno::Reference<xml::sax::XWriter> writer = xml::sax::Writer::create(comphelper::getProcessComponentContext());
+ writer->setOutputStream(openFragmentStream("customXml/itemProps"+OUString::number((j+1))+".xml",
+ "application/vnd.openxmlformats-officedocument.customXmlProperties+xml"));
+ serializer->serialize(uno::Reference<xml::sax::XDocumentHandler>(writer, uno::UNO_QUERY_THROW),
+ uno::Sequence<beans::StringPair>());
+
+ // Adding itemprops's relationship entry to item.xml.rels file
+ addRelation(openFragmentStream(fragmentPath, "application/xml"),
+ oox::getRelationship(Relationship::CUSTOMXMLPROPS),
+ "itemProps"+OUString::number((j+1))+".xml");
+ }
+ }
+
+ // Expect customFragments.getLength() == customFragmentTypes.getLength() == customFragmentTargets.getLength().
+ for (sal_Int32 j = 0; j < customFragments.getLength(); j++)
+ {
+ addRelation(customFragmentTypes[j], customFragmentTargets[j]);
+ Reference<XOutputStream> xOutStream = openOutputStream(customFragmentTargets[j]);
+ xOutStream->writeBytes(customFragments[j]);
+ // BinaryXInputStream aInStrm(openOutputStream(customFragmentTargets[j]), true);
+ // aInStrm.copyToStream(xOutputStream);
+ }
+}
+
} // namespace core
} // namespace oox
commit e26a95360e60e0c17e70e72f36fb988bb664ddb5
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date: Tue Feb 6 17:46:28 2018 -0500
oox: move putPropertiesToDocumentGrabBag to XmlFilterBase
Change-Id: Ic3cbabc420c7856682b889528043563622997c14
Reviewed-on: https://gerrit.libreoffice.org/49235
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
diff --git a/include/oox/core/xmlfilterbase.hxx b/include/oox/core/xmlfilterbase.hxx
index 26948588e1dd..7621a0081a53 100644
--- a/include/oox/core/xmlfilterbase.hxx
+++ b/include/oox/core/xmlfilterbase.hxx
@@ -228,6 +228,8 @@ public:
void exportDocumentProperties( const css::uno::Reference< css::document::XDocumentProperties >& xProperties );
void importDocumentProperties();
+ static void putPropertiesToDocumentGrabBag(const css::uno::Reference<css::lang::XComponent>& xDstDoc,
+ const comphelper::SequenceAsHashMap& rProperties);
static FastParser* createParser();
diff --git a/oox/source/core/xmlfilterbase.cxx b/oox/source/core/xmlfilterbase.cxx
index 7f20d13b8200..15f253c734c7 100644
--- a/oox/source/core/xmlfilterbase.cxx
+++ b/oox/source/core/xmlfilterbase.cxx
@@ -234,6 +234,36 @@ void XmlFilterBase::checkDocumentProperties(const Reference<XDocumentProperties>
mbMSO2007 = true;
}
+void XmlFilterBase::putPropertiesToDocumentGrabBag(const css::uno::Reference<css::lang::XComponent>& xDstDoc,
+ const comphelper::SequenceAsHashMap& rProperties)
+{
+ try
+ {
+ uno::Reference<beans::XPropertySet> xDocProps(xDstDoc, uno::UNO_QUERY);
+ if (xDocProps.is())
+ {
+ uno::Reference<beans::XPropertySetInfo> xPropsInfo = xDocProps->getPropertySetInfo();
+
+ static const OUString aGrabBagPropName = "InteropGrabBag";
+ if (xPropsInfo.is() && xPropsInfo->hasPropertyByName(aGrabBagPropName))
+ {
+ // get existing grab bag
+ comphelper::SequenceAsHashMap aGrabBag(xDocProps->getPropertyValue(aGrabBagPropName));
+
+ // put the new items
+ aGrabBag.update(rProperties);
+
+ // put it back to the document
+ xDocProps->setPropertyValue(aGrabBagPropName, uno::Any(aGrabBag.getAsConstPropertyValueList()));
+ }
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ SAL_WARN("oox","Failed to save documents grab bag");
+ }
+}
+
void XmlFilterBase::importDocumentProperties()
{
MediaDescriptor aMediaDesc( getMediaDescriptor() );
diff --git a/writerfilter/source/filter/WriterFilter.cxx b/writerfilter/source/filter/WriterFilter.cxx
index af348d9eb33b..2953c6cc3f17 100644
--- a/writerfilter/source/filter/WriterFilter.cxx
+++ b/writerfilter/source/filter/WriterFilter.cxx
@@ -35,6 +35,7 @@
#include <cppuhelper/supportsservice.hxx>
#include <dmapper/DomainMapperFactory.hxx>
#include <oox/core/filterdetect.hxx>
+#include <oox/core/xmlfilterbase.hxx>
#include <oox/helper/graphichelper.hxx>
#include <oox/ole/olestorage.hxx>
#include <oox/ole/vbaproject.hxx>
@@ -115,10 +116,6 @@ public:
OUString SAL_CALL getImplementationName() override;
sal_Bool SAL_CALL supportsService(const OUString& rServiceName) override;
uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
-
-private:
- void putPropertiesToDocumentGrabBag(const comphelper::SequenceAsHashMap& rProperties);
-
};
sal_Bool WriterFilter::filter(const uno::Sequence< beans::PropertyValue >& rDescriptor)
@@ -231,7 +228,7 @@ sal_Bool WriterFilter::filter(const uno::Sequence< beans::PropertyValue >& rDesc
// Adding the saved embedding document to document's grab bag
aGrabBagProperties["OOXEmbeddings"] <<= pDocument->getEmbeddingsList();
- putPropertiesToDocumentGrabBag(aGrabBagProperties);
+ oox::core::XmlFilterBase::putPropertiesToDocumentGrabBag(m_xDstDoc, aGrabBagProperties);
writerfilter::ooxml::OOXMLStream::Pointer_t pVBAProjectStream(writerfilter::ooxml::OOXMLDocumentFactory::createStream(pDocStream, writerfilter::ooxml::OOXMLStream::VBAPROJECT));
oox::StorageRef xVbaPrjStrg(new ::oox::ole::OleStorage(m_xContext, pVBAProjectStream->getDocumentStream(), false));
@@ -336,35 +333,6 @@ uno::Sequence<OUString> WriterFilter::getSupportedServiceNames()
return aRet;
}
-void WriterFilter::putPropertiesToDocumentGrabBag(const comphelper::SequenceAsHashMap& rProperties)
-{
- try
- {
- uno::Reference<beans::XPropertySet> xDocProps(m_xDstDoc, uno::UNO_QUERY);
- if (xDocProps.is())
- {
- uno::Reference<beans::XPropertySetInfo> xPropsInfo = xDocProps->getPropertySetInfo();
-
- const OUString aGrabBagPropName = "InteropGrabBag";
- if (xPropsInfo.is() && xPropsInfo->hasPropertyByName(aGrabBagPropName))
- {
- // get existing grab bag
- comphelper::SequenceAsHashMap aGrabBag(xDocProps->getPropertyValue(aGrabBagPropName));
-
- // put the new items
- aGrabBag.update(rProperties);
-
- // put it back to the document
- xDocProps->setPropertyValue(aGrabBagPropName, uno::Any(aGrabBag.getAsConstPropertyValueList()));
- }
- }
- }
- catch (const uno::Exception&)
- {
- SAL_WARN("writerfilter","Failed to save documents grab bag");
- }
-}
-
extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface* com_sun_star_comp_Writer_WriterFilter_get_implementation(uno::XComponentContext* component, uno::Sequence<uno::Any> const& /*rSequence*/)
{
return cppu::acquire(new WriterFilter(component));
More information about the Libreoffice-commits
mailing list