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 <comphelper/servicehelper.hxx>
66 #include <comphelper/string.hxx>
67 #include <cppuhelper/implbase.hxx>
68 #include <cppuhelper/supportsservice.hxx>
69 #include <comphelper/extract.hxx>
70 #include <comphelper/documentconstants.hxx>
71 #include <comphelper/documentinfo.hxx>
72 #include <comphelper/storagehelper.hxx>
73 #include <comphelper/attributelist.hxx>
74 #include <unotools/fontcvt.hxx>
75 #include <fasttokenhandler.hxx>
76 #include <vcl/GraphicExternalLink.hxx>
77 #include <o3tl/string_view.hxx>
79 #include <com/sun/star/rdf/XMetadatable.hpp>
80 #include <com/sun/star/rdf/XRepositorySupplier.hpp>
81 #include <RDFaImportHelper.hxx>
83 using ::com::sun::star::beans::XPropertySetInfo
;
85 using namespace ::com::sun::star
;
86 using namespace ::com::sun::star::uno
;
87 using namespace ::com::sun::star::util
;
88 using namespace ::com::sun::star::io
;
89 using namespace ::com::sun::star::container
;
90 using namespace ::com::sun::star::document
;
91 using namespace ::xmloff::token
;
93 rtl::Reference
< FastTokenHandler
> SvXMLImport::xTokenHandler( new FastTokenHandler() );
94 std::unordered_map
< sal_Int32
, std::pair
< OUString
, OUString
> > SvXMLImport::aNamespaceMap
;
95 std::unordered_map
< OUString
, OUString
> SvXMLImport::aNamespaceURIPrefixMap
;
96 bool SvXMLImport::bIsNSMapsInitialized
= false;
100 class SvXMLImportEventListener
: public cppu::WeakImplHelper
< css::lang::XEventListener
>
103 SvXMLImport
* pImport
;
106 explicit SvXMLImportEventListener(SvXMLImport
* pImport
);
109 virtual void SAL_CALL
disposing(const lang::EventObject
& rEventObject
) override
;
114 SvXMLImportEventListener::SvXMLImportEventListener(SvXMLImport
* pTempImport
)
115 : pImport(pTempImport
)
120 void SAL_CALL
SvXMLImportEventListener::disposing( const lang::EventObject
& )
124 pImport
->DisposingModel();
133 getBuildIdsProperty(uno::Reference
<beans::XPropertySet
> const& xImportInfo
)
135 if (xImportInfo
.is())
139 Reference
< XPropertySetInfo
> const xSetInfo(
140 xImportInfo
->getPropertySetInfo());
141 if (xSetInfo
.is() && xSetInfo
->hasPropertyByName("BuildId"))
144 xImportInfo
->getPropertyValue("BuildId") >>= aBuildId
;
148 catch (Exception
const&)
150 DBG_UNHANDLED_EXCEPTION("xmloff.core", "exception getting BuildId");
159 sal_uInt16 mnGeneratorVersion
;
162 explicit DocumentInfo( const SvXMLImport
& rImport
)
163 : mnGeneratorVersion( SvXMLImport::ProductVersionUnknown
)
165 OUString
const buildIds(
166 getBuildIdsProperty(rImport
.getImportInfo()));
167 if (!buildIds
.isEmpty())
169 sal_Int32
const ix
= buildIds
.indexOf(';');
172 OUString
const loVersion(buildIds
.copy(ix
+ 1));
173 if (!loVersion
.isEmpty())
175 if ('3' == loVersion
[0])
177 mnGeneratorVersion
= SvXMLImport::LO_3x
;
179 else if ('4' == loVersion
[0])
181 if (loVersion
.getLength() > 1
182 && (loVersion
[1] == '0' || loVersion
[1] == '1'))
184 mnGeneratorVersion
= SvXMLImport::LO_41x
; // 4.0/4.1
186 else if (loVersion
.getLength() > 1 && '2' == loVersion
[1])
188 mnGeneratorVersion
= SvXMLImport::LO_42x
; // 4.2
190 else if (loVersion
.getLength() > 1 && '3' == loVersion
[1])
192 mnGeneratorVersion
= SvXMLImport::LO_43x
; // 4.3
194 else if (loVersion
.getLength() > 1 && '4' == loVersion
[1])
196 mnGeneratorVersion
= SvXMLImport::LO_44x
; // 4.4
199 else if ('5' == loVersion
[0])
201 mnGeneratorVersion
= SvXMLImport::LO_5x
;
203 else if ('6' == loVersion
[0])
205 if (loVersion
.getLength() > 1
206 && (loVersion
[1] == '0' || loVersion
[1] == '1'
207 || loVersion
[1] == '2'))
209 mnGeneratorVersion
= SvXMLImport::LO_6x
; // 6.0/6.1/6.2
213 mnGeneratorVersion
= SvXMLImport::LO_63x
; // 6.3/6.4
216 else if ('7' == loVersion
[0])
218 mnGeneratorVersion
= SvXMLImport::LO_7x
;
222 SAL_INFO("xmloff.core", "unknown LO version: " << loVersion
);
224 return; // ignore buildIds
228 sal_Int32 nUPD
, nBuild
;
229 if ( !rImport
.getBuildIds( nUPD
, nBuild
) )
232 if ( nUPD
>= 640 && nUPD
<= 645 )
234 mnGeneratorVersion
= SvXMLImport::OOo_1x
;
236 else if ( nUPD
== 680 )
238 mnGeneratorVersion
= SvXMLImport::OOo_2x
;
240 else if ( nUPD
== 300 && nBuild
<= 9379 )
242 mnGeneratorVersion
= SvXMLImport::OOo_30x
;
244 else if ( nUPD
== 310 )
246 mnGeneratorVersion
= SvXMLImport::OOo_31x
;
248 else if ( nUPD
== 320 )
250 mnGeneratorVersion
= SvXMLImport::OOo_32x
;
252 else if ( nUPD
== 330 )
254 mnGeneratorVersion
= SvXMLImport::OOo_33x
;
256 else if ( nUPD
== 340 )
258 mnGeneratorVersion
= SvXMLImport::OOo_34x
;
260 else if (nUPD
== 400 || nUPD
== 401)
262 mnGeneratorVersion
= SvXMLImport::AOO_40x
;
264 else if (nUPD
>= 410)
266 // effectively this means "latest", see use
267 // in XMLGraphicsDefaultStyle::SetDefaults()!
268 mnGeneratorVersion
= SvXMLImport::AOO_4x
;
272 sal_uInt16
getGeneratorVersion() const
274 return mnGeneratorVersion
;
280 class SvXMLImport_Impl
283 FontToSubsFontConverter hBatsFontConv
;
284 FontToSubsFontConverter hMathFontConv
;
286 bool mbOwnGraphicResolver
;
287 bool mbOwnEmbeddedResolver
;
288 INetURLObject aBaseURL
;
289 INetURLObject aDocBase
;
291 /// name of stream in package, e.g., "content.xml"
292 OUString mStreamName
;
294 std::optional
<OUString
> mxODFVersion
;
298 std::optional
<bool> mbIsMSO
;
300 // Boolean, indicating that position attributes
301 // of shapes are given in horizontal left-to-right layout. This is the case
302 // for the OpenOffice.org file format. (#i28749#)
303 bool mbShapePositionInHoriL2R
;
304 bool mbTextDocInOOoFileFormat
;
306 const uno::Reference
< uno::XComponentContext
> mxComponentContext
;
307 OUString implementationName
;
308 css::uno::Sequence
< OUString
> maSupportedServiceNames
;
310 uno::Reference
< embed::XStorage
> mxSourceStorage
;
312 std::unique_ptr
< xmloff::RDFaImportHelper
> mpRDFaHelper
;
314 std::unique_ptr
< DocumentInfo
> mpDocumentInfo
;
316 SvXMLImport_Impl( uno::Reference
< uno::XComponentContext
> xContext
,
317 OUString theImplementationName
,
318 const css::uno::Sequence
< OUString
> & sSupportedServiceNames
= {})
319 : hBatsFontConv( nullptr )
320 , hMathFontConv( nullptr )
321 , mbOwnGraphicResolver( false )
322 , mbOwnEmbeddedResolver( false )
324 // Convert drawing object positions from OOo file format to OASIS (#i28749#)
325 , mbShapePositionInHoriL2R( false )
326 , mbTextDocInOOoFileFormat( false )
327 , mxComponentContext(std::move( xContext
))
328 , implementationName(std::move(theImplementationName
))
329 , maSupportedServiceNames(sSupportedServiceNames
)
331 SAL_WARN_IF(!mxComponentContext
.is(), "xmloff.core", "SvXMLImport: no ComponentContext");
332 if (!mxComponentContext
.is()) throw uno::RuntimeException();
333 if (!maSupportedServiceNames
.hasElements())
334 maSupportedServiceNames
= { "com.sun.star.document.ImportFilter", "com.sun.star.xml.XMLImportFilter" };
337 sal_uInt16
getGeneratorVersion( const SvXMLImport
& rImport
)
341 mpDocumentInfo
.reset( new DocumentInfo( rImport
) );
344 return mpDocumentInfo
->getGeneratorVersion();
347 ::comphelper::UnoInterfaceToUniqueIdentifierMapper maInterfaceToIdentifierMapper
;
350 SvXMLImportContext
*SvXMLImport::CreateFastContext( sal_Int32 nElement
,
351 const uno::Reference
< xml::sax::XFastAttributeList
>& /*xAttrList*/ )
354 SAL_WARN( "xmloff.core", "CreateFastContext should be overridden, for element " << nElement
);
355 return new SvXMLImportContext( *this );
358 void SvXMLImport::InitCtor_()
360 if( mnImportFlags
!= SvXMLImportFlags::NONE
)
362 // implicit "xml" namespace prefix
363 mxNamespaceMap
->Add( GetXMLToken(XML_XML
), GetXMLToken(XML_N_XML
), XML_NAMESPACE_XML
);
364 mxNamespaceMap
->Add( "_office", GetXMLToken(XML_N_OFFICE
), XML_NAMESPACE_OFFICE
);
365 mxNamespaceMap
->Add( "_office_ooo", GetXMLToken(XML_N_OFFICE_EXT
), XML_NAMESPACE_OFFICE_EXT
);
366 mxNamespaceMap
->Add( "_ooo", GetXMLToken(XML_N_OOO
), XML_NAMESPACE_OOO
);
367 mxNamespaceMap
->Add( "_style", GetXMLToken(XML_N_STYLE
), XML_NAMESPACE_STYLE
);
368 mxNamespaceMap
->Add( "_text", GetXMLToken(XML_N_TEXT
), XML_NAMESPACE_TEXT
);
369 mxNamespaceMap
->Add( "_table", GetXMLToken(XML_N_TABLE
), XML_NAMESPACE_TABLE
);
370 mxNamespaceMap
->Add( "_table_ooo", GetXMLToken(XML_N_TABLE_EXT
), XML_NAMESPACE_TABLE_EXT
);
371 mxNamespaceMap
->Add( "_draw", GetXMLToken(XML_N_DRAW
), XML_NAMESPACE_DRAW
);
372 mxNamespaceMap
->Add( "_draw_ooo", GetXMLToken(XML_N_DRAW_EXT
), XML_NAMESPACE_DRAW_EXT
);
373 mxNamespaceMap
->Add( "_dr3d", GetXMLToken(XML_N_DR3D
), XML_NAMESPACE_DR3D
);
374 mxNamespaceMap
->Add( "_fo", GetXMLToken(XML_N_FO_COMPAT
), XML_NAMESPACE_FO
);
375 mxNamespaceMap
->Add( "_xlink", GetXMLToken(XML_N_XLINK
), XML_NAMESPACE_XLINK
);
376 mxNamespaceMap
->Add( "_dc", GetXMLToken(XML_N_DC
), XML_NAMESPACE_DC
);
377 mxNamespaceMap
->Add( "_dom", GetXMLToken(XML_N_DOM
), XML_NAMESPACE_DOM
);
378 mxNamespaceMap
->Add( "_meta", GetXMLToken(XML_N_META
), XML_NAMESPACE_META
);
379 mxNamespaceMap
->Add( "_number", GetXMLToken(XML_N_NUMBER
), XML_NAMESPACE_NUMBER
);
380 mxNamespaceMap
->Add( "_svg", GetXMLToken(XML_N_SVG_COMPAT
), XML_NAMESPACE_SVG
);
381 mxNamespaceMap
->Add( "_chart", GetXMLToken(XML_N_CHART
), XML_NAMESPACE_CHART
);
382 mxNamespaceMap
->Add( "_math", GetXMLToken(XML_N_MATH
), XML_NAMESPACE_MATH
);
383 mxNamespaceMap
->Add( "_form", GetXMLToken(XML_N_FORM
), XML_NAMESPACE_FORM
);
384 mxNamespaceMap
->Add( "_script", GetXMLToken(XML_N_SCRIPT
), XML_NAMESPACE_SCRIPT
);
385 mxNamespaceMap
->Add( "_config", GetXMLToken(XML_N_CONFIG
), XML_NAMESPACE_CONFIG
);
386 mxNamespaceMap
->Add( "_xforms", GetXMLToken(XML_N_XFORMS_1_0
), XML_NAMESPACE_XFORMS
);
387 mxNamespaceMap
->Add( "_formx", GetXMLToken( XML_N_FORMX
), XML_NAMESPACE_FORMX
);
388 mxNamespaceMap
->Add( "_xsd", GetXMLToken(XML_N_XSD
), XML_NAMESPACE_XSD
);
389 mxNamespaceMap
->Add( "_xsi", GetXMLToken(XML_N_XSI
), XML_NAMESPACE_XFORMS
);
390 mxNamespaceMap
->Add( "_ooow", GetXMLToken(XML_N_OOOW
), XML_NAMESPACE_OOOW
);
391 mxNamespaceMap
->Add( "_oooc", GetXMLToken(XML_N_OOOC
), XML_NAMESPACE_OOOC
);
392 mxNamespaceMap
->Add( "_field", GetXMLToken(XML_N_FIELD
), XML_NAMESPACE_FIELD
);
393 mxNamespaceMap
->Add( "_of", GetXMLToken(XML_N_OF
), XML_NAMESPACE_OF
);
394 mxNamespaceMap
->Add( "_xhtml", GetXMLToken(XML_N_XHTML
), XML_NAMESPACE_XHTML
);
395 mxNamespaceMap
->Add( "_css3text", GetXMLToken(XML_N_CSS3TEXT
), XML_NAMESPACE_CSS3TEXT
);
397 mxNamespaceMap
->Add( "_calc_libo", GetXMLToken(XML_N_CALC_EXT
), XML_NAMESPACE_CALC_EXT
);
398 mxNamespaceMap
->Add( "_office_libo",
399 GetXMLToken(XML_N_LO_EXT
), XML_NAMESPACE_LO_EXT
);
402 if (mxNumberFormatsSupplier
.is())
403 mpNumImport
= std::make_unique
<SvXMLNumFmtHelper
>(mxNumberFormatsSupplier
, GetComponentContext());
405 if (mxModel
.is() && !mxEventListener
.is())
407 mxEventListener
.set(new SvXMLImportEventListener(this));
408 mxModel
->addEventListener(mxEventListener
);
412 SvXMLImport::SvXMLImport(
413 const css::uno::Reference
< css::uno::XComponentContext
>& xContext
,
414 OUString
const & implementationName
,
415 SvXMLImportFlags nImportFlags
,
416 const css::uno::Sequence
< OUString
> & sSupportedServiceNames
)
417 : mpImpl( new SvXMLImport_Impl(xContext
, implementationName
, sSupportedServiceNames
) ),
418 mxNamespaceMap( SvXMLNamespaceMap() ),
420 mpUnitConv( new SvXMLUnitConverter( xContext
,
421 util::MeasureUnit::MM_100TH
, util::MeasureUnit::MM_100TH
,
422 SvtSaveOptions::ODFSVER_LATEST_EXTENDED
) ),
424 mnImportFlags( nImportFlags
),
425 maNamespaceHandler( new SvXMLImportFastNamespaceHandler() ),
426 mbIsFormsSupported( true ),
427 mbIsTableShapeSupported( false ),
428 mbNotifyMacroEventRead( false )
430 SAL_WARN_IF( !xContext
.is(), "xmloff.core", "got no service manager" );
432 mxParser
= xml::sax::FastParser::create( xContext
);
433 setNamespaceHandler( maNamespaceHandler
);
434 setTokenHandler( xTokenHandler
);
435 if ( !bIsNSMapsInitialized
)
437 initializeNamespaceMaps();
438 bIsNSMapsInitialized
= true;
440 registerNamespaces();
441 maNamespaceAttrList
= new comphelper::AttributeList
;
444 void SvXMLImport::cleanup() noexcept
446 if (mxEventListener
.is() && mxModel
.is())
447 mxModel
->removeEventListener(mxEventListener
);
448 // clear context stacks first in case of parse error because the context
449 // class dtors are full of application logic
450 while (!maContexts
.empty())
452 if (SvXMLStylesContext
* pStylesContext
= dynamic_cast<SvXMLStylesContext
*>(maContexts
.top().get()))
453 pStylesContext
->dispose();
457 mxTextImport
->dispose();
458 mxTextImport
.clear(); // XMLRedlineImportHelper needs model
462 SvXMLImport::~SvXMLImport() noexcept
467 bool SvXMLImport::addEmbeddedFont(const css::uno::Reference
< css::io::XInputStream
>& stream
,
468 const OUString
& fontName
, const char* extra
,
469 std::vector
<unsigned char> const & key
, bool eot
)
471 if (!mxEmbeddedFontHelper
)
472 mxEmbeddedFontHelper
.reset(new EmbeddedFontsHelper
);
473 return mxEmbeddedFontHelper
->addEmbeddedFont(stream
, fontName
, extra
, key
, eot
);
476 const css::uno::Sequence
<sal_Int8
>& SvXMLImport::getUnoTunnelId() noexcept
478 static const comphelper::UnoIdInit theSvXMLImportUnoTunnelId
;
479 return theSvXMLImportUnoTunnelId
.getSeq();
483 sal_Int64 SAL_CALL
SvXMLImport::getSomething( const uno::Sequence
< sal_Int8
>& rId
)
485 return comphelper::getSomethingImpl(rId
, this);
490 class setFastDocumentHandlerGuard
493 css::uno::Reference
<css::xml::sax::XFastParser
> mxParser
;
495 setFastDocumentHandlerGuard(css::uno::Reference
<css::xml::sax::XFastParser
> Parser
,
496 const css::uno::Reference
<css::xml::sax::XFastDocumentHandler
>& Handler
)
497 : mxParser(std::move(Parser
))
499 mxParser
->setFastDocumentHandler(Handler
);
501 //guarantee restoration of null document handler
502 ~setFastDocumentHandlerGuard()
504 mxParser
->setFastDocumentHandler(nullptr);
510 void SAL_CALL
SvXMLImport::parseStream( const xml::sax::InputSource
& aInputSource
)
512 setFastDocumentHandlerGuard
aDocumentHandlerGuard(mxParser
, mxFastDocumentHandler
.is() ? mxFastDocumentHandler
: this);
513 mxParser
->parseStream(aInputSource
);
516 void SAL_CALL
SvXMLImport::setFastDocumentHandler( const uno::Reference
< xml::sax::XFastDocumentHandler
>& Handler
)
518 mxFastDocumentHandler
= Handler
;
521 void SAL_CALL
SvXMLImport::setTokenHandler( const uno::Reference
< xml::sax::XFastTokenHandler
>& Handler
)
523 mxParser
->setTokenHandler( Handler
);
526 void SAL_CALL
SvXMLImport::registerNamespace( const OUString
& NamespaceURL
, sal_Int32 NamespaceToken
)
528 mxParser
->registerNamespace( NamespaceURL
, NamespaceToken
);
531 OUString SAL_CALL
SvXMLImport::getNamespaceURL( const OUString
& rPrefix
)
533 return mxParser
->getNamespaceURL( rPrefix
);
536 void SAL_CALL
SvXMLImport::setErrorHandler( const uno::Reference
< xml::sax::XErrorHandler
>& Handler
)
538 mxParser
->setErrorHandler( Handler
);
541 void SAL_CALL
SvXMLImport::setEntityResolver( const uno::Reference
< xml::sax::XEntityResolver
>& Resolver
)
543 mxParser
->setEntityResolver( Resolver
);
546 void SAL_CALL
SvXMLImport::setLocale( const lang::Locale
& rLocale
)
548 mxParser
->setLocale( rLocale
);
551 void SAL_CALL
SvXMLImport::setNamespaceHandler( const uno::Reference
< xml::sax::XFastNamespaceHandler
>& Handler
)
553 mxParser
->setNamespaceHandler( Handler
);
556 void SAL_CALL
SvXMLImport::setCustomEntityNames( const ::css::uno::Sequence
< ::css::beans::Pair
<::rtl::OUString
, ::rtl::OUString
> >& replacements
)
558 mxParser
->setCustomEntityNames( replacements
);
561 void SAL_CALL
SvXMLImport::startDocument()
563 SAL_INFO( "xmloff.core", "{ SvXMLImport::startDocument" );
564 if (mxGraphicStorageHandler
.is() && mxEmbeddedResolver
.is())
567 Reference
< lang::XMultiServiceFactory
> xFactory( mxModel
, UNO_QUERY
);
573 if (!mxGraphicStorageHandler
.is())
575 // #99870# Import... instead of Export...
576 mxGraphicStorageHandler
.set(
577 xFactory
->createInstance("com.sun.star.document.ImportGraphicStorageHandler"),
579 mpImpl
->mbOwnGraphicResolver
= mxGraphicStorageHandler
.is();
582 if( !mxEmbeddedResolver
.is() )
584 // #99870# Import... instead of Export...
585 mxEmbeddedResolver
.set(
586 xFactory
->createInstance("com.sun.star.document.ImportEmbeddedObjectResolver"),
588 mpImpl
->mbOwnEmbeddedResolver
= mxEmbeddedResolver
.is();
591 catch( css::uno::Exception
& )
596 void SAL_CALL
SvXMLImport::endDocument()
598 SAL_INFO( "xmloff.core", "} SvXMLImport::endDocument" );
599 // #i9518# All the stuff that accesses the document has to be done here, not in the dtor,
600 // because the SvXMLImport dtor might not be called until after the document has been closed.
603 mxTextImport
->MapCrossRefHeadingFieldsHorribly();
605 if (mpImpl
->mpRDFaHelper
)
607 const uno::Reference
<rdf::XRepositorySupplier
> xRS(mxModel
,
611 mpImpl
->mpRDFaHelper
->InsertRDFa( xRS
);
616 if (mxImportInfo
.is())
618 uno::Reference
< beans::XPropertySetInfo
> xPropertySetInfo
= mxImportInfo
->getPropertySetInfo();
619 if (xPropertySetInfo
.is())
621 if (bool(mpProgressBarHelper
))
623 OUString
sProgressMax(XML_PROGRESSMAX
);
624 OUString
sProgressCurrent(XML_PROGRESSCURRENT
);
625 OUString
sRepeat(XML_PROGRESSREPEAT
);
626 if (xPropertySetInfo
->hasPropertyByName(sProgressMax
) &&
627 xPropertySetInfo
->hasPropertyByName(sProgressCurrent
))
629 sal_Int32
nProgressMax(mpProgressBarHelper
->GetReference());
630 sal_Int32
nProgressCurrent(mpProgressBarHelper
->GetValue());
631 mxImportInfo
->setPropertyValue(sProgressMax
, uno::Any(nProgressMax
));
632 mxImportInfo
->setPropertyValue(sProgressCurrent
, uno::Any(nProgressCurrent
));
634 if (xPropertySetInfo
->hasPropertyByName(sRepeat
))
635 mxImportInfo
->setPropertyValue(sRepeat
, css::uno::Any(mpProgressBarHelper
->GetRepeat()));
636 // pProgressBarHelper is deleted in dtor
638 OUString
sNumberStyles(XML_NUMBERSTYLES
);
639 if (mxNumberStyles
.is() && xPropertySetInfo
->hasPropertyByName(sNumberStyles
))
641 mxImportInfo
->setPropertyValue(sNumberStyles
, Any(mxNumberStyles
));
646 if( mxFontDecls
.is() )
647 mxFontDecls
->dispose();
650 if( mxAutoStyles
.is() )
651 mxAutoStyles
->dispose();
652 if( mxMasterStyles
.is() )
653 mxMasterStyles
->dispose();
655 // possible form-layer related knittings which can only be done when
656 // the whole document exists
657 if ( mxFormImport
.is() )
658 mxFormImport
->documentDone();
660 // The shape import helper does the z-order sorting in the dtor,
661 // so it must be deleted here, too.
662 mxShapeImport
= nullptr;
664 if( mpImpl
->mbOwnGraphicResolver
)
666 Reference
<lang::XComponent
> xComp(mxGraphicStorageHandler
, UNO_QUERY
);
670 if( mpImpl
->mbOwnEmbeddedResolver
)
672 Reference
< lang::XComponent
> xComp( mxEmbeddedResolver
, UNO_QUERY
);
677 if ( bool( mpXMLErrors
) )
679 mpXMLErrors
->ThrowErrorAsSAXException( XMLERROR_FLAG_SEVERE
);
683 std::optional
<SvXMLNamespaceMap
> SvXMLImport::processNSAttributes(
684 std::optional
<SvXMLNamespaceMap
> & rpNamespaceMap
,
685 SvXMLImport
*const pImport
, // TODO???
686 const uno::Reference
< xml::sax::XAttributeList
>& xAttrList
)
688 std::optional
<SvXMLNamespaceMap
> pRewindMap
;
689 sal_Int16 nAttrCount
= xAttrList
.is() ? xAttrList
->getLength() : 0;
690 for( sal_Int16 i
=0; i
< nAttrCount
; i
++ )
692 const OUString
& rAttrName
= xAttrList
->getNameByIndex( i
);
693 if (pImport
&& rAttrName
== "office:version" && !pImport
->mpImpl
->mxODFVersion
)
695 pImport
->mpImpl
->mxODFVersion
= xAttrList
->getValueByIndex( i
);
697 // the ODF version in content.xml and manifest.xml must be the same starting from ODF1.2
698 if (pImport
->mpImpl
->mStreamName
== "content.xml"
699 && !pImport
->IsODFVersionConsistent(*pImport
->mpImpl
->mxODFVersion
))
701 throw xml::sax::SAXException("Inconsistent ODF versions in content.xml and manifest.xml!",
702 uno::Reference
< uno::XInterface
>(),
704 packages::zip::ZipIOException("Inconsistent ODF versions in content.xml and manifest.xml!" ) ) );
707 else if( ( rAttrName
.getLength() >= 5 ) &&
708 ( rAttrName
.startsWith( GetXMLToken(XML_XMLNS
) ) ) &&
709 ( rAttrName
.getLength() == 5 || ':' == rAttrName
[5] ) )
713 pRewindMap
= std::move(rpNamespaceMap
);
714 rpNamespaceMap
.emplace(*pRewindMap
);
716 const OUString
& rAttrValue
= xAttrList
->getValueByIndex( i
);
718 OUString
aPrefix( ( rAttrName
.getLength() == 5 )
720 : rAttrName
.copy( 6 ) );
721 // Add namespace, but only if it is known.
722 sal_uInt16 nKey
= rpNamespaceMap
->AddIfKnown( aPrefix
, rAttrValue
);
723 // If namespace is unknown, try to match a name with similar
725 if( XML_NAMESPACE_UNKNOWN
== nKey
)
727 OUString
aTestName( rAttrValue
);
728 if( SvXMLNamespaceMap::NormalizeURI( aTestName
) )
729 nKey
= rpNamespaceMap
->AddIfKnown( aPrefix
, aTestName
);
731 // If that namespace is not known, too, add it as unknown
732 if( XML_NAMESPACE_UNKNOWN
== nKey
)
733 rpNamespaceMap
->Add( aPrefix
, rAttrValue
);
741 void SAL_CALL
SvXMLImport::characters( const OUString
& rChars
)
743 maContexts
.top()->characters( rChars
);
746 void SAL_CALL
SvXMLImport::processingInstruction( const OUString
&,
751 void SAL_CALL
SvXMLImport::setDocumentLocator( const uno::Reference
< xml::sax::XLocator
>& rLocator
)
753 mxLocator
= rLocator
;
756 // XFastContextHandler
757 void SAL_CALL
SvXMLImport::startFastElement (sal_Int32 Element
,
758 const uno::Reference
< xml::sax::XFastAttributeList
> & Attribs
)
760 SAL_INFO("xmloff.core", "startFastElement " << SvXMLImport::getNameFromToken( Element
));
761 if ( Attribs
.is() && !mpImpl
->mxODFVersion
)
763 sax_fastparser::FastAttributeList
& rAttribList
=
764 sax_fastparser::castToFastAttributeList( Attribs
);
765 auto aIter( rAttribList
.find( XML_ELEMENT( OFFICE
, XML_VERSION
) ) );
766 if( aIter
!= rAttribList
.end() )
768 mpImpl
->mxODFVersion
= aIter
.toString();
770 // the ODF version in content.xml and manifest.xml must be the same starting from ODF1.2
771 if ( mpImpl
->mStreamName
== "content.xml" && !IsODFVersionConsistent( *mpImpl
->mxODFVersion
) )
773 throw xml::sax::SAXException("Inconsistent ODF versions in content.xml and manifest.xml!",
774 uno::Reference
< uno::XInterface
>(),
776 packages::zip::ZipIOException("Inconsistent ODF versions in content.xml and manifest.xml!" ) ) );
781 maNamespaceAttrList
->Clear();
783 maNamespaceHandler
->addNSDeclAttributes( maNamespaceAttrList
);
784 std::optional
<SvXMLNamespaceMap
> pRewindMap
= processNSAttributes(mxNamespaceMap
, this, maNamespaceAttrList
);
786 SvXMLImportContextRef xContext
;
787 const bool bRootContext
= maContexts
.empty();
788 if (!maContexts
.empty())
790 const SvXMLImportContextRef
& pHandler
= maContexts
.top();
791 SAL_INFO("xmloff.core", "calling createFastChildContext on " << typeid(*pHandler
.get()).name());
792 auto tmp
= pHandler
->createFastChildContext( Element
, Attribs
);
793 xContext
= static_cast<SvXMLImportContext
*>(tmp
.get());
794 assert((tmp
&& xContext
) || (!tmp
&& !xContext
));
797 xContext
.set( CreateFastContext( Element
, Attribs
) );
799 SAL_INFO_IF(!xContext
.is(), "xmloff.core", "No fast context for element " << getNameFromToken(Element
));
800 if (bRootContext
&& !xContext
)
802 OUString aName
= getNameFromToken(Element
);
803 SetError( XMLERROR_FLAG_SEVERE
| XMLERROR_UNKNOWN_ROOT
,
804 { aName
}, "Root element " + aName
+ " unknown", Reference
<xml::sax::XLocator
>() );
807 xContext
.set( new SvXMLImportContext( *this ) );
809 // Remember old namespace map.
811 xContext
->PutRewindMap(std::move(pRewindMap
));
813 // Call a startElement at the new context.
814 xContext
->startFastElement( Element
, Attribs
);
816 // Push context on stack.
817 maContexts
.push(xContext
);
820 void SAL_CALL
SvXMLImport::startUnknownElement (const OUString
& rNamespace
, const OUString
& rName
,
821 const uno::Reference
< xml::sax::XFastAttributeList
> & Attribs
)
823 SAL_INFO("xmloff.core", "startUnknownElement " << rNamespace
<< " " << rName
);
824 SvXMLImportContextRef xContext
;
825 const bool bRootContext
= maContexts
.empty();
826 if (!maContexts
.empty())
828 const SvXMLImportContextRef
& pHandler
= maContexts
.top();
829 SAL_INFO("xmloff.core", "calling createUnknownChildContext on " << typeid(*pHandler
.get()).name());
830 auto tmp
= pHandler
->createUnknownChildContext( rNamespace
, rName
, Attribs
);
831 xContext
= static_cast<SvXMLImportContext
*>(tmp
.get());
832 assert((tmp
&& xContext
) || (!tmp
&& !xContext
));
835 xContext
.set( CreateFastContext( -1, Attribs
) );
837 SAL_WARN_IF(!xContext
.is(), "xmloff.core", "No context for unknown-element " << rNamespace
<< " " << rName
);
838 if (bRootContext
&& !xContext
)
840 SetError( XMLERROR_FLAG_SEVERE
| XMLERROR_UNKNOWN_ROOT
,
841 { rName
}, "Root element " + rName
+ " unknown", Reference
<xml::sax::XLocator
>() );
845 if (!maContexts
.empty())
846 // This is pretty weird, but it's what the code did before I simplified it, and some parts of the
847 // code rely on this behaviour e.g. DocumentBuilderContext
848 xContext
= maContexts
.top();
850 xContext
= new SvXMLImportContext( *this );
853 xContext
->startUnknownElement( rNamespace
, rName
, Attribs
);
854 maContexts
.push(xContext
);
857 void SAL_CALL
SvXMLImport::endFastElement (sal_Int32 Element
)
859 SAL_INFO("xmloff.core", "endFastElement " << SvXMLImport::getNameFromToken( Element
));
860 if (maContexts
.empty())
862 SAL_WARN("xmloff.core", "SvXMLImport::endFastElement: no context left");
866 SvXMLImportContextRef xContext
= std::move(maContexts
.top());
867 // Get a namespace map to rewind.
868 std::optional
<SvXMLNamespaceMap
> pRewindMap
= xContext
->TakeRewindMap();
870 xContext
->endFastElement( Element
);
871 // Rewind a namespace map.
873 mxNamespaceMap
= std::move(pRewindMap
);
876 void SAL_CALL
SvXMLImport::endUnknownElement (const OUString
& rPrefix
, const OUString
& rLocalName
)
878 SAL_INFO("xmloff.core", "endUnknownElement " << rPrefix
<< " " << rLocalName
);
879 if (maContexts
.empty())
881 SAL_WARN("xmloff.core", "SvXMLImport::endUnknownElement: no context left");
885 SvXMLImportContextRef xContext
= std::move(maContexts
.top());
887 xContext
->endUnknownElement( rPrefix
, rLocalName
);
890 uno::Reference
< xml::sax::XFastContextHandler
> SAL_CALL
891 SvXMLImport::createFastChildContext (sal_Int32
,
892 const uno::Reference
< xml::sax::XFastAttributeList
> &)
897 uno::Reference
< xml::sax::XFastContextHandler
> SAL_CALL
898 SvXMLImport::createUnknownChildContext (const OUString
&, const OUString
&,
899 const uno::Reference
< xml::sax::XFastAttributeList
> &)
904 void SvXMLImport::SetStatistics(const uno::Sequence
< beans::NamedValue
> &)
906 GetProgressBarHelper()->SetRepeat(false);
907 GetProgressBarHelper()->SetReference(0);
911 void SAL_CALL
SvXMLImport::setTargetDocument( const uno::Reference
< lang::XComponent
>& xDoc
)
913 mxModel
.set( xDoc
, UNO_QUERY
);
915 throw lang::IllegalArgumentException();
919 uno::Reference
<document::XStorageBasedDocument
> const xSBDoc(mxModel
, uno::UNO_QUERY
);
920 uno::Reference
<embed::XStorage
> const xStor(xSBDoc
.is() ? xSBDoc
->getDocumentStorage()
925 ::comphelper::OStorageHelper::GetXStorageFormat(xStor
)
926 < SOFFICE_FILEFORMAT_8
;
929 catch (uno::Exception
const&)
931 DBG_UNHANDLED_EXCEPTION("xmloff.core");
933 if (!mxEventListener
.is())
935 mxEventListener
.set(new SvXMLImportEventListener(this));
936 mxModel
->addEventListener(mxEventListener
);
939 SAL_WARN_IF( bool(mpNumImport
), "xmloff.core", "number format import already exists." );
944 sal_Bool SAL_CALL
SvXMLImport::filter( const uno::Sequence
< beans::PropertyValue
>& )
949 void SAL_CALL
SvXMLImport::cancel( )
954 void SAL_CALL
SvXMLImport::initialize( const uno::Sequence
< uno::Any
>& aArguments
)
956 for( const auto& rAny
: aArguments
)
958 Reference
<XInterface
> xValue
;
961 uno::Reference
<task::XStatusIndicator
> xTmpStatusIndicator(
963 if( xTmpStatusIndicator
.is() )
964 mxStatusIndicator
= xTmpStatusIndicator
;
966 uno::Reference
<document::XGraphicStorageHandler
> xGraphicStorageHandler(xValue
, UNO_QUERY
);
967 if (xGraphicStorageHandler
.is())
968 mxGraphicStorageHandler
= xGraphicStorageHandler
;
970 uno::Reference
<document::XEmbeddedObjectResolver
> xTmpObjectResolver(
972 if( xTmpObjectResolver
.is() )
973 mxEmbeddedResolver
= xTmpObjectResolver
;
975 uno::Reference
<beans::XPropertySet
> xTmpPropSet( xValue
, UNO_QUERY
);
976 if( xTmpPropSet
.is() )
978 mxImportInfo
= xTmpPropSet
;
979 uno::Reference
< beans::XPropertySetInfo
> xPropertySetInfo
= mxImportInfo
->getPropertySetInfo();
980 if (xPropertySetInfo
.is())
982 OUString
sPropName(XML_NUMBERSTYLES
);
983 if (xPropertySetInfo
->hasPropertyByName(sPropName
))
985 uno::Any aAny
= mxImportInfo
->getPropertyValue(sPropName
);
986 aAny
>>= mxNumberStyles
;
989 sPropName
= "PrivateData";
990 if (xPropertySetInfo
->hasPropertyByName(sPropName
))
992 Reference
< XInterface
> xIfc
;
993 uno::Any aAny
= mxImportInfo
->getPropertyValue(sPropName
);
996 StyleMap
*pSMap
= comphelper::getFromUnoTunnel
<StyleMap
>( xIfc
);
1003 sPropName
= "BaseURI";
1004 if (xPropertySetInfo
->hasPropertyByName(sPropName
))
1006 uno::Any aAny
= mxImportInfo
->getPropertyValue(sPropName
);
1008 mpImpl
->aBaseURL
.SetURL( sBaseURI
);
1009 mpImpl
->aDocBase
.SetURL( sBaseURI
);
1012 sPropName
= "StreamRelPath";
1013 if( xPropertySetInfo
->hasPropertyByName(sPropName
) )
1015 uno::Any aAny
= mxImportInfo
->getPropertyValue(sPropName
);
1019 sPropName
= "StreamName";
1020 if( xPropertySetInfo
->hasPropertyByName(sPropName
) )
1022 uno::Any aAny
= mxImportInfo
->getPropertyValue(sPropName
);
1025 if( !sBaseURI
.isEmpty() && !sName
.isEmpty() )
1027 if( !sRelPath
.isEmpty() )
1028 mpImpl
->aBaseURL
.insertName( sRelPath
);
1029 mpImpl
->aBaseURL
.insertName( sName
);
1031 mpImpl
->mStreamName
= sName
; // Note: may be empty (XSLT)
1032 // Retrieve property <ShapePositionInHoriL2R> (#i28749#)
1033 sPropName
= "ShapePositionInHoriL2R";
1034 if( xPropertySetInfo
->hasPropertyByName(sPropName
) )
1036 uno::Any aAny
= mxImportInfo
->getPropertyValue(sPropName
);
1037 aAny
>>= mpImpl
->mbShapePositionInHoriL2R
;
1039 sPropName
= "TextDocInOOoFileFormat";
1040 if( xPropertySetInfo
->hasPropertyByName(sPropName
) )
1042 uno::Any aAny
= mxImportInfo
->getPropertyValue(sPropName
);
1043 aAny
>>= mpImpl
->mbTextDocInOOoFileFormat
;
1046 sPropName
= "SourceStorage";
1047 if( xPropertySetInfo
->hasPropertyByName(sPropName
) )
1048 mxImportInfo
->getPropertyValue(sPropName
) >>= mpImpl
->mxSourceStorage
;
1053 uno::Reference
<lang::XInitialization
> const xInit(mxParser
, uno::UNO_QUERY_THROW
);
1054 xInit
->initialize( { Any(OUString("IgnoreMissingNSDecl")) });
1058 OUString SAL_CALL
SvXMLImport::getImplementationName()
1060 return mpImpl
->implementationName
;
1063 sal_Bool SAL_CALL
SvXMLImport::supportsService( const OUString
& rServiceName
)
1065 return cppu::supportsService(this, rServiceName
);
1068 uno::Sequence
< OUString
> SAL_CALL
SvXMLImport::getSupportedServiceNames( )
1070 return mpImpl
->maSupportedServiceNames
;
1073 XMLTextImportHelper
* SvXMLImport::CreateTextImport()
1075 return new XMLTextImportHelper( mxModel
, *this );
1078 XMLShapeImportHelper
* SvXMLImport::CreateShapeImport()
1080 return new XMLShapeImportHelper( *this, mxModel
);
1083 SchXMLImportHelper
* SvXMLImport::CreateChartImport()
1085 // WASM_CHART change
1086 // TODO: Instead of importing the ChartModel an alternative may be
1087 // added to convert not to Chart/OLE SdrObejct, but to GraphicObject
1088 // with the Chart visualization. There should be a preview available
1089 // in the imported chart data
1090 #if !ENABLE_WASM_STRIP_CHART
1091 return new SchXMLImportHelper();
1097 ::xmloff::OFormLayerXMLImport
* SvXMLImport::CreateFormImport()
1099 return new ::xmloff::OFormLayerXMLImport(*this);
1103 // Get or create fill/line/lineend-style-helper
1106 const Reference
< container::XNameContainer
> & SvXMLImport::GetGradientHelper()
1108 if( !mxGradientHelper
.is() )
1112 Reference
< lang::XMultiServiceFactory
> xServiceFact( mxModel
, UNO_QUERY
);
1113 if( xServiceFact
.is() )
1117 mxGradientHelper
.set( xServiceFact
->createInstance(
1118 "com.sun.star.drawing.GradientTable" ), UNO_QUERY
);
1120 catch( lang::ServiceNotRegisteredException
& )
1126 return mxGradientHelper
;
1129 const Reference
< container::XNameContainer
> & SvXMLImport::GetHatchHelper()
1131 if( !mxHatchHelper
.is() )
1135 Reference
< lang::XMultiServiceFactory
> xServiceFact( mxModel
, UNO_QUERY
);
1136 if( xServiceFact
.is() )
1140 mxHatchHelper
.set( xServiceFact
->createInstance(
1141 "com.sun.star.drawing.HatchTable" ), UNO_QUERY
);
1143 catch( lang::ServiceNotRegisteredException
& )
1149 return mxHatchHelper
;
1152 const Reference
< container::XNameContainer
> & SvXMLImport::GetBitmapHelper()
1154 if( !mxBitmapHelper
.is() )
1158 Reference
< lang::XMultiServiceFactory
> xServiceFact( mxModel
, UNO_QUERY
);
1159 if( xServiceFact
.is() )
1163 mxBitmapHelper
.set( xServiceFact
->createInstance(
1164 "com.sun.star.drawing.BitmapTable" ), UNO_QUERY
);
1166 catch( lang::ServiceNotRegisteredException
& )
1172 return mxBitmapHelper
;
1175 const Reference
< container::XNameContainer
> & SvXMLImport::GetTransGradientHelper()
1177 if( !mxTransGradientHelper
.is() )
1181 Reference
< lang::XMultiServiceFactory
> xServiceFact( mxModel
, UNO_QUERY
);
1182 if( xServiceFact
.is() )
1186 mxTransGradientHelper
.set( xServiceFact
->createInstance(
1187 "com.sun.star.drawing.TransparencyGradientTable" ), UNO_QUERY
);
1189 catch( lang::ServiceNotRegisteredException
& )
1195 return mxTransGradientHelper
;
1198 const Reference
< container::XNameContainer
> & SvXMLImport::GetMarkerHelper()
1200 if( !mxMarkerHelper
.is() )
1204 Reference
< lang::XMultiServiceFactory
> xServiceFact( mxModel
, UNO_QUERY
);
1205 if( xServiceFact
.is() )
1209 mxMarkerHelper
.set( xServiceFact
->createInstance( "com.sun.star.drawing.MarkerTable" ), UNO_QUERY
);
1211 catch( lang::ServiceNotRegisteredException
& )
1217 return mxMarkerHelper
;
1220 const Reference
< container::XNameContainer
> & SvXMLImport::GetDashHelper()
1222 if( !mxDashHelper
.is() && mxModel
.is() )
1224 Reference
< lang::XMultiServiceFactory
> xServiceFact( mxModel
, UNO_QUERY
);
1225 if( xServiceFact
.is() )
1229 mxDashHelper
.set( xServiceFact
->createInstance( "com.sun.star.drawing.DashTable" ), UNO_QUERY
);
1231 catch( lang::ServiceNotRegisteredException
& )
1236 return mxDashHelper
;
1239 bool SvXMLImport::IsPackageURL( std::u16string_view rURL
) const
1242 // if, and only if, only parts are imported, then we're in a package
1243 const SvXMLImportFlags nTest
= SvXMLImportFlags::META
|SvXMLImportFlags::STYLES
|SvXMLImportFlags::CONTENT
|SvXMLImportFlags::SETTINGS
;
1244 if( (mnImportFlags
& nTest
) == nTest
)
1247 // TODO: from this point extract to own static function
1249 // Some quick tests: Some may rely on the package structure!
1250 size_t nLen
= rURL
.size();
1251 if( nLen
> 0 && '/' == rURL
[0] )
1252 // RFC2396 net_path or abs_path
1254 else if( nLen
> 1 && '.' == rURL
[0] )
1256 if( '.' == rURL
[1] )
1257 // ../: We are never going up one level, so we know
1258 // it's not an external URI
1260 else if( '/' == rURL
[1] )
1261 // we are remaining on a level, so it's a package URI
1265 // Now check for a RFC2396 schema
1267 while( nPos
< nLen
)
1269 switch( rURL
[nPos
] )
1272 // a relative path segment
1279 // we don't care about any other characters
1287 uno::Reference
<graphic::XGraphic
> SvXMLImport::loadGraphicByURL(OUString
const & rURL
)
1289 uno::Reference
<graphic::XGraphic
> xGraphic
;
1291 if (mxGraphicStorageHandler
.is())
1293 if (IsPackageURL(rURL
))
1295 xGraphic
= mxGraphicStorageHandler
->loadGraphic(rURL
);
1299 OUString
const & rAbsoluteURL
= GetAbsoluteReference(rURL
);
1300 GraphicExternalLink
aExternalLink(rAbsoluteURL
);
1301 Graphic
aGraphic(aExternalLink
);
1302 xGraphic
= aGraphic
.GetXGraphic();
1309 uno::Reference
<graphic::XGraphic
> SvXMLImport::loadGraphicFromBase64(uno::Reference
<io::XOutputStream
> const & rxOutputStream
)
1311 uno::Reference
<graphic::XGraphic
> xGraphic
;
1313 if (mxGraphicStorageHandler
.is())
1315 xGraphic
= mxGraphicStorageHandler
->loadGraphicFromOutputStream(rxOutputStream
);
1321 Reference
< XOutputStream
> SvXMLImport::GetStreamForGraphicObjectURLFromBase64() const
1323 Reference
< XOutputStream
> xOStm
;
1324 Reference
< document::XBinaryStreamResolver
> xStmResolver(mxGraphicStorageHandler
, UNO_QUERY
);
1326 if( xStmResolver
.is() )
1327 xOStm
= xStmResolver
->createOutputStream();
1332 OUString
SvXMLImport::ResolveEmbeddedObjectURL(
1333 const OUString
& rURL
,
1334 std::u16string_view rClassId
)
1338 if( IsPackageURL( rURL
) )
1340 if ( mxEmbeddedResolver
.is() )
1342 OUString
sURL( rURL
);
1343 if( !rClassId
.empty() )
1345 sURL
+= OUString::Concat("!") + rClassId
;
1347 sRet
= mxEmbeddedResolver
->resolveEmbeddedObjectURL( sURL
);
1351 sRet
= GetAbsoluteReference( rURL
);
1356 Reference
< embed::XStorage
> const & SvXMLImport::GetSourceStorage() const
1358 return mpImpl
->mxSourceStorage
;
1361 Reference
< XOutputStream
>
1362 SvXMLImport::GetStreamForEmbeddedObjectURLFromBase64() const
1364 Reference
< XOutputStream
> xOLEStream
;
1366 if( mxEmbeddedResolver
.is() )
1368 Reference
< XNameAccess
> xNA( mxEmbeddedResolver
, UNO_QUERY
);
1371 Any aAny
= xNA
->getByName( "Obj12345678" );
1372 aAny
>>= xOLEStream
;
1379 OUString
SvXMLImport::ResolveEmbeddedObjectURLFromBase64()
1383 if( mxEmbeddedResolver
.is() )
1385 sRet
= mxEmbeddedResolver
->resolveEmbeddedObjectURL( "Obj12345678" );
1391 void SvXMLImport::AddStyleDisplayName( XmlStyleFamily nFamily
,
1392 const OUString
& rName
,
1393 const OUString
& rDisplayName
)
1395 if( !mpStyleMap
.is() )
1397 mpStyleMap
= new StyleMap
;
1398 if( mxImportInfo
.is() )
1400 OUString
sPrivateData( "PrivateData" );
1401 Reference
< beans::XPropertySetInfo
> xPropertySetInfo
=
1402 mxImportInfo
->getPropertySetInfo();
1403 if( xPropertySetInfo
.is() &&
1404 xPropertySetInfo
->hasPropertyByName(sPrivateData
) )
1406 Reference
< XInterface
> xIfc(
1407 static_cast< XUnoTunnel
*>( mpStyleMap
.get() ) );
1408 mxImportInfo
->setPropertyValue( sPrivateData
, Any(xIfc
) );
1413 StyleMap::key_type
aKey( nFamily
, rName
);
1414 StyleMap::value_type
aValue( aKey
, rDisplayName
);
1415 ::std::pair
<StyleMap::iterator
,bool> aRes( mpStyleMap
->insert( aValue
) );
1416 SAL_WARN_IF( !aRes
.second
,
1418 "duplicate style name of family " << static_cast<int>(nFamily
) << ": \"" << rName
<< "\"");
1422 OUString
SvXMLImport::GetStyleDisplayName( XmlStyleFamily nFamily
,
1423 const OUString
& rName
) const
1425 OUString
sName( rName
);
1426 if( mpStyleMap
.is() && !rName
.isEmpty() )
1428 StyleMap::key_type
aKey( nFamily
, rName
);
1429 StyleMap::const_iterator aIter
= mpStyleMap
->find( aKey
);
1430 if( aIter
!= mpStyleMap
->end() )
1431 sName
= (*aIter
).second
;
1436 void SvXMLImport::SetViewSettings(const css::uno::Sequence
<css::beans::PropertyValue
>&)
1440 void SvXMLImport::SetConfigurationSettings(const css::uno::Sequence
<css::beans::PropertyValue
>&)
1444 void SvXMLImport::SetDocumentSpecificSettings(const OUString
&, const uno::Sequence
<beans::PropertyValue
>&)
1448 ProgressBarHelper
* SvXMLImport::GetProgressBarHelper()
1450 if (!mpProgressBarHelper
)
1452 mpProgressBarHelper
= std::make_unique
<ProgressBarHelper
>(mxStatusIndicator
, false);
1454 if (mxImportInfo
.is())
1456 uno::Reference
< beans::XPropertySetInfo
> xPropertySetInfo
= mxImportInfo
->getPropertySetInfo();
1457 if (xPropertySetInfo
.is())
1459 OUString
sProgressRange(XML_PROGRESSRANGE
);
1460 OUString
sProgressMax(XML_PROGRESSMAX
);
1461 OUString
sProgressCurrent(XML_PROGRESSCURRENT
);
1462 OUString
sRepeat(XML_PROGRESSREPEAT
);
1463 if (xPropertySetInfo
->hasPropertyByName(sProgressMax
) &&
1464 xPropertySetInfo
->hasPropertyByName(sProgressCurrent
) &&
1465 xPropertySetInfo
->hasPropertyByName(sProgressRange
))
1468 sal_Int32
nProgressMax(0);
1469 sal_Int32
nProgressCurrent(0);
1470 sal_Int32
nProgressRange(0);
1471 aAny
= mxImportInfo
->getPropertyValue(sProgressRange
);
1472 if (aAny
>>= nProgressRange
)
1473 mpProgressBarHelper
->SetRange(nProgressRange
);
1474 aAny
= mxImportInfo
->getPropertyValue(sProgressMax
);
1475 if (aAny
>>= nProgressMax
)
1476 mpProgressBarHelper
->SetReference(nProgressMax
);
1477 aAny
= mxImportInfo
->getPropertyValue(sProgressCurrent
);
1478 if (aAny
>>= nProgressCurrent
)
1479 mpProgressBarHelper
->SetValue(nProgressCurrent
);
1481 if (xPropertySetInfo
->hasPropertyByName(sRepeat
))
1483 uno::Any aAny
= mxImportInfo
->getPropertyValue(sRepeat
);
1484 if (aAny
.getValueType() == cppu::UnoType
<bool>::get())
1485 mpProgressBarHelper
->SetRepeat(::cppu::any2bool(aAny
));
1487 SAL_WARN( "xmloff.core", "why is it no boolean?" );
1493 return mpProgressBarHelper
.get();
1496 void SvXMLImport::AddNumberStyle(sal_Int32 nKey
, const OUString
& rName
)
1498 if (!mxNumberStyles
.is())
1499 mxNumberStyles
.set( comphelper::NameContainer_createInstance( ::cppu::UnoType
<sal_Int32
>::get()) );
1500 if (mxNumberStyles
.is())
1504 mxNumberStyles
->insertByName(rName
, Any(nKey
));
1506 catch ( uno::Exception
& )
1508 DBG_UNHANDLED_EXCEPTION( "xmloff.core", "Numberformat could not be inserted");
1512 SAL_WARN( "xmloff.core", "not possible to create NameContainer");
1516 XMLEventImportHelper
& SvXMLImport::GetEventImport()
1518 if (!mpEventImportHelper
)
1520 // construct event helper and register StarBasic handler and standard
1522 mpEventImportHelper
= std::make_unique
<XMLEventImportHelper
>();
1523 const OUString
& sStarBasic(GetXMLToken(XML_STARBASIC
));
1524 mpEventImportHelper
->RegisterFactory(sStarBasic
,
1525 std::make_unique
<XMLStarBasicContextFactory
>());
1526 const OUString
& sScript(GetXMLToken(XML_SCRIPT
));
1527 mpEventImportHelper
->RegisterFactory(sScript
,
1528 std::make_unique
<XMLScriptContextFactory
>());
1529 mpEventImportHelper
->AddTranslationTable(aStandardEventTable
);
1531 // register StarBasic event handler with capitalized spelling
1532 mpEventImportHelper
->RegisterFactory("StarBasic",
1533 std::make_unique
<XMLStarBasicContextFactory
>());
1536 return *mpEventImportHelper
;
1539 void SvXMLImport::SetFontDecls( XMLFontStylesContext
*pFontDecls
)
1541 if (mxFontDecls
.is())
1542 mxFontDecls
->dispose();
1543 mxFontDecls
= pFontDecls
;
1546 void SvXMLImport::SetStyles( SvXMLStylesContext
*pStyles
)
1549 mxStyles
->dispose();
1553 void SvXMLImport::SetAutoStyles( SvXMLStylesContext
*pAutoStyles
)
1555 if (pAutoStyles
&& mxNumberStyles
.is())
1557 uno::Reference
<xml::sax::XFastAttributeList
> xAttrList
= new sax_fastparser::FastAttributeList(nullptr);
1558 const uno::Sequence
<OUString
> aStyleNames
= mxNumberStyles
->getElementNames();
1559 for (const auto& name
: aStyleNames
)
1561 uno::Any
aAny(mxNumberStyles
->getByName(name
));
1565 SvXMLStyleContext
* pContext
= new SvXMLNumFormatContext(
1566 *this, name
, xAttrList
, nKey
,
1567 GetDataStylesImport()->GetLanguageForKey(nKey
), *pAutoStyles
);
1568 pAutoStyles
->AddStyle(*pContext
);
1572 if (mxAutoStyles
.is())
1573 mxAutoStyles
->dispose();
1574 mxAutoStyles
= pAutoStyles
;
1575 GetTextImport()->SetAutoStyles( pAutoStyles
);
1576 GetShapeImport()->SetAutoStylesContext( pAutoStyles
);
1577 #if !ENABLE_WASM_STRIP_CHART
1578 GetChartImport()->SetAutoStylesContext( pAutoStyles
);
1580 GetFormImport()->setAutoStyleContext( pAutoStyles
);
1583 void SvXMLImport::SetMasterStyles( SvXMLStylesContext
*pMasterStyles
)
1585 if (mxMasterStyles
.is())
1586 mxMasterStyles
->dispose();
1587 mxMasterStyles
= pMasterStyles
;
1590 XMLFontStylesContext
*SvXMLImport::GetFontDecls()
1592 return mxFontDecls
.get();
1595 SvXMLStylesContext
*SvXMLImport::GetStyles()
1597 return mxStyles
.get();
1600 SvXMLStylesContext
*SvXMLImport::GetAutoStyles()
1602 return mxAutoStyles
.get();
1605 const XMLFontStylesContext
*SvXMLImport::GetFontDecls() const
1607 return mxFontDecls
.get();
1610 const SvXMLStylesContext
*SvXMLImport::GetStyles() const
1612 return mxStyles
.get();
1615 const SvXMLStylesContext
*SvXMLImport::GetAutoStyles() const
1617 return mxAutoStyles
.get();
1620 OUString
SvXMLImport::GetAbsoluteReference(const OUString
& rValue
) const
1622 if( rValue
.isEmpty() || rValue
[0] == '#' )
1625 INetURLObject aAbsURL
;
1626 if( mpImpl
->aBaseURL
.GetNewAbsURL( rValue
, &aAbsURL
) )
1627 return aAbsURL
.GetMainURL( INetURLObject::DecodeMechanism::ToIUri
);
1632 bool SvXMLImport::IsODFVersionConsistent( const OUString
& aODFVersion
)
1634 // the check returns false only if the storage version could be retrieved
1635 bool bResult
= true;
1637 if ( !aODFVersion
.isEmpty() && aODFVersion
.compareTo( ODFVER_012_TEXT
) >= 0 )
1639 // check the consistency only for the ODF1.2 and later ( according to content.xml )
1640 // manifest.xml might have no version, it should be checked here and the correct version should be set
1642 { // don't use getDocumentStorage(), it's temporary and latest version
1643 uno::Reference
<embed::XStorage
> const xStor(GetSourceStorage());
1646 uno::Reference
< beans::XPropertySet
> xStorProps( xStor
, uno::UNO_QUERY_THROW
);
1648 // the check should be done only for OASIS format
1651 bool bRepairPackage
= false;
1654 xStorProps
->getPropertyValue( "RepairPackage" )
1656 } catch ( uno::Exception
& )
1659 // check only if not in Repair mode
1660 if ( !bRepairPackage
)
1662 OUString aStorVersion
;
1663 xStorProps
->getPropertyValue( "Version" )
1666 // if the storage version is set in manifest.xml, it must be the same as in content.xml
1667 // if not, set it explicitly to be used further ( it will work even for readonly storage )
1668 // This workaround is not nice, but I see no other way to handle it, since there are
1669 // ODF1.2 documents without version in manifest.xml
1670 if ( !aStorVersion
.isEmpty() )
1671 bResult
= aODFVersion
== aStorVersion
;
1673 xStorProps
->setPropertyValue( "Version",
1674 uno::Any( aODFVersion
) );
1678 bool bInconsistent
= false;
1679 xStorProps
->getPropertyValue( "IsInconsistent" )
1681 bResult
= !bInconsistent
;
1686 catch( uno::Exception
& )
1693 void SvXMLImport::CreateNumberFormatsSupplier_()
1695 SAL_WARN_IF( mxNumberFormatsSupplier
.is(), "xmloff.core", "number formats supplier already exists!" );
1697 mxNumberFormatsSupplier
=
1698 uno::Reference
< util::XNumberFormatsSupplier
> (mxModel
, uno::UNO_QUERY
);
1701 void SvXMLImport::CreateDataStylesImport_()
1703 SAL_WARN_IF( bool(mpNumImport
), "xmloff.core", "data styles import already exists!" );
1704 uno::Reference
<util::XNumberFormatsSupplier
> xNum
=
1705 GetNumberFormatsSupplier();
1707 mpNumImport
= std::make_unique
<SvXMLNumFmtHelper
>(xNum
, GetComponentContext() );
1710 sal_Unicode
SvXMLImport::ConvStarBatsCharToStarSymbol( sal_Unicode c
)
1712 sal_Unicode cNew
= c
;
1713 if( !mpImpl
->hBatsFontConv
)
1715 mpImpl
->hBatsFontConv
= CreateFontToSubsFontConverter( u
"StarBats",
1716 FontToSubsFontFlags::IMPORT
);
1717 SAL_WARN_IF( !mpImpl
->hBatsFontConv
, "xmloff.core", "Got no symbol font converter" );
1719 if( mpImpl
->hBatsFontConv
)
1721 cNew
= ConvertFontToSubsFontChar( mpImpl
->hBatsFontConv
, c
);
1727 sal_Unicode
SvXMLImport::ConvStarMathCharToStarSymbol( sal_Unicode c
)
1729 sal_Unicode cNew
= c
;
1730 if( !mpImpl
->hMathFontConv
)
1732 mpImpl
->hMathFontConv
= CreateFontToSubsFontConverter( u
"StarMath",
1733 FontToSubsFontFlags::IMPORT
);
1734 SAL_WARN_IF( !mpImpl
->hMathFontConv
, "xmloff.core", "Got no symbol font converter" );
1736 if( mpImpl
->hMathFontConv
)
1738 cNew
= ConvertFontToSubsFontChar( mpImpl
->hMathFontConv
, c
);
1744 void SvXMLImport::SetError(
1746 const Sequence
<OUString
>& rMsgParams
,
1747 const OUString
& rExceptionMessage
,
1748 const Reference
<xml::sax::XLocator
>& rLocator
)
1750 // create error list on demand
1752 mpXMLErrors
= std::make_unique
<XMLErrors
>();
1754 // save error information
1755 // use document locator (if none supplied)
1756 mpXMLErrors
->AddRecord( nId
, rMsgParams
, rExceptionMessage
,
1757 rLocator
.is() ? rLocator
: mxLocator
);
1760 void SvXMLImport::SetError(
1762 const Sequence
<OUString
>& rMsgParams
)
1764 SetError( nId
, rMsgParams
, "", nullptr );
1767 void SvXMLImport::SetError(
1769 const OUString
& rMsg1
)
1771 Sequence
<OUString
> aSeq
{ rMsg1
};
1772 SetError( nId
, aSeq
);
1775 void SvXMLImport::DisposingModel()
1777 if( mxFontDecls
.is() )
1778 mxFontDecls
->dispose();
1780 mxStyles
->dispose();
1781 if( mxAutoStyles
.is() )
1782 mxAutoStyles
->dispose();
1783 if( mxMasterStyles
.is() )
1784 mxMasterStyles
->dispose();
1786 mxModel
.set(nullptr);
1787 mxEventListener
.set(nullptr);
1790 ::comphelper::UnoInterfaceToUniqueIdentifierMapper
& SvXMLImport::getInterfaceToIdentifierMapper()
1792 return mpImpl
->maInterfaceToIdentifierMapper
;
1795 uno::Reference
< uno::XComponentContext
> const &
1796 SvXMLImport::GetComponentContext() const
1798 return mpImpl
->mxComponentContext
;
1801 OUString
SvXMLImport::GetBaseURL() const
1803 return mpImpl
->aBaseURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
1806 OUString
SvXMLImport::GetDocumentBase() const
1808 return mpImpl
->aDocBase
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
1811 // Convert drawing object positions from OOo file format to OASIS (#i28749#)
1812 bool SvXMLImport::IsShapePositionInHoriL2R() const
1814 return mpImpl
->mbShapePositionInHoriL2R
;
1817 bool SvXMLImport::IsTextDocInOOoFileFormat() const
1819 return mpImpl
->mbTextDocInOOoFileFormat
;
1822 void SvXMLImport::initXForms()
1824 // dummy method; to be implemented by derived classes supporting XForms
1827 bool SvXMLImport::getBuildIds( sal_Int32
& rUPD
, sal_Int32
& rBuild
) const
1830 OUString
const aBuildId(getBuildIdsProperty(mxImportInfo
));
1831 if (!aBuildId
.isEmpty())
1833 sal_Int32 nIndex
= aBuildId
.indexOf('$');
1836 rUPD
= o3tl::toInt32(aBuildId
.subView( 0, nIndex
));
1837 sal_Int32 nIndexEnd
= aBuildId
.indexOf(';', nIndex
);
1838 rBuild
= (nIndexEnd
== -1)
1839 ? o3tl::toInt32(aBuildId
.subView(nIndex
+ 1))
1840 : o3tl::toInt32(aBuildId
.subView(nIndex
+ 1, nIndexEnd
- nIndex
- 1));
1847 sal_uInt16
SvXMLImport::getGeneratorVersion() const
1850 return mpImpl
->getGeneratorVersion( *this );
1854 bool SvXMLImport::isGeneratorVersionOlderThan(
1855 sal_uInt16
const nOOoVersion
, sal_uInt16
const nLOVersion
)
1857 assert( (nLOVersion
& LO_flag
));
1858 assert(!(nOOoVersion
& LO_flag
));
1859 const sal_uInt16
nGeneratorVersion(getGeneratorVersion());
1860 return (nGeneratorVersion
& LO_flag
)
1861 ? nGeneratorVersion
< nLOVersion
1862 : nGeneratorVersion
< nOOoVersion
;
1866 OUString
SvXMLImport::GetODFVersion() const
1868 return mpImpl
->mxODFVersion
? *mpImpl
->mxODFVersion
: OUString();
1871 bool SvXMLImport::IsOOoXML() const
1873 return mpImpl
->mbIsOOoXML
;
1876 bool SvXMLImport::IsMSO() const
1878 if (!mpImpl
->mbIsMSO
.has_value())
1880 uno::Reference
<document::XDocumentPropertiesSupplier
> xSupplier(GetModel(), uno::UNO_QUERY
);
1883 uno::Reference
<document::XDocumentProperties
> xProps
1884 = xSupplier
->getDocumentProperties();
1887 mpImpl
->mbIsMSO
= xProps
->getGenerator().startsWith("MicrosoftOffice");
1892 return mpImpl
->mbIsMSO
.has_value() ? *mpImpl
->mbIsMSO
: false;
1895 // xml:id for RDF metadata
1896 void SvXMLImport::SetXmlId(uno::Reference
<uno::XInterface
> const & i_xIfc
,
1897 OUString
const & i_rXmlId
)
1899 if (i_rXmlId
.isEmpty())
1903 const uno::Reference
<rdf::XMetadatable
> xMeta(i_xIfc
,
1907 const beans::StringPair
mdref( mpImpl
->mStreamName
, i_rXmlId
);
1909 xMeta
->setMetadataReference(mdref
);
1910 } catch (lang::IllegalArgumentException
&) {
1911 // probably duplicate; ignore
1912 SAL_INFO("xmloff.core", "SvXMLImport::SetXmlId: cannot set xml:id");
1915 } catch (uno::Exception
&) {
1916 TOOLS_WARN_EXCEPTION("xmloff.core","SvXMLImport::SetXmlId");
1920 ::xmloff::RDFaImportHelper
&
1921 SvXMLImport::GetRDFaImportHelper()
1923 if (!mpImpl
->mpRDFaHelper
)
1925 mpImpl
->mpRDFaHelper
.reset( new ::xmloff::RDFaImportHelper(*this) );
1927 return *mpImpl
->mpRDFaHelper
;
1931 SvXMLImport::AddRDFa(const uno::Reference
<rdf::XMetadatable
>& i_xObject
,
1932 OUString
const & i_rAbout
,
1933 OUString
const & i_rProperty
,
1934 OUString
const & i_rContent
,
1935 OUString
const & i_rDatatype
)
1937 // N.B.: we only get called if i_xObject had xhtml:about attribute
1938 // (an empty attribute value is valid)
1939 ::xmloff::RDFaImportHelper
& rRDFaHelper( GetRDFaImportHelper() );
1940 rRDFaHelper
.ParseAndAddRDFa(i_xObject
,
1941 i_rAbout
, i_rProperty
, i_rContent
, i_rDatatype
);
1944 bool SvXMLImport::embeddedFontAlreadyProcessed( const OUString
& url
)
1946 if( embeddedFontUrlsKnown
.count( url
) != 0 )
1948 embeddedFontUrlsKnown
.insert( url
);
1952 const OUString
& SvXMLImport::getNameFromToken( sal_Int32 nToken
)
1954 return xTokenHandler
->getIdentifier( nToken
& TOKEN_MASK
);
1957 OUString
SvXMLImport::getPrefixAndNameFromToken( sal_Int32 nToken
)
1960 sal_Int32 nNamespaceToken
= ( nToken
& NMSP_MASK
) >> NMSP_SHIFT
;
1961 auto aIter( aNamespaceMap
.find( nNamespaceToken
) );
1962 if( aIter
!= aNamespaceMap
.end() )
1963 rv
= (*aIter
).second
.second
+ " " + aIter
->second
.first
+ ":";
1964 return rv
+ xTokenHandler
->getIdentifier( nToken
& TOKEN_MASK
);
1967 OUString
SvXMLImport::getNamespacePrefixFromToken(sal_Int32 nToken
, const SvXMLNamespaceMap
* pMap
)
1969 sal_Int32 nNamespaceToken
= ( nToken
& NMSP_MASK
) >> NMSP_SHIFT
;
1970 auto aIter( aNamespaceMap
.find( nNamespaceToken
) );
1971 if( aIter
!= aNamespaceMap
.end() )
1975 OUString sRet
= pMap
->GetPrefixByKey(pMap
->GetKeyByName((*aIter
).second
.second
));
1976 if (!sRet
.isEmpty())
1979 return (*aIter
).second
.first
;
1985 OUString
SvXMLImport::getNamespaceURIFromToken( sal_Int32 nToken
)
1987 sal_Int32 nNamespaceToken
= ( nToken
& NMSP_MASK
) >> NMSP_SHIFT
;
1988 auto aIter( aNamespaceMap
.find( nNamespaceToken
) );
1989 if( aIter
!= aNamespaceMap
.end() )
1990 return (*aIter
).second
.second
;
1995 OUString
SvXMLImport::getNamespacePrefixFromURI( const OUString
& rURI
)
1997 auto aIter( aNamespaceURIPrefixMap
.find(rURI
) );
1998 if( aIter
!= aNamespaceURIPrefixMap
.end() )
1999 return (*aIter
).second
;
2004 sal_Int32
SvXMLImport::getTokenFromName( std::u16string_view rName
)
2006 Sequence
< sal_Int8
> aLocalNameSeq( reinterpret_cast<sal_Int8
const *>(
2007 OUStringToOString( rName
, RTL_TEXTENCODING_UTF8
).getStr()), rName
.size() );
2008 return xTokenHandler
->getTokenFromUTF8( aLocalNameSeq
);
2011 void SvXMLImport::initializeNamespaceMaps()
2013 auto mapTokenToNamespace
= []( sal_Int32 nToken
, sal_Int32 nPrefix
, sal_Int32 nNamespace
)
2017 const OUString
& sNamespace
= GetXMLToken( static_cast<XMLTokenEnum
>( nNamespace
) );
2018 const OUString
& sPrefix
= GetXMLToken( static_cast<XMLTokenEnum
>( nPrefix
) );
2019 assert( aNamespaceMap
.find(nToken
+1) == aNamespaceMap
.end() && "cannot map two namespaces to the same token here");
2020 aNamespaceMap
[ nToken
+ 1 ] = std::make_pair( sPrefix
, sNamespace
);
2021 aNamespaceURIPrefixMap
.emplace( sNamespace
, sPrefix
);
2025 mapTokenToNamespace( XML_NAMESPACE_XML
, XML_XML
, XML_N_XML
); // implicit "xml" namespace prefix
2026 mapTokenToNamespace( XML_NAMESPACE_OFFICE
, XML_NP_OFFICE
, XML_N_OFFICE
);
2027 mapTokenToNamespace( XML_NAMESPACE_OFFICE_SO52
, XML_NP_OFFICE
, XML_N_OFFICE_OLD
);
2028 mapTokenToNamespace( XML_NAMESPACE_OFFICE_OOO
, XML_NP_OFFICE
, XML_N_OFFICE_OOO
);
2029 mapTokenToNamespace( XML_NAMESPACE_STYLE
, XML_NP_STYLE
, XML_N_STYLE
);
2030 mapTokenToNamespace( XML_NAMESPACE_STYLE_SO52
, XML_NP_STYLE
, XML_N_STYLE_OLD
);
2031 mapTokenToNamespace( XML_NAMESPACE_STYLE_OOO
, XML_NP_STYLE
, XML_N_STYLE_OOO
);
2032 mapTokenToNamespace( XML_NAMESPACE_TEXT
, XML_NP_TEXT
, XML_N_TEXT
);
2033 mapTokenToNamespace( XML_NAMESPACE_TEXT_SO52
, XML_NP_TEXT
, XML_N_TEXT_OLD
);
2034 mapTokenToNamespace( XML_NAMESPACE_TEXT_OOO
, XML_NP_TEXT
, XML_N_TEXT_OOO
);
2035 mapTokenToNamespace( XML_NAMESPACE_TABLE
, XML_NP_TABLE
, XML_N_TABLE
);
2036 mapTokenToNamespace( XML_NAMESPACE_TABLE_SO52
, XML_NP_TABLE
, XML_N_TABLE_OLD
);
2037 mapTokenToNamespace( XML_NAMESPACE_TABLE_OOO
, XML_NP_TABLE
, XML_N_TABLE_OOO
);
2038 mapTokenToNamespace( XML_NAMESPACE_DRAW
, XML_NP_DRAW
, XML_N_DRAW
);
2039 mapTokenToNamespace( XML_NAMESPACE_DRAW_SO52
, XML_NP_DRAW
, XML_N_DRAW_OLD
);
2040 mapTokenToNamespace( XML_NAMESPACE_DRAW_OOO
, XML_NP_DRAW
, XML_N_DRAW_OOO
);
2041 mapTokenToNamespace( XML_NAMESPACE_FO
, XML_NP_FO
, XML_N_FO
);
2042 mapTokenToNamespace( XML_NAMESPACE_FO_SO52
, XML_NP_FO
, XML_N_FO_OLD
);
2043 mapTokenToNamespace( XML_NAMESPACE_FO_COMPAT
, XML_NP_FO
, XML_N_FO_COMPAT
);
2044 mapTokenToNamespace( XML_NAMESPACE_XLINK
, XML_NP_XLINK
, XML_N_XLINK
);
2045 mapTokenToNamespace( XML_NAMESPACE_XLINK_SO52
, XML_NP_XLINK
, XML_N_XLINK_OLD
);
2046 mapTokenToNamespace( XML_NAMESPACE_DC
, XML_NP_DC
, XML_N_DC
);
2047 mapTokenToNamespace( XML_NAMESPACE_META
, XML_NP_META
, XML_N_META
);
2048 mapTokenToNamespace( XML_NAMESPACE_META_SO52
, XML_NP_META
, XML_N_META_OLD
);
2049 mapTokenToNamespace( XML_NAMESPACE_META_OOO
, XML_NP_META
, XML_N_META_OOO
);
2050 mapTokenToNamespace( XML_NAMESPACE_NUMBER
, XML_NP_NUMBER
, XML_N_NUMBER
);
2051 mapTokenToNamespace( XML_NAMESPACE_NUMBER_SO52
, XML_NP_NUMBER
, XML_N_NUMBER_OLD
);
2052 mapTokenToNamespace( XML_NAMESPACE_NUMBER_OOO
, XML_NP_NUMBER
, XML_N_NUMBER_OOO
);
2053 mapTokenToNamespace( XML_NAMESPACE_PRESENTATION
, XML_NP_PRESENTATION
, XML_N_PRESENTATION
);
2054 mapTokenToNamespace( XML_NAMESPACE_PRESENTATION_SO52
,XML_NP_PRESENTATION
, XML_N_PRESENTATION_OLD
);
2055 mapTokenToNamespace( XML_NAMESPACE_PRESENTATION_OOO
, XML_NP_PRESENTATION
, XML_N_PRESENTATION_OOO
);
2056 mapTokenToNamespace( XML_NAMESPACE_PRESENTATION_OASIS
, XML_NP_PRESENTATION
, XML_N_PRESENTATION_OASIS
);
2057 mapTokenToNamespace( XML_NAMESPACE_SVG
, XML_NP_SVG
, XML_N_SVG
);
2058 mapTokenToNamespace( XML_NAMESPACE_SVG_COMPAT
, XML_NP_SVG
, XML_N_SVG_COMPAT
);
2059 mapTokenToNamespace( XML_NAMESPACE_CHART
, XML_NP_CHART
, XML_N_CHART
);
2060 mapTokenToNamespace( XML_NAMESPACE_CHART_SO52
, XML_NP_CHART
, XML_N_CHART_OLD
);
2061 mapTokenToNamespace( XML_NAMESPACE_CHART_OOO
, XML_NP_CHART
, XML_N_CHART_OOO
);
2062 mapTokenToNamespace( XML_NAMESPACE_DR3D
, XML_NP_DR3D
, XML_N_DR3D
);
2063 mapTokenToNamespace( XML_NAMESPACE_DR3D_OOO
, XML_NP_DR3D
, XML_N_DR3D_OOO
);
2064 mapTokenToNamespace( XML_NAMESPACE_MATH
, XML_NP_MATH
, XML_N_MATH
);
2065 mapTokenToNamespace( XML_NAMESPACE_VERSIONS_LIST
, XML_NP_VERSIONS_LIST
, XML_N_VERSIONS_LIST
);
2066 mapTokenToNamespace( XML_NAMESPACE_FORM
, XML_NP_FORM
, XML_N_FORM
);
2067 mapTokenToNamespace( XML_NAMESPACE_FORM_OOO
, XML_NP_FORM
, XML_N_FORM_OOO
);
2068 mapTokenToNamespace( XML_NAMESPACE_SCRIPT
, XML_NP_SCRIPT
, XML_N_SCRIPT
);
2069 mapTokenToNamespace( XML_NAMESPACE_SCRIPT_OOO
, XML_NP_SCRIPT
, XML_N_SCRIPT_OOO
);
2070 mapTokenToNamespace( XML_NAMESPACE_BLOCKLIST
, XML_NP_BLOCK_LIST
, XML_N_BLOCK_LIST
);
2071 mapTokenToNamespace( XML_NAMESPACE_CONFIG
, XML_NP_CONFIG
, XML_N_CONFIG
);
2072 mapTokenToNamespace( XML_NAMESPACE_CONFIG_OOO
, XML_NP_CONFIG
, XML_N_CONFIG_OOO
);
2073 mapTokenToNamespace( XML_NAMESPACE_OOO
, XML_NP_OOO
, XML_N_OOO
);
2074 mapTokenToNamespace( XML_NAMESPACE_OOOW
, XML_NP_OOOW
, XML_N_OOOW
);
2075 mapTokenToNamespace( XML_NAMESPACE_OOOC
, XML_NP_OOOC
, XML_N_OOOC
);
2076 mapTokenToNamespace( XML_NAMESPACE_DOM
, XML_NP_DOM
, XML_N_DOM
);
2077 mapTokenToNamespace( XML_NAMESPACE_DB
, XML_NP_DB
, XML_N_DB
);
2078 mapTokenToNamespace( XML_NAMESPACE_DB_OASIS
, XML_NP_DB
, XML_N_DB_OASIS
);
2079 mapTokenToNamespace( XML_NAMESPACE_DLG
, XML_NP_DLG
, XML_N_DLG
);
2080 mapTokenToNamespace( XML_NAMESPACE_XFORMS
, XML_NP_XFORMS_1_0
, XML_N_XFORMS_1_0
);
2081 mapTokenToNamespace( XML_NAMESPACE_XSD
, XML_NP_XSD
, XML_N_XSD
);
2082 mapTokenToNamespace( XML_NAMESPACE_XSI
, XML_NP_XSI
, XML_N_XSI
);
2083 mapTokenToNamespace( XML_NAMESPACE_SMIL
, XML_NP_SMIL
, XML_N_SMIL
);
2084 mapTokenToNamespace( XML_NAMESPACE_SMIL_SO52
, XML_NP_SMIL
, XML_N_SMIL_OLD
);
2085 mapTokenToNamespace( XML_NAMESPACE_SMIL_COMPAT
, XML_NP_SMIL
, XML_N_SMIL_COMPAT
);
2086 mapTokenToNamespace( XML_NAMESPACE_ANIMATION
, XML_NP_ANIMATION
, XML_N_ANIMATION
);
2087 mapTokenToNamespace( XML_NAMESPACE_ANIMATION_OOO
, XML_NP_ANIMATION
, XML_N_ANIMATION_OOO
);
2088 mapTokenToNamespace( XML_NAMESPACE_REPORT
, XML_NP_RPT
, XML_N_RPT
);
2089 mapTokenToNamespace( XML_NAMESPACE_REPORT_OASIS
, XML_NP_RPT
, XML_N_RPT_OASIS
);
2090 mapTokenToNamespace( XML_NAMESPACE_OF
, XML_NP_OF
, XML_N_OF
);
2091 mapTokenToNamespace( XML_NAMESPACE_XHTML
, XML_NP_XHTML
, XML_N_XHTML
);
2092 mapTokenToNamespace( XML_NAMESPACE_GRDDL
, XML_NP_GRDDL
, XML_N_GRDDL
);
2093 mapTokenToNamespace( XML_NAMESPACE_OFFICE_EXT
, XML_NP_OFFICE_EXT
, XML_N_OFFICE_EXT
);
2094 mapTokenToNamespace( XML_NAMESPACE_TABLE_EXT
, XML_NP_TABLE_EXT
, XML_N_TABLE_EXT
);
2095 mapTokenToNamespace( XML_NAMESPACE_CHART_EXT
, XML_NP_CHART_EXT
, XML_N_CHART_EXT
);
2096 mapTokenToNamespace( XML_NAMESPACE_DRAW_EXT
, XML_NP_DRAW_EXT
, XML_N_DRAW_EXT
);
2097 mapTokenToNamespace( XML_NAMESPACE_CALC_EXT
, XML_NP_CALC_EXT
, XML_N_CALC_EXT
);
2098 mapTokenToNamespace( XML_NAMESPACE_LO_EXT
, XML_NP_LO_EXT
, XML_N_LO_EXT
);
2099 mapTokenToNamespace( XML_NAMESPACE_CSS3TEXT
, XML_NP_CSS3TEXT
, XML_N_CSS3TEXT
);
2100 mapTokenToNamespace( XML_NAMESPACE_FIELD
, XML_NP_FIELD
, XML_N_FIELD
);
2101 mapTokenToNamespace( XML_NAMESPACE_FORMX
, XML_NP_FORMX
, XML_N_FORMX
);
2104 void SvXMLImport::registerNamespaces()
2106 for( auto const &aNamespaceEntry
: aNamespaceMap
)
2108 // aNamespaceMap = { Token : ( NamespacePrefix, NamespaceURI ) }
2109 registerNamespace( aNamespaceEntry
.second
.second
, aNamespaceEntry
.first
<< NMSP_SHIFT
);
2113 void SvXMLImport::NotifyMacroEventRead()
2115 if (mbNotifyMacroEventRead
)
2118 comphelper::DocumentInfo::notifyMacroEventRead(mxModel
);
2120 mbNotifyMacroEventRead
= true;
2123 SvXMLImportFastNamespaceHandler::SvXMLImportFastNamespaceHandler()
2127 void SvXMLImportFastNamespaceHandler::addNSDeclAttributes( rtl::Reference
< comphelper::AttributeList
> const & rAttrList
)
2129 for(const auto& aNamespaceDefine
: m_aNamespaceDefines
)
2131 const OUString
& rPrefix
= aNamespaceDefine
.m_aPrefix
;
2132 const OUString
& rNamespaceURI
= aNamespaceDefine
.m_aNamespaceURI
;
2134 if ( rPrefix
.isEmpty() )
2137 sDecl
= "xmlns:" + rPrefix
;
2138 rAttrList
->AddAttribute( sDecl
, "CDATA", rNamespaceURI
);
2140 m_aNamespaceDefines
.clear();
2143 void SvXMLImportFastNamespaceHandler::registerNamespace( const OUString
& rNamespacePrefix
, const OUString
& rNamespaceURI
)
2145 // Elements with default namespace parsed by FastParser have namespace prefix.
2146 // A default namespace needs to be registered with the prefix, to maintain the compatibility.
2147 if ( rNamespacePrefix
.isEmpty() )
2148 m_aNamespaceDefines
.push_back( NamespaceDefine(
2149 SvXMLImport::getNamespacePrefixFromURI( rNamespaceURI
), rNamespaceURI
) );
2151 m_aNamespaceDefines
.push_back( NamespaceDefine(
2152 rNamespacePrefix
, rNamespaceURI
) );
2155 OUString
SvXMLImportFastNamespaceHandler::getNamespaceURI( const OUString
&/* rNamespacePrefix */ )
2160 SvXMLLegacyToFastDocHandler::SvXMLLegacyToFastDocHandler( rtl::Reference
< SvXMLImport
> xImport
)
2161 : mrImport(std::move( xImport
)),
2162 mxFastAttributes( new sax_fastparser::FastAttributeList( SvXMLImport::xTokenHandler
.get() ) )
2166 void SAL_CALL
SvXMLLegacyToFastDocHandler::setTargetDocument( const uno::Reference
< lang::XComponent
>& xDoc
)
2168 mrImport
->setTargetDocument( xDoc
);
2171 void SAL_CALL
SvXMLLegacyToFastDocHandler::startDocument()
2173 mrImport
->startDocument();
2176 void SAL_CALL
SvXMLLegacyToFastDocHandler::endDocument()
2178 mrImport
->endDocument();
2181 void SAL_CALL
SvXMLLegacyToFastDocHandler::startElement( const OUString
& rName
,
2182 const uno::Reference
< xml::sax::XAttributeList
>& xAttrList
)
2184 sal_uInt16 nDefaultNamespace
= XML_NAMESPACE_UNKNOWN
;
2185 if (!maDefaultNamespaces
.empty())
2186 nDefaultNamespace
= maDefaultNamespaces
.top();
2187 SvXMLImport::processNSAttributes(mrImport
->mxNamespaceMap
, mrImport
.get(), xAttrList
);
2188 OUString aLocalName
;
2189 sal_uInt16 nPrefix
= mrImport
->mxNamespaceMap
->GetKeyByAttrName( rName
, &aLocalName
);
2190 sal_Int32 mnElement
= NAMESPACE_TOKEN( nPrefix
) | SvXMLImport::getTokenFromName( aLocalName
);
2191 mxFastAttributes
->clear();
2193 sal_Int16 nAttrCount
= xAttrList
.is() ? xAttrList
->getLength() : 0;
2194 for( sal_Int16 i
=0; i
< nAttrCount
; i
++ )
2196 const OUString
& rAttrName
= xAttrList
->getNameByIndex( i
);
2197 const OUString
& rAttrValue
= xAttrList
->getValueByIndex( i
);
2198 if (rAttrName
== "xmlns")
2200 sal_uInt16 nNamespaceKey
= mrImport
->mxNamespaceMap
->GetKeyByName(rAttrValue
);
2201 if (nNamespaceKey
!= XML_NAMESPACE_UNKNOWN
)
2203 nDefaultNamespace
= nNamespaceKey
;
2206 assert(false && "unknown namespace");
2208 else if (rAttrName
.indexOf(":") == -1 && nDefaultNamespace
!= XML_NAMESPACE_UNKNOWN
)
2210 auto const nToken
= SvXMLImport::getTokenFromName(rAttrName
);
2211 if (nToken
== xmloff::XML_TOKEN_INVALID
)
2213 mxFastAttributes
->addUnknown(mrImport
->mxNamespaceMap
->GetNameByKey(nDefaultNamespace
),
2214 OUStringToOString(rAttrName
, RTL_TEXTENCODING_UTF8
),
2215 OUStringToOString(rAttrValue
, RTL_TEXTENCODING_UTF8
));
2219 sal_Int32
const nAttr
= NAMESPACE_TOKEN(nDefaultNamespace
) | nToken
;
2220 mxFastAttributes
->add(nAttr
, OUStringToOString(rAttrValue
, RTL_TEXTENCODING_UTF8
));
2225 OUString aLocalAttrName
;
2226 OUString aNamespace
;
2227 // don't add unknown namespaces to the map
2228 sal_uInt16
const nAttrPrefix
= mrImport
->mxNamespaceMap
->GetKeyByQName(
2229 rAttrName
, nullptr, &aLocalAttrName
, &aNamespace
, SvXMLNamespaceMap::QNameMode::AttrValue
);
2230 if( XML_NAMESPACE_XMLNS
== nAttrPrefix
)
2232 auto const nToken
= SvXMLImport::getTokenFromName(aLocalAttrName
);
2233 if (XML_NAMESPACE_UNKNOWN
== nAttrPrefix
|| nToken
== xmloff::XML_TOKEN_INVALID
)
2235 mxFastAttributes
->addUnknown(aNamespace
,
2236 OUStringToOString(rAttrName
, RTL_TEXTENCODING_UTF8
),
2237 OUStringToOString(rAttrValue
, RTL_TEXTENCODING_UTF8
));
2241 sal_Int32
const nAttr
= NAMESPACE_TOKEN(nAttrPrefix
) | nToken
;
2242 mxFastAttributes
->add(nAttr
, OUStringToOString(rAttrValue
, RTL_TEXTENCODING_UTF8
));
2245 mrImport
->startFastElement( mnElement
, mxFastAttributes
);
2246 maDefaultNamespaces
.push(nDefaultNamespace
);
2249 void SAL_CALL
SvXMLLegacyToFastDocHandler::endElement( const OUString
& rName
)
2251 OUString aLocalName
;
2252 sal_uInt16 nPrefix
= mrImport
->mxNamespaceMap
->GetKeyByAttrName( rName
, &aLocalName
);
2253 sal_Int32 mnElement
= NAMESPACE_TOKEN( nPrefix
) | SvXMLImport::getTokenFromName(aLocalName
);
2254 mrImport
->endFastElement( mnElement
);
2255 maDefaultNamespaces
.pop();
2258 void SAL_CALL
SvXMLLegacyToFastDocHandler::characters( const OUString
& aChars
)
2260 mrImport
->characters( aChars
);
2263 void SAL_CALL
SvXMLLegacyToFastDocHandler::ignorableWhitespace( const OUString
& )
2267 void SAL_CALL
SvXMLLegacyToFastDocHandler::processingInstruction( const OUString
& aTarget
,
2268 const OUString
& aData
)
2270 mrImport
->processingInstruction( aTarget
, aData
);
2273 void SAL_CALL
SvXMLLegacyToFastDocHandler::setDocumentLocator( const uno::Reference
< xml::sax::XLocator
>& rLocator
)
2275 mrImport
->setDocumentLocator( rLocator
);
2280 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */