diff options
author | sushil_shinde <sushil.shinde@synerzip.com> | 2013-11-07 10:45:03 +0530 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2013-11-13 10:27:28 +0100 |
commit | 52ee03760e26e2ac7eb2561e96ab557ad287de58 (patch) | |
tree | 6d2cfbb823dee012397eb9055c86e0462e64cd2e | |
parent | 97747499b26314bb308b12cd331bf0d99f21c96c (diff) |
[docx] CustomXml relationship files saved in InteropGrabBag and exported.
The XDocuments representing the DOM of an OOXML's customxml property
document is stored as the PropertyValue "OOXCustomXmlProps" into the
"InteropGraBag".
Added mxCustomXmlDomPropList object which holds xDocument for each
itemProps.xml from relationship of item.xml.
Exporting all itemprops files from customxml.
Reviewed on:
https://gerrit.libreoffice.org/6603
Change-Id: I3973e6ce40382bbc4da247b5b27d99b03e851744
-rw-r--r-- | sw/qa/extras/ooxmlexport/ooxmlexport.cxx | 9 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxexport.cxx | 35 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxexport.hxx | 2 | ||||
-rw-r--r-- | writerfilter/inc/ooxml/OOXMLDocument.hxx | 3 | ||||
-rw-r--r-- | writerfilter/source/filter/ImportFilter.cxx | 7 | ||||
-rw-r--r-- | writerfilter/source/ooxml/OOXMLDocumentImpl.cxx | 77 | ||||
-rw-r--r-- | writerfilter/source/ooxml/OOXMLDocumentImpl.hxx | 5 | ||||
-rw-r--r-- | writerfilter/source/ooxml/OOXMLStreamImpl.cxx | 4 |
8 files changed, 127 insertions, 15 deletions
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx index e3f60a94ca68..5c44dc818fd4 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx @@ -1534,7 +1534,8 @@ DECLARE_OOXML_TEST(testCharHighlight, "char_highlight.docx") DECLARE_OOXML_TEST(testCustomXmlGrabBag, "customxml.docx") { - // The problem was that CustomXml/item[n].xml files were missing from docx file after saving file. + // The problem was that item[n].xml and itemProps[n].xml and .rels files for item[n].xml + // files were missing from docx file after saving file. // This test case tests whether customxml files grabbagged properly in correct object. uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY); @@ -1545,15 +1546,15 @@ DECLARE_OOXML_TEST(testCustomXmlGrabBag, "customxml.docx") sal_Bool CustomXml = sal_False; for(int i = 0; i < aGrabBag.getLength(); ++i) { - if (aGrabBag[i].Name == OUString("OOXCustomXml")) + if (aGrabBag[i].Name == "OOXCustomXml" || aGrabBag[i].Name == "OOXCustomXmlProps") { CustomXml = sal_True; uno::Reference<xml::dom::XDocument> aCustomXmlDom; uno::Sequence<uno::Reference<xml::dom::XDocument> > aCustomXmlDomList; CPPUNIT_ASSERT(aGrabBag[i].Value >>= aCustomXmlDomList); // PropertyValue of proper type sal_Int32 length = aCustomXmlDomList.getLength(); - CPPUNIT_ASSERT_EQUAL(sal_Int32(3), length); - aCustomXmlDom = aCustomXmlDomList[1]; + CPPUNIT_ASSERT_EQUAL(sal_Int32(1), length); + aCustomXmlDom = aCustomXmlDomList[0]; CPPUNIT_ASSERT(aCustomXmlDom.get()); // Reference not empty } } diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx index fffa8e3c8916..126e3ef31e33 100644 --- a/sw/source/filter/ww8/docxexport.cxx +++ b/sw/source/filter/ww8/docxexport.cxx @@ -794,6 +794,7 @@ void DocxExport::WriteCustomXml() return; uno::Sequence<uno::Reference<xml::dom::XDocument> > customXmlDomlist; + uno::Sequence<uno::Reference<xml::dom::XDocument> > customXmlDomPropslist; uno::Sequence< beans::PropertyValue > propList; xPropSet->getPropertyValue( pName ) >>= propList; for ( sal_Int32 nProp=0; nProp < propList.getLength(); ++nProp ) @@ -806,23 +807,51 @@ void DocxExport::WriteCustomXml() } } - for (sal_Int32 j = 1; j < customXmlDomlist.getLength(); j++) + for ( sal_Int32 nProp=0; nProp < propList.getLength(); ++nProp ) { + OUString propName = propList[nProp].Name; + if ( propName == "OOXCustomXmlProps" ) + { + propList[nProp].Value >>= customXmlDomPropslist; + break; + } + } + + 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]; if ( customXmlDom.is() ) { m_pFilter->addRelation( m_pDocumentFS->getOutputStream(), "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml", - "../customXml/item"+OUString::number(j)+".xml" ); + "../customXml/item"+OUString::number((j+1))+".xml" ); uno::Reference< xml::sax::XSAXSerializable > serializer( customXmlDom, uno::UNO_QUERY ); uno::Reference< xml::sax::XWriter > writer = xml::sax::Writer::create( comphelper::getProcessComponentContext() ); - writer->setOutputStream( GetFilter().openFragmentStream( "customXml/item"+OUString::number(j)+".xml", + writer->setOutputStream( GetFilter().openFragmentStream( "customXml/item"+OUString::number((j+1))+".xml", "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( GetFilter().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 + m_pFilter->addRelation( GetFilter().openFragmentStream( "customXml/item"+OUString::number((j+1))+".xml", + "application/xml" ) , + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXmlProps", + "itemProps"+OUString::number((j+1))+".xml" ); + + } } } diff --git a/sw/source/filter/ww8/docxexport.hxx b/sw/source/filter/ww8/docxexport.hxx index 531dcc511e5c..8c2f958e36b5 100644 --- a/sw/source/filter/ww8/docxexport.hxx +++ b/sw/source/filter/ww8/docxexport.hxx @@ -207,7 +207,9 @@ private: /// Write word/theme/theme1.xml void WriteTheme(); + /// Write customXml/item[n].xml and customXml/itemProps[n].xml void WriteCustomXml(); + /// All xml namespaces to be used at the top of any text .xml file (main doc, headers, footers,...) sax_fastparser::XFastAttributeListRef MainXmlNamespaces( sax_fastparser::FSHelperPtr serializer ); diff --git a/writerfilter/inc/ooxml/OOXMLDocument.hxx b/writerfilter/inc/ooxml/OOXMLDocument.hxx index 2fb68a5eebab..91d9adce87fe 100644 --- a/writerfilter/inc/ooxml/OOXMLDocument.hxx +++ b/writerfilter/inc/ooxml/OOXMLDocument.hxx @@ -76,7 +76,7 @@ class WRITERFILTER_OOXML_DLLPUBLIC OOXMLStream { public: enum StreamType_t { UNKNOWN, DOCUMENT, STYLES, FONTTABLE, NUMBERING, - FOOTNOTES, ENDNOTES, COMMENTS, THEME, CUSTOMXML, SETTINGS, VBAPROJECT }; + FOOTNOTES, ENDNOTES, COMMENTS, THEME, CUSTOMXML, CUSTOMXMLPROPS, SETTINGS, VBAPROJECT }; typedef boost::shared_ptr<OOXMLStream> Pointer_t; virtual ~OOXMLStream() {} @@ -243,6 +243,7 @@ public: virtual uno::Reference<xml::dom::XDocument> getThemeDom( ) = 0; virtual void setThemeDom( uno::Reference<xml::dom::XDocument> xThemeDom ) = 0; virtual uno::Sequence<uno::Reference<xml::dom::XDocument> > getCustomXmlDomList( ) = 0; + virtual uno::Sequence<uno::Reference<xml::dom::XDocument> > getCustomXmlDomPropsList( ) = 0; }; diff --git a/writerfilter/source/filter/ImportFilter.cxx b/writerfilter/source/filter/ImportFilter.cxx index 36bbbc7274d9..e9a429cc515e 100644 --- a/writerfilter/source/filter/ImportFilter.cxx +++ b/writerfilter/source/filter/ImportFilter.cxx @@ -167,13 +167,18 @@ sal_Bool WriterFilter::filter( const uno::Sequence< beans::PropertyValue >& aDes // We want to keep the previous items xDocProps->getPropertyValue( aGrabBagPropName ) >>= aGrabBag; sal_Int32 length = aGrabBag.getLength(); - aGrabBag.realloc(length+1); + aGrabBag.realloc(length+2); beans::PropertyValue* pValue = aGrabBag.getArray(); pValue[length].Name = "OOXCustomXml"; pValue[length].Value = uno::makeAny( pDocument->getCustomXmlDomList() ); + pValue[length+1].Name = "OOXCustomXmlProps"; + pValue[length+1].Value = uno::makeAny( pDocument->getCustomXmlDomPropsList() ); + xDocProps->setPropertyValue( aGrabBagPropName, uno::Any( aGrabBag ) ); + + } } } diff --git a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx index 776344779ae1..c29ac5d18617 100644 --- a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx +++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx @@ -149,9 +149,59 @@ uno::Reference<xml::dom::XDocument> OOXMLDocumentImpl::importSubStream(OOXMLStre } } + if(OOXMLStream::CUSTOMXML == nType) + { + importSubStreamRelations(pStream, OOXMLStream::CUSTOMXMLPROPS); + } + return xRet; } + +void OOXMLDocumentImpl::importSubStreamRelations(OOXMLStream::Pointer_t pStream, OOXMLStream::StreamType_t nType) +{ + // imporing itemprops files for item.xml from customXml. + if(OOXMLStream::CUSTOMXMLPROPS == nType) + { + uno::Reference<xml::dom::XDocument> xCustomProps; + OOXMLStream::Pointer_t cStream; + try + { + cStream = OOXMLDocumentFactory::createStream(pStream, OOXMLStream::CUSTOMXMLPROPS); + } + catch (uno::Exception const& e) + { + SAL_WARN("writerfilter", "importSubStreamRelations: exception while " + "importing stream " << nType << " : " << e.Message); + mxCustomXmlProsDom = xCustomProps; + } + + uno::Reference<io::XInputStream> xcpInputStream = + cStream->getDocumentStream(); + + if (xcpInputStream.is()) + { + try + { + uno::Reference<uno::XComponentContext> xcpContext(pStream->getContext()); + uno::Reference<xml::dom::XDocumentBuilder> xDomBuilder(xml::dom::DocumentBuilder::create(xcpContext)); + xCustomProps = xDomBuilder->parse(xcpInputStream); + } + catch (uno::Exception const& e) + { + SAL_WARN("writerfilter", "importSubStream: exception while " + "parsing stream " << nType << " : " << e.Message); + mxCustomXmlProsDom = xCustomProps; + } + } + + if(xCustomProps.is()) + { + mxCustomXmlProsDom = xCustomProps; + } + } +} + void OOXMLDocumentImpl::setXNoteId(const sal_Int32 nId) { mnXNoteId = nId; @@ -416,10 +466,11 @@ void OOXMLDocumentImpl::resolveCustomXmlStream(Stream & rStream) OUString sCustomType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml"); OUString sTarget("Target"); bool bFound = false; - sal_Int32 counter = 1; + sal_Int32 counter = 0; uno::Sequence< uno::Sequence< beans::StringPair > >aSeqs = mxRelationshipAccess->getAllRelationships(); uno::Sequence<uno::Reference<xml::dom::XDocument> > mxCustomXmlDomListTemp(aSeqs.getLength()); + uno::Sequence<uno::Reference<xml::dom::XDocument> > mxCustomXmlDomPropsListTemp(aSeqs.getLength()); for (sal_Int32 j = 0; j < aSeqs.getLength(); j++) { uno::Sequence< beans::StringPair > aSeq = aSeqs[j]; @@ -439,15 +490,24 @@ void OOXMLDocumentImpl::resolveCustomXmlStream(Stream & rStream) } if(bFound) { - uno::Reference<xml::dom::XDocument> temp = importSubStream(OOXMLStream::CUSTOMXML); - mxCustomXmlDomListTemp[counter] = temp; - counter++; - resolveFastSubStream(rStream, OOXMLStream::CUSTOMXML); + uno::Reference<xml::dom::XDocument> customXmlTemp = importSubStream(OOXMLStream::CUSTOMXML); + // This will add all item[n].xml with it's relationship file i.e itemprops.xml to + // grabbag list. + if(mxCustomXmlProsDom.is() && customXmlTemp.is()) + { + mxCustomXmlDomListTemp[counter] = customXmlTemp; + mxCustomXmlDomPropsListTemp[counter] = mxCustomXmlProsDom; + counter++; + resolveFastSubStream(rStream, OOXMLStream::CUSTOMXML); + } bFound = false; } } - mxCustomXmlDomListTemp.realloc(counter+1); + + mxCustomXmlDomListTemp.realloc(counter); + mxCustomXmlDomPropsListTemp.realloc(counter); mxCustomXmlDomList = mxCustomXmlDomListTemp; + mxCustomXmlDomPropsList = mxCustomXmlDomPropsListTemp; } } @@ -518,6 +578,11 @@ uno::Sequence<uno::Reference<xml::dom::XDocument> > OOXMLDocumentImpl::getCustom return mxCustomXmlDomList; } +uno::Sequence<uno::Reference<xml::dom::XDocument> > OOXMLDocumentImpl::getCustomXmlDomPropsList( ) +{ + return mxCustomXmlDomPropsList; +} + OOXMLDocument * OOXMLDocumentFactory::createDocument (OOXMLStream::Pointer_t pStream) diff --git a/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx b/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx index 2ec5033a7ead..07511331e8fe 100644 --- a/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx +++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx @@ -43,6 +43,8 @@ class OOXMLDocumentImpl : public OOXMLDocument uno::Reference<xml::sax::XFastShapeContextHandler> mxShapeContext; uno::Reference<xml::dom::XDocument> mxThemeDom; uno::Sequence<uno::Reference<xml::dom::XDocument> > mxCustomXmlDomList; + uno::Sequence<uno::Reference<xml::dom::XDocument> > mxCustomXmlDomPropsList; + uno::Reference<xml::dom::XDocument> mxCustomXmlProsDom; bool mbIsSubstream; protected: @@ -55,6 +57,8 @@ protected: uno::Reference<xml::dom::XDocument> importSubStream(OOXMLStream::StreamType_t nType); + void importSubStreamRelations(OOXMLStream::Pointer_t pStream, OOXMLStream::StreamType_t nType); + writerfilter::Reference<Stream>::Pointer_t getSubStream(const OUString & rId); @@ -112,6 +116,7 @@ public: virtual void setThemeDom(uno::Reference<xml::dom::XDocument> xThemeDom); virtual uno::Reference<xml::dom::XDocument> getThemeDom(); virtual uno::Sequence<uno::Reference<xml::dom::XDocument> > getCustomXmlDomList(); + virtual uno::Sequence<uno::Reference<xml::dom::XDocument> > getCustomXmlDomPropsList(); }; }} #endif // OOXML_DOCUMENT_IMPL_HXX diff --git a/writerfilter/source/ooxml/OOXMLStreamImpl.cxx b/writerfilter/source/ooxml/OOXMLStreamImpl.cxx index c1cb79811ea9..333df28b2242 100644 --- a/writerfilter/source/ooxml/OOXMLStreamImpl.cxx +++ b/writerfilter/source/ooxml/OOXMLStreamImpl.cxx @@ -111,6 +111,7 @@ bool OOXMLStreamImpl::lcl_getTarget(uno::Reference<embed::XRelationshipAccess> static OUString sCommentsType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments"); static OUString sThemeType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme"); static OUString sCustomType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml"); + static OUString sCustomPropsType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXmlProps"); static OUString sSettingsType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings"); static OUString sTarget("Target"); static OUString sTargetMode("TargetMode"); @@ -151,6 +152,9 @@ bool OOXMLStreamImpl::lcl_getTarget(uno::Reference<embed::XRelationshipAccess> case CUSTOMXML: sStreamType = sCustomType; break; + case CUSTOMXMLPROPS: + sStreamType = sCustomPropsType; + break; case SETTINGS: sStreamType = sSettingsType; break; |