Update git submodules
[LibreOffice.git] / xmloff / source / core / xmlimp.cxx
blob54ef1abfebba0d82d6760aad4d779bd574c55790
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
22 #include <memory>
23 #include <optional>
25 #include <comphelper/diagnose_ex.hxx>
26 #include <sal/log.hxx>
27 #include <com/sun/star/beans/XPropertySetInfo.hpp>
28 #include <tools/urlobj.hxx>
29 #include <utility>
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;
96 namespace {
98 class SvXMLImportEventListener : public cppu::WeakImplHelper< css::lang::XEventListener >
100 private:
101 SvXMLImport* pImport;
103 public:
104 explicit SvXMLImportEventListener(SvXMLImport* pImport);
106 // XEventListener
107 virtual void SAL_CALL disposing(const lang::EventObject& rEventObject) override;
112 SvXMLImportEventListener::SvXMLImportEventListener(SvXMLImport* pTempImport)
113 : pImport(pTempImport)
117 // XEventListener
118 void SAL_CALL SvXMLImportEventListener::disposing( const lang::EventObject& )
120 if (pImport)
122 pImport->DisposingModel();
123 pImport = nullptr;
127 namespace
130 OUString
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))
141 OUString aBuildId;
142 xImportInfo->getPropertyValue(u"BuildId"_ustr) >>= aBuildId;
143 return aBuildId;
146 catch (Exception const&)
148 DBG_UNHANDLED_EXCEPTION("xmloff.core", "exception getting BuildId");
151 return OUString();
154 class DocumentInfo
156 private:
157 sal_uInt16 mnGeneratorVersion;
159 public:
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(';');
168 if (-1 != ix)
170 OUString const loVersion(buildIds.copy(ix + 1));
171 if (!loVersion.isEmpty())
173 auto const firstDot(loVersion.indexOf('.'));
174 if (firstDot == 1)
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
212 else
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
223 else
225 mnGeneratorVersion = SvXMLImport::LO_7x;
228 else
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());
238 if (0 < year)
240 mnGeneratorVersion = SvXMLImport::LO_New;
242 else
244 SAL_INFO("xmloff.core", "unknown LO version: " << loVersion);
247 else
249 SAL_INFO("xmloff.core", "unknown LO version: " << loVersion);
251 return; // ignore buildIds
255 sal_Int32 nUPD, nBuild;
256 if ( !rImport.getBuildIds( nUPD, nBuild ) )
257 return;
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
309 public:
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;
323 bool mbIsOOoXML;
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 )
350 , mbIsOOoXML(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 )
366 if (!moDocumentInfo)
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*/ )
380 assert(false);
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" );
458 InitCtor_();
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();
481 maContexts.pop();
483 if( mxTextImport )
484 mxTextImport->dispose();
485 mxTextImport.clear(); // XMLRedlineImportHelper needs model
486 DisposingModel();
489 SvXMLImport::~SvXMLImport() noexcept
491 cleanup();
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);
503 namespace
505 class setFastDocumentHandlerGuard
507 private:
508 css::uno::Reference<css::xml::sax::XFastParser> mxParser;
509 public:
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);
524 // XFastParser
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())
580 return;
582 Reference< lang::XMultiServiceFactory > xFactory( mxModel, UNO_QUERY );
583 if( !xFactory.is() )
584 return;
588 if (!mxGraphicStorageHandler.is())
590 // #99870# Import... instead of Export...
591 mxGraphicStorageHandler.set(
592 xFactory->createInstance(u"com.sun.star.document.ImportGraphicStorageHandler"_ustr),
593 UNO_QUERY);
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),
602 UNO_QUERY);
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.
617 if (mxTextImport)
618 mxTextImport->MapCrossRefHeadingFieldsHorribly();
620 if (mpImpl->mpRDFaHelper)
622 const uno::Reference<rdf::XRepositorySupplier> xRS(mxModel,
623 uno::UNO_QUERY);
624 if (xRS.is())
626 mpImpl->mpRDFaHelper->InsertRDFa( xRS );
630 mpNumImport.reset();
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();
663 if( mxStyles.is() )
664 mxStyles->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);
682 xComp->dispose();
685 if( mpImpl->mbOwnEmbeddedResolver )
687 Reference< lang::XComponent > xComp( mxEmbeddedResolver, UNO_QUERY );
688 xComp->dispose();
690 mpStyleMap.clear();
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 >(),
718 uno::Any(
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] ) )
726 if( !pRewindMap )
728 pRewindMap = std::move(rpNamespaceMap);
729 rpNamespaceMap.emplace(*pRewindMap);
731 const OUString aAttrValue = xAttrList->getValueByIndex( i );
733 OUString aPrefix( ( aAttrName.getLength() == 5 )
734 ? OUString()
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
739 // TC Id and version
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 );
752 return pRewindMap;
756 void SAL_CALL SvXMLImport::characters( const OUString& rChars )
758 maContexts.top()->characters( rChars );
761 void SAL_CALL SvXMLImport::processingInstruction( const OUString&,
762 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 >(),
790 uno::Any(
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));
811 else
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>() );
821 if ( !xContext )
822 xContext.set( new SvXMLImportContext( *this ) );
824 // Remember old namespace map.
825 if( pRewindMap )
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));
849 else
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>() );
858 if (!xContext)
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();
864 else
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");
878 assert(false);
879 return;
881 SvXMLImportContextRef xContext = std::move(maContexts.top());
882 // Get a namespace map to rewind.
883 std::optional<SvXMLNamespaceMap> pRewindMap = xContext->TakeRewindMap();
884 maContexts.pop();
885 xContext->endFastElement( Element );
886 // Rewind a namespace map.
887 if (pRewindMap)
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");
897 assert(false);
898 return;
900 SvXMLImportContextRef xContext = std::move(maContexts.top());
901 maContexts.pop();
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 > &)
909 return this;
912 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
913 SvXMLImport::createUnknownChildContext (const OUString &, const OUString &,
914 const uno::Reference< xml::sax::XFastAttributeList > &)
916 return this;
919 void SvXMLImport::SetStatistics(const uno::Sequence< beans::NamedValue> &)
921 GetProgressBarHelper()->SetRepeat(false);
922 GetProgressBarHelper()->SetReference(0);
925 // XImporter
926 void SAL_CALL SvXMLImport::setTargetDocument( const uno::Reference< lang::XComponent >& xDoc )
928 mxModel.set( xDoc, UNO_QUERY );
929 if( !mxModel.is() )
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()
936 : nullptr);
937 if (xStor.is())
939 mpImpl->mbIsOOoXML =
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." );
955 mpNumImport.reset();
958 // XFilter
959 sal_Bool SAL_CALL SvXMLImport::filter( const uno::Sequence< beans::PropertyValue >& )
961 return false;
964 void SAL_CALL SvXMLImport::cancel( )
968 // XInitialize
969 void SAL_CALL SvXMLImport::initialize( const uno::Sequence< uno::Any >& aArguments )
971 for( const auto& rAny : aArguments )
973 Reference<XInterface> xValue;
974 rAny >>= xValue;
976 uno::Reference<task::XStatusIndicator> xTmpStatusIndicator(
977 xValue, UNO_QUERY );
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(
986 xValue, UNO_QUERY );
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);
1009 aAny >>= xIfc;
1011 StyleMap *pSMap = dynamic_cast<StyleMap*>( xIfc.get() );
1012 if( pSMap )
1014 mpStyleMap = pSMap;
1017 OUString sBaseURI;
1018 sPropName = "BaseURI";
1019 if (xPropertySetInfo->hasPropertyByName(sPropName))
1021 uno::Any aAny = mxImportInfo->getPropertyValue(sPropName);
1022 aAny >>= sBaseURI;
1023 mpImpl->aBaseURL.SetURL( sBaseURI );
1024 mpImpl->aDocBase.SetURL( sBaseURI );
1026 OUString sRelPath;
1027 sPropName = "StreamRelPath";
1028 if( xPropertySetInfo->hasPropertyByName(sPropName) )
1030 uno::Any aAny = mxImportInfo->getPropertyValue(sPropName);
1031 aAny >>= sRelPath;
1033 OUString sName;
1034 sPropName = "StreamName";
1035 if( xPropertySetInfo->hasPropertyByName(sPropName) )
1037 uno::Any aAny = mxImportInfo->getPropertyValue(sPropName);
1038 aAny >>= sName;
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) });
1072 // XServiceInfo
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();
1107 #else
1108 return nullptr;
1109 #endif
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() )
1125 if( mxModel.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() )
1148 if( mxModel.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() )
1171 if( mxModel.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() )
1194 if( mxModel.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() )
1217 if( mxModel.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 )
1260 return false;
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
1268 return false;
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
1274 return false;
1275 else if( '/' == rURL[1] )
1276 // we are remaining on a level, so it's a package URI
1277 return true;
1280 // Now check for a RFC2396 schema
1281 size_t nPos = 1;
1282 while( nPos < nLen )
1284 switch( rURL[nPos] )
1286 case '/':
1287 // a relative path segment
1288 return true;
1289 case ':':
1290 // a schema
1291 return false;
1292 default:
1293 break;
1294 // we don't care about any other characters
1296 ++nPos;
1299 return true;
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);
1314 else
1316 OUString const aAbsoluteURL = GetAbsoluteReference(rURL);
1317 GraphicExternalLink aExternalLink(aAbsoluteURL);
1318 Graphic aGraphic(aExternalLink);
1319 xGraphic = aGraphic.GetXGraphic();
1323 catch (...)
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)
1337 throw;
1340 return xGraphic;
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);
1352 return xGraphic;
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();
1363 return xOStm;
1366 OUString SvXMLImport::ResolveEmbeddedObjectURL(
1367 const OUString& rURL,
1368 std::u16string_view rClassId )
1370 OUString sRet;
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 );
1384 else
1385 sRet = GetAbsoluteReference( rURL );
1387 return sRet;
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 );
1403 if( xNA.is() )
1405 Any aAny = xNA->getByName( u"Obj12345678"_ustr );
1406 aAny >>= xOLEStream;
1410 return xOLEStream;
1413 OUString SvXMLImport::ResolveEmbeddedObjectURLFromBase64()
1415 OUString sRet;
1417 if( mxEmbeddedResolver.is() )
1419 sRet = mxEmbeddedResolver->resolveEmbeddedObjectURL( u"Obj12345678"_ustr );
1422 return sRet;
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,
1451 "xmloff.core",
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;
1467 return sName;
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))
1501 uno::Any aAny;
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));
1520 else {
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");
1545 else {
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
1555 // event tables
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 )
1582 if (mxStyles.is())
1583 mxStyles->dispose();
1584 mxStyles = pStyles;
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));
1596 sal_Int32 nKey(0);
1597 if (aAny >>= nKey)
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 );
1613 #endif
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] == '#' )
1657 return rValue;
1659 INetURLObject aAbsURL;
1660 if( mpImpl->aBaseURL.GetNewAbsURL( rValue, &aAbsURL ) )
1661 return aAbsURL.GetMainURL( INetURLObject::DecodeMechanism::ToIUri );
1662 else
1663 return rValue;
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());
1678 if (!xStor.is())
1679 return bResult;
1680 uno::Reference< beans::XPropertySet > xStorProps( xStor, uno::UNO_QUERY_THROW );
1682 // the check should be done only for OASIS format
1683 if (!IsOOoXML())
1685 bool bRepairPackage = false;
1688 xStorProps->getPropertyValue( u"RepairPackage"_ustr )
1689 >>= bRepairPackage;
1690 } catch ( uno::Exception& )
1693 // check only if not in Repair mode
1694 if ( !bRepairPackage )
1696 OUString aStorVersion;
1697 xStorProps->getPropertyValue( u"Version"_ustr )
1698 >>= aStorVersion;
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;
1706 else
1707 xStorProps->setPropertyValue( u"Version"_ustr,
1708 uno::Any( aODFVersion ) );
1710 if ( bResult )
1712 bool bInconsistent = false;
1713 xStorProps->getPropertyValue( u"IsInconsistent"_ustr )
1714 >>= bInconsistent;
1715 bResult = !bInconsistent;
1720 catch( uno::Exception& )
1724 return bResult;
1727 void SvXMLImport::CreateNumberFormatsSupplier_()
1729 SAL_WARN_IF( mxNumberFormatsSupplier.is(), "xmloff.core", "number formats supplier already exists!" );
1730 if(mxModel.is())
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();
1740 if ( xNum.is() )
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 );
1758 return cNew;
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 );
1775 return cNew;
1778 void SvXMLImport::SetError(
1779 sal_Int32 nId,
1780 const Sequence<OUString>& rMsgParams,
1781 const OUString& rExceptionMessage,
1782 const Reference<xml::sax::XLocator>& rLocator )
1784 // create error list on demand
1785 if ( !mpXMLErrors )
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(
1795 sal_Int32 nId,
1796 const Sequence<OUString>& rMsgParams)
1798 SetError( nId, rMsgParams, u""_ustr, nullptr );
1801 void SvXMLImport::SetError(
1802 sal_Int32 nId,
1803 const OUString& rMsg1)
1805 Sequence<OUString> aSeq { rMsg1 };
1806 SetError( nId, aSeq );
1809 void SvXMLImport::DisposingModel()
1811 if( mxFontDecls.is() )
1812 mxFontDecls->dispose();
1813 if( mxStyles.is() )
1814 mxStyles->dispose();
1815 if( mxAutoStyles.is() )
1816 mxAutoStyles->dispose();
1817 if( mxMasterStyles.is() )
1818 mxMasterStyles->dispose();
1820 mxModel.clear();
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
1863 bool bRet = false;
1864 OUString const aBuildId(getBuildIdsProperty(mxImportInfo));
1865 if (!aBuildId.isEmpty())
1867 sal_Int32 nIndex = aBuildId.indexOf('$');
1868 if (nIndex != -1)
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));
1875 bRet = true;
1878 return bRet;
1881 sal_uInt16 SvXMLImport::getGeneratorVersion() const
1883 // --> ORW
1884 return mpImpl->getGeneratorVersion( *this );
1885 // <--
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);
1915 if (xSupplier.is())
1917 uno::Reference<document::XDocumentProperties> xProps
1918 = xSupplier->getDocumentProperties();
1919 if (xProps.is())
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())
1934 return;
1936 try {
1937 const uno::Reference<rdf::XMetadatable> xMeta(i_xIfc,
1938 uno::UNO_QUERY);
1939 //FIXME: not yet
1940 if (xMeta.is()) {
1941 const beans::StringPair mdref( mpImpl->mStreamName, i_rXmlId );
1942 try {
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;
1964 void
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 )
1981 return true;
1982 m_embeddedFontUrlsKnown.insert( url );
1983 return false;
1986 const OUString & SvXMLImport::getNameFromToken( sal_Int32 nToken )
1988 return FastTokenHandler::getIdentifier( nToken & TOKEN_MASK );
1991 OUString SvXMLImport::getPrefixAndNameFromToken( sal_Int32 nToken )
1993 OUString rv;
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() )
2007 if (pMap)
2009 OUString sRet = pMap->GetPrefixByKey(pMap->GetKeyByName((*aIter).second.second));
2010 if (!sRet.isEmpty())
2011 return sRet;
2013 return (*aIter).second.first;
2015 else
2016 return OUString();
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;
2025 else
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;
2034 else
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 )
2049 if ( nToken >= 0 )
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)
2150 return;
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;
2167 OUString sDecl;
2168 if ( rPrefix.isEmpty() )
2169 sDecl = "xmlns";
2170 else
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 */ )
2191 return OUString();
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;
2238 continue;
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));
2251 else
2253 sal_Int32 const nAttr = NAMESPACE_TOKEN(nDefaultNamespace) | nToken;
2254 mxFastAttributes->add(nAttr, OUStringToOString(aAttrValue, RTL_TEXTENCODING_UTF8));
2256 continue;
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 )
2265 continue; // ignore
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));
2273 else
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: */