27#include <com/sun/star/beans/StringPair.hpp>
28#include <com/sun/star/xml/sax/Parser.hpp>
29#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
30#include <com/sun/star/xml/sax/SAXException.hpp>
31#include <com/sun/star/xml/sax/Writer.hpp>
32#include <com/sun/star/lang/IllegalArgumentException.hpp>
35#define RELATIONINFO_FORMAT 0
36#define CONTENTTYPE_FORMAT 1
37#define FORMAT_MAX_ID CONTENTTYPE_FORMAT
46class OFOPXMLHelper_Impl
47 :
public cppu::WeakImplHelper< css::xml::sax::XDocumentHandler >
51 css::uno::Sequence< css::uno::Sequence< css::beans::StringPair > >
m_aResultSeq;
56 css::uno::Sequence< css::uno::Sequence< css::beans::StringPair > >
const & GetParsingResult()
const;
58 explicit OFOPXMLHelper_Impl( sal_uInt16 nFormat );
61 virtual void SAL_CALL startDocument()
override;
62 virtual void SAL_CALL endDocument()
override;
63 virtual void SAL_CALL startElement(
const OUString& aName,
const css::uno::Reference< css::xml::sax::XAttributeList >& xAttribs )
override;
64 virtual void SAL_CALL endElement(
const OUString& aName )
override;
65 virtual void SAL_CALL characters(
const OUString& aChars )
override;
66 virtual void SAL_CALL ignorableWhitespace(
const OUString& aWhitespaces )
override;
67 virtual void SAL_CALL processingInstruction(
const OUString& aTarget,
const OUString& aData )
override;
68 virtual void SAL_CALL setDocumentLocator(
const css::uno::Reference< css::xml::sax::XLocator >& xLocator )
override;
73namespace OFOPXMLHelper {
77 const uno::Reference<io::XInputStream>& xInStream,
78 const OUString& aStringID, sal_uInt16 nFormat,
79 const uno::Reference<uno::XComponentContext>& xContext);
82 const uno::Reference< io::XInputStream >& xInStream,
83 std::u16string_view aStreamName,
84 const uno::Reference< uno::XComponentContext >& rContext )
86 OUString aStringID = OUString::Concat(
"_rels/") + aStreamName;
92 const uno::Reference< io::XInputStream >& xInStream,
93 const uno::Reference< uno::XComponentContext >& rContext )
99 const css::uno::Sequence<css::uno::Sequence<css::beans::StringPair>>& rContentTypes,
100 const OUString& rFilename)
102 if (rContentTypes.getLength() < 2)
107 const uno::Sequence<beans::StringPair>& rDefaults = rContentTypes[0];
108 const uno::Sequence<beans::StringPair>& rOverrides = rContentTypes[1];
111 const sal_Int32 nDotOffset = rFilename.lastIndexOf(
'.');
112 const OUString aExt = (nDotOffset >= 0 ? rFilename.copy(nDotOffset + 1) : rFilename);
114 const std::vector<OUString> aNames = { aExt,
"/" + rFilename };
115 for (
const OUString&
aName : aNames)
117 const auto it1 = std::find_if(rOverrides.begin(), rOverrides.end(), [&
aName](
const beans::StringPair& rPair)
118 { return rPair.First == aName; });
119 if (it1 != rOverrides.end())
122 const auto it2 = std::find_if(rDefaults.begin(), rDefaults.end(), [&
aName](
const beans::StringPair& rPair)
123 { return rPair.First == aName; });
124 if (it2 != rDefaults.end())
132 const uno::Reference< io::XOutputStream >& xOutStream,
133 const uno::Sequence< uno::Sequence< beans::StringPair > >& aSequence,
134 const uno::Reference< uno::XComponentContext >& rContext )
136 if ( !xOutStream.is() )
137 throw uno::RuntimeException();
139 uno::Reference< css::xml::sax::XWriter > xWriter = css::xml::sax::Writer::create(rContext);
141 xWriter->setOutputStream( xOutStream );
143 OUString aRelListElement(
"Relationships" );
144 OUString aRelElement(
"Relationship" );
145 OUString aWhiteSpace(
" " );
149 pRootAttrList->AddAttribute(
151 "http://schemas.openxmlformats.org/package/2006/relationships" );
153 xWriter->startDocument();
154 xWriter->startElement( aRelListElement, pRootAttrList );
156 for (
const auto &
i : aSequence )
159 for(
const beans::StringPair & pair :
i )
161 if ( !(pair.First ==
"Id"
162 || pair.First ==
"Type"
163 || pair.First ==
"TargetMode"
164 || pair.First ==
"Target") )
167 throw lang::IllegalArgumentException();
169 pAttrList->AddAttribute( pair.First, pair.Second );
172 xWriter->startElement( aRelElement, pAttrList );
173 xWriter->ignorableWhitespace( aWhiteSpace );
174 xWriter->endElement( aRelElement );
177 xWriter->ignorableWhitespace( aWhiteSpace );
178 xWriter->endElement( aRelListElement );
179 xWriter->endDocument();
184 const uno::Reference< io::XOutputStream >& xOutStream,
185 const uno::Sequence< beans::StringPair >& aDefaultsSequence,
186 const uno::Sequence< beans::StringPair >& aOverridesSequence,
187 const uno::Reference< uno::XComponentContext >& rContext )
189 if ( !xOutStream.is() )
190 throw uno::RuntimeException();
192 uno::Reference< css::xml::sax::XWriter > xWriter = css::xml::sax::Writer::create(rContext);
194 xWriter->setOutputStream( xOutStream );
196 static constexpr OUStringLiteral aTypesElement(
u"Types");
197 static constexpr OUStringLiteral aDefaultElement(
u"Default");
198 static constexpr OUStringLiteral aOverrideElement(
u"Override");
199 static constexpr OUStringLiteral aContentTypeAttr(
u"ContentType");
200 static constexpr OUStringLiteral aWhiteSpace(
u" ");
204 pRootAttrList->AddAttribute(
206 "http://schemas.openxmlformats.org/package/2006/content-types" );
208 xWriter->startDocument();
209 xWriter->startElement( aTypesElement, pRootAttrList );
211 for (
const beans::StringPair & pair : aDefaultsSequence )
214 pAttrList->AddAttribute(
"Extension", pair.First );
215 pAttrList->AddAttribute( aContentTypeAttr, pair.Second );
217 xWriter->startElement( aDefaultElement, pAttrList );
218 xWriter->ignorableWhitespace( aWhiteSpace );
219 xWriter->endElement( aDefaultElement );
222 for (
const beans::StringPair & pair : aOverridesSequence )
225 pAttrList->AddAttribute(
"PartName", pair.First );
226 pAttrList->AddAttribute( aContentTypeAttr, pair.Second );
228 xWriter->startElement( aOverrideElement, pAttrList );
229 xWriter->ignorableWhitespace( aWhiteSpace );
230 xWriter->endElement( aOverrideElement );
233 xWriter->ignorableWhitespace( aWhiteSpace );
234 xWriter->endElement( aTypesElement );
235 xWriter->endDocument();
240 const uno::Reference< io::XInputStream >& xInStream,
241 const OUString& aStringID, sal_uInt16 nFormat,
242 const uno::Reference< uno::XComponentContext >& rContext )
244 if ( !rContext.is() || !xInStream.is() || nFormat >
FORMAT_MAX_ID )
245 throw uno::RuntimeException();
247 uno::Reference< css::xml::sax::XParser > xParser = css::xml::sax::Parser::create( rContext );
250 css::xml::sax::InputSource aParserInput;
251 aParserInput.aInputStream = xInStream;
252 aParserInput.sSystemId = aStringID;
253 xParser->setDocumentHandler( pHelper );
254 xParser->parseStream( aParserInput );
255 xParser->setDocumentHandler( uno::Reference < css::xml::sax::XDocumentHandler > () );
257 return pHelper->GetParsingResult();
278OFOPXMLHelper_Impl::OFOPXMLHelper_Impl( sal_uInt16 nFormat )
283uno::Sequence< uno::Sequence< beans::StringPair > >
const & OFOPXMLHelper_Impl::GetParsingResult()
const
286 throw uno::RuntimeException();
292void SAL_CALL OFOPXMLHelper_Impl::startDocument()
297void SAL_CALL OFOPXMLHelper_Impl::endDocument()
302void SAL_CALL OFOPXMLHelper_Impl::startElement(
const OUString& aName,
const uno::Reference< css::xml::sax::XAttributeList >& xAttribs )
310 if ( nNewLength != 1 )
311 throw css::xml::sax::SAXException();
320 if ( nNewLength != 2 )
321 throw css::xml::sax::SAXException();
328 sal_Int32 nAttrNum = 0;
329 pResultSeq[nNewEntryNum-1].realloc( 4 );
330 auto pAttrs = pResultSeq[nNewEntryNum-1].getArray();
332 OUString aIDValue = xAttribs->getValueByName(
g_aIDAttr );
333 if ( aIDValue.isEmpty() )
334 throw css::xml::sax::SAXException();
336 OUString aTypeValue = xAttribs->getValueByName(
g_aTypeAttr );
337 OUString aTargetValue = xAttribs->getValueByName(
g_aTargetAttr );
340 pAttrs[++nAttrNum - 1].First =
g_aIDAttr;
341 pAttrs[nAttrNum - 1].Second = aIDValue;
343 if ( !aTypeValue.isEmpty() )
346 pAttrs[nAttrNum - 1].Second = aTypeValue;
349 if ( !aTargetValue.isEmpty() )
352 pAttrs[nAttrNum - 1].Second = aTargetValue;
355 if ( !aTargetModeValue.isEmpty() )
358 pAttrs[nAttrNum - 1].Second = aTargetModeValue;
361 pResultSeq[nNewEntryNum-1].realloc( nAttrNum );
364 throw css::xml::sax::SAXException();
372 if ( nNewLength != 1 )
373 throw css::xml::sax::SAXException();
385 if ( nNewLength != 2 )
386 throw css::xml::sax::SAXException();
394 throw uno::RuntimeException();
398 const OUString aExtensionValue = xAttribs->getValueByName(
g_aExtensionAttr );
399 if ( aExtensionValue.isEmpty() )
400 throw css::xml::sax::SAXException();
403 if ( aContentTypeValue.isEmpty() )
404 throw css::xml::sax::SAXException();
406 const sal_Int32 nNewResultLen =
m_aResultSeq[0].getLength() + 1;
407 pResultSeq[0].realloc( nNewResultLen );
408 auto pSeq = pResultSeq[0].getArray();
410 pSeq[nNewResultLen-1].First = aExtensionValue;
411 pSeq[nNewResultLen-1].Second = aContentTypeValue;
416 if ( nNewLength != 2 )
417 throw css::xml::sax::SAXException();
425 throw uno::RuntimeException();
430 if ( aPartNameValue.isEmpty() )
431 throw css::xml::sax::SAXException();
434 if ( aContentTypeValue.isEmpty() )
435 throw css::xml::sax::SAXException();
437 sal_Int32 nNewResultLen =
m_aResultSeq[1].getLength() + 1;
438 pResultSeq[1].realloc( nNewResultLen );
439 auto pSeq = pResultSeq[1].getArray();
441 pSeq[nNewResultLen-1].First = aPartNameValue;
442 pSeq[nNewResultLen-1].Second = aContentTypeValue;
445 throw css::xml::sax::SAXException();
448 throw css::xml::sax::SAXException();
452void SAL_CALL OFOPXMLHelper_Impl::endElement(
const OUString& aName )
458 throw css::xml::sax::SAXException();
461 throw css::xml::sax::SAXException();
468void SAL_CALL OFOPXMLHelper_Impl::characters(
const OUString& )
473void SAL_CALL OFOPXMLHelper_Impl::ignorableWhitespace(
const OUString& )
478void SAL_CALL OFOPXMLHelper_Impl::processingInstruction(
const OUString& ,
const OUString& )
483void SAL_CALL OFOPXMLHelper_Impl::setDocumentLocator(
const uno::Reference< css::xml::sax::XLocator >& )
uno::Sequence< uno::Sequence< beans::StringPair > > ReadContentTypeSequence(const uno::Reference< io::XInputStream > &xInStream, const uno::Reference< uno::XComponentContext > &rContext)
void WriteContentSequence(const uno::Reference< io::XOutputStream > &xOutStream, const uno::Sequence< beans::StringPair > &aDefaultsSequence, const uno::Sequence< beans::StringPair > &aOverridesSequence, const uno::Reference< uno::XComponentContext > &rContext)
OUString GetContentTypeByName(const css::uno::Sequence< css::uno::Sequence< css::beans::StringPair > > &rContentTypes, const OUString &rFilename)
static uno::Sequence< uno::Sequence< beans::StringPair > > ReadSequence_Impl(const uno::Reference< io::XInputStream > &xInStream, const OUString &aStringID, sal_uInt16 nFormat, const uno::Reference< uno::XComponentContext > &xContext)
uno::Sequence< uno::Sequence< beans::StringPair > > ReadRelationsInfoSequence(const uno::Reference< io::XInputStream > &xInStream, std::u16string_view aStreamName, const uno::Reference< uno::XComponentContext > &rContext)
void WriteRelationsInfoSequence(const uno::Reference< io::XOutputStream > &xOutStream, const uno::Sequence< uno::Sequence< beans::StringPair > > &aSequence, const uno::Reference< uno::XComponentContext > &rContext)
constexpr OUStringLiteral g_aRelListElement(u"Relationships")
constexpr OUStringLiteral g_aIDAttr(u"Id")
constexpr OUStringLiteral g_aTargetModeAttr(u"TargetMode")
constexpr OUStringLiteral g_aTypeAttr(u"Type")
constexpr OUStringLiteral g_aPartNameAttr(u"PartName")
constexpr OUStringLiteral g_aOverrideElement(u"Override")
constexpr OUStringLiteral g_aExtensionAttr(u"Extension")
constexpr OUStringLiteral g_aTargetAttr(u"Target")
constexpr OUStringLiteral g_aContentTypeAttr(u"ContentType")
constexpr OUStringLiteral g_aTypesElement(u"Types")
constexpr OUStringLiteral g_aDefaultElement(u"Default")
constexpr OUStringLiteral g_aRelElement(u"Relationship")
css::uno::Sequence< css::uno::Sequence< css::beans::StringPair > > m_aResultSeq
#define CONTENTTYPE_FORMAT
#define RELATIONINFO_FORMAT
sal_uInt16 const m_nFormat
std::vector< OUString > m_aElementsSeq