1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <config_wasm_strip.h>
25 #include <comphelper/diagnose_ex.hxx>
26 #include <sal/log.hxx>
27 #include <com/sun/star/beans/XPropertySetInfo.hpp>
28 #include <tools/urlobj.hxx>
30 #include <vcl/embeddedfontshelper.hxx>
31 #include <vcl/graph.hxx>
32 #include <xmloff/unointerfacetouniqueidentifiermapper.hxx>
33 #include <xmloff/namespacemap.hxx>
34 #include <xmloff/xmluconv.hxx>
35 #include <xmloff/xmlnamespace.hxx>
36 #include <xmloff/xmltoken.hxx>
37 #include <xmloff/XMLFontStylesContext.hxx>
38 #include <xmloff/xmlictxt.hxx>
39 #include <xmloff/xmlimp.hxx>
40 #include <xmloff/xmlnumfi.hxx>
41 #include <XMLEventImportHelper.hxx>
42 #include <XMLStarBasicContextFactory.hxx>
43 #include <XMLScriptContextFactory.hxx>
44 #include <StyleMap.hxx>
45 #include <xmloff/ProgressBarHelper.hxx>
46 #include <xmloff/xmlerror.hxx>
47 #include <com/sun/star/container/XNameContainer.hpp>
48 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
49 #include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
50 #include <com/sun/star/io/XOutputStream.hpp>
51 #include <com/sun/star/util/MeasureUnit.hpp>
52 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
53 #include <com/sun/star/frame/XModel.hpp>
54 #include <com/sun/star/document/XBinaryStreamResolver.hpp>
55 #include <com/sun/star/document/XStorageBasedDocument.hpp>
56 #include <com/sun/star/document/XGraphicStorageHandler.hpp>
57 #include <com/sun/star/document/XEmbeddedObjectResolver.hpp>
58 #include <com/sun/star/xml/sax/XLocator.hpp>
59 #include <com/sun/star/xml/sax/FastParser.hpp>
60 #include <com/sun/star/xml/sax/SAXException.hpp>
61 #include <com/sun/star/packages/zip/ZipIOException.hpp>
62 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
63 #include <comphelper/fileformat.h>
64 #include <comphelper/namecontainer.hxx>
65 #include <cppuhelper/implbase.hxx>
66 #include <cppuhelper/supportsservice.hxx>
67 #include <comphelper/extract.hxx>
68 #include <comphelper/documentconstants.hxx>
69 #include <comphelper/documentinfo.hxx>
70 #include <comphelper/storagehelper.hxx>
71 #include <comphelper/attributelist.hxx>
72 #include <unotools/fontcvt.hxx>
73 #include <fasttokenhandler.hxx>
74 #include <vcl/GraphicExternalLink.hxx>
75 #include <o3tl/string_view.hxx>
77 #include <com/sun/star/rdf/XMetadatable.hpp>
78 #include <com/sun/star/rdf/XRepositorySupplier.hpp>
79 #include <RDFaImportHelper.hxx>
81 using ::com::sun::star::beans::XPropertySetInfo
;
83 using namespace ::com::sun::star
;
84 using namespace ::com::sun::star::uno
;
85 using namespace ::com::sun::star::util
;
86 using namespace ::com::sun::star::io
;
87 using namespace ::com::sun::star::container
;
88 using namespace ::com::sun::star::document
;
89 using namespace ::xmloff::token
;
91 rtl::Reference
<FastTokenHandler
> SvXMLImport::xTokenHandler(new FastTokenHandler
);
92 std::unordered_map
< sal_Int32
, std::pair
< OUString
, OUString
> > SvXMLImport::aNamespaceMap
;
93 std::unordered_map
< OUString
, OUString
> SvXMLImport::aNamespaceURIPrefixMap
;
94 bool SvXMLImport::bIsNSMapsInitialized
= false;
98 class SvXMLImportEventListener
: public cppu::WeakImplHelper
< css::lang::XEventListener
>
101 SvXMLImport
* pImport
;
104 explicit SvXMLImportEventListener(SvXMLImport
* pImport
);
107 virtual void SAL_CALL
disposing(const lang::EventObject
& rEventObject
) override
;
112 SvXMLImportEventListener::SvXMLImportEventListener(SvXMLImport
* pTempImport
)
113 : pImport(pTempImport
)
118 void SAL_CALL
SvXMLImportEventListener::disposing( const lang::EventObject
& )
122 pImport
->DisposingModel();
131 getBuildIdsProperty(uno::Reference
<beans::XPropertySet
> const& xImportInfo
)
133 if (xImportInfo
.is())
137 Reference
< XPropertySetInfo
> const xSetInfo(
138 xImportInfo
->getPropertySetInfo());
139 if (xSetInfo
.is() && xSetInfo
->hasPropertyByName(u
"BuildId"_ustr
))
142 xImportInfo
->getPropertyValue(u
"BuildId"_ustr
) >>= aBuildId
;
146 catch (Exception
const&)
148 DBG_UNHANDLED_EXCEPTION("xmloff.core", "exception getting BuildId");
157 sal_uInt16 mnGeneratorVersion
;
160 explicit DocumentInfo( const SvXMLImport
& rImport
)
161 : mnGeneratorVersion( SvXMLImport::ProductVersionUnknown
)
163 OUString
const buildIds(
164 getBuildIdsProperty(rImport
.getImportInfo()));
165 if (!buildIds
.isEmpty())
167 sal_Int32
const ix
= buildIds
.indexOf(';');
170 OUString
const loVersion(buildIds
.copy(ix
+ 1));
171 if (!loVersion
.isEmpty())
173 auto const firstDot(loVersion
.indexOf('.'));
175 { // old version scheme 3.3 ... 7.6
176 if ('3' == loVersion
[0])
178 mnGeneratorVersion
= SvXMLImport::LO_3x
;
180 else if ('4' == loVersion
[0])
182 if (loVersion
.getLength() > 2
183 && (loVersion
[2] == '0' || loVersion
[2] == '1'))
185 mnGeneratorVersion
= SvXMLImport::LO_41x
; // 4.0/4.1
187 else if (loVersion
.getLength() > 2 && '2' == loVersion
[2])
189 mnGeneratorVersion
= SvXMLImport::LO_42x
; // 4.2
191 else if (loVersion
.getLength() > 2 && '3' == loVersion
[2])
193 mnGeneratorVersion
= SvXMLImport::LO_43x
; // 4.3
195 else if (loVersion
.getLength() > 2 && '4' == loVersion
[2])
197 mnGeneratorVersion
= SvXMLImport::LO_44x
; // 4.4
200 else if ('5' == loVersion
[0])
202 mnGeneratorVersion
= SvXMLImport::LO_5x
;
204 else if ('6' == loVersion
[0])
206 if (loVersion
.getLength() > 2
207 && (loVersion
[2] == '0' || loVersion
[2] == '1'
208 || loVersion
[2] == '2'))
210 mnGeneratorVersion
= SvXMLImport::LO_6x
; // 6.0/6.1/6.2
214 mnGeneratorVersion
= SvXMLImport::LO_63x
; // 6.3/6.4
217 else if ('7' == loVersion
[0])
219 if (loVersion
.getLength() > 2 && loVersion
[2] == '6')
221 mnGeneratorVersion
= SvXMLImport::LO_76
; // 7.6
225 mnGeneratorVersion
= SvXMLImport::LO_7x
;
230 SAL_INFO("xmloff.core", "unknown LO version: " << loVersion
);
233 else if (1 < firstDot
) // new version scheme 24.2 ...
235 OUString
const nMajor(loVersion
.subView(0, firstDot
));
236 auto const year(nMajor
.toInt32());
237 //auto const month(loVersion.copy(firstDot+1).toInt32());
240 mnGeneratorVersion
= SvXMLImport::LO_New
;
244 SAL_INFO("xmloff.core", "unknown LO version: " << loVersion
);
249 SAL_INFO("xmloff.core", "unknown LO version: " << loVersion
);
251 return; // ignore buildIds
255 sal_Int32 nUPD
, nBuild
;
256 if ( !rImport
.getBuildIds( nUPD
, nBuild
) )
259 if ( nUPD
>= 640 && nUPD
<= 645 )
261 mnGeneratorVersion
= SvXMLImport::OOo_1x
;
263 else if ( nUPD
== 680 )
265 mnGeneratorVersion
= SvXMLImport::OOo_2x
;
267 else if ( nUPD
== 300 && nBuild
<= 9379 )
269 mnGeneratorVersion
= SvXMLImport::OOo_30x
;
271 else if ( nUPD
== 310 )
273 mnGeneratorVersion
= SvXMLImport::OOo_31x
;
275 else if ( nUPD
== 320 )
277 mnGeneratorVersion
= SvXMLImport::OOo_32x
;
279 else if ( nUPD
== 330 )
281 mnGeneratorVersion
= SvXMLImport::OOo_33x
;
283 else if ( nUPD
== 340 )
285 mnGeneratorVersion
= SvXMLImport::OOo_34x
;
287 else if (nUPD
== 400 || nUPD
== 401)
289 mnGeneratorVersion
= SvXMLImport::AOO_40x
;
291 else if (nUPD
>= 410)
293 // effectively this means "latest", see use
294 // in XMLGraphicsDefaultStyle::SetDefaults()!
295 mnGeneratorVersion
= SvXMLImport::AOO_4x
;
299 sal_uInt16
getGeneratorVersion() const
301 return mnGeneratorVersion
;
307 class SvXMLImport_Impl
310 FontToSubsFontConverter hBatsFontConv
;
311 FontToSubsFontConverter hMathFontConv
;
313 bool mbOwnGraphicResolver
;
314 bool mbOwnEmbeddedResolver
;
315 INetURLObject aBaseURL
;
316 INetURLObject aDocBase
;
318 /// name of stream in package, e.g., "content.xml"
319 OUString mStreamName
;
321 std::optional
<OUString
> mxODFVersion
;
325 std::optional
<bool> mbIsMSO
;
327 // Boolean, indicating that position attributes
328 // of shapes are given in horizontal left-to-right layout. This is the case
329 // for the OpenOffice.org file format. (#i28749#)
330 bool mbShapePositionInHoriL2R
;
331 bool mbTextDocInOOoFileFormat
;
333 const uno::Reference
< uno::XComponentContext
> mxComponentContext
;
334 OUString implementationName
;
335 css::uno::Sequence
< OUString
> maSupportedServiceNames
;
337 uno::Reference
< embed::XStorage
> mxSourceStorage
;
339 std::unique_ptr
< xmloff::RDFaImportHelper
> mpRDFaHelper
;
341 std::optional
< DocumentInfo
> moDocumentInfo
;
343 SvXMLImport_Impl( uno::Reference
< uno::XComponentContext
> xContext
,
344 OUString theImplementationName
,
345 const css::uno::Sequence
< OUString
> & sSupportedServiceNames
= {})
346 : hBatsFontConv( nullptr )
347 , hMathFontConv( nullptr )
348 , mbOwnGraphicResolver( false )
349 , mbOwnEmbeddedResolver( false )
351 // Convert drawing object positions from OOo file format to OASIS (#i28749#)
352 , mbShapePositionInHoriL2R( false )
353 , mbTextDocInOOoFileFormat( false )
354 , mxComponentContext(std::move( xContext
))
355 , implementationName(std::move(theImplementationName
))
356 , maSupportedServiceNames(sSupportedServiceNames
)
358 SAL_WARN_IF(!mxComponentContext
.is(), "xmloff.core", "SvXMLImport: no ComponentContext");
359 if (!mxComponentContext
.is()) throw uno::RuntimeException();
360 if (!maSupportedServiceNames
.hasElements())
361 maSupportedServiceNames
= { u
"com.sun.star.document.ImportFilter"_ustr
, u
"com.sun.star.xml.XMLImportFilter"_ustr
};
364 sal_uInt16
getGeneratorVersion( const SvXMLImport
& rImport
)
368 moDocumentInfo
.emplace( rImport
);
371 return moDocumentInfo
->getGeneratorVersion();
374 ::comphelper::UnoInterfaceToUniqueIdentifierMapper maInterfaceToIdentifierMapper
;
377 SvXMLImportContext
*SvXMLImport::CreateFastContext( sal_Int32 nElement
,
378 const uno::Reference
< xml::sax::XFastAttributeList
>& /*xAttrList*/ )
381 SAL_WARN( "xmloff.core", "CreateFastContext should be overridden, for element " << nElement
);
382 return new SvXMLImportContext( *this );
385 void SvXMLImport::InitCtor_()
387 if( mnImportFlags
!= SvXMLImportFlags::NONE
)
389 // implicit "xml" namespace prefix
390 mxNamespaceMap
->Add( GetXMLToken(XML_XML
), GetXMLToken(XML_N_XML
), XML_NAMESPACE_XML
);
391 mxNamespaceMap
->Add( u
"_office"_ustr
, GetXMLToken(XML_N_OFFICE
), XML_NAMESPACE_OFFICE
);
392 mxNamespaceMap
->Add( u
"_office_ooo"_ustr
, GetXMLToken(XML_N_OFFICE_EXT
), XML_NAMESPACE_OFFICE_EXT
);
393 mxNamespaceMap
->Add( u
"_ooo"_ustr
, GetXMLToken(XML_N_OOO
), XML_NAMESPACE_OOO
);
394 mxNamespaceMap
->Add( u
"_style"_ustr
, GetXMLToken(XML_N_STYLE
), XML_NAMESPACE_STYLE
);
395 mxNamespaceMap
->Add( u
"_text"_ustr
, GetXMLToken(XML_N_TEXT
), XML_NAMESPACE_TEXT
);
396 mxNamespaceMap
->Add( u
"_table"_ustr
, GetXMLToken(XML_N_TABLE
), XML_NAMESPACE_TABLE
);
397 mxNamespaceMap
->Add( u
"_table_ooo"_ustr
, GetXMLToken(XML_N_TABLE_EXT
), XML_NAMESPACE_TABLE_EXT
);
398 mxNamespaceMap
->Add( u
"_draw"_ustr
, GetXMLToken(XML_N_DRAW
), XML_NAMESPACE_DRAW
);
399 mxNamespaceMap
->Add( u
"_draw_ooo"_ustr
, GetXMLToken(XML_N_DRAW_EXT
), XML_NAMESPACE_DRAW_EXT
);
400 mxNamespaceMap
->Add( u
"_dr3d"_ustr
, GetXMLToken(XML_N_DR3D
), XML_NAMESPACE_DR3D
);
401 mxNamespaceMap
->Add( u
"_fo"_ustr
, GetXMLToken(XML_N_FO_COMPAT
), XML_NAMESPACE_FO
);
402 mxNamespaceMap
->Add( u
"_xlink"_ustr
, GetXMLToken(XML_N_XLINK
), XML_NAMESPACE_XLINK
);
403 mxNamespaceMap
->Add( u
"_dc"_ustr
, GetXMLToken(XML_N_DC
), XML_NAMESPACE_DC
);
404 mxNamespaceMap
->Add( u
"_dom"_ustr
, GetXMLToken(XML_N_DOM
), XML_NAMESPACE_DOM
);
405 mxNamespaceMap
->Add( u
"_meta"_ustr
, GetXMLToken(XML_N_META
), XML_NAMESPACE_META
);
406 mxNamespaceMap
->Add( u
"_number"_ustr
, GetXMLToken(XML_N_NUMBER
), XML_NAMESPACE_NUMBER
);
407 mxNamespaceMap
->Add( u
"_svg"_ustr
, GetXMLToken(XML_N_SVG_COMPAT
), XML_NAMESPACE_SVG
);
408 mxNamespaceMap
->Add( u
"_chart"_ustr
, GetXMLToken(XML_N_CHART
), XML_NAMESPACE_CHART
);
409 mxNamespaceMap
->Add( u
"_math"_ustr
, GetXMLToken(XML_N_MATH
), XML_NAMESPACE_MATH
);
410 mxNamespaceMap
->Add( u
"_form"_ustr
, GetXMLToken(XML_N_FORM
), XML_NAMESPACE_FORM
);
411 mxNamespaceMap
->Add( u
"_script"_ustr
, GetXMLToken(XML_N_SCRIPT
), XML_NAMESPACE_SCRIPT
);
412 mxNamespaceMap
->Add( u
"_config"_ustr
, GetXMLToken(XML_N_CONFIG
), XML_NAMESPACE_CONFIG
);
413 mxNamespaceMap
->Add( u
"_xforms"_ustr
, GetXMLToken(XML_N_XFORMS_1_0
), XML_NAMESPACE_XFORMS
);
414 mxNamespaceMap
->Add( u
"_formx"_ustr
, GetXMLToken( XML_N_FORMX
), XML_NAMESPACE_FORMX
);
415 mxNamespaceMap
->Add( u
"_xsd"_ustr
, GetXMLToken(XML_N_XSD
), XML_NAMESPACE_XSD
);
416 mxNamespaceMap
->Add( u
"_xsi"_ustr
, GetXMLToken(XML_N_XSI
), XML_NAMESPACE_XFORMS
);
417 mxNamespaceMap
->Add( u
"_ooow"_ustr
, GetXMLToken(XML_N_OOOW
), XML_NAMESPACE_OOOW
);
418 mxNamespaceMap
->Add( u
"_oooc"_ustr
, GetXMLToken(XML_N_OOOC
), XML_NAMESPACE_OOOC
);
419 mxNamespaceMap
->Add( u
"_field"_ustr
, GetXMLToken(XML_N_FIELD
), XML_NAMESPACE_FIELD
);
420 mxNamespaceMap
->Add( u
"_of"_ustr
, GetXMLToken(XML_N_OF
), XML_NAMESPACE_OF
);
421 mxNamespaceMap
->Add( u
"_xhtml"_ustr
, GetXMLToken(XML_N_XHTML
), XML_NAMESPACE_XHTML
);
422 mxNamespaceMap
->Add( u
"_css3text"_ustr
, GetXMLToken(XML_N_CSS3TEXT
), XML_NAMESPACE_CSS3TEXT
);
424 mxNamespaceMap
->Add( u
"_calc_libo"_ustr
, GetXMLToken(XML_N_CALC_EXT
), XML_NAMESPACE_CALC_EXT
);
425 mxNamespaceMap
->Add( u
"_office_libo"_ustr
,
426 GetXMLToken(XML_N_LO_EXT
), XML_NAMESPACE_LO_EXT
);
429 if (mxNumberFormatsSupplier
.is())
430 mpNumImport
= std::make_unique
<SvXMLNumFmtHelper
>(mxNumberFormatsSupplier
, GetComponentContext());
432 if (mxModel
.is() && !mxEventListener
.is())
434 mxEventListener
.set(new SvXMLImportEventListener(this));
435 mxModel
->addEventListener(mxEventListener
);
439 SvXMLImport::SvXMLImport(
440 const css::uno::Reference
< css::uno::XComponentContext
>& xContext
,
441 OUString
const & implementationName
,
442 SvXMLImportFlags nImportFlags
,
443 const css::uno::Sequence
< OUString
> & sSupportedServiceNames
)
444 : mpImpl( new SvXMLImport_Impl(xContext
, implementationName
, sSupportedServiceNames
) ),
445 mxNamespaceMap( SvXMLNamespaceMap() ),
447 mpUnitConv( new SvXMLUnitConverter( xContext
,
448 util::MeasureUnit::MM_100TH
, util::MeasureUnit::MM_100TH
,
449 SvtSaveOptions::ODFSVER_LATEST_EXTENDED
) ),
451 mnImportFlags( nImportFlags
),
452 maNamespaceHandler( new SvXMLImportFastNamespaceHandler() ),
453 mbIsFormsSupported( true ),
454 mbIsTableShapeSupported( false ),
455 mbNotifyMacroEventRead( false )
457 SAL_WARN_IF( !xContext
.is(), "xmloff.core", "got no service manager" );
459 mxParser
= xml::sax::FastParser::create( xContext
);
460 setNamespaceHandler( maNamespaceHandler
);
461 setTokenHandler( xTokenHandler
);
462 if ( !bIsNSMapsInitialized
)
464 initializeNamespaceMaps();
465 bIsNSMapsInitialized
= true;
467 registerNamespaces();
468 maNamespaceAttrList
= new comphelper::AttributeList
;
471 void SvXMLImport::cleanup() noexcept
473 if (mxEventListener
.is() && mxModel
.is())
474 mxModel
->removeEventListener(mxEventListener
);
475 // clear context stacks first in case of parse error because the context
476 // class dtors are full of application logic
477 while (!maContexts
.empty())
479 if (SvXMLStylesContext
* pStylesContext
= dynamic_cast<SvXMLStylesContext
*>(maContexts
.top().get()))
480 pStylesContext
->dispose();
484 mxTextImport
->dispose();
485 mxTextImport
.clear(); // XMLRedlineImportHelper needs model
489 SvXMLImport::~SvXMLImport() noexcept
494 bool SvXMLImport::addEmbeddedFont(const css::uno::Reference
< css::io::XInputStream
>& stream
,
495 const OUString
& fontName
, std::u16string_view extra
,
496 std::vector
<unsigned char> const & key
, bool eot
)
498 if (!mxEmbeddedFontHelper
)
499 mxEmbeddedFontHelper
.reset(new EmbeddedFontsHelper
);
500 return mxEmbeddedFontHelper
->addEmbeddedFont(stream
, fontName
, extra
, key
, eot
);
505 class setFastDocumentHandlerGuard
508 css::uno::Reference
<css::xml::sax::XFastParser
> mxParser
;
510 setFastDocumentHandlerGuard(css::uno::Reference
<css::xml::sax::XFastParser
> Parser
,
511 const css::uno::Reference
<css::xml::sax::XFastDocumentHandler
>& Handler
)
512 : mxParser(std::move(Parser
))
514 mxParser
->setFastDocumentHandler(Handler
);
516 //guarantee restoration of null document handler
517 ~setFastDocumentHandlerGuard()
519 mxParser
->setFastDocumentHandler(nullptr);
525 void SAL_CALL
SvXMLImport::parseStream( const xml::sax::InputSource
& aInputSource
)
527 setFastDocumentHandlerGuard
aDocumentHandlerGuard(mxParser
, mxFastDocumentHandler
.is() ? mxFastDocumentHandler
: this);
528 mxParser
->parseStream(aInputSource
);
531 void SAL_CALL
SvXMLImport::setFastDocumentHandler( const uno::Reference
< xml::sax::XFastDocumentHandler
>& Handler
)
533 mxFastDocumentHandler
= Handler
;
536 void SAL_CALL
SvXMLImport::setTokenHandler( const uno::Reference
< xml::sax::XFastTokenHandler
>& Handler
)
538 mxParser
->setTokenHandler( Handler
);
541 void SAL_CALL
SvXMLImport::registerNamespace( const OUString
& NamespaceURL
, sal_Int32 NamespaceToken
)
543 mxParser
->registerNamespace( NamespaceURL
, NamespaceToken
);
546 OUString SAL_CALL
SvXMLImport::getNamespaceURL( const OUString
& rPrefix
)
548 return mxParser
->getNamespaceURL( rPrefix
);
551 void SAL_CALL
SvXMLImport::setErrorHandler( const uno::Reference
< xml::sax::XErrorHandler
>& Handler
)
553 mxParser
->setErrorHandler( Handler
);
556 void SAL_CALL
SvXMLImport::setEntityResolver( const uno::Reference
< xml::sax::XEntityResolver
>& Resolver
)
558 mxParser
->setEntityResolver( Resolver
);
561 void SAL_CALL
SvXMLImport::setLocale( const lang::Locale
& rLocale
)
563 mxParser
->setLocale( rLocale
);
566 void SAL_CALL
SvXMLImport::setNamespaceHandler( const uno::Reference
< xml::sax::XFastNamespaceHandler
>& Handler
)
568 mxParser
->setNamespaceHandler( Handler
);
571 void SAL_CALL
SvXMLImport::setCustomEntityNames( const ::css::uno::Sequence
< ::css::beans::Pair
<::rtl::OUString
, ::rtl::OUString
> >& replacements
)
573 mxParser
->setCustomEntityNames( replacements
);
576 void SAL_CALL
SvXMLImport::startDocument()
578 SAL_INFO( "xmloff.core", "{ SvXMLImport::startDocument" );
579 if (mxGraphicStorageHandler
.is() && mxEmbeddedResolver
.is())
582 Reference
< lang::XMultiServiceFactory
> xFactory( mxModel
, UNO_QUERY
);
588 if (!mxGraphicStorageHandler
.is())
590 // #99870# Import... instead of Export...
591 mxGraphicStorageHandler
.set(
592 xFactory
->createInstance(u
"com.sun.star.document.ImportGraphicStorageHandler"_ustr
),
594 mpImpl
->mbOwnGraphicResolver
= mxGraphicStorageHandler
.is();
597 if( !mxEmbeddedResolver
.is() )
599 // #99870# Import... instead of Export...
600 mxEmbeddedResolver
.set(
601 xFactory
->createInstance(u
"com.sun.star.document.ImportEmbeddedObjectResolver"_ustr
),
603 mpImpl
->mbOwnEmbeddedResolver
= mxEmbeddedResolver
.is();
606 catch( css::uno::Exception
& )
611 void SAL_CALL
SvXMLImport::endDocument()
613 SAL_INFO( "xmloff.core", "} SvXMLImport::endDocument" );
614 // #i9518# All the stuff that accesses the document has to be done here, not in the dtor,
615 // because the SvXMLImport dtor might not be called until after the document has been closed.
618 mxTextImport
->MapCrossRefHeadingFieldsHorribly();
620 if (mpImpl
->mpRDFaHelper
)
622 const uno::Reference
<rdf::XRepositorySupplier
> xRS(mxModel
,
626 mpImpl
->mpRDFaHelper
->InsertRDFa( xRS
);
631 if (mxImportInfo
.is())
633 uno::Reference
< beans::XPropertySetInfo
> xPropertySetInfo
= mxImportInfo
->getPropertySetInfo();
634 if (xPropertySetInfo
.is())
636 if (bool(mpProgressBarHelper
))
638 OUString
sProgressMax(XML_PROGRESSMAX
);
639 OUString
sProgressCurrent(XML_PROGRESSCURRENT
);
640 OUString
sRepeat(XML_PROGRESSREPEAT
);
641 if (xPropertySetInfo
->hasPropertyByName(sProgressMax
) &&
642 xPropertySetInfo
->hasPropertyByName(sProgressCurrent
))
644 sal_Int32
nProgressMax(mpProgressBarHelper
->GetReference());
645 sal_Int32
nProgressCurrent(mpProgressBarHelper
->GetValue());
646 mxImportInfo
->setPropertyValue(sProgressMax
, uno::Any(nProgressMax
));
647 mxImportInfo
->setPropertyValue(sProgressCurrent
, uno::Any(nProgressCurrent
));
649 if (xPropertySetInfo
->hasPropertyByName(sRepeat
))
650 mxImportInfo
->setPropertyValue(sRepeat
, css::uno::Any(mpProgressBarHelper
->GetRepeat()));
651 // pProgressBarHelper is deleted in dtor
653 OUString
sNumberStyles(XML_NUMBERSTYLES
);
654 if (mxNumberStyles
.is() && xPropertySetInfo
->hasPropertyByName(sNumberStyles
))
656 mxImportInfo
->setPropertyValue(sNumberStyles
, Any(mxNumberStyles
));
661 if( mxFontDecls
.is() )
662 mxFontDecls
->dispose();
665 if( mxAutoStyles
.is() )
666 mxAutoStyles
->dispose();
667 if( mxMasterStyles
.is() )
668 mxMasterStyles
->dispose();
670 // possible form-layer related knittings which can only be done when
671 // the whole document exists
672 if ( mxFormImport
.is() )
673 mxFormImport
->documentDone();
675 // The shape import helper does the z-order sorting in the dtor,
676 // so it must be deleted here, too.
677 mxShapeImport
= nullptr;
679 if( mpImpl
->mbOwnGraphicResolver
)
681 Reference
<lang::XComponent
> xComp(mxGraphicStorageHandler
, UNO_QUERY
);
685 if( mpImpl
->mbOwnEmbeddedResolver
)
687 Reference
< lang::XComponent
> xComp( mxEmbeddedResolver
, UNO_QUERY
);
692 if ( bool( mpXMLErrors
) )
694 mpXMLErrors
->ThrowErrorAsSAXException( XMLERROR_FLAG_SEVERE
);
698 std::optional
<SvXMLNamespaceMap
> SvXMLImport::processNSAttributes(
699 std::optional
<SvXMLNamespaceMap
> & rpNamespaceMap
,
700 SvXMLImport
*const pImport
, // TODO???
701 const uno::Reference
< xml::sax::XAttributeList
>& xAttrList
)
703 std::optional
<SvXMLNamespaceMap
> pRewindMap
;
704 sal_Int16 nAttrCount
= xAttrList
.is() ? xAttrList
->getLength() : 0;
705 for( sal_Int16 i
=0; i
< nAttrCount
; i
++ )
707 const OUString aAttrName
= xAttrList
->getNameByIndex( i
);
708 if (pImport
&& aAttrName
== "office:version" && !pImport
->mpImpl
->mxODFVersion
)
710 pImport
->mpImpl
->mxODFVersion
= xAttrList
->getValueByIndex( i
);
712 // the ODF version in content.xml and manifest.xml must be the same starting from ODF1.2
713 if (pImport
->mpImpl
->mStreamName
== "content.xml"
714 && !pImport
->IsODFVersionConsistent(*pImport
->mpImpl
->mxODFVersion
))
716 throw xml::sax::SAXException(u
"Inconsistent ODF versions in content.xml and manifest.xml!"_ustr
,
717 uno::Reference
< uno::XInterface
>(),
719 packages::zip::ZipIOException(u
"Inconsistent ODF versions in content.xml and manifest.xml!"_ustr
) ) );
722 else if( ( aAttrName
.getLength() >= 5 ) &&
723 ( aAttrName
.startsWith( GetXMLToken(XML_XMLNS
) ) ) &&
724 ( aAttrName
.getLength() == 5 || ':' == aAttrName
[5] ) )
728 pRewindMap
= std::move(rpNamespaceMap
);
729 rpNamespaceMap
.emplace(*pRewindMap
);
731 const OUString aAttrValue
= xAttrList
->getValueByIndex( i
);
733 OUString
aPrefix( ( aAttrName
.getLength() == 5 )
735 : aAttrName
.copy( 6 ) );
736 // Add namespace, but only if it is known.
737 sal_uInt16 nKey
= rpNamespaceMap
->AddIfKnown( aPrefix
, aAttrValue
);
738 // If namespace is unknown, try to match a name with similar
740 if( XML_NAMESPACE_UNKNOWN
== nKey
)
742 OUString
aTestName( aAttrValue
);
743 if( SvXMLNamespaceMap::NormalizeURI( aTestName
) )
744 nKey
= rpNamespaceMap
->AddIfKnown( aPrefix
, aTestName
);
746 // If that namespace is not known, too, add it as unknown
747 if( XML_NAMESPACE_UNKNOWN
== nKey
)
748 rpNamespaceMap
->Add( aPrefix
, aAttrValue
);
756 void SAL_CALL
SvXMLImport::characters( const OUString
& rChars
)
758 maContexts
.top()->characters( rChars
);
761 void SAL_CALL
SvXMLImport::processingInstruction( const OUString
&,
766 void SAL_CALL
SvXMLImport::setDocumentLocator( const uno::Reference
< xml::sax::XLocator
>& rLocator
)
768 mxLocator
= rLocator
;
771 // XFastContextHandler
772 void SAL_CALL
SvXMLImport::startFastElement (sal_Int32 Element
,
773 const uno::Reference
< xml::sax::XFastAttributeList
> & Attribs
)
775 SAL_INFO("xmloff.core", "startFastElement " << SvXMLImport::getNameFromToken( Element
));
776 if ( Attribs
.is() && !mpImpl
->mxODFVersion
)
778 sax_fastparser::FastAttributeList
& rAttribList
=
779 sax_fastparser::castToFastAttributeList( Attribs
);
780 auto aIter( rAttribList
.find( XML_ELEMENT( OFFICE
, XML_VERSION
) ) );
781 if( aIter
!= rAttribList
.end() )
783 mpImpl
->mxODFVersion
= aIter
.toString();
785 // the ODF version in content.xml and manifest.xml must be the same starting from ODF1.2
786 if ( mpImpl
->mStreamName
== "content.xml" && !IsODFVersionConsistent( *mpImpl
->mxODFVersion
) )
788 throw xml::sax::SAXException(u
"Inconsistent ODF versions in content.xml and manifest.xml!"_ustr
,
789 uno::Reference
< uno::XInterface
>(),
791 packages::zip::ZipIOException(u
"Inconsistent ODF versions in content.xml and manifest.xml!"_ustr
) ) );
796 maNamespaceAttrList
->Clear();
798 maNamespaceHandler
->addNSDeclAttributes( maNamespaceAttrList
);
799 std::optional
<SvXMLNamespaceMap
> pRewindMap
= processNSAttributes(mxNamespaceMap
, this, maNamespaceAttrList
);
801 SvXMLImportContextRef xContext
;
802 const bool bRootContext
= maContexts
.empty();
803 if (!maContexts
.empty())
805 const SvXMLImportContextRef
& pHandler
= maContexts
.top();
806 SAL_INFO("xmloff.core", "calling createFastChildContext on " << typeid(*pHandler
.get()).name());
807 auto tmp
= pHandler
->createFastChildContext( Element
, Attribs
);
808 xContext
= static_cast<SvXMLImportContext
*>(tmp
.get());
809 assert((tmp
&& xContext
) || (!tmp
&& !xContext
));
812 xContext
.set( CreateFastContext( Element
, Attribs
) );
814 SAL_INFO_IF(!xContext
.is(), "xmloff.core", "No fast context for element " << getNameFromToken(Element
));
815 if (bRootContext
&& !xContext
)
817 OUString aName
= getNameFromToken(Element
);
818 SetError( XMLERROR_FLAG_SEVERE
| XMLERROR_UNKNOWN_ROOT
,
819 { aName
}, "Root element " + aName
+ " unknown", Reference
<xml::sax::XLocator
>() );
822 xContext
.set( new SvXMLImportContext( *this ) );
824 // Remember old namespace map.
826 xContext
->PutRewindMap(std::move(pRewindMap
));
828 // Call a startElement at the new context.
829 xContext
->startFastElement( Element
, Attribs
);
831 // Push context on stack.
832 maContexts
.push(xContext
);
835 void SAL_CALL
SvXMLImport::startUnknownElement (const OUString
& rNamespace
, const OUString
& rName
,
836 const uno::Reference
< xml::sax::XFastAttributeList
> & Attribs
)
838 SAL_INFO("xmloff.core", "startUnknownElement " << rNamespace
<< " " << rName
);
839 SvXMLImportContextRef xContext
;
840 const bool bRootContext
= maContexts
.empty();
841 if (!maContexts
.empty())
843 const SvXMLImportContextRef
& pHandler
= maContexts
.top();
844 SAL_INFO("xmloff.core", "calling createUnknownChildContext on " << typeid(*pHandler
.get()).name());
845 auto tmp
= pHandler
->createUnknownChildContext( rNamespace
, rName
, Attribs
);
846 xContext
= static_cast<SvXMLImportContext
*>(tmp
.get());
847 assert((tmp
&& xContext
) || (!tmp
&& !xContext
));
850 xContext
.set( CreateFastContext( -1, Attribs
) );
852 SAL_WARN_IF(!xContext
.is(), "xmloff.core", "No context for unknown-element " << rNamespace
<< " " << rName
);
853 if (bRootContext
&& !xContext
)
855 SetError( XMLERROR_FLAG_SEVERE
| XMLERROR_UNKNOWN_ROOT
,
856 { rName
}, "Root element " + rName
+ " unknown", Reference
<xml::sax::XLocator
>() );
860 if (!maContexts
.empty())
861 // This is pretty weird, but it's what the code did before I simplified it, and some parts of the
862 // code rely on this behaviour e.g. DocumentBuilderContext
863 xContext
= maContexts
.top();
865 xContext
= new SvXMLImportContext( *this );
868 xContext
->startUnknownElement( rNamespace
, rName
, Attribs
);
869 maContexts
.push(xContext
);
872 void SAL_CALL
SvXMLImport::endFastElement (sal_Int32 Element
)
874 SAL_INFO("xmloff.core", "endFastElement " << SvXMLImport::getNameFromToken( Element
));
875 if (maContexts
.empty())
877 SAL_WARN("xmloff.core", "SvXMLImport::endFastElement: no context left");
881 SvXMLImportContextRef xContext
= std::move(maContexts
.top());
882 // Get a namespace map to rewind.
883 std::optional
<SvXMLNamespaceMap
> pRewindMap
= xContext
->TakeRewindMap();
885 xContext
->endFastElement( Element
);
886 // Rewind a namespace map.
888 mxNamespaceMap
= std::move(pRewindMap
);
891 void SAL_CALL
SvXMLImport::endUnknownElement (const OUString
& rPrefix
, const OUString
& rLocalName
)
893 SAL_INFO("xmloff.core", "endUnknownElement " << rPrefix
<< " " << rLocalName
);
894 if (maContexts
.empty())
896 SAL_WARN("xmloff.core", "SvXMLImport::endUnknownElement: no context left");
900 SvXMLImportContextRef xContext
= std::move(maContexts
.top());
902 xContext
->endUnknownElement( rPrefix
, rLocalName
);
905 uno::Reference
< xml::sax::XFastContextHandler
> SAL_CALL
906 SvXMLImport::createFastChildContext (sal_Int32
,
907 const uno::Reference
< xml::sax::XFastAttributeList
> &)
912 uno::Reference
< xml::sax::XFastContextHandler
> SAL_CALL
913 SvXMLImport::createUnknownChildContext (const OUString
&, const OUString
&,
914 const uno::Reference
< xml::sax::XFastAttributeList
> &)
919 void SvXMLImport::SetStatistics(const uno::Sequence
< beans::NamedValue
> &)
921 GetProgressBarHelper()->SetRepeat(false);
922 GetProgressBarHelper()->SetReference(0);
926 void SAL_CALL
SvXMLImport::setTargetDocument( const uno::Reference
< lang::XComponent
>& xDoc
)
928 mxModel
.set( xDoc
, UNO_QUERY
);
930 throw lang::IllegalArgumentException();
934 uno::Reference
<document::XStorageBasedDocument
> const xSBDoc(mxModel
, uno::UNO_QUERY
);
935 uno::Reference
<embed::XStorage
> const xStor(xSBDoc
.is() ? xSBDoc
->getDocumentStorage()
940 ::comphelper::OStorageHelper::GetXStorageFormat(xStor
)
941 < SOFFICE_FILEFORMAT_8
;
944 catch (uno::Exception
const&)
946 DBG_UNHANDLED_EXCEPTION("xmloff.core");
948 if (!mxEventListener
.is())
950 mxEventListener
.set(new SvXMLImportEventListener(this));
951 mxModel
->addEventListener(mxEventListener
);
954 SAL_WARN_IF( bool(mpNumImport
), "xmloff.core", "number format import already exists." );
959 sal_Bool SAL_CALL
SvXMLImport::filter( const uno::Sequence
< beans::PropertyValue
>& )
964 void SAL_CALL
SvXMLImport::cancel( )
969 void SAL_CALL
SvXMLImport::initialize( const uno::Sequence
< uno::Any
>& aArguments
)
971 for( const auto& rAny
: aArguments
)
973 Reference
<XInterface
> xValue
;
976 uno::Reference
<task::XStatusIndicator
> xTmpStatusIndicator(
978 if( xTmpStatusIndicator
.is() )
979 mxStatusIndicator
= std::move(xTmpStatusIndicator
);
981 uno::Reference
<document::XGraphicStorageHandler
> xGraphicStorageHandler(xValue
, UNO_QUERY
);
982 if (xGraphicStorageHandler
.is())
983 mxGraphicStorageHandler
= std::move(xGraphicStorageHandler
);
985 uno::Reference
<document::XEmbeddedObjectResolver
> xTmpObjectResolver(
987 if( xTmpObjectResolver
.is() )
988 mxEmbeddedResolver
= std::move(xTmpObjectResolver
);
990 uno::Reference
<beans::XPropertySet
> xTmpPropSet( xValue
, UNO_QUERY
);
991 if( xTmpPropSet
.is() )
993 mxImportInfo
= std::move(xTmpPropSet
);
994 uno::Reference
< beans::XPropertySetInfo
> xPropertySetInfo
= mxImportInfo
->getPropertySetInfo();
995 if (xPropertySetInfo
.is())
997 OUString
sPropName(XML_NUMBERSTYLES
);
998 if (xPropertySetInfo
->hasPropertyByName(sPropName
))
1000 uno::Any aAny
= mxImportInfo
->getPropertyValue(sPropName
);
1001 aAny
>>= mxNumberStyles
;
1004 sPropName
= "PrivateData";
1005 if (xPropertySetInfo
->hasPropertyByName(sPropName
))
1007 Reference
< XInterface
> xIfc
;
1008 uno::Any aAny
= mxImportInfo
->getPropertyValue(sPropName
);
1011 StyleMap
*pSMap
= dynamic_cast<StyleMap
*>( xIfc
.get() );
1018 sPropName
= "BaseURI";
1019 if (xPropertySetInfo
->hasPropertyByName(sPropName
))
1021 uno::Any aAny
= mxImportInfo
->getPropertyValue(sPropName
);
1023 mpImpl
->aBaseURL
.SetURL( sBaseURI
);
1024 mpImpl
->aDocBase
.SetURL( sBaseURI
);
1027 sPropName
= "StreamRelPath";
1028 if( xPropertySetInfo
->hasPropertyByName(sPropName
) )
1030 uno::Any aAny
= mxImportInfo
->getPropertyValue(sPropName
);
1034 sPropName
= "StreamName";
1035 if( xPropertySetInfo
->hasPropertyByName(sPropName
) )
1037 uno::Any aAny
= mxImportInfo
->getPropertyValue(sPropName
);
1040 if( !sBaseURI
.isEmpty() && !sName
.isEmpty() )
1042 if( !sRelPath
.isEmpty() )
1043 mpImpl
->aBaseURL
.insertName( sRelPath
);
1044 mpImpl
->aBaseURL
.insertName( sName
);
1046 mpImpl
->mStreamName
= sName
; // Note: may be empty (XSLT)
1047 // Retrieve property <ShapePositionInHoriL2R> (#i28749#)
1048 sPropName
= "ShapePositionInHoriL2R";
1049 if( xPropertySetInfo
->hasPropertyByName(sPropName
) )
1051 uno::Any aAny
= mxImportInfo
->getPropertyValue(sPropName
);
1052 aAny
>>= mpImpl
->mbShapePositionInHoriL2R
;
1054 sPropName
= "TextDocInOOoFileFormat";
1055 if( xPropertySetInfo
->hasPropertyByName(sPropName
) )
1057 uno::Any aAny
= mxImportInfo
->getPropertyValue(sPropName
);
1058 aAny
>>= mpImpl
->mbTextDocInOOoFileFormat
;
1061 sPropName
= "SourceStorage";
1062 if( xPropertySetInfo
->hasPropertyByName(sPropName
) )
1063 mxImportInfo
->getPropertyValue(sPropName
) >>= mpImpl
->mxSourceStorage
;
1068 uno::Reference
<lang::XInitialization
> const xInit(mxParser
, uno::UNO_QUERY_THROW
);
1069 xInit
->initialize( { Any(u
"IgnoreMissingNSDecl"_ustr
) });
1073 OUString SAL_CALL
SvXMLImport::getImplementationName()
1075 return mpImpl
->implementationName
;
1078 sal_Bool SAL_CALL
SvXMLImport::supportsService( const OUString
& rServiceName
)
1080 return cppu::supportsService(this, rServiceName
);
1083 uno::Sequence
< OUString
> SAL_CALL
SvXMLImport::getSupportedServiceNames( )
1085 return mpImpl
->maSupportedServiceNames
;
1088 XMLTextImportHelper
* SvXMLImport::CreateTextImport()
1090 return new XMLTextImportHelper( mxModel
, *this );
1093 XMLShapeImportHelper
* SvXMLImport::CreateShapeImport()
1095 return new XMLShapeImportHelper( *this, mxModel
);
1098 SchXMLImportHelper
* SvXMLImport::CreateChartImport()
1100 // WASM_CHART change
1101 // TODO: Instead of importing the ChartModel an alternative may be
1102 // added to convert not to Chart/OLE SdrObejct, but to GraphicObject
1103 // with the Chart visualization. There should be a preview available
1104 // in the imported chart data
1105 #if !ENABLE_WASM_STRIP_CHART
1106 return new SchXMLImportHelper();
1112 ::xmloff::OFormLayerXMLImport
* SvXMLImport::CreateFormImport()
1114 return new ::xmloff::OFormLayerXMLImport(*this);
1118 // Get or create fill/line/lineend-style-helper
1121 const Reference
< container::XNameContainer
> & SvXMLImport::GetGradientHelper()
1123 if( !mxGradientHelper
.is() )
1127 Reference
< lang::XMultiServiceFactory
> xServiceFact( mxModel
, UNO_QUERY
);
1128 if( xServiceFact
.is() )
1132 mxGradientHelper
.set( xServiceFact
->createInstance(
1133 u
"com.sun.star.drawing.GradientTable"_ustr
), UNO_QUERY
);
1135 catch( lang::ServiceNotRegisteredException
& )
1141 return mxGradientHelper
;
1144 const Reference
< container::XNameContainer
> & SvXMLImport::GetHatchHelper()
1146 if( !mxHatchHelper
.is() )
1150 Reference
< lang::XMultiServiceFactory
> xServiceFact( mxModel
, UNO_QUERY
);
1151 if( xServiceFact
.is() )
1155 mxHatchHelper
.set( xServiceFact
->createInstance(
1156 u
"com.sun.star.drawing.HatchTable"_ustr
), UNO_QUERY
);
1158 catch( lang::ServiceNotRegisteredException
& )
1164 return mxHatchHelper
;
1167 const Reference
< container::XNameContainer
> & SvXMLImport::GetBitmapHelper()
1169 if( !mxBitmapHelper
.is() )
1173 Reference
< lang::XMultiServiceFactory
> xServiceFact( mxModel
, UNO_QUERY
);
1174 if( xServiceFact
.is() )
1178 mxBitmapHelper
.set( xServiceFact
->createInstance(
1179 u
"com.sun.star.drawing.BitmapTable"_ustr
), UNO_QUERY
);
1181 catch( lang::ServiceNotRegisteredException
& )
1187 return mxBitmapHelper
;
1190 const Reference
< container::XNameContainer
> & SvXMLImport::GetTransGradientHelper()
1192 if( !mxTransGradientHelper
.is() )
1196 Reference
< lang::XMultiServiceFactory
> xServiceFact( mxModel
, UNO_QUERY
);
1197 if( xServiceFact
.is() )
1201 mxTransGradientHelper
.set( xServiceFact
->createInstance(
1202 u
"com.sun.star.drawing.TransparencyGradientTable"_ustr
), UNO_QUERY
);
1204 catch( lang::ServiceNotRegisteredException
& )
1210 return mxTransGradientHelper
;
1213 const Reference
< container::XNameContainer
> & SvXMLImport::GetMarkerHelper()
1215 if( !mxMarkerHelper
.is() )
1219 Reference
< lang::XMultiServiceFactory
> xServiceFact( mxModel
, UNO_QUERY
);
1220 if( xServiceFact
.is() )
1224 mxMarkerHelper
.set( xServiceFact
->createInstance( u
"com.sun.star.drawing.MarkerTable"_ustr
), UNO_QUERY
);
1226 catch( lang::ServiceNotRegisteredException
& )
1232 return mxMarkerHelper
;
1235 const Reference
< container::XNameContainer
> & SvXMLImport::GetDashHelper()
1237 if( !mxDashHelper
.is() && mxModel
.is() )
1239 Reference
< lang::XMultiServiceFactory
> xServiceFact( mxModel
, UNO_QUERY
);
1240 if( xServiceFact
.is() )
1244 mxDashHelper
.set( xServiceFact
->createInstance( u
"com.sun.star.drawing.DashTable"_ustr
), UNO_QUERY
);
1246 catch( lang::ServiceNotRegisteredException
& )
1251 return mxDashHelper
;
1254 bool SvXMLImport::IsPackageURL( std::u16string_view rURL
) const
1257 // if, and only if, only parts are imported, then we're in a package
1258 const SvXMLImportFlags nTest
= SvXMLImportFlags::META
|SvXMLImportFlags::STYLES
|SvXMLImportFlags::CONTENT
|SvXMLImportFlags::SETTINGS
;
1259 if( (mnImportFlags
& nTest
) == nTest
)
1262 // TODO: from this point extract to own static function
1264 // Some quick tests: Some may rely on the package structure!
1265 size_t nLen
= rURL
.size();
1266 if( nLen
> 0 && '/' == rURL
[0] )
1267 // RFC2396 net_path or abs_path
1269 else if( nLen
> 1 && '.' == rURL
[0] )
1271 if( '.' == rURL
[1] )
1272 // ../: We are never going up one level, so we know
1273 // it's not an external URI
1275 else if( '/' == rURL
[1] )
1276 // we are remaining on a level, so it's a package URI
1280 // Now check for a RFC2396 schema
1282 while( nPos
< nLen
)
1284 switch( rURL
[nPos
] )
1287 // a relative path segment
1294 // we don't care about any other characters
1302 uno::Reference
<graphic::XGraphic
> SvXMLImport::loadGraphicByURL(OUString
const & rURL
)
1304 uno::Reference
<graphic::XGraphic
> xGraphic
;
1308 if (mxGraphicStorageHandler
.is())
1310 if (IsPackageURL(rURL
))
1312 xGraphic
= mxGraphicStorageHandler
->loadGraphic(rURL
);
1316 OUString
const aAbsoluteURL
= GetAbsoluteReference(rURL
);
1317 GraphicExternalLink
aExternalLink(aAbsoluteURL
);
1318 Graphic
aGraphic(aExternalLink
);
1319 xGraphic
= aGraphic
.GetXGraphic();
1325 bool bRepairPackage
= false;
1326 if (auto const xStorProps
{ GetSourceStorage().query
<beans::XPropertySet
>() })
1330 xStorProps
->getPropertyValue(u
"RepairPackage"_ustr
) >>= bRepairPackage
;
1332 catch (uno::Exception
&)
1336 if (!bRepairPackage
)
1343 uno::Reference
<graphic::XGraphic
> SvXMLImport::loadGraphicFromBase64(uno::Reference
<io::XOutputStream
> const & rxOutputStream
)
1345 uno::Reference
<graphic::XGraphic
> xGraphic
;
1347 if (mxGraphicStorageHandler
.is())
1349 xGraphic
= mxGraphicStorageHandler
->loadGraphicFromOutputStream(rxOutputStream
);
1355 Reference
< XOutputStream
> SvXMLImport::GetStreamForGraphicObjectURLFromBase64() const
1357 Reference
< XOutputStream
> xOStm
;
1358 Reference
< document::XBinaryStreamResolver
> xStmResolver(mxGraphicStorageHandler
, UNO_QUERY
);
1360 if( xStmResolver
.is() )
1361 xOStm
= xStmResolver
->createOutputStream();
1366 OUString
SvXMLImport::ResolveEmbeddedObjectURL(
1367 const OUString
& rURL
,
1368 std::u16string_view rClassId
)
1372 if( IsPackageURL( rURL
) )
1374 if ( mxEmbeddedResolver
.is() )
1376 OUString
sURL( rURL
);
1377 if( !rClassId
.empty() )
1379 sURL
+= OUString::Concat("!") + rClassId
;
1381 sRet
= mxEmbeddedResolver
->resolveEmbeddedObjectURL( sURL
);
1385 sRet
= GetAbsoluteReference( rURL
);
1390 Reference
< embed::XStorage
> const & SvXMLImport::GetSourceStorage() const
1392 return mpImpl
->mxSourceStorage
;
1395 Reference
< XOutputStream
>
1396 SvXMLImport::GetStreamForEmbeddedObjectURLFromBase64() const
1398 Reference
< XOutputStream
> xOLEStream
;
1400 if( mxEmbeddedResolver
.is() )
1402 Reference
< XNameAccess
> xNA( mxEmbeddedResolver
, UNO_QUERY
);
1405 Any aAny
= xNA
->getByName( u
"Obj12345678"_ustr
);
1406 aAny
>>= xOLEStream
;
1413 OUString
SvXMLImport::ResolveEmbeddedObjectURLFromBase64()
1417 if( mxEmbeddedResolver
.is() )
1419 sRet
= mxEmbeddedResolver
->resolveEmbeddedObjectURL( u
"Obj12345678"_ustr
);
1425 void SvXMLImport::AddStyleDisplayName( XmlStyleFamily nFamily
,
1426 const OUString
& rName
,
1427 const OUString
& rDisplayName
)
1429 if( !mpStyleMap
.is() )
1431 mpStyleMap
= new StyleMap
;
1432 if( mxImportInfo
.is() )
1434 OUString
sPrivateData( u
"PrivateData"_ustr
);
1435 Reference
< beans::XPropertySetInfo
> xPropertySetInfo
=
1436 mxImportInfo
->getPropertySetInfo();
1437 if( xPropertySetInfo
.is() &&
1438 xPropertySetInfo
->hasPropertyByName(sPrivateData
) )
1440 Reference
< XInterface
> xIfc(
1441 static_cast< css::lang::XTypeProvider
*>( mpStyleMap
.get() ) );
1442 mxImportInfo
->setPropertyValue( sPrivateData
, Any(xIfc
) );
1447 StyleMap::key_type
aKey( nFamily
, rName
);
1448 StyleMap::value_type
aValue( aKey
, rDisplayName
);
1449 ::std::pair
<StyleMap::iterator
,bool> aRes( mpStyleMap
->insert( aValue
) );
1450 SAL_WARN_IF( !aRes
.second
,
1452 "duplicate style name of family " << static_cast<int>(nFamily
) << ": \"" << rName
<< "\"");
1456 OUString
SvXMLImport::GetStyleDisplayName( XmlStyleFamily nFamily
,
1457 const OUString
& rName
) const
1459 OUString
sName( rName
);
1460 if( mpStyleMap
.is() && !rName
.isEmpty() )
1462 StyleMap::key_type
aKey( nFamily
, rName
);
1463 StyleMap::const_iterator aIter
= mpStyleMap
->find( aKey
);
1464 if( aIter
!= mpStyleMap
->end() )
1465 sName
= (*aIter
).second
;
1470 void SvXMLImport::SetViewSettings(const css::uno::Sequence
<css::beans::PropertyValue
>&)
1474 void SvXMLImport::SetConfigurationSettings(const css::uno::Sequence
<css::beans::PropertyValue
>&)
1478 void SvXMLImport::SetDocumentSpecificSettings(const OUString
&, const uno::Sequence
<beans::PropertyValue
>&)
1482 ProgressBarHelper
* SvXMLImport::GetProgressBarHelper()
1484 if (!mpProgressBarHelper
)
1486 mpProgressBarHelper
= std::make_unique
<ProgressBarHelper
>(mxStatusIndicator
, false);
1488 if (mxImportInfo
.is())
1490 uno::Reference
< beans::XPropertySetInfo
> xPropertySetInfo
= mxImportInfo
->getPropertySetInfo();
1491 if (xPropertySetInfo
.is())
1493 OUString
sProgressRange(XML_PROGRESSRANGE
);
1494 OUString
sProgressMax(XML_PROGRESSMAX
);
1495 OUString
sProgressCurrent(XML_PROGRESSCURRENT
);
1496 OUString
sRepeat(XML_PROGRESSREPEAT
);
1497 if (xPropertySetInfo
->hasPropertyByName(sProgressMax
) &&
1498 xPropertySetInfo
->hasPropertyByName(sProgressCurrent
) &&
1499 xPropertySetInfo
->hasPropertyByName(sProgressRange
))
1502 sal_Int32
nProgressMax(0);
1503 sal_Int32
nProgressCurrent(0);
1504 sal_Int32
nProgressRange(0);
1505 aAny
= mxImportInfo
->getPropertyValue(sProgressRange
);
1506 if (aAny
>>= nProgressRange
)
1507 mpProgressBarHelper
->SetRange(nProgressRange
);
1508 aAny
= mxImportInfo
->getPropertyValue(sProgressMax
);
1509 if (aAny
>>= nProgressMax
)
1510 mpProgressBarHelper
->SetReference(nProgressMax
);
1511 aAny
= mxImportInfo
->getPropertyValue(sProgressCurrent
);
1512 if (aAny
>>= nProgressCurrent
)
1513 mpProgressBarHelper
->SetValue(nProgressCurrent
);
1515 if (xPropertySetInfo
->hasPropertyByName(sRepeat
))
1517 uno::Any aAny
= mxImportInfo
->getPropertyValue(sRepeat
);
1518 if (aAny
.getValueType() == cppu::UnoType
<bool>::get())
1519 mpProgressBarHelper
->SetRepeat(::cppu::any2bool(aAny
));
1521 SAL_WARN( "xmloff.core", "why is it no boolean?" );
1527 return mpProgressBarHelper
.get();
1530 void SvXMLImport::AddNumberStyle(sal_Int32 nKey
, const OUString
& rName
)
1532 if (!mxNumberStyles
.is())
1533 mxNumberStyles
.set( comphelper::NameContainer_createInstance( ::cppu::UnoType
<sal_Int32
>::get()) );
1534 if (mxNumberStyles
.is())
1538 mxNumberStyles
->insertByName(rName
, Any(nKey
));
1540 catch ( uno::Exception
& )
1542 DBG_UNHANDLED_EXCEPTION( "xmloff.core", "Numberformat could not be inserted");
1546 SAL_WARN( "xmloff.core", "not possible to create NameContainer");
1550 XMLEventImportHelper
& SvXMLImport::GetEventImport()
1552 if (!mpEventImportHelper
)
1554 // construct event helper and register StarBasic handler and standard
1556 mpEventImportHelper
= std::make_unique
<XMLEventImportHelper
>();
1557 const OUString
& sStarBasic(GetXMLToken(XML_STARBASIC
));
1558 mpEventImportHelper
->RegisterFactory(sStarBasic
,
1559 std::make_unique
<XMLStarBasicContextFactory
>());
1560 const OUString
& sScript(GetXMLToken(XML_SCRIPT
));
1561 mpEventImportHelper
->RegisterFactory(sScript
,
1562 std::make_unique
<XMLScriptContextFactory
>());
1563 mpEventImportHelper
->AddTranslationTable(aStandardEventTable
);
1565 // register StarBasic event handler with capitalized spelling
1566 mpEventImportHelper
->RegisterFactory(u
"StarBasic"_ustr
,
1567 std::make_unique
<XMLStarBasicContextFactory
>());
1570 return *mpEventImportHelper
;
1573 void SvXMLImport::SetFontDecls( XMLFontStylesContext
*pFontDecls
)
1575 if (mxFontDecls
.is())
1576 mxFontDecls
->dispose();
1577 mxFontDecls
= pFontDecls
;
1580 void SvXMLImport::SetStyles( SvXMLStylesContext
*pStyles
)
1583 mxStyles
->dispose();
1587 void SvXMLImport::SetAutoStyles( SvXMLStylesContext
*pAutoStyles
)
1589 if (pAutoStyles
&& mxNumberStyles
.is())
1591 uno::Reference
<xml::sax::XFastAttributeList
> xAttrList
= new sax_fastparser::FastAttributeList(nullptr);
1592 const uno::Sequence
<OUString
> aStyleNames
= mxNumberStyles
->getElementNames();
1593 for (const auto& name
: aStyleNames
)
1595 uno::Any
aAny(mxNumberStyles
->getByName(name
));
1599 SvXMLStyleContext
* pContext
= new SvXMLNumFormatContext(
1600 *this, name
, xAttrList
, nKey
,
1601 GetDataStylesImport()->GetLanguageForKey(nKey
), *pAutoStyles
);
1602 pAutoStyles
->AddStyle(*pContext
);
1606 if (mxAutoStyles
.is())
1607 mxAutoStyles
->dispose();
1608 mxAutoStyles
= pAutoStyles
;
1609 GetTextImport()->SetAutoStyles( pAutoStyles
);
1610 GetShapeImport()->SetAutoStylesContext( pAutoStyles
);
1611 #if !ENABLE_WASM_STRIP_CHART
1612 GetChartImport()->SetAutoStylesContext( pAutoStyles
);
1614 GetFormImport()->setAutoStyleContext( pAutoStyles
);
1617 void SvXMLImport::SetMasterStyles( SvXMLStylesContext
*pMasterStyles
)
1619 if (mxMasterStyles
.is())
1620 mxMasterStyles
->dispose();
1621 mxMasterStyles
= pMasterStyles
;
1624 XMLFontStylesContext
*SvXMLImport::GetFontDecls()
1626 return mxFontDecls
.get();
1629 SvXMLStylesContext
*SvXMLImport::GetStyles()
1631 return mxStyles
.get();
1634 SvXMLStylesContext
*SvXMLImport::GetAutoStyles()
1636 return mxAutoStyles
.get();
1639 const XMLFontStylesContext
*SvXMLImport::GetFontDecls() const
1641 return mxFontDecls
.get();
1644 const SvXMLStylesContext
*SvXMLImport::GetStyles() const
1646 return mxStyles
.get();
1649 const SvXMLStylesContext
*SvXMLImport::GetAutoStyles() const
1651 return mxAutoStyles
.get();
1654 OUString
SvXMLImport::GetAbsoluteReference(const OUString
& rValue
) const
1656 if( rValue
.isEmpty() || rValue
[0] == '#' )
1659 INetURLObject aAbsURL
;
1660 if( mpImpl
->aBaseURL
.GetNewAbsURL( rValue
, &aAbsURL
) )
1661 return aAbsURL
.GetMainURL( INetURLObject::DecodeMechanism::ToIUri
);
1666 bool SvXMLImport::IsODFVersionConsistent( const OUString
& aODFVersion
)
1668 // the check returns false only if the storage version could be retrieved
1669 bool bResult
= true;
1671 if ( !aODFVersion
.isEmpty() && aODFVersion
.compareTo( ODFVER_012_TEXT
) >= 0 )
1673 // check the consistency only for the ODF1.2 and later ( according to content.xml )
1674 // manifest.xml might have no version, it should be checked here and the correct version should be set
1676 { // don't use getDocumentStorage(), it's temporary and latest version
1677 uno::Reference
<embed::XStorage
> const xStor(GetSourceStorage());
1680 uno::Reference
< beans::XPropertySet
> xStorProps( xStor
, uno::UNO_QUERY_THROW
);
1682 // the check should be done only for OASIS format
1685 bool bRepairPackage
= false;
1688 xStorProps
->getPropertyValue( u
"RepairPackage"_ustr
)
1690 } catch ( uno::Exception
& )
1693 // check only if not in Repair mode
1694 if ( !bRepairPackage
)
1696 OUString aStorVersion
;
1697 xStorProps
->getPropertyValue( u
"Version"_ustr
)
1700 // if the storage version is set in manifest.xml, it must be the same as in content.xml
1701 // if not, set it explicitly to be used further ( it will work even for readonly storage )
1702 // This workaround is not nice, but I see no other way to handle it, since there are
1703 // ODF1.2 documents without version in manifest.xml
1704 if ( !aStorVersion
.isEmpty() )
1705 bResult
= aODFVersion
== aStorVersion
;
1707 xStorProps
->setPropertyValue( u
"Version"_ustr
,
1708 uno::Any( aODFVersion
) );
1712 bool bInconsistent
= false;
1713 xStorProps
->getPropertyValue( u
"IsInconsistent"_ustr
)
1715 bResult
= !bInconsistent
;
1720 catch( uno::Exception
& )
1727 void SvXMLImport::CreateNumberFormatsSupplier_()
1729 SAL_WARN_IF( mxNumberFormatsSupplier
.is(), "xmloff.core", "number formats supplier already exists!" );
1731 mxNumberFormatsSupplier
=
1732 uno::Reference
< util::XNumberFormatsSupplier
> (mxModel
, uno::UNO_QUERY
);
1735 void SvXMLImport::CreateDataStylesImport_()
1737 SAL_WARN_IF( bool(mpNumImport
), "xmloff.core", "data styles import already exists!" );
1738 uno::Reference
<util::XNumberFormatsSupplier
> xNum
=
1739 GetNumberFormatsSupplier();
1741 mpNumImport
= std::make_unique
<SvXMLNumFmtHelper
>(xNum
, GetComponentContext() );
1744 sal_Unicode
SvXMLImport::ConvStarBatsCharToStarSymbol( sal_Unicode c
)
1746 sal_Unicode cNew
= c
;
1747 if( !mpImpl
->hBatsFontConv
)
1749 mpImpl
->hBatsFontConv
= CreateFontToSubsFontConverter( u
"StarBats",
1750 FontToSubsFontFlags::IMPORT
);
1751 SAL_WARN_IF( !mpImpl
->hBatsFontConv
, "xmloff.core", "Got no symbol font converter" );
1753 if( mpImpl
->hBatsFontConv
)
1755 cNew
= ConvertFontToSubsFontChar( mpImpl
->hBatsFontConv
, c
);
1761 sal_Unicode
SvXMLImport::ConvStarMathCharToStarSymbol( sal_Unicode c
)
1763 sal_Unicode cNew
= c
;
1764 if( !mpImpl
->hMathFontConv
)
1766 mpImpl
->hMathFontConv
= CreateFontToSubsFontConverter( u
"StarMath",
1767 FontToSubsFontFlags::IMPORT
);
1768 SAL_WARN_IF( !mpImpl
->hMathFontConv
, "xmloff.core", "Got no symbol font converter" );
1770 if( mpImpl
->hMathFontConv
)
1772 cNew
= ConvertFontToSubsFontChar( mpImpl
->hMathFontConv
, c
);
1778 void SvXMLImport::SetError(
1780 const Sequence
<OUString
>& rMsgParams
,
1781 const OUString
& rExceptionMessage
,
1782 const Reference
<xml::sax::XLocator
>& rLocator
)
1784 // create error list on demand
1786 mpXMLErrors
= std::make_unique
<XMLErrors
>();
1788 // save error information
1789 // use document locator (if none supplied)
1790 mpXMLErrors
->AddRecord( nId
, rMsgParams
, rExceptionMessage
,
1791 rLocator
.is() ? rLocator
: mxLocator
);
1794 void SvXMLImport::SetError(
1796 const Sequence
<OUString
>& rMsgParams
)
1798 SetError( nId
, rMsgParams
, u
""_ustr
, nullptr );
1801 void SvXMLImport::SetError(
1803 const OUString
& rMsg1
)
1805 Sequence
<OUString
> aSeq
{ rMsg1
};
1806 SetError( nId
, aSeq
);
1809 void SvXMLImport::DisposingModel()
1811 if( mxFontDecls
.is() )
1812 mxFontDecls
->dispose();
1814 mxStyles
->dispose();
1815 if( mxAutoStyles
.is() )
1816 mxAutoStyles
->dispose();
1817 if( mxMasterStyles
.is() )
1818 mxMasterStyles
->dispose();
1821 mxEventListener
.clear();
1824 ::comphelper::UnoInterfaceToUniqueIdentifierMapper
& SvXMLImport::getInterfaceToIdentifierMapper()
1826 return mpImpl
->maInterfaceToIdentifierMapper
;
1829 uno::Reference
< uno::XComponentContext
> const &
1830 SvXMLImport::GetComponentContext() const
1832 return mpImpl
->mxComponentContext
;
1835 OUString
SvXMLImport::GetBaseURL() const
1837 return mpImpl
->aBaseURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
1840 OUString
SvXMLImport::GetDocumentBase() const
1842 return mpImpl
->aDocBase
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
1845 // Convert drawing object positions from OOo file format to OASIS (#i28749#)
1846 bool SvXMLImport::IsShapePositionInHoriL2R() const
1848 return mpImpl
->mbShapePositionInHoriL2R
;
1851 bool SvXMLImport::IsTextDocInOOoFileFormat() const
1853 return mpImpl
->mbTextDocInOOoFileFormat
;
1856 void SvXMLImport::initXForms()
1858 // dummy method; to be implemented by derived classes supporting XForms
1861 bool SvXMLImport::getBuildIds( sal_Int32
& rUPD
, sal_Int32
& rBuild
) const
1864 OUString
const aBuildId(getBuildIdsProperty(mxImportInfo
));
1865 if (!aBuildId
.isEmpty())
1867 sal_Int32 nIndex
= aBuildId
.indexOf('$');
1870 rUPD
= o3tl::toInt32(aBuildId
.subView( 0, nIndex
));
1871 sal_Int32 nIndexEnd
= aBuildId
.indexOf(';', nIndex
);
1872 rBuild
= (nIndexEnd
== -1)
1873 ? o3tl::toInt32(aBuildId
.subView(nIndex
+ 1))
1874 : o3tl::toInt32(aBuildId
.subView(nIndex
+ 1, nIndexEnd
- nIndex
- 1));
1881 sal_uInt16
SvXMLImport::getGeneratorVersion() const
1884 return mpImpl
->getGeneratorVersion( *this );
1888 bool SvXMLImport::isGeneratorVersionOlderThan(
1889 sal_uInt16
const nOOoVersion
, sal_uInt16
const nLOVersion
)
1891 assert( (nLOVersion
& LO_flag
));
1892 assert(!(nOOoVersion
& LO_flag
));
1893 const sal_uInt16
nGeneratorVersion(getGeneratorVersion());
1894 return (nGeneratorVersion
& LO_flag
)
1895 ? nGeneratorVersion
< nLOVersion
1896 : nGeneratorVersion
< nOOoVersion
;
1900 OUString
SvXMLImport::GetODFVersion() const
1902 return mpImpl
->mxODFVersion
? *mpImpl
->mxODFVersion
: OUString();
1905 bool SvXMLImport::IsOOoXML() const
1907 return mpImpl
->mbIsOOoXML
;
1910 bool SvXMLImport::IsMSO() const
1912 if (!mpImpl
->mbIsMSO
.has_value())
1914 uno::Reference
<document::XDocumentPropertiesSupplier
> xSupplier(GetModel(), uno::UNO_QUERY
);
1917 uno::Reference
<document::XDocumentProperties
> xProps
1918 = xSupplier
->getDocumentProperties();
1921 mpImpl
->mbIsMSO
= xProps
->getGenerator().startsWith("MicrosoftOffice");
1926 return mpImpl
->mbIsMSO
.has_value() ? *mpImpl
->mbIsMSO
: false;
1929 // xml:id for RDF metadata
1930 void SvXMLImport::SetXmlId(uno::Reference
<uno::XInterface
> const & i_xIfc
,
1931 OUString
const & i_rXmlId
)
1933 if (i_rXmlId
.isEmpty())
1937 const uno::Reference
<rdf::XMetadatable
> xMeta(i_xIfc
,
1941 const beans::StringPair
mdref( mpImpl
->mStreamName
, i_rXmlId
);
1943 xMeta
->setMetadataReference(mdref
);
1944 } catch (lang::IllegalArgumentException
&) {
1945 // probably duplicate; ignore
1946 SAL_INFO("xmloff.core", "SvXMLImport::SetXmlId: cannot set xml:id");
1949 } catch (uno::Exception
&) {
1950 TOOLS_WARN_EXCEPTION("xmloff.core","SvXMLImport::SetXmlId");
1954 ::xmloff::RDFaImportHelper
&
1955 SvXMLImport::GetRDFaImportHelper()
1957 if (!mpImpl
->mpRDFaHelper
)
1959 mpImpl
->mpRDFaHelper
.reset( new ::xmloff::RDFaImportHelper(*this) );
1961 return *mpImpl
->mpRDFaHelper
;
1965 SvXMLImport::AddRDFa(const uno::Reference
<rdf::XMetadatable
>& i_xObject
,
1966 OUString
const & i_rAbout
,
1967 OUString
const & i_rProperty
,
1968 OUString
const & i_rContent
,
1969 OUString
const & i_rDatatype
)
1971 // N.B.: we only get called if i_xObject had xhtml:about attribute
1972 // (an empty attribute value is valid)
1973 ::xmloff::RDFaImportHelper
& rRDFaHelper( GetRDFaImportHelper() );
1974 rRDFaHelper
.ParseAndAddRDFa(i_xObject
,
1975 i_rAbout
, i_rProperty
, i_rContent
, i_rDatatype
);
1978 bool SvXMLImport::embeddedFontAlreadyProcessed( const OUString
& url
)
1980 if( m_embeddedFontUrlsKnown
.count( url
) != 0 )
1982 m_embeddedFontUrlsKnown
.insert( url
);
1986 const OUString
& SvXMLImport::getNameFromToken( sal_Int32 nToken
)
1988 return FastTokenHandler::getIdentifier( nToken
& TOKEN_MASK
);
1991 OUString
SvXMLImport::getPrefixAndNameFromToken( sal_Int32 nToken
)
1994 sal_Int32 nNamespaceToken
= ( nToken
& NMSP_MASK
) >> NMSP_SHIFT
;
1995 auto aIter( aNamespaceMap
.find( nNamespaceToken
) );
1996 if( aIter
!= aNamespaceMap
.end() )
1997 rv
= (*aIter
).second
.second
+ " " + aIter
->second
.first
+ ":";
1998 return rv
+ FastTokenHandler::getIdentifier(nToken
& TOKEN_MASK
);
2001 OUString
SvXMLImport::getNamespacePrefixFromToken(sal_Int32 nToken
, const SvXMLNamespaceMap
* pMap
)
2003 sal_Int32 nNamespaceToken
= ( nToken
& NMSP_MASK
) >> NMSP_SHIFT
;
2004 auto aIter( aNamespaceMap
.find( nNamespaceToken
) );
2005 if( aIter
!= aNamespaceMap
.end() )
2009 OUString sRet
= pMap
->GetPrefixByKey(pMap
->GetKeyByName((*aIter
).second
.second
));
2010 if (!sRet
.isEmpty())
2013 return (*aIter
).second
.first
;
2019 const OUString
& SvXMLImport::getNamespaceURIFromToken( sal_Int32 nToken
)
2021 sal_Int32 nNamespaceToken
= ( nToken
& NMSP_MASK
) >> NMSP_SHIFT
;
2022 auto aIter( aNamespaceMap
.find( nNamespaceToken
) );
2023 if( aIter
!= aNamespaceMap
.end() )
2024 return (*aIter
).second
.second
;
2026 return EMPTY_OUSTRING
;
2029 const OUString
& SvXMLImport::getNamespacePrefixFromURI( const OUString
& rURI
)
2031 auto aIter( aNamespaceURIPrefixMap
.find(rURI
) );
2032 if( aIter
!= aNamespaceURIPrefixMap
.end() )
2033 return (*aIter
).second
;
2035 return EMPTY_OUSTRING
;
2038 sal_Int32
SvXMLImport::getTokenFromName( std::u16string_view rName
)
2040 Sequence
< sal_Int8
> aLocalNameSeq( reinterpret_cast<sal_Int8
const *>(
2041 OUStringToOString( rName
, RTL_TEXTENCODING_UTF8
).getStr()), rName
.size() );
2042 return xTokenHandler
->getTokenFromUTF8( aLocalNameSeq
);
2045 void SvXMLImport::initializeNamespaceMaps()
2047 auto mapTokenToNamespace
= []( sal_Int32 nToken
, sal_Int32 nPrefix
, sal_Int32 nNamespace
)
2051 const OUString
& sNamespace
= GetXMLToken( static_cast<XMLTokenEnum
>( nNamespace
) );
2052 const OUString
& sPrefix
= GetXMLToken( static_cast<XMLTokenEnum
>( nPrefix
) );
2053 assert( aNamespaceMap
.find(nToken
+1) == aNamespaceMap
.end() && "cannot map two namespaces to the same token here");
2054 aNamespaceMap
[ nToken
+ 1 ] = std::make_pair( sPrefix
, sNamespace
);
2055 aNamespaceURIPrefixMap
.emplace( sNamespace
, sPrefix
);
2059 mapTokenToNamespace( XML_NAMESPACE_XML
, XML_XML
, XML_N_XML
); // implicit "xml" namespace prefix
2060 mapTokenToNamespace( XML_NAMESPACE_OFFICE
, XML_NP_OFFICE
, XML_N_OFFICE
);
2061 mapTokenToNamespace( XML_NAMESPACE_OFFICE_SO52
, XML_NP_OFFICE
, XML_N_OFFICE_OLD
);
2062 mapTokenToNamespace( XML_NAMESPACE_OFFICE_OOO
, XML_NP_OFFICE
, XML_N_OFFICE_OOO
);
2063 mapTokenToNamespace( XML_NAMESPACE_STYLE
, XML_NP_STYLE
, XML_N_STYLE
);
2064 mapTokenToNamespace( XML_NAMESPACE_STYLE_SO52
, XML_NP_STYLE
, XML_N_STYLE_OLD
);
2065 mapTokenToNamespace( XML_NAMESPACE_STYLE_OOO
, XML_NP_STYLE
, XML_N_STYLE_OOO
);
2066 mapTokenToNamespace( XML_NAMESPACE_TEXT
, XML_NP_TEXT
, XML_N_TEXT
);
2067 mapTokenToNamespace( XML_NAMESPACE_TEXT_SO52
, XML_NP_TEXT
, XML_N_TEXT_OLD
);
2068 mapTokenToNamespace( XML_NAMESPACE_TEXT_OOO
, XML_NP_TEXT
, XML_N_TEXT_OOO
);
2069 mapTokenToNamespace( XML_NAMESPACE_TABLE
, XML_NP_TABLE
, XML_N_TABLE
);
2070 mapTokenToNamespace( XML_NAMESPACE_TABLE_SO52
, XML_NP_TABLE
, XML_N_TABLE_OLD
);
2071 mapTokenToNamespace( XML_NAMESPACE_TABLE_OOO
, XML_NP_TABLE
, XML_N_TABLE_OOO
);
2072 mapTokenToNamespace( XML_NAMESPACE_DRAW
, XML_NP_DRAW
, XML_N_DRAW
);
2073 mapTokenToNamespace( XML_NAMESPACE_DRAW_SO52
, XML_NP_DRAW
, XML_N_DRAW_OLD
);
2074 mapTokenToNamespace( XML_NAMESPACE_DRAW_OOO
, XML_NP_DRAW
, XML_N_DRAW_OOO
);
2075 mapTokenToNamespace( XML_NAMESPACE_FO
, XML_NP_FO
, XML_N_FO
);
2076 mapTokenToNamespace( XML_NAMESPACE_FO_SO52
, XML_NP_FO
, XML_N_FO_OLD
);
2077 mapTokenToNamespace( XML_NAMESPACE_FO_COMPAT
, XML_NP_FO
, XML_N_FO_COMPAT
);
2078 mapTokenToNamespace( XML_NAMESPACE_XLINK
, XML_NP_XLINK
, XML_N_XLINK
);
2079 mapTokenToNamespace( XML_NAMESPACE_XLINK_SO52
, XML_NP_XLINK
, XML_N_XLINK_OLD
);
2080 mapTokenToNamespace( XML_NAMESPACE_DC
, XML_NP_DC
, XML_N_DC
);
2081 mapTokenToNamespace( XML_NAMESPACE_META
, XML_NP_META
, XML_N_META
);
2082 mapTokenToNamespace( XML_NAMESPACE_META_SO52
, XML_NP_META
, XML_N_META_OLD
);
2083 mapTokenToNamespace( XML_NAMESPACE_META_OOO
, XML_NP_META
, XML_N_META_OOO
);
2084 mapTokenToNamespace( XML_NAMESPACE_NUMBER
, XML_NP_NUMBER
, XML_N_NUMBER
);
2085 mapTokenToNamespace( XML_NAMESPACE_NUMBER_SO52
, XML_NP_NUMBER
, XML_N_NUMBER_OLD
);
2086 mapTokenToNamespace( XML_NAMESPACE_NUMBER_OOO
, XML_NP_NUMBER
, XML_N_NUMBER_OOO
);
2087 mapTokenToNamespace( XML_NAMESPACE_PRESENTATION
, XML_NP_PRESENTATION
, XML_N_PRESENTATION
);
2088 mapTokenToNamespace( XML_NAMESPACE_PRESENTATION_SO52
,XML_NP_PRESENTATION
, XML_N_PRESENTATION_OLD
);
2089 mapTokenToNamespace( XML_NAMESPACE_PRESENTATION_OOO
, XML_NP_PRESENTATION
, XML_N_PRESENTATION_OOO
);
2090 mapTokenToNamespace( XML_NAMESPACE_PRESENTATION_OASIS
, XML_NP_PRESENTATION
, XML_N_PRESENTATION_OASIS
);
2091 mapTokenToNamespace( XML_NAMESPACE_SVG
, XML_NP_SVG
, XML_N_SVG
);
2092 mapTokenToNamespace( XML_NAMESPACE_SVG_COMPAT
, XML_NP_SVG
, XML_N_SVG_COMPAT
);
2093 mapTokenToNamespace( XML_NAMESPACE_CHART
, XML_NP_CHART
, XML_N_CHART
);
2094 mapTokenToNamespace( XML_NAMESPACE_CHART_SO52
, XML_NP_CHART
, XML_N_CHART_OLD
);
2095 mapTokenToNamespace( XML_NAMESPACE_CHART_OOO
, XML_NP_CHART
, XML_N_CHART_OOO
);
2096 mapTokenToNamespace( XML_NAMESPACE_DR3D
, XML_NP_DR3D
, XML_N_DR3D
);
2097 mapTokenToNamespace( XML_NAMESPACE_DR3D_OOO
, XML_NP_DR3D
, XML_N_DR3D_OOO
);
2098 mapTokenToNamespace( XML_NAMESPACE_MATH
, XML_NP_MATH
, XML_N_MATH
);
2099 mapTokenToNamespace( XML_NAMESPACE_VERSIONS_LIST
, XML_NP_VERSIONS_LIST
, XML_N_VERSIONS_LIST
);
2100 mapTokenToNamespace( XML_NAMESPACE_FORM
, XML_NP_FORM
, XML_N_FORM
);
2101 mapTokenToNamespace( XML_NAMESPACE_FORM_OOO
, XML_NP_FORM
, XML_N_FORM_OOO
);
2102 mapTokenToNamespace( XML_NAMESPACE_SCRIPT
, XML_NP_SCRIPT
, XML_N_SCRIPT
);
2103 mapTokenToNamespace( XML_NAMESPACE_SCRIPT_OOO
, XML_NP_SCRIPT
, XML_N_SCRIPT_OOO
);
2104 mapTokenToNamespace( XML_NAMESPACE_BLOCKLIST
, XML_NP_BLOCK_LIST
, XML_N_BLOCK_LIST
);
2105 mapTokenToNamespace( XML_NAMESPACE_CONFIG
, XML_NP_CONFIG
, XML_N_CONFIG
);
2106 mapTokenToNamespace( XML_NAMESPACE_CONFIG_OOO
, XML_NP_CONFIG
, XML_N_CONFIG_OOO
);
2107 mapTokenToNamespace( XML_NAMESPACE_OOO
, XML_NP_OOO
, XML_N_OOO
);
2108 mapTokenToNamespace( XML_NAMESPACE_OOOW
, XML_NP_OOOW
, XML_N_OOOW
);
2109 mapTokenToNamespace( XML_NAMESPACE_OOOC
, XML_NP_OOOC
, XML_N_OOOC
);
2110 mapTokenToNamespace( XML_NAMESPACE_DOM
, XML_NP_DOM
, XML_N_DOM
);
2111 mapTokenToNamespace( XML_NAMESPACE_DB
, XML_NP_DB
, XML_N_DB
);
2112 mapTokenToNamespace( XML_NAMESPACE_DB_OASIS
, XML_NP_DB
, XML_N_DB_OASIS
);
2113 mapTokenToNamespace( XML_NAMESPACE_DLG
, XML_NP_DLG
, XML_N_DLG
);
2114 mapTokenToNamespace( XML_NAMESPACE_XFORMS
, XML_NP_XFORMS_1_0
, XML_N_XFORMS_1_0
);
2115 mapTokenToNamespace( XML_NAMESPACE_XSD
, XML_NP_XSD
, XML_N_XSD
);
2116 mapTokenToNamespace( XML_NAMESPACE_XSI
, XML_NP_XSI
, XML_N_XSI
);
2117 mapTokenToNamespace( XML_NAMESPACE_SMIL
, XML_NP_SMIL
, XML_N_SMIL
);
2118 mapTokenToNamespace( XML_NAMESPACE_SMIL_SO52
, XML_NP_SMIL
, XML_N_SMIL_OLD
);
2119 mapTokenToNamespace( XML_NAMESPACE_SMIL_COMPAT
, XML_NP_SMIL
, XML_N_SMIL_COMPAT
);
2120 mapTokenToNamespace( XML_NAMESPACE_ANIMATION
, XML_NP_ANIMATION
, XML_N_ANIMATION
);
2121 mapTokenToNamespace( XML_NAMESPACE_ANIMATION_OOO
, XML_NP_ANIMATION
, XML_N_ANIMATION_OOO
);
2122 mapTokenToNamespace( XML_NAMESPACE_REPORT
, XML_NP_RPT
, XML_N_RPT
);
2123 mapTokenToNamespace( XML_NAMESPACE_REPORT_OASIS
, XML_NP_RPT
, XML_N_RPT_OASIS
);
2124 mapTokenToNamespace( XML_NAMESPACE_OF
, XML_NP_OF
, XML_N_OF
);
2125 mapTokenToNamespace( XML_NAMESPACE_XHTML
, XML_NP_XHTML
, XML_N_XHTML
);
2126 mapTokenToNamespace( XML_NAMESPACE_GRDDL
, XML_NP_GRDDL
, XML_N_GRDDL
);
2127 mapTokenToNamespace( XML_NAMESPACE_OFFICE_EXT
, XML_NP_OFFICE_EXT
, XML_N_OFFICE_EXT
);
2128 mapTokenToNamespace( XML_NAMESPACE_TABLE_EXT
, XML_NP_TABLE_EXT
, XML_N_TABLE_EXT
);
2129 mapTokenToNamespace( XML_NAMESPACE_CHART_EXT
, XML_NP_CHART_EXT
, XML_N_CHART_EXT
);
2130 mapTokenToNamespace( XML_NAMESPACE_DRAW_EXT
, XML_NP_DRAW_EXT
, XML_N_DRAW_EXT
);
2131 mapTokenToNamespace( XML_NAMESPACE_CALC_EXT
, XML_NP_CALC_EXT
, XML_N_CALC_EXT
);
2132 mapTokenToNamespace( XML_NAMESPACE_LO_EXT
, XML_NP_LO_EXT
, XML_N_LO_EXT
);
2133 mapTokenToNamespace( XML_NAMESPACE_CSS3TEXT
, XML_NP_CSS3TEXT
, XML_N_CSS3TEXT
);
2134 mapTokenToNamespace( XML_NAMESPACE_FIELD
, XML_NP_FIELD
, XML_N_FIELD
);
2135 mapTokenToNamespace( XML_NAMESPACE_FORMX
, XML_NP_FORMX
, XML_N_FORMX
);
2138 void SvXMLImport::registerNamespaces()
2140 for( auto const &aNamespaceEntry
: aNamespaceMap
)
2142 // aNamespaceMap = { Token : ( NamespacePrefix, NamespaceURI ) }
2143 registerNamespace( aNamespaceEntry
.second
.second
, aNamespaceEntry
.first
<< NMSP_SHIFT
);
2147 void SvXMLImport::NotifyMacroEventRead()
2149 if (mbNotifyMacroEventRead
)
2152 comphelper::DocumentInfo::notifyMacroEventRead(mxModel
);
2154 mbNotifyMacroEventRead
= true;
2157 SvXMLImportFastNamespaceHandler::SvXMLImportFastNamespaceHandler()
2161 void SvXMLImportFastNamespaceHandler::addNSDeclAttributes( rtl::Reference
< comphelper::AttributeList
> const & rAttrList
)
2163 for(const auto& aNamespaceDefine
: m_aNamespaceDefines
)
2165 const OUString
& rPrefix
= aNamespaceDefine
.m_aPrefix
;
2166 const OUString
& rNamespaceURI
= aNamespaceDefine
.m_aNamespaceURI
;
2168 if ( rPrefix
.isEmpty() )
2171 sDecl
= "xmlns:" + rPrefix
;
2172 rAttrList
->AddAttribute( sDecl
, rNamespaceURI
);
2174 m_aNamespaceDefines
.clear();
2177 void SvXMLImportFastNamespaceHandler::registerNamespace( const OUString
& rNamespacePrefix
, const OUString
& rNamespaceURI
)
2179 // Elements with default namespace parsed by FastParser have namespace prefix.
2180 // A default namespace needs to be registered with the prefix, to maintain the compatibility.
2181 if ( rNamespacePrefix
.isEmpty() )
2182 m_aNamespaceDefines
.push_back( NamespaceDefine(
2183 SvXMLImport::getNamespacePrefixFromURI( rNamespaceURI
), rNamespaceURI
) );
2185 m_aNamespaceDefines
.push_back( NamespaceDefine(
2186 rNamespacePrefix
, rNamespaceURI
) );
2189 OUString
SvXMLImportFastNamespaceHandler::getNamespaceURI( const OUString
&/* rNamespacePrefix */ )
2194 SvXMLLegacyToFastDocHandler::SvXMLLegacyToFastDocHandler( rtl::Reference
< SvXMLImport
> xImport
)
2195 : mrImport(std::move( xImport
)),
2196 mxFastAttributes( new sax_fastparser::FastAttributeList( SvXMLImport::xTokenHandler
.get() ) )
2200 void SAL_CALL
SvXMLLegacyToFastDocHandler::setTargetDocument( const uno::Reference
< lang::XComponent
>& xDoc
)
2202 mrImport
->setTargetDocument( xDoc
);
2205 void SAL_CALL
SvXMLLegacyToFastDocHandler::startDocument()
2207 mrImport
->startDocument();
2210 void SAL_CALL
SvXMLLegacyToFastDocHandler::endDocument()
2212 mrImport
->endDocument();
2215 void SAL_CALL
SvXMLLegacyToFastDocHandler::startElement( const OUString
& rName
,
2216 const uno::Reference
< xml::sax::XAttributeList
>& xAttrList
)
2218 sal_uInt16 nDefaultNamespace
= XML_NAMESPACE_UNKNOWN
;
2219 if (!maDefaultNamespaces
.empty())
2220 nDefaultNamespace
= maDefaultNamespaces
.top();
2221 SvXMLImport::processNSAttributes(mrImport
->mxNamespaceMap
, mrImport
.get(), xAttrList
);
2222 OUString aLocalName
;
2223 sal_uInt16 nPrefix
= mrImport
->mxNamespaceMap
->GetKeyByAttrName( rName
, &aLocalName
);
2224 sal_Int32 mnElement
= NAMESPACE_TOKEN( nPrefix
) | SvXMLImport::getTokenFromName( aLocalName
);
2225 mxFastAttributes
->clear();
2227 sal_Int16 nAttrCount
= xAttrList
.is() ? xAttrList
->getLength() : 0;
2228 for( sal_Int16 i
=0; i
< nAttrCount
; i
++ )
2230 const OUString aAttrName
= xAttrList
->getNameByIndex( i
);
2231 const OUString aAttrValue
= xAttrList
->getValueByIndex( i
);
2232 if (aAttrName
== "xmlns")
2234 sal_uInt16 nNamespaceKey
= mrImport
->mxNamespaceMap
->GetKeyByName(aAttrValue
);
2235 if (nNamespaceKey
!= XML_NAMESPACE_UNKNOWN
)
2237 nDefaultNamespace
= nNamespaceKey
;
2240 assert(false && "unknown namespace");
2242 else if (aAttrName
.indexOf(":") == -1 && nDefaultNamespace
!= XML_NAMESPACE_UNKNOWN
)
2244 auto const nToken
= SvXMLImport::getTokenFromName(aAttrName
);
2245 if (nToken
== xmloff::XML_TOKEN_INVALID
)
2247 mxFastAttributes
->addUnknown(mrImport
->mxNamespaceMap
->GetNameByKey(nDefaultNamespace
),
2248 OUStringToOString(aAttrName
, RTL_TEXTENCODING_UTF8
),
2249 OUStringToOString(aAttrValue
, RTL_TEXTENCODING_UTF8
));
2253 sal_Int32
const nAttr
= NAMESPACE_TOKEN(nDefaultNamespace
) | nToken
;
2254 mxFastAttributes
->add(nAttr
, OUStringToOString(aAttrValue
, RTL_TEXTENCODING_UTF8
));
2259 OUString aLocalAttrName
;
2260 OUString aNamespace
;
2261 // don't add unknown namespaces to the map
2262 sal_uInt16
const nAttrPrefix
= mrImport
->mxNamespaceMap
->GetKeyByQName(
2263 aAttrName
, nullptr, &aLocalAttrName
, &aNamespace
, SvXMLNamespaceMap::QNameMode::AttrValue
);
2264 if( XML_NAMESPACE_XMLNS
== nAttrPrefix
)
2266 auto const nToken
= SvXMLImport::getTokenFromName(aLocalAttrName
);
2267 if (XML_NAMESPACE_UNKNOWN
== nAttrPrefix
|| nToken
== xmloff::XML_TOKEN_INVALID
)
2269 mxFastAttributes
->addUnknown(aNamespace
,
2270 OUStringToOString(aAttrName
, RTL_TEXTENCODING_UTF8
),
2271 OUStringToOString(aAttrValue
, RTL_TEXTENCODING_UTF8
));
2275 sal_Int32
const nAttr
= NAMESPACE_TOKEN(nAttrPrefix
) | nToken
;
2276 mxFastAttributes
->add(nAttr
, OUStringToOString(aAttrValue
, RTL_TEXTENCODING_UTF8
));
2279 mrImport
->startFastElement( mnElement
, mxFastAttributes
);
2280 maDefaultNamespaces
.push(nDefaultNamespace
);
2283 void SAL_CALL
SvXMLLegacyToFastDocHandler::endElement( const OUString
& rName
)
2285 OUString aLocalName
;
2286 sal_uInt16 nPrefix
= mrImport
->mxNamespaceMap
->GetKeyByAttrName( rName
, &aLocalName
);
2287 sal_Int32 mnElement
= NAMESPACE_TOKEN( nPrefix
) | SvXMLImport::getTokenFromName(aLocalName
);
2288 mrImport
->endFastElement( mnElement
);
2289 maDefaultNamespaces
.pop();
2292 void SAL_CALL
SvXMLLegacyToFastDocHandler::characters( const OUString
& aChars
)
2294 mrImport
->characters( aChars
);
2297 void SAL_CALL
SvXMLLegacyToFastDocHandler::ignorableWhitespace( const OUString
& )
2301 void SAL_CALL
SvXMLLegacyToFastDocHandler::processingInstruction( const OUString
& aTarget
,
2302 const OUString
& aData
)
2304 mrImport
->processingInstruction( aTarget
, aData
);
2307 void SAL_CALL
SvXMLLegacyToFastDocHandler::setDocumentLocator( const uno::Reference
< xml::sax::XLocator
>& rLocator
)
2309 mrImport
->setDocumentLocator( rLocator
);
2314 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */