Version 24.2.2.2, tag libreoffice-24.2.2.2
[LibreOffice.git] / xmloff / source / core / xmlimp.cxx
blob209c141fb0d40286cc5ac71a07c2c0b77758c914
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/XUnoTunnel.hpp>
50 #include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
51 #include <com/sun/star/io/XOutputStream.hpp>
52 #include <com/sun/star/util/MeasureUnit.hpp>
53 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
54 #include <com/sun/star/frame/XModel.hpp>
55 #include <com/sun/star/document/XBinaryStreamResolver.hpp>
56 #include <com/sun/star/document/XStorageBasedDocument.hpp>
57 #include <com/sun/star/document/XGraphicStorageHandler.hpp>
58 #include <com/sun/star/document/XEmbeddedObjectResolver.hpp>
59 #include <com/sun/star/xml/sax/XLocator.hpp>
60 #include <com/sun/star/xml/sax/FastParser.hpp>
61 #include <com/sun/star/xml/sax/SAXException.hpp>
62 #include <com/sun/star/packages/zip/ZipIOException.hpp>
63 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
64 #include <comphelper/fileformat.h>
65 #include <comphelper/namecontainer.hxx>
66 #include <comphelper/servicehelper.hxx>
67 #include <comphelper/string.hxx>
68 #include <cppuhelper/implbase.hxx>
69 #include <cppuhelper/supportsservice.hxx>
70 #include <comphelper/extract.hxx>
71 #include <comphelper/documentconstants.hxx>
72 #include <comphelper/documentinfo.hxx>
73 #include <comphelper/storagehelper.hxx>
74 #include <comphelper/attributelist.hxx>
75 #include <unotools/fontcvt.hxx>
76 #include <fasttokenhandler.hxx>
77 #include <vcl/GraphicExternalLink.hxx>
78 #include <o3tl/string_view.hxx>
80 #include <com/sun/star/rdf/XMetadatable.hpp>
81 #include <com/sun/star/rdf/XRepositorySupplier.hpp>
82 #include <RDFaImportHelper.hxx>
84 using ::com::sun::star::beans::XPropertySetInfo;
86 using namespace ::com::sun::star;
87 using namespace ::com::sun::star::uno;
88 using namespace ::com::sun::star::util;
89 using namespace ::com::sun::star::io;
90 using namespace ::com::sun::star::container;
91 using namespace ::com::sun::star::document;
92 using namespace ::xmloff::token;
94 rtl::Reference< FastTokenHandler > SvXMLImport::xTokenHandler( new FastTokenHandler() );
95 std::unordered_map< sal_Int32, std::pair< OUString, OUString > > SvXMLImport::aNamespaceMap;
96 std::unordered_map< OUString, OUString > SvXMLImport::aNamespaceURIPrefixMap;
97 bool SvXMLImport::bIsNSMapsInitialized = false;
99 namespace {
101 class SvXMLImportEventListener : public cppu::WeakImplHelper< css::lang::XEventListener >
103 private:
104 SvXMLImport* pImport;
106 public:
107 explicit SvXMLImportEventListener(SvXMLImport* pImport);
109 // XEventListener
110 virtual void SAL_CALL disposing(const lang::EventObject& rEventObject) override;
115 SvXMLImportEventListener::SvXMLImportEventListener(SvXMLImport* pTempImport)
116 : pImport(pTempImport)
120 // XEventListener
121 void SAL_CALL SvXMLImportEventListener::disposing( const lang::EventObject& )
123 if (pImport)
125 pImport->DisposingModel();
126 pImport = nullptr;
130 namespace
133 OUString
134 getBuildIdsProperty(uno::Reference<beans::XPropertySet> const& xImportInfo)
136 if (xImportInfo.is())
140 Reference< XPropertySetInfo > const xSetInfo(
141 xImportInfo->getPropertySetInfo());
142 if (xSetInfo.is() && xSetInfo->hasPropertyByName("BuildId"))
144 OUString aBuildId;
145 xImportInfo->getPropertyValue("BuildId") >>= aBuildId;
146 return aBuildId;
149 catch (Exception const&)
151 DBG_UNHANDLED_EXCEPTION("xmloff.core", "exception getting BuildId");
154 return OUString();
157 class DocumentInfo
159 private:
160 sal_uInt16 mnGeneratorVersion;
162 public:
163 explicit DocumentInfo( const SvXMLImport& rImport )
164 : mnGeneratorVersion( SvXMLImport::ProductVersionUnknown )
166 OUString const buildIds(
167 getBuildIdsProperty(rImport.getImportInfo()));
168 if (!buildIds.isEmpty())
170 sal_Int32 const ix = buildIds.indexOf(';');
171 if (-1 != ix)
173 OUString const loVersion(buildIds.copy(ix + 1));
174 if (!loVersion.isEmpty())
176 auto const firstDot(loVersion.indexOf('.'));
177 if (firstDot == 1)
178 { // old version scheme 3.3 ... 7.6
179 if ('3' == loVersion[0])
181 mnGeneratorVersion = SvXMLImport::LO_3x;
183 else if ('4' == loVersion[0])
185 if (loVersion.getLength() > 2
186 && (loVersion[2] == '0' || loVersion[2] == '1'))
188 mnGeneratorVersion = SvXMLImport::LO_41x; // 4.0/4.1
190 else if (loVersion.getLength() > 2 && '2' == loVersion[2])
192 mnGeneratorVersion = SvXMLImport::LO_42x; // 4.2
194 else if (loVersion.getLength() > 2 && '3' == loVersion[2])
196 mnGeneratorVersion = SvXMLImport::LO_43x; // 4.3
198 else if (loVersion.getLength() > 2 && '4' == loVersion[2])
200 mnGeneratorVersion = SvXMLImport::LO_44x; // 4.4
203 else if ('5' == loVersion[0])
205 mnGeneratorVersion = SvXMLImport::LO_5x;
207 else if ('6' == loVersion[0])
209 if (loVersion.getLength() > 2
210 && (loVersion[2] == '0' || loVersion[2] == '1'
211 || loVersion[2] == '2'))
213 mnGeneratorVersion = SvXMLImport::LO_6x; // 6.0/6.1/6.2
215 else
217 mnGeneratorVersion = SvXMLImport::LO_63x; // 6.3/6.4
220 else if ('7' == loVersion[0])
222 if (loVersion.getLength() > 2 && loVersion[2] == '6')
224 mnGeneratorVersion = SvXMLImport::LO_76; // 7.6
226 else
228 mnGeneratorVersion = SvXMLImport::LO_7x;
231 else
233 SAL_INFO("xmloff.core", "unknown LO version: " << loVersion);
236 else if (1 < firstDot) // new version scheme 24.2 ...
238 OUString const nMajor(loVersion.subView(0, firstDot));
239 auto const year(nMajor.toInt32());
240 //auto const month(loVersion.copy(firstDot+1).toInt32());
241 if (0 < year)
243 mnGeneratorVersion = SvXMLImport::LO_New;
245 else
247 SAL_INFO("xmloff.core", "unknown LO version: " << loVersion);
250 else
252 SAL_INFO("xmloff.core", "unknown LO version: " << loVersion);
254 return; // ignore buildIds
258 sal_Int32 nUPD, nBuild;
259 if ( !rImport.getBuildIds( nUPD, nBuild ) )
260 return;
262 if ( nUPD >= 640 && nUPD <= 645 )
264 mnGeneratorVersion = SvXMLImport::OOo_1x;
266 else if ( nUPD == 680 )
268 mnGeneratorVersion = SvXMLImport::OOo_2x;
270 else if ( nUPD == 300 && nBuild <= 9379 )
272 mnGeneratorVersion = SvXMLImport::OOo_30x;
274 else if ( nUPD == 310 )
276 mnGeneratorVersion = SvXMLImport::OOo_31x;
278 else if ( nUPD == 320 )
280 mnGeneratorVersion = SvXMLImport::OOo_32x;
282 else if ( nUPD == 330 )
284 mnGeneratorVersion = SvXMLImport::OOo_33x;
286 else if ( nUPD == 340 )
288 mnGeneratorVersion = SvXMLImport::OOo_34x;
290 else if (nUPD == 400 || nUPD == 401)
292 mnGeneratorVersion = SvXMLImport::AOO_40x;
294 else if (nUPD >= 410)
296 // effectively this means "latest", see use
297 // in XMLGraphicsDefaultStyle::SetDefaults()!
298 mnGeneratorVersion = SvXMLImport::AOO_4x;
302 sal_uInt16 getGeneratorVersion() const
304 return mnGeneratorVersion;
310 class SvXMLImport_Impl
312 public:
313 FontToSubsFontConverter hBatsFontConv;
314 FontToSubsFontConverter hMathFontConv;
316 bool mbOwnGraphicResolver;
317 bool mbOwnEmbeddedResolver;
318 INetURLObject aBaseURL;
319 INetURLObject aDocBase;
321 /// name of stream in package, e.g., "content.xml"
322 OUString mStreamName;
324 std::optional<OUString> mxODFVersion;
326 bool mbIsOOoXML;
328 std::optional<bool> mbIsMSO;
330 // Boolean, indicating that position attributes
331 // of shapes are given in horizontal left-to-right layout. This is the case
332 // for the OpenOffice.org file format. (#i28749#)
333 bool mbShapePositionInHoriL2R;
334 bool mbTextDocInOOoFileFormat;
336 const uno::Reference< uno::XComponentContext > mxComponentContext;
337 OUString implementationName;
338 css::uno::Sequence< OUString > maSupportedServiceNames;
340 uno::Reference< embed::XStorage > mxSourceStorage;
342 std::unique_ptr< xmloff::RDFaImportHelper > mpRDFaHelper;
344 std::optional< DocumentInfo > moDocumentInfo;
346 SvXMLImport_Impl( uno::Reference< uno::XComponentContext > xContext,
347 OUString theImplementationName,
348 const css::uno::Sequence< OUString > & sSupportedServiceNames = {})
349 : hBatsFontConv( nullptr )
350 , hMathFontConv( nullptr )
351 , mbOwnGraphicResolver( false )
352 , mbOwnEmbeddedResolver( false )
353 , mbIsOOoXML(false)
354 // Convert drawing object positions from OOo file format to OASIS (#i28749#)
355 , mbShapePositionInHoriL2R( false )
356 , mbTextDocInOOoFileFormat( false )
357 , mxComponentContext(std::move( xContext ))
358 , implementationName(std::move(theImplementationName))
359 , maSupportedServiceNames(sSupportedServiceNames)
361 SAL_WARN_IF(!mxComponentContext.is(), "xmloff.core", "SvXMLImport: no ComponentContext");
362 if (!mxComponentContext.is()) throw uno::RuntimeException();
363 if (!maSupportedServiceNames.hasElements())
364 maSupportedServiceNames = { "com.sun.star.document.ImportFilter", "com.sun.star.xml.XMLImportFilter" };
367 sal_uInt16 getGeneratorVersion( const SvXMLImport& rImport )
369 if (!moDocumentInfo)
371 moDocumentInfo.emplace( rImport );
374 return moDocumentInfo->getGeneratorVersion();
377 ::comphelper::UnoInterfaceToUniqueIdentifierMapper maInterfaceToIdentifierMapper;
380 SvXMLImportContext *SvXMLImport::CreateFastContext( sal_Int32 nElement,
381 const uno::Reference< xml::sax::XFastAttributeList >& /*xAttrList*/ )
383 assert(false);
384 SAL_WARN( "xmloff.core", "CreateFastContext should be overridden, for element " << nElement);
385 return new SvXMLImportContext( *this );
388 void SvXMLImport::InitCtor_()
390 if( mnImportFlags != SvXMLImportFlags::NONE )
392 // implicit "xml" namespace prefix
393 mxNamespaceMap->Add( GetXMLToken(XML_XML), GetXMLToken(XML_N_XML), XML_NAMESPACE_XML );
394 mxNamespaceMap->Add( "_office", GetXMLToken(XML_N_OFFICE), XML_NAMESPACE_OFFICE );
395 mxNamespaceMap->Add( "_office_ooo", GetXMLToken(XML_N_OFFICE_EXT), XML_NAMESPACE_OFFICE_EXT );
396 mxNamespaceMap->Add( "_ooo", GetXMLToken(XML_N_OOO), XML_NAMESPACE_OOO );
397 mxNamespaceMap->Add( "_style", GetXMLToken(XML_N_STYLE), XML_NAMESPACE_STYLE );
398 mxNamespaceMap->Add( "_text", GetXMLToken(XML_N_TEXT), XML_NAMESPACE_TEXT );
399 mxNamespaceMap->Add( "_table", GetXMLToken(XML_N_TABLE), XML_NAMESPACE_TABLE );
400 mxNamespaceMap->Add( "_table_ooo", GetXMLToken(XML_N_TABLE_EXT), XML_NAMESPACE_TABLE_EXT );
401 mxNamespaceMap->Add( "_draw", GetXMLToken(XML_N_DRAW), XML_NAMESPACE_DRAW );
402 mxNamespaceMap->Add( "_draw_ooo", GetXMLToken(XML_N_DRAW_EXT), XML_NAMESPACE_DRAW_EXT );
403 mxNamespaceMap->Add( "_dr3d", GetXMLToken(XML_N_DR3D), XML_NAMESPACE_DR3D );
404 mxNamespaceMap->Add( "_fo", GetXMLToken(XML_N_FO_COMPAT), XML_NAMESPACE_FO );
405 mxNamespaceMap->Add( "_xlink", GetXMLToken(XML_N_XLINK), XML_NAMESPACE_XLINK );
406 mxNamespaceMap->Add( "_dc", GetXMLToken(XML_N_DC), XML_NAMESPACE_DC );
407 mxNamespaceMap->Add( "_dom", GetXMLToken(XML_N_DOM), XML_NAMESPACE_DOM );
408 mxNamespaceMap->Add( "_meta", GetXMLToken(XML_N_META), XML_NAMESPACE_META );
409 mxNamespaceMap->Add( "_number", GetXMLToken(XML_N_NUMBER), XML_NAMESPACE_NUMBER );
410 mxNamespaceMap->Add( "_svg", GetXMLToken(XML_N_SVG_COMPAT), XML_NAMESPACE_SVG );
411 mxNamespaceMap->Add( "_chart", GetXMLToken(XML_N_CHART), XML_NAMESPACE_CHART );
412 mxNamespaceMap->Add( "_math", GetXMLToken(XML_N_MATH), XML_NAMESPACE_MATH );
413 mxNamespaceMap->Add( "_form", GetXMLToken(XML_N_FORM), XML_NAMESPACE_FORM );
414 mxNamespaceMap->Add( "_script", GetXMLToken(XML_N_SCRIPT), XML_NAMESPACE_SCRIPT );
415 mxNamespaceMap->Add( "_config", GetXMLToken(XML_N_CONFIG), XML_NAMESPACE_CONFIG );
416 mxNamespaceMap->Add( "_xforms", GetXMLToken(XML_N_XFORMS_1_0), XML_NAMESPACE_XFORMS );
417 mxNamespaceMap->Add( "_formx", GetXMLToken( XML_N_FORMX ), XML_NAMESPACE_FORMX );
418 mxNamespaceMap->Add( "_xsd", GetXMLToken(XML_N_XSD), XML_NAMESPACE_XSD );
419 mxNamespaceMap->Add( "_xsi", GetXMLToken(XML_N_XSI), XML_NAMESPACE_XFORMS );
420 mxNamespaceMap->Add( "_ooow", GetXMLToken(XML_N_OOOW), XML_NAMESPACE_OOOW );
421 mxNamespaceMap->Add( "_oooc", GetXMLToken(XML_N_OOOC), XML_NAMESPACE_OOOC );
422 mxNamespaceMap->Add( "_field", GetXMLToken(XML_N_FIELD), XML_NAMESPACE_FIELD );
423 mxNamespaceMap->Add( "_of", GetXMLToken(XML_N_OF), XML_NAMESPACE_OF );
424 mxNamespaceMap->Add( "_xhtml", GetXMLToken(XML_N_XHTML), XML_NAMESPACE_XHTML );
425 mxNamespaceMap->Add( "_css3text", GetXMLToken(XML_N_CSS3TEXT), XML_NAMESPACE_CSS3TEXT );
427 mxNamespaceMap->Add( "_calc_libo", GetXMLToken(XML_N_CALC_EXT), XML_NAMESPACE_CALC_EXT);
428 mxNamespaceMap->Add( "_office_libo",
429 GetXMLToken(XML_N_LO_EXT), XML_NAMESPACE_LO_EXT);
432 if (mxNumberFormatsSupplier.is())
433 mpNumImport = std::make_unique<SvXMLNumFmtHelper>(mxNumberFormatsSupplier, GetComponentContext());
435 if (mxModel.is() && !mxEventListener.is())
437 mxEventListener.set(new SvXMLImportEventListener(this));
438 mxModel->addEventListener(mxEventListener);
442 SvXMLImport::SvXMLImport(
443 const css::uno::Reference< css::uno::XComponentContext >& xContext,
444 OUString const & implementationName,
445 SvXMLImportFlags nImportFlags,
446 const css::uno::Sequence< OUString > & sSupportedServiceNames )
447 : mpImpl( new SvXMLImport_Impl(xContext, implementationName, sSupportedServiceNames) ),
448 mxNamespaceMap( SvXMLNamespaceMap() ),
450 mpUnitConv( new SvXMLUnitConverter( xContext,
451 util::MeasureUnit::MM_100TH, util::MeasureUnit::MM_100TH,
452 SvtSaveOptions::ODFSVER_LATEST_EXTENDED) ),
454 mnImportFlags( nImportFlags ),
455 maNamespaceHandler( new SvXMLImportFastNamespaceHandler() ),
456 mbIsFormsSupported( true ),
457 mbIsTableShapeSupported( false ),
458 mbNotifyMacroEventRead( false )
460 SAL_WARN_IF( !xContext.is(), "xmloff.core", "got no service manager" );
461 InitCtor_();
462 mxParser = xml::sax::FastParser::create( xContext );
463 setNamespaceHandler( maNamespaceHandler );
464 setTokenHandler( xTokenHandler );
465 if ( !bIsNSMapsInitialized )
467 initializeNamespaceMaps();
468 bIsNSMapsInitialized = true;
470 registerNamespaces();
471 maNamespaceAttrList = new comphelper::AttributeList;
474 void SvXMLImport::cleanup() noexcept
476 if (mxEventListener.is() && mxModel.is())
477 mxModel->removeEventListener(mxEventListener);
478 // clear context stacks first in case of parse error because the context
479 // class dtors are full of application logic
480 while (!maContexts.empty())
482 if (SvXMLStylesContext* pStylesContext = dynamic_cast<SvXMLStylesContext*>(maContexts.top().get()))
483 pStylesContext->dispose();
484 maContexts.pop();
486 if( mxTextImport )
487 mxTextImport->dispose();
488 mxTextImport.clear(); // XMLRedlineImportHelper needs model
489 DisposingModel();
492 SvXMLImport::~SvXMLImport() noexcept
494 cleanup();
497 bool SvXMLImport::addEmbeddedFont(const css::uno::Reference< css::io::XInputStream >& stream,
498 const OUString& fontName, std::u16string_view extra,
499 std::vector<unsigned char> const & key, bool eot)
501 if (!mxEmbeddedFontHelper)
502 mxEmbeddedFontHelper.reset(new EmbeddedFontsHelper);
503 return mxEmbeddedFontHelper->addEmbeddedFont(stream, fontName, extra, key, eot);
506 namespace
508 class setFastDocumentHandlerGuard
510 private:
511 css::uno::Reference<css::xml::sax::XFastParser> mxParser;
512 public:
513 setFastDocumentHandlerGuard(css::uno::Reference<css::xml::sax::XFastParser> Parser,
514 const css::uno::Reference<css::xml::sax::XFastDocumentHandler>& Handler)
515 : mxParser(std::move(Parser))
517 mxParser->setFastDocumentHandler(Handler);
519 //guarantee restoration of null document handler
520 ~setFastDocumentHandlerGuard()
522 mxParser->setFastDocumentHandler(nullptr);
527 // XFastParser
528 void SAL_CALL SvXMLImport::parseStream( const xml::sax::InputSource& aInputSource )
530 setFastDocumentHandlerGuard aDocumentHandlerGuard(mxParser, mxFastDocumentHandler.is() ? mxFastDocumentHandler : this);
531 mxParser->parseStream(aInputSource);
534 void SAL_CALL SvXMLImport::setFastDocumentHandler( const uno::Reference< xml::sax::XFastDocumentHandler >& Handler )
536 mxFastDocumentHandler = Handler;
539 void SAL_CALL SvXMLImport::setTokenHandler( const uno::Reference< xml::sax::XFastTokenHandler >& Handler )
541 mxParser->setTokenHandler( Handler );
544 void SAL_CALL SvXMLImport::registerNamespace( const OUString& NamespaceURL, sal_Int32 NamespaceToken )
546 mxParser->registerNamespace( NamespaceURL, NamespaceToken );
549 OUString SAL_CALL SvXMLImport::getNamespaceURL( const OUString& rPrefix )
551 return mxParser->getNamespaceURL( rPrefix );
554 void SAL_CALL SvXMLImport::setErrorHandler( const uno::Reference< xml::sax::XErrorHandler >& Handler )
556 mxParser->setErrorHandler( Handler );
559 void SAL_CALL SvXMLImport::setEntityResolver( const uno::Reference< xml::sax::XEntityResolver >& Resolver )
561 mxParser->setEntityResolver( Resolver );
564 void SAL_CALL SvXMLImport::setLocale( const lang::Locale& rLocale )
566 mxParser->setLocale( rLocale );
569 void SAL_CALL SvXMLImport::setNamespaceHandler( const uno::Reference< xml::sax::XFastNamespaceHandler >& Handler)
571 mxParser->setNamespaceHandler( Handler );
574 void SAL_CALL SvXMLImport::setCustomEntityNames( const ::css::uno::Sequence< ::css::beans::Pair<::rtl::OUString, ::rtl::OUString> >& replacements )
576 mxParser->setCustomEntityNames( replacements );
579 void SAL_CALL SvXMLImport::startDocument()
581 SAL_INFO( "xmloff.core", "{ SvXMLImport::startDocument" );
582 if (mxGraphicStorageHandler.is() && mxEmbeddedResolver.is())
583 return;
585 Reference< lang::XMultiServiceFactory > xFactory( mxModel, UNO_QUERY );
586 if( !xFactory.is() )
587 return;
591 if (!mxGraphicStorageHandler.is())
593 // #99870# Import... instead of Export...
594 mxGraphicStorageHandler.set(
595 xFactory->createInstance("com.sun.star.document.ImportGraphicStorageHandler"),
596 UNO_QUERY);
597 mpImpl->mbOwnGraphicResolver = mxGraphicStorageHandler.is();
600 if( !mxEmbeddedResolver.is() )
602 // #99870# Import... instead of Export...
603 mxEmbeddedResolver.set(
604 xFactory->createInstance("com.sun.star.document.ImportEmbeddedObjectResolver"),
605 UNO_QUERY);
606 mpImpl->mbOwnEmbeddedResolver = mxEmbeddedResolver.is();
609 catch( css::uno::Exception& )
614 void SAL_CALL SvXMLImport::endDocument()
616 SAL_INFO( "xmloff.core", "} SvXMLImport::endDocument" );
617 // #i9518# All the stuff that accesses the document has to be done here, not in the dtor,
618 // because the SvXMLImport dtor might not be called until after the document has been closed.
620 if (mxTextImport)
621 mxTextImport->MapCrossRefHeadingFieldsHorribly();
623 if (mpImpl->mpRDFaHelper)
625 const uno::Reference<rdf::XRepositorySupplier> xRS(mxModel,
626 uno::UNO_QUERY);
627 if (xRS.is())
629 mpImpl->mpRDFaHelper->InsertRDFa( xRS );
633 mpNumImport.reset();
634 if (mxImportInfo.is())
636 uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = mxImportInfo->getPropertySetInfo();
637 if (xPropertySetInfo.is())
639 if (bool(mpProgressBarHelper))
641 OUString sProgressMax(XML_PROGRESSMAX);
642 OUString sProgressCurrent(XML_PROGRESSCURRENT);
643 OUString sRepeat(XML_PROGRESSREPEAT);
644 if (xPropertySetInfo->hasPropertyByName(sProgressMax) &&
645 xPropertySetInfo->hasPropertyByName(sProgressCurrent))
647 sal_Int32 nProgressMax(mpProgressBarHelper->GetReference());
648 sal_Int32 nProgressCurrent(mpProgressBarHelper->GetValue());
649 mxImportInfo->setPropertyValue(sProgressMax, uno::Any(nProgressMax));
650 mxImportInfo->setPropertyValue(sProgressCurrent, uno::Any(nProgressCurrent));
652 if (xPropertySetInfo->hasPropertyByName(sRepeat))
653 mxImportInfo->setPropertyValue(sRepeat, css::uno::Any(mpProgressBarHelper->GetRepeat()));
654 // pProgressBarHelper is deleted in dtor
656 OUString sNumberStyles(XML_NUMBERSTYLES);
657 if (mxNumberStyles.is() && xPropertySetInfo->hasPropertyByName(sNumberStyles))
659 mxImportInfo->setPropertyValue(sNumberStyles, Any(mxNumberStyles));
664 if( mxFontDecls.is() )
665 mxFontDecls->dispose();
666 if( mxStyles.is() )
667 mxStyles->dispose();
668 if( mxAutoStyles.is() )
669 mxAutoStyles->dispose();
670 if( mxMasterStyles.is() )
671 mxMasterStyles->dispose();
673 // possible form-layer related knittings which can only be done when
674 // the whole document exists
675 if ( mxFormImport.is() )
676 mxFormImport->documentDone();
678 // The shape import helper does the z-order sorting in the dtor,
679 // so it must be deleted here, too.
680 mxShapeImport = nullptr;
682 if( mpImpl->mbOwnGraphicResolver )
684 Reference<lang::XComponent> xComp(mxGraphicStorageHandler, UNO_QUERY);
685 xComp->dispose();
688 if( mpImpl->mbOwnEmbeddedResolver )
690 Reference< lang::XComponent > xComp( mxEmbeddedResolver, UNO_QUERY );
691 xComp->dispose();
693 mpStyleMap.clear();
695 if ( bool( mpXMLErrors ) )
697 mpXMLErrors->ThrowErrorAsSAXException( XMLERROR_FLAG_SEVERE );
701 std::optional<SvXMLNamespaceMap> SvXMLImport::processNSAttributes(
702 std::optional<SvXMLNamespaceMap> & rpNamespaceMap,
703 SvXMLImport *const pImport, // TODO???
704 const uno::Reference< xml::sax::XAttributeList >& xAttrList)
706 std::optional<SvXMLNamespaceMap> pRewindMap;
707 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
708 for( sal_Int16 i=0; i < nAttrCount; i++ )
710 const OUString& rAttrName = xAttrList->getNameByIndex( i );
711 if (pImport && rAttrName == "office:version" && !pImport->mpImpl->mxODFVersion)
713 pImport->mpImpl->mxODFVersion = xAttrList->getValueByIndex( i );
715 // the ODF version in content.xml and manifest.xml must be the same starting from ODF1.2
716 if (pImport->mpImpl->mStreamName == "content.xml"
717 && !pImport->IsODFVersionConsistent(*pImport->mpImpl->mxODFVersion))
719 throw xml::sax::SAXException("Inconsistent ODF versions in content.xml and manifest.xml!",
720 uno::Reference< uno::XInterface >(),
721 uno::Any(
722 packages::zip::ZipIOException("Inconsistent ODF versions in content.xml and manifest.xml!" ) ) );
725 else if( ( rAttrName.getLength() >= 5 ) &&
726 ( rAttrName.startsWith( GetXMLToken(XML_XMLNS) ) ) &&
727 ( rAttrName.getLength() == 5 || ':' == rAttrName[5] ) )
729 if( !pRewindMap )
731 pRewindMap = std::move(rpNamespaceMap);
732 rpNamespaceMap.emplace(*pRewindMap);
734 const OUString& rAttrValue = xAttrList->getValueByIndex( i );
736 OUString aPrefix( ( rAttrName.getLength() == 5 )
737 ? OUString()
738 : rAttrName.copy( 6 ) );
739 // Add namespace, but only if it is known.
740 sal_uInt16 nKey = rpNamespaceMap->AddIfKnown( aPrefix, rAttrValue );
741 // If namespace is unknown, try to match a name with similar
742 // TC Id and version
743 if( XML_NAMESPACE_UNKNOWN == nKey )
745 OUString aTestName( rAttrValue );
746 if( SvXMLNamespaceMap::NormalizeURI( aTestName ) )
747 nKey = rpNamespaceMap->AddIfKnown( aPrefix, aTestName );
749 // If that namespace is not known, too, add it as unknown
750 if( XML_NAMESPACE_UNKNOWN == nKey )
751 rpNamespaceMap->Add( aPrefix, rAttrValue );
755 return pRewindMap;
759 void SAL_CALL SvXMLImport::characters( const OUString& rChars )
761 maContexts.top()->characters( rChars );
764 void SAL_CALL SvXMLImport::processingInstruction( const OUString&,
765 const OUString& )
769 void SAL_CALL SvXMLImport::setDocumentLocator( const uno::Reference< xml::sax::XLocator >& rLocator )
771 mxLocator = rLocator;
774 // XFastContextHandler
775 void SAL_CALL SvXMLImport::startFastElement (sal_Int32 Element,
776 const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
778 SAL_INFO("xmloff.core", "startFastElement " << SvXMLImport::getNameFromToken( Element ));
779 if ( Attribs.is() && !mpImpl->mxODFVersion)
781 sax_fastparser::FastAttributeList& rAttribList =
782 sax_fastparser::castToFastAttributeList( Attribs );
783 auto aIter( rAttribList.find( XML_ELEMENT( OFFICE, XML_VERSION ) ) );
784 if( aIter != rAttribList.end() )
786 mpImpl->mxODFVersion = aIter.toString();
788 // the ODF version in content.xml and manifest.xml must be the same starting from ODF1.2
789 if ( mpImpl->mStreamName == "content.xml" && !IsODFVersionConsistent( *mpImpl->mxODFVersion ) )
791 throw xml::sax::SAXException("Inconsistent ODF versions in content.xml and manifest.xml!",
792 uno::Reference< uno::XInterface >(),
793 uno::Any(
794 packages::zip::ZipIOException("Inconsistent ODF versions in content.xml and manifest.xml!" ) ) );
799 maNamespaceAttrList->Clear();
801 maNamespaceHandler->addNSDeclAttributes( maNamespaceAttrList );
802 std::optional<SvXMLNamespaceMap> pRewindMap = processNSAttributes(mxNamespaceMap, this, maNamespaceAttrList);
804 SvXMLImportContextRef xContext;
805 const bool bRootContext = maContexts.empty();
806 if (!maContexts.empty())
808 const SvXMLImportContextRef & pHandler = maContexts.top();
809 SAL_INFO("xmloff.core", "calling createFastChildContext on " << typeid(*pHandler.get()).name());
810 auto tmp = pHandler->createFastChildContext( Element, Attribs );
811 xContext = static_cast<SvXMLImportContext*>(tmp.get());
812 assert((tmp && xContext) || (!tmp && !xContext));
814 else
815 xContext.set( CreateFastContext( Element, Attribs ) );
817 SAL_INFO_IF(!xContext.is(), "xmloff.core", "No fast context for element " << getNameFromToken(Element));
818 if (bRootContext && !xContext)
820 OUString aName = getNameFromToken(Element);
821 SetError( XMLERROR_FLAG_SEVERE | XMLERROR_UNKNOWN_ROOT,
822 { aName }, "Root element " + aName + " unknown", Reference<xml::sax::XLocator>() );
824 if ( !xContext )
825 xContext.set( new SvXMLImportContext( *this ) );
827 // Remember old namespace map.
828 if( pRewindMap )
829 xContext->PutRewindMap(std::move(pRewindMap));
831 // Call a startElement at the new context.
832 xContext->startFastElement( Element, Attribs );
834 // Push context on stack.
835 maContexts.push(xContext);
838 void SAL_CALL SvXMLImport::startUnknownElement (const OUString & rNamespace, const OUString & rName,
839 const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
841 SAL_INFO("xmloff.core", "startUnknownElement " << rNamespace << " " << rName);
842 SvXMLImportContextRef xContext;
843 const bool bRootContext = maContexts.empty();
844 if (!maContexts.empty())
846 const SvXMLImportContextRef & pHandler = maContexts.top();
847 SAL_INFO("xmloff.core", "calling createUnknownChildContext on " << typeid(*pHandler.get()).name());
848 auto tmp = pHandler->createUnknownChildContext( rNamespace, rName, Attribs );
849 xContext = static_cast<SvXMLImportContext*>(tmp.get());
850 assert((tmp && xContext) || (!tmp && !xContext));
852 else
853 xContext.set( CreateFastContext( -1, Attribs ) );
855 SAL_WARN_IF(!xContext.is(), "xmloff.core", "No context for unknown-element " << rNamespace << " " << rName);
856 if (bRootContext && !xContext)
858 SetError( XMLERROR_FLAG_SEVERE | XMLERROR_UNKNOWN_ROOT,
859 { rName }, "Root element " + rName + " unknown", Reference<xml::sax::XLocator>() );
861 if (!xContext)
863 if (!maContexts.empty())
864 // This is pretty weird, but it's what the code did before I simplified it, and some parts of the
865 // code rely on this behaviour e.g. DocumentBuilderContext
866 xContext = maContexts.top();
867 else
868 xContext = new SvXMLImportContext( *this );
871 xContext->startUnknownElement( rNamespace, rName, Attribs );
872 maContexts.push(xContext);
875 void SAL_CALL SvXMLImport::endFastElement (sal_Int32 Element)
877 SAL_INFO("xmloff.core", "endFastElement " << SvXMLImport::getNameFromToken( Element ));
878 if (maContexts.empty())
880 SAL_WARN("xmloff.core", "SvXMLImport::endFastElement: no context left");
881 assert(false);
882 return;
884 SvXMLImportContextRef xContext = std::move(maContexts.top());
885 // Get a namespace map to rewind.
886 std::optional<SvXMLNamespaceMap> pRewindMap = xContext->TakeRewindMap();
887 maContexts.pop();
888 xContext->endFastElement( Element );
889 // Rewind a namespace map.
890 if (pRewindMap)
891 mxNamespaceMap = std::move(pRewindMap);
894 void SAL_CALL SvXMLImport::endUnknownElement (const OUString & rPrefix, const OUString & rLocalName)
896 SAL_INFO("xmloff.core", "endUnknownElement " << rPrefix << " " << rLocalName);
897 if (maContexts.empty())
899 SAL_WARN("xmloff.core", "SvXMLImport::endUnknownElement: no context left");
900 assert(false);
901 return;
903 SvXMLImportContextRef xContext = std::move(maContexts.top());
904 maContexts.pop();
905 xContext->endUnknownElement( rPrefix, rLocalName );
908 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
909 SvXMLImport::createFastChildContext (sal_Int32,
910 const uno::Reference< xml::sax::XFastAttributeList > &)
912 return this;
915 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
916 SvXMLImport::createUnknownChildContext (const OUString &, const OUString &,
917 const uno::Reference< xml::sax::XFastAttributeList > &)
919 return this;
922 void SvXMLImport::SetStatistics(const uno::Sequence< beans::NamedValue> &)
924 GetProgressBarHelper()->SetRepeat(false);
925 GetProgressBarHelper()->SetReference(0);
928 // XImporter
929 void SAL_CALL SvXMLImport::setTargetDocument( const uno::Reference< lang::XComponent >& xDoc )
931 mxModel.set( xDoc, UNO_QUERY );
932 if( !mxModel.is() )
933 throw lang::IllegalArgumentException();
937 uno::Reference<document::XStorageBasedDocument> const xSBDoc(mxModel, uno::UNO_QUERY);
938 uno::Reference<embed::XStorage> const xStor(xSBDoc.is() ? xSBDoc->getDocumentStorage()
939 : nullptr);
940 if (xStor.is())
942 mpImpl->mbIsOOoXML =
943 ::comphelper::OStorageHelper::GetXStorageFormat(xStor)
944 < SOFFICE_FILEFORMAT_8;
947 catch (uno::Exception const&)
949 DBG_UNHANDLED_EXCEPTION("xmloff.core");
951 if (!mxEventListener.is())
953 mxEventListener.set(new SvXMLImportEventListener(this));
954 mxModel->addEventListener(mxEventListener);
957 SAL_WARN_IF( bool(mpNumImport), "xmloff.core", "number format import already exists." );
958 mpNumImport.reset();
961 // XFilter
962 sal_Bool SAL_CALL SvXMLImport::filter( const uno::Sequence< beans::PropertyValue >& )
964 return false;
967 void SAL_CALL SvXMLImport::cancel( )
971 // XInitialize
972 void SAL_CALL SvXMLImport::initialize( const uno::Sequence< uno::Any >& aArguments )
974 for( const auto& rAny : aArguments )
976 Reference<XInterface> xValue;
977 rAny >>= xValue;
979 uno::Reference<task::XStatusIndicator> xTmpStatusIndicator(
980 xValue, UNO_QUERY );
981 if( xTmpStatusIndicator.is() )
982 mxStatusIndicator = xTmpStatusIndicator;
984 uno::Reference<document::XGraphicStorageHandler> xGraphicStorageHandler(xValue, UNO_QUERY);
985 if (xGraphicStorageHandler.is())
986 mxGraphicStorageHandler = xGraphicStorageHandler;
988 uno::Reference<document::XEmbeddedObjectResolver> xTmpObjectResolver(
989 xValue, UNO_QUERY );
990 if( xTmpObjectResolver.is() )
991 mxEmbeddedResolver = xTmpObjectResolver;
993 uno::Reference<beans::XPropertySet> xTmpPropSet( xValue, UNO_QUERY );
994 if( xTmpPropSet.is() )
996 mxImportInfo = xTmpPropSet;
997 uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = mxImportInfo->getPropertySetInfo();
998 if (xPropertySetInfo.is())
1000 OUString sPropName(XML_NUMBERSTYLES);
1001 if (xPropertySetInfo->hasPropertyByName(sPropName))
1003 uno::Any aAny = mxImportInfo->getPropertyValue(sPropName);
1004 aAny >>= mxNumberStyles;
1007 sPropName = "PrivateData";
1008 if (xPropertySetInfo->hasPropertyByName(sPropName))
1010 Reference < XInterface > xIfc;
1011 uno::Any aAny = mxImportInfo->getPropertyValue(sPropName);
1012 aAny >>= xIfc;
1014 StyleMap *pSMap = dynamic_cast<StyleMap*>( xIfc.get() );
1015 if( pSMap )
1017 mpStyleMap = pSMap;
1020 OUString sBaseURI;
1021 sPropName = "BaseURI";
1022 if (xPropertySetInfo->hasPropertyByName(sPropName))
1024 uno::Any aAny = mxImportInfo->getPropertyValue(sPropName);
1025 aAny >>= sBaseURI;
1026 mpImpl->aBaseURL.SetURL( sBaseURI );
1027 mpImpl->aDocBase.SetURL( sBaseURI );
1029 OUString sRelPath;
1030 sPropName = "StreamRelPath";
1031 if( xPropertySetInfo->hasPropertyByName(sPropName) )
1033 uno::Any aAny = mxImportInfo->getPropertyValue(sPropName);
1034 aAny >>= sRelPath;
1036 OUString sName;
1037 sPropName = "StreamName";
1038 if( xPropertySetInfo->hasPropertyByName(sPropName) )
1040 uno::Any aAny = mxImportInfo->getPropertyValue(sPropName);
1041 aAny >>= sName;
1043 if( !sBaseURI.isEmpty() && !sName.isEmpty() )
1045 if( !sRelPath.isEmpty() )
1046 mpImpl->aBaseURL.insertName( sRelPath );
1047 mpImpl->aBaseURL.insertName( sName );
1049 mpImpl->mStreamName = sName; // Note: may be empty (XSLT)
1050 // Retrieve property <ShapePositionInHoriL2R> (#i28749#)
1051 sPropName = "ShapePositionInHoriL2R";
1052 if( xPropertySetInfo->hasPropertyByName(sPropName) )
1054 uno::Any aAny = mxImportInfo->getPropertyValue(sPropName);
1055 aAny >>= mpImpl->mbShapePositionInHoriL2R;
1057 sPropName = "TextDocInOOoFileFormat";
1058 if( xPropertySetInfo->hasPropertyByName(sPropName) )
1060 uno::Any aAny = mxImportInfo->getPropertyValue(sPropName);
1061 aAny >>= mpImpl->mbTextDocInOOoFileFormat;
1064 sPropName = "SourceStorage";
1065 if( xPropertySetInfo->hasPropertyByName(sPropName) )
1066 mxImportInfo->getPropertyValue(sPropName) >>= mpImpl->mxSourceStorage;
1071 uno::Reference<lang::XInitialization> const xInit(mxParser, uno::UNO_QUERY_THROW);
1072 xInit->initialize( { Any(OUString("IgnoreMissingNSDecl")) });
1075 // XServiceInfo
1076 OUString SAL_CALL SvXMLImport::getImplementationName()
1078 return mpImpl->implementationName;
1081 sal_Bool SAL_CALL SvXMLImport::supportsService( const OUString& rServiceName )
1083 return cppu::supportsService(this, rServiceName);
1086 uno::Sequence< OUString > SAL_CALL SvXMLImport::getSupportedServiceNames( )
1088 return mpImpl->maSupportedServiceNames;
1091 XMLTextImportHelper* SvXMLImport::CreateTextImport()
1093 return new XMLTextImportHelper( mxModel, *this );
1096 XMLShapeImportHelper* SvXMLImport::CreateShapeImport()
1098 return new XMLShapeImportHelper( *this, mxModel );
1101 SchXMLImportHelper* SvXMLImport::CreateChartImport()
1103 // WASM_CHART change
1104 // TODO: Instead of importing the ChartModel an alternative may be
1105 // added to convert not to Chart/OLE SdrObejct, but to GraphicObject
1106 // with the Chart visualization. There should be a preview available
1107 // in the imported chart data
1108 #if !ENABLE_WASM_STRIP_CHART
1109 return new SchXMLImportHelper();
1110 #else
1111 return nullptr;
1112 #endif
1115 ::xmloff::OFormLayerXMLImport* SvXMLImport::CreateFormImport()
1117 return new ::xmloff::OFormLayerXMLImport(*this);
1121 // Get or create fill/line/lineend-style-helper
1124 const Reference< container::XNameContainer > & SvXMLImport::GetGradientHelper()
1126 if( !mxGradientHelper.is() )
1128 if( mxModel.is() )
1130 Reference< lang::XMultiServiceFactory > xServiceFact( mxModel, UNO_QUERY);
1131 if( xServiceFact.is() )
1135 mxGradientHelper.set( xServiceFact->createInstance(
1136 "com.sun.star.drawing.GradientTable" ), UNO_QUERY);
1138 catch( lang::ServiceNotRegisteredException& )
1144 return mxGradientHelper;
1147 const Reference< container::XNameContainer > & SvXMLImport::GetHatchHelper()
1149 if( !mxHatchHelper.is() )
1151 if( mxModel.is() )
1153 Reference< lang::XMultiServiceFactory > xServiceFact( mxModel, UNO_QUERY);
1154 if( xServiceFact.is() )
1158 mxHatchHelper.set( xServiceFact->createInstance(
1159 "com.sun.star.drawing.HatchTable" ), UNO_QUERY);
1161 catch( lang::ServiceNotRegisteredException& )
1167 return mxHatchHelper;
1170 const Reference< container::XNameContainer > & SvXMLImport::GetBitmapHelper()
1172 if( !mxBitmapHelper.is() )
1174 if( mxModel.is() )
1176 Reference< lang::XMultiServiceFactory > xServiceFact( mxModel, UNO_QUERY);
1177 if( xServiceFact.is() )
1181 mxBitmapHelper.set( xServiceFact->createInstance(
1182 "com.sun.star.drawing.BitmapTable" ), UNO_QUERY);
1184 catch( lang::ServiceNotRegisteredException& )
1190 return mxBitmapHelper;
1193 const Reference< container::XNameContainer > & SvXMLImport::GetTransGradientHelper()
1195 if( !mxTransGradientHelper.is() )
1197 if( mxModel.is() )
1199 Reference< lang::XMultiServiceFactory > xServiceFact( mxModel, UNO_QUERY);
1200 if( xServiceFact.is() )
1204 mxTransGradientHelper.set( xServiceFact->createInstance(
1205 "com.sun.star.drawing.TransparencyGradientTable" ), UNO_QUERY);
1207 catch( lang::ServiceNotRegisteredException& )
1213 return mxTransGradientHelper;
1216 const Reference< container::XNameContainer > & SvXMLImport::GetMarkerHelper()
1218 if( !mxMarkerHelper.is() )
1220 if( mxModel.is() )
1222 Reference< lang::XMultiServiceFactory > xServiceFact( mxModel, UNO_QUERY);
1223 if( xServiceFact.is() )
1227 mxMarkerHelper.set( xServiceFact->createInstance( "com.sun.star.drawing.MarkerTable" ), UNO_QUERY);
1229 catch( lang::ServiceNotRegisteredException& )
1235 return mxMarkerHelper;
1238 const Reference< container::XNameContainer > & SvXMLImport::GetDashHelper()
1240 if( !mxDashHelper.is() && mxModel.is() )
1242 Reference< lang::XMultiServiceFactory > xServiceFact( mxModel, UNO_QUERY);
1243 if( xServiceFact.is() )
1247 mxDashHelper.set( xServiceFact->createInstance( "com.sun.star.drawing.DashTable" ), UNO_QUERY);
1249 catch( lang::ServiceNotRegisteredException& )
1254 return mxDashHelper;
1257 bool SvXMLImport::IsPackageURL( std::u16string_view rURL ) const
1260 // if, and only if, only parts are imported, then we're in a package
1261 const SvXMLImportFlags nTest = SvXMLImportFlags::META|SvXMLImportFlags::STYLES|SvXMLImportFlags::CONTENT|SvXMLImportFlags::SETTINGS;
1262 if( (mnImportFlags & nTest) == nTest )
1263 return false;
1265 // TODO: from this point extract to own static function
1267 // Some quick tests: Some may rely on the package structure!
1268 size_t nLen = rURL.size();
1269 if( nLen > 0 && '/' == rURL[0] )
1270 // RFC2396 net_path or abs_path
1271 return false;
1272 else if( nLen > 1 && '.' == rURL[0] )
1274 if( '.' == rURL[1] )
1275 // ../: We are never going up one level, so we know
1276 // it's not an external URI
1277 return false;
1278 else if( '/' == rURL[1] )
1279 // we are remaining on a level, so it's a package URI
1280 return true;
1283 // Now check for a RFC2396 schema
1284 size_t nPos = 1;
1285 while( nPos < nLen )
1287 switch( rURL[nPos] )
1289 case '/':
1290 // a relative path segment
1291 return true;
1292 case ':':
1293 // a schema
1294 return false;
1295 default:
1296 break;
1297 // we don't care about any other characters
1299 ++nPos;
1302 return true;
1305 uno::Reference<graphic::XGraphic> SvXMLImport::loadGraphicByURL(OUString const & rURL)
1307 uno::Reference<graphic::XGraphic> xGraphic;
1309 if (mxGraphicStorageHandler.is())
1311 if (IsPackageURL(rURL))
1313 xGraphic = mxGraphicStorageHandler->loadGraphic(rURL);
1315 else
1317 OUString const & rAbsoluteURL = GetAbsoluteReference(rURL);
1318 GraphicExternalLink aExternalLink(rAbsoluteURL);
1319 Graphic aGraphic(aExternalLink);
1320 xGraphic = aGraphic.GetXGraphic();
1324 return xGraphic;
1327 uno::Reference<graphic::XGraphic> SvXMLImport::loadGraphicFromBase64(uno::Reference<io::XOutputStream> const & rxOutputStream)
1329 uno::Reference<graphic::XGraphic> xGraphic;
1331 if (mxGraphicStorageHandler.is())
1333 xGraphic = mxGraphicStorageHandler->loadGraphicFromOutputStream(rxOutputStream);
1336 return xGraphic;
1339 Reference< XOutputStream > SvXMLImport::GetStreamForGraphicObjectURLFromBase64() const
1341 Reference< XOutputStream > xOStm;
1342 Reference< document::XBinaryStreamResolver > xStmResolver(mxGraphicStorageHandler, UNO_QUERY);
1344 if( xStmResolver.is() )
1345 xOStm = xStmResolver->createOutputStream();
1347 return xOStm;
1350 OUString SvXMLImport::ResolveEmbeddedObjectURL(
1351 const OUString& rURL,
1352 std::u16string_view rClassId )
1354 OUString sRet;
1356 if( IsPackageURL( rURL ) )
1358 if ( mxEmbeddedResolver.is() )
1360 OUString sURL( rURL );
1361 if( !rClassId.empty() )
1363 sURL += OUString::Concat("!") + rClassId;
1365 sRet = mxEmbeddedResolver->resolveEmbeddedObjectURL( sURL );
1368 else
1369 sRet = GetAbsoluteReference( rURL );
1371 return sRet;
1374 Reference< embed::XStorage > const & SvXMLImport::GetSourceStorage() const
1376 return mpImpl->mxSourceStorage;
1379 Reference < XOutputStream >
1380 SvXMLImport::GetStreamForEmbeddedObjectURLFromBase64() const
1382 Reference < XOutputStream > xOLEStream;
1384 if( mxEmbeddedResolver.is() )
1386 Reference< XNameAccess > xNA( mxEmbeddedResolver, UNO_QUERY );
1387 if( xNA.is() )
1389 Any aAny = xNA->getByName( "Obj12345678" );
1390 aAny >>= xOLEStream;
1394 return xOLEStream;
1397 OUString SvXMLImport::ResolveEmbeddedObjectURLFromBase64()
1399 OUString sRet;
1401 if( mxEmbeddedResolver.is() )
1403 sRet = mxEmbeddedResolver->resolveEmbeddedObjectURL( "Obj12345678" );
1406 return sRet;
1409 void SvXMLImport::AddStyleDisplayName( XmlStyleFamily nFamily,
1410 const OUString& rName,
1411 const OUString& rDisplayName )
1413 if( !mpStyleMap.is() )
1415 mpStyleMap = new StyleMap;
1416 if( mxImportInfo.is() )
1418 OUString sPrivateData( "PrivateData" );
1419 Reference< beans::XPropertySetInfo > xPropertySetInfo =
1420 mxImportInfo->getPropertySetInfo();
1421 if( xPropertySetInfo.is() &&
1422 xPropertySetInfo->hasPropertyByName(sPrivateData) )
1424 Reference < XInterface > xIfc(
1425 static_cast< css::lang::XTypeProvider *>( mpStyleMap.get() ) );
1426 mxImportInfo->setPropertyValue( sPrivateData, Any(xIfc) );
1431 StyleMap::key_type aKey( nFamily, rName );
1432 StyleMap::value_type aValue( aKey, rDisplayName );
1433 ::std::pair<StyleMap::iterator,bool> aRes( mpStyleMap->insert( aValue ) );
1434 SAL_WARN_IF( !aRes.second,
1435 "xmloff.core",
1436 "duplicate style name of family " << static_cast<int>(nFamily) << ": \"" << rName << "\"");
1440 OUString SvXMLImport::GetStyleDisplayName( XmlStyleFamily nFamily,
1441 const OUString& rName ) const
1443 OUString sName( rName );
1444 if( mpStyleMap.is() && !rName.isEmpty() )
1446 StyleMap::key_type aKey( nFamily, rName );
1447 StyleMap::const_iterator aIter = mpStyleMap->find( aKey );
1448 if( aIter != mpStyleMap->end() )
1449 sName = (*aIter).second;
1451 return sName;
1454 void SvXMLImport::SetViewSettings(const css::uno::Sequence<css::beans::PropertyValue>&)
1458 void SvXMLImport::SetConfigurationSettings(const css::uno::Sequence<css::beans::PropertyValue>&)
1462 void SvXMLImport::SetDocumentSpecificSettings(const OUString&, const uno::Sequence<beans::PropertyValue>&)
1466 ProgressBarHelper* SvXMLImport::GetProgressBarHelper()
1468 if (!mpProgressBarHelper)
1470 mpProgressBarHelper = std::make_unique<ProgressBarHelper>(mxStatusIndicator, false);
1472 if (mxImportInfo.is())
1474 uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = mxImportInfo->getPropertySetInfo();
1475 if (xPropertySetInfo.is())
1477 OUString sProgressRange(XML_PROGRESSRANGE);
1478 OUString sProgressMax(XML_PROGRESSMAX);
1479 OUString sProgressCurrent(XML_PROGRESSCURRENT);
1480 OUString sRepeat(XML_PROGRESSREPEAT);
1481 if (xPropertySetInfo->hasPropertyByName(sProgressMax) &&
1482 xPropertySetInfo->hasPropertyByName(sProgressCurrent) &&
1483 xPropertySetInfo->hasPropertyByName(sProgressRange))
1485 uno::Any aAny;
1486 sal_Int32 nProgressMax(0);
1487 sal_Int32 nProgressCurrent(0);
1488 sal_Int32 nProgressRange(0);
1489 aAny = mxImportInfo->getPropertyValue(sProgressRange);
1490 if (aAny >>= nProgressRange)
1491 mpProgressBarHelper->SetRange(nProgressRange);
1492 aAny = mxImportInfo->getPropertyValue(sProgressMax);
1493 if (aAny >>= nProgressMax)
1494 mpProgressBarHelper->SetReference(nProgressMax);
1495 aAny = mxImportInfo->getPropertyValue(sProgressCurrent);
1496 if (aAny >>= nProgressCurrent)
1497 mpProgressBarHelper->SetValue(nProgressCurrent);
1499 if (xPropertySetInfo->hasPropertyByName(sRepeat))
1501 uno::Any aAny = mxImportInfo->getPropertyValue(sRepeat);
1502 if (aAny.getValueType() == cppu::UnoType<bool>::get())
1503 mpProgressBarHelper->SetRepeat(::cppu::any2bool(aAny));
1504 else {
1505 SAL_WARN( "xmloff.core", "why is it no boolean?" );
1511 return mpProgressBarHelper.get();
1514 void SvXMLImport::AddNumberStyle(sal_Int32 nKey, const OUString& rName)
1516 if (!mxNumberStyles.is())
1517 mxNumberStyles.set( comphelper::NameContainer_createInstance( ::cppu::UnoType<sal_Int32>::get()) );
1518 if (mxNumberStyles.is())
1522 mxNumberStyles->insertByName(rName, Any(nKey));
1524 catch ( uno::Exception& )
1526 DBG_UNHANDLED_EXCEPTION( "xmloff.core", "Numberformat could not be inserted");
1529 else {
1530 SAL_WARN( "xmloff.core", "not possible to create NameContainer");
1534 XMLEventImportHelper& SvXMLImport::GetEventImport()
1536 if (!mpEventImportHelper)
1538 // construct event helper and register StarBasic handler and standard
1539 // event tables
1540 mpEventImportHelper = std::make_unique<XMLEventImportHelper>();
1541 const OUString& sStarBasic(GetXMLToken(XML_STARBASIC));
1542 mpEventImportHelper->RegisterFactory(sStarBasic,
1543 std::make_unique<XMLStarBasicContextFactory>());
1544 const OUString& sScript(GetXMLToken(XML_SCRIPT));
1545 mpEventImportHelper->RegisterFactory(sScript,
1546 std::make_unique<XMLScriptContextFactory>());
1547 mpEventImportHelper->AddTranslationTable(aStandardEventTable);
1549 // register StarBasic event handler with capitalized spelling
1550 mpEventImportHelper->RegisterFactory("StarBasic",
1551 std::make_unique<XMLStarBasicContextFactory>());
1554 return *mpEventImportHelper;
1557 void SvXMLImport::SetFontDecls( XMLFontStylesContext *pFontDecls )
1559 if (mxFontDecls.is())
1560 mxFontDecls->dispose();
1561 mxFontDecls = pFontDecls;
1564 void SvXMLImport::SetStyles( SvXMLStylesContext *pStyles )
1566 if (mxStyles.is())
1567 mxStyles->dispose();
1568 mxStyles = pStyles;
1571 void SvXMLImport::SetAutoStyles( SvXMLStylesContext *pAutoStyles )
1573 if (pAutoStyles && mxNumberStyles.is())
1575 uno::Reference<xml::sax::XFastAttributeList> xAttrList = new sax_fastparser::FastAttributeList(nullptr);
1576 const uno::Sequence<OUString> aStyleNames = mxNumberStyles->getElementNames();
1577 for (const auto& name : aStyleNames)
1579 uno::Any aAny(mxNumberStyles->getByName(name));
1580 sal_Int32 nKey(0);
1581 if (aAny >>= nKey)
1583 SvXMLStyleContext* pContext = new SvXMLNumFormatContext(
1584 *this, name, xAttrList, nKey,
1585 GetDataStylesImport()->GetLanguageForKey(nKey), *pAutoStyles);
1586 pAutoStyles->AddStyle(*pContext);
1590 if (mxAutoStyles.is())
1591 mxAutoStyles->dispose();
1592 mxAutoStyles = pAutoStyles;
1593 GetTextImport()->SetAutoStyles( pAutoStyles );
1594 GetShapeImport()->SetAutoStylesContext( pAutoStyles );
1595 #if !ENABLE_WASM_STRIP_CHART
1596 GetChartImport()->SetAutoStylesContext( pAutoStyles );
1597 #endif
1598 GetFormImport()->setAutoStyleContext( pAutoStyles );
1601 void SvXMLImport::SetMasterStyles( SvXMLStylesContext *pMasterStyles )
1603 if (mxMasterStyles.is())
1604 mxMasterStyles->dispose();
1605 mxMasterStyles = pMasterStyles;
1608 XMLFontStylesContext *SvXMLImport::GetFontDecls()
1610 return mxFontDecls.get();
1613 SvXMLStylesContext *SvXMLImport::GetStyles()
1615 return mxStyles.get();
1618 SvXMLStylesContext *SvXMLImport::GetAutoStyles()
1620 return mxAutoStyles.get();
1623 const XMLFontStylesContext *SvXMLImport::GetFontDecls() const
1625 return mxFontDecls.get();
1628 const SvXMLStylesContext *SvXMLImport::GetStyles() const
1630 return mxStyles.get();
1633 const SvXMLStylesContext *SvXMLImport::GetAutoStyles() const
1635 return mxAutoStyles.get();
1638 OUString SvXMLImport::GetAbsoluteReference(const OUString& rValue) const
1640 if( rValue.isEmpty() || rValue[0] == '#' )
1641 return rValue;
1643 INetURLObject aAbsURL;
1644 if( mpImpl->aBaseURL.GetNewAbsURL( rValue, &aAbsURL ) )
1645 return aAbsURL.GetMainURL( INetURLObject::DecodeMechanism::ToIUri );
1646 else
1647 return rValue;
1650 bool SvXMLImport::IsODFVersionConsistent( const OUString& aODFVersion )
1652 // the check returns false only if the storage version could be retrieved
1653 bool bResult = true;
1655 if ( !aODFVersion.isEmpty() && aODFVersion.compareTo( ODFVER_012_TEXT ) >= 0 )
1657 // check the consistency only for the ODF1.2 and later ( according to content.xml )
1658 // manifest.xml might have no version, it should be checked here and the correct version should be set
1660 { // don't use getDocumentStorage(), it's temporary and latest version
1661 uno::Reference<embed::XStorage> const xStor(GetSourceStorage());
1662 if (!xStor.is())
1663 return bResult;
1664 uno::Reference< beans::XPropertySet > xStorProps( xStor, uno::UNO_QUERY_THROW );
1666 // the check should be done only for OASIS format
1667 if (!IsOOoXML())
1669 bool bRepairPackage = false;
1672 xStorProps->getPropertyValue( "RepairPackage" )
1673 >>= bRepairPackage;
1674 } catch ( uno::Exception& )
1677 // check only if not in Repair mode
1678 if ( !bRepairPackage )
1680 OUString aStorVersion;
1681 xStorProps->getPropertyValue( "Version" )
1682 >>= aStorVersion;
1684 // if the storage version is set in manifest.xml, it must be the same as in content.xml
1685 // if not, set it explicitly to be used further ( it will work even for readonly storage )
1686 // This workaround is not nice, but I see no other way to handle it, since there are
1687 // ODF1.2 documents without version in manifest.xml
1688 if ( !aStorVersion.isEmpty() )
1689 bResult = aODFVersion == aStorVersion;
1690 else
1691 xStorProps->setPropertyValue( "Version",
1692 uno::Any( aODFVersion ) );
1694 if ( bResult )
1696 bool bInconsistent = false;
1697 xStorProps->getPropertyValue( "IsInconsistent" )
1698 >>= bInconsistent;
1699 bResult = !bInconsistent;
1704 catch( uno::Exception& )
1708 return bResult;
1711 void SvXMLImport::CreateNumberFormatsSupplier_()
1713 SAL_WARN_IF( mxNumberFormatsSupplier.is(), "xmloff.core", "number formats supplier already exists!" );
1714 if(mxModel.is())
1715 mxNumberFormatsSupplier =
1716 uno::Reference< util::XNumberFormatsSupplier> (mxModel, uno::UNO_QUERY);
1719 void SvXMLImport::CreateDataStylesImport_()
1721 SAL_WARN_IF( bool(mpNumImport), "xmloff.core", "data styles import already exists!" );
1722 uno::Reference<util::XNumberFormatsSupplier> xNum =
1723 GetNumberFormatsSupplier();
1724 if ( xNum.is() )
1725 mpNumImport = std::make_unique<SvXMLNumFmtHelper>(xNum, GetComponentContext() );
1728 sal_Unicode SvXMLImport::ConvStarBatsCharToStarSymbol( sal_Unicode c )
1730 sal_Unicode cNew = c;
1731 if( !mpImpl->hBatsFontConv )
1733 mpImpl->hBatsFontConv = CreateFontToSubsFontConverter( u"StarBats",
1734 FontToSubsFontFlags::IMPORT );
1735 SAL_WARN_IF( !mpImpl->hBatsFontConv, "xmloff.core", "Got no symbol font converter" );
1737 if( mpImpl->hBatsFontConv )
1739 cNew = ConvertFontToSubsFontChar( mpImpl->hBatsFontConv, c );
1742 return cNew;
1745 sal_Unicode SvXMLImport::ConvStarMathCharToStarSymbol( sal_Unicode c )
1747 sal_Unicode cNew = c;
1748 if( !mpImpl->hMathFontConv )
1750 mpImpl->hMathFontConv = CreateFontToSubsFontConverter( u"StarMath",
1751 FontToSubsFontFlags::IMPORT );
1752 SAL_WARN_IF( !mpImpl->hMathFontConv, "xmloff.core", "Got no symbol font converter" );
1754 if( mpImpl->hMathFontConv )
1756 cNew = ConvertFontToSubsFontChar( mpImpl->hMathFontConv, c );
1759 return cNew;
1762 void SvXMLImport::SetError(
1763 sal_Int32 nId,
1764 const Sequence<OUString>& rMsgParams,
1765 const OUString& rExceptionMessage,
1766 const Reference<xml::sax::XLocator>& rLocator )
1768 // create error list on demand
1769 if ( !mpXMLErrors )
1770 mpXMLErrors = std::make_unique<XMLErrors>();
1772 // save error information
1773 // use document locator (if none supplied)
1774 mpXMLErrors->AddRecord( nId, rMsgParams, rExceptionMessage,
1775 rLocator.is() ? rLocator : mxLocator );
1778 void SvXMLImport::SetError(
1779 sal_Int32 nId,
1780 const Sequence<OUString>& rMsgParams)
1782 SetError( nId, rMsgParams, "", nullptr );
1785 void SvXMLImport::SetError(
1786 sal_Int32 nId,
1787 const OUString& rMsg1)
1789 Sequence<OUString> aSeq { rMsg1 };
1790 SetError( nId, aSeq );
1793 void SvXMLImport::DisposingModel()
1795 if( mxFontDecls.is() )
1796 mxFontDecls->dispose();
1797 if( mxStyles.is() )
1798 mxStyles->dispose();
1799 if( mxAutoStyles.is() )
1800 mxAutoStyles->dispose();
1801 if( mxMasterStyles.is() )
1802 mxMasterStyles->dispose();
1804 mxModel.clear();
1805 mxEventListener.clear();
1808 ::comphelper::UnoInterfaceToUniqueIdentifierMapper& SvXMLImport::getInterfaceToIdentifierMapper()
1810 return mpImpl->maInterfaceToIdentifierMapper;
1813 uno::Reference< uno::XComponentContext > const &
1814 SvXMLImport::GetComponentContext() const
1816 return mpImpl->mxComponentContext;
1819 OUString SvXMLImport::GetBaseURL() const
1821 return mpImpl->aBaseURL.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1824 OUString SvXMLImport::GetDocumentBase() const
1826 return mpImpl->aDocBase.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1829 // Convert drawing object positions from OOo file format to OASIS (#i28749#)
1830 bool SvXMLImport::IsShapePositionInHoriL2R() const
1832 return mpImpl->mbShapePositionInHoriL2R;
1835 bool SvXMLImport::IsTextDocInOOoFileFormat() const
1837 return mpImpl->mbTextDocInOOoFileFormat;
1840 void SvXMLImport::initXForms()
1842 // dummy method; to be implemented by derived classes supporting XForms
1845 bool SvXMLImport::getBuildIds( sal_Int32& rUPD, sal_Int32& rBuild ) const
1847 bool bRet = false;
1848 OUString const aBuildId(getBuildIdsProperty(mxImportInfo));
1849 if (!aBuildId.isEmpty())
1851 sal_Int32 nIndex = aBuildId.indexOf('$');
1852 if (nIndex != -1)
1854 rUPD = o3tl::toInt32(aBuildId.subView( 0, nIndex ));
1855 sal_Int32 nIndexEnd = aBuildId.indexOf(';', nIndex);
1856 rBuild = (nIndexEnd == -1)
1857 ? o3tl::toInt32(aBuildId.subView(nIndex + 1))
1858 : o3tl::toInt32(aBuildId.subView(nIndex + 1, nIndexEnd - nIndex - 1));
1859 bRet = true;
1862 return bRet;
1865 sal_uInt16 SvXMLImport::getGeneratorVersion() const
1867 // --> ORW
1868 return mpImpl->getGeneratorVersion( *this );
1869 // <--
1872 bool SvXMLImport::isGeneratorVersionOlderThan(
1873 sal_uInt16 const nOOoVersion, sal_uInt16 const nLOVersion)
1875 assert( (nLOVersion & LO_flag));
1876 assert(!(nOOoVersion & LO_flag));
1877 const sal_uInt16 nGeneratorVersion(getGeneratorVersion());
1878 return (nGeneratorVersion & LO_flag)
1879 ? nGeneratorVersion < nLOVersion
1880 : nGeneratorVersion < nOOoVersion;
1884 OUString SvXMLImport::GetODFVersion() const
1886 return mpImpl->mxODFVersion ? *mpImpl->mxODFVersion : OUString();
1889 bool SvXMLImport::IsOOoXML() const
1891 return mpImpl->mbIsOOoXML;
1894 bool SvXMLImport::IsMSO() const
1896 if (!mpImpl->mbIsMSO.has_value())
1898 uno::Reference<document::XDocumentPropertiesSupplier> xSupplier(GetModel(), uno::UNO_QUERY);
1899 if (xSupplier.is())
1901 uno::Reference<document::XDocumentProperties> xProps
1902 = xSupplier->getDocumentProperties();
1903 if (xProps.is())
1905 mpImpl->mbIsMSO = xProps->getGenerator().startsWith("MicrosoftOffice");
1910 return mpImpl->mbIsMSO.has_value() ? *mpImpl->mbIsMSO : false;
1913 // xml:id for RDF metadata
1914 void SvXMLImport::SetXmlId(uno::Reference<uno::XInterface> const & i_xIfc,
1915 OUString const & i_rXmlId)
1917 if (i_rXmlId.isEmpty())
1918 return;
1920 try {
1921 const uno::Reference<rdf::XMetadatable> xMeta(i_xIfc,
1922 uno::UNO_QUERY);
1923 //FIXME: not yet
1924 if (xMeta.is()) {
1925 const beans::StringPair mdref( mpImpl->mStreamName, i_rXmlId );
1926 try {
1927 xMeta->setMetadataReference(mdref);
1928 } catch (lang::IllegalArgumentException &) {
1929 // probably duplicate; ignore
1930 SAL_INFO("xmloff.core", "SvXMLImport::SetXmlId: cannot set xml:id");
1933 } catch (uno::Exception &) {
1934 TOOLS_WARN_EXCEPTION("xmloff.core","SvXMLImport::SetXmlId");
1938 ::xmloff::RDFaImportHelper &
1939 SvXMLImport::GetRDFaImportHelper()
1941 if (!mpImpl->mpRDFaHelper)
1943 mpImpl->mpRDFaHelper.reset( new ::xmloff::RDFaImportHelper(*this) );
1945 return *mpImpl->mpRDFaHelper;
1948 void
1949 SvXMLImport::AddRDFa(const uno::Reference<rdf::XMetadatable>& i_xObject,
1950 OUString const & i_rAbout,
1951 OUString const & i_rProperty,
1952 OUString const & i_rContent,
1953 OUString const & i_rDatatype)
1955 // N.B.: we only get called if i_xObject had xhtml:about attribute
1956 // (an empty attribute value is valid)
1957 ::xmloff::RDFaImportHelper & rRDFaHelper( GetRDFaImportHelper() );
1958 rRDFaHelper.ParseAndAddRDFa(i_xObject,
1959 i_rAbout, i_rProperty, i_rContent, i_rDatatype);
1962 bool SvXMLImport::embeddedFontAlreadyProcessed( const OUString& url )
1964 if( m_embeddedFontUrlsKnown.count( url ) != 0 )
1965 return true;
1966 m_embeddedFontUrlsKnown.insert( url );
1967 return false;
1970 const OUString & SvXMLImport::getNameFromToken( sal_Int32 nToken )
1972 return xTokenHandler->getIdentifier( nToken & TOKEN_MASK );
1975 OUString SvXMLImport::getPrefixAndNameFromToken( sal_Int32 nToken )
1977 OUString rv;
1978 sal_Int32 nNamespaceToken = ( nToken & NMSP_MASK ) >> NMSP_SHIFT;
1979 auto aIter( aNamespaceMap.find( nNamespaceToken ) );
1980 if( aIter != aNamespaceMap.end() )
1981 rv = (*aIter).second.second + " " + aIter->second.first + ":";
1982 return rv + xTokenHandler->getIdentifier( nToken & TOKEN_MASK );
1985 OUString SvXMLImport::getNamespacePrefixFromToken(sal_Int32 nToken, const SvXMLNamespaceMap* pMap)
1987 sal_Int32 nNamespaceToken = ( nToken & NMSP_MASK ) >> NMSP_SHIFT;
1988 auto aIter( aNamespaceMap.find( nNamespaceToken ) );
1989 if( aIter != aNamespaceMap.end() )
1991 if (pMap)
1993 OUString sRet = pMap->GetPrefixByKey(pMap->GetKeyByName((*aIter).second.second));
1994 if (!sRet.isEmpty())
1995 return sRet;
1997 return (*aIter).second.first;
1999 else
2000 return OUString();
2003 OUString SvXMLImport::getNamespaceURIFromToken( sal_Int32 nToken )
2005 sal_Int32 nNamespaceToken = ( nToken & NMSP_MASK ) >> NMSP_SHIFT;
2006 auto aIter( aNamespaceMap.find( nNamespaceToken ) );
2007 if( aIter != aNamespaceMap.end() )
2008 return (*aIter).second.second;
2009 else
2010 return OUString();
2013 OUString SvXMLImport::getNamespacePrefixFromURI( const OUString& rURI )
2015 auto aIter( aNamespaceURIPrefixMap.find(rURI) );
2016 if( aIter != aNamespaceURIPrefixMap.end() )
2017 return (*aIter).second;
2018 else
2019 return OUString();
2022 sal_Int32 SvXMLImport::getTokenFromName( std::u16string_view rName )
2024 Sequence< sal_Int8 > aLocalNameSeq( reinterpret_cast<sal_Int8 const *>(
2025 OUStringToOString( rName, RTL_TEXTENCODING_UTF8 ).getStr()), rName.size() );
2026 return xTokenHandler->getTokenFromUTF8( aLocalNameSeq );
2029 void SvXMLImport::initializeNamespaceMaps()
2031 auto mapTokenToNamespace = []( sal_Int32 nToken, sal_Int32 nPrefix, sal_Int32 nNamespace )
2033 if ( nToken >= 0 )
2035 const OUString& sNamespace = GetXMLToken( static_cast<XMLTokenEnum>( nNamespace ) );
2036 const OUString& sPrefix = GetXMLToken( static_cast<XMLTokenEnum>( nPrefix ) );
2037 assert( aNamespaceMap.find(nToken +1) == aNamespaceMap.end() && "cannot map two namespaces to the same token here");
2038 aNamespaceMap[ nToken + 1 ] = std::make_pair( sPrefix, sNamespace );
2039 aNamespaceURIPrefixMap.emplace( sNamespace, sPrefix );
2043 mapTokenToNamespace( XML_NAMESPACE_XML, XML_XML, XML_N_XML ); // implicit "xml" namespace prefix
2044 mapTokenToNamespace( XML_NAMESPACE_OFFICE, XML_NP_OFFICE, XML_N_OFFICE );
2045 mapTokenToNamespace( XML_NAMESPACE_OFFICE_SO52, XML_NP_OFFICE, XML_N_OFFICE_OLD );
2046 mapTokenToNamespace( XML_NAMESPACE_OFFICE_OOO, XML_NP_OFFICE, XML_N_OFFICE_OOO );
2047 mapTokenToNamespace( XML_NAMESPACE_STYLE, XML_NP_STYLE, XML_N_STYLE );
2048 mapTokenToNamespace( XML_NAMESPACE_STYLE_SO52, XML_NP_STYLE, XML_N_STYLE_OLD );
2049 mapTokenToNamespace( XML_NAMESPACE_STYLE_OOO, XML_NP_STYLE, XML_N_STYLE_OOO );
2050 mapTokenToNamespace( XML_NAMESPACE_TEXT, XML_NP_TEXT, XML_N_TEXT );
2051 mapTokenToNamespace( XML_NAMESPACE_TEXT_SO52, XML_NP_TEXT, XML_N_TEXT_OLD );
2052 mapTokenToNamespace( XML_NAMESPACE_TEXT_OOO, XML_NP_TEXT, XML_N_TEXT_OOO );
2053 mapTokenToNamespace( XML_NAMESPACE_TABLE, XML_NP_TABLE, XML_N_TABLE );
2054 mapTokenToNamespace( XML_NAMESPACE_TABLE_SO52, XML_NP_TABLE, XML_N_TABLE_OLD );
2055 mapTokenToNamespace( XML_NAMESPACE_TABLE_OOO, XML_NP_TABLE, XML_N_TABLE_OOO );
2056 mapTokenToNamespace( XML_NAMESPACE_DRAW, XML_NP_DRAW, XML_N_DRAW );
2057 mapTokenToNamespace( XML_NAMESPACE_DRAW_SO52, XML_NP_DRAW, XML_N_DRAW_OLD );
2058 mapTokenToNamespace( XML_NAMESPACE_DRAW_OOO, XML_NP_DRAW, XML_N_DRAW_OOO );
2059 mapTokenToNamespace( XML_NAMESPACE_FO, XML_NP_FO, XML_N_FO );
2060 mapTokenToNamespace( XML_NAMESPACE_FO_SO52, XML_NP_FO, XML_N_FO_OLD );
2061 mapTokenToNamespace( XML_NAMESPACE_FO_COMPAT, XML_NP_FO, XML_N_FO_COMPAT );
2062 mapTokenToNamespace( XML_NAMESPACE_XLINK, XML_NP_XLINK, XML_N_XLINK );
2063 mapTokenToNamespace( XML_NAMESPACE_XLINK_SO52, XML_NP_XLINK, XML_N_XLINK_OLD );
2064 mapTokenToNamespace( XML_NAMESPACE_DC, XML_NP_DC, XML_N_DC );
2065 mapTokenToNamespace( XML_NAMESPACE_META, XML_NP_META, XML_N_META );
2066 mapTokenToNamespace( XML_NAMESPACE_META_SO52, XML_NP_META, XML_N_META_OLD );
2067 mapTokenToNamespace( XML_NAMESPACE_META_OOO, XML_NP_META, XML_N_META_OOO );
2068 mapTokenToNamespace( XML_NAMESPACE_NUMBER, XML_NP_NUMBER, XML_N_NUMBER );
2069 mapTokenToNamespace( XML_NAMESPACE_NUMBER_SO52, XML_NP_NUMBER, XML_N_NUMBER_OLD );
2070 mapTokenToNamespace( XML_NAMESPACE_NUMBER_OOO, XML_NP_NUMBER, XML_N_NUMBER_OOO );
2071 mapTokenToNamespace( XML_NAMESPACE_PRESENTATION, XML_NP_PRESENTATION, XML_N_PRESENTATION );
2072 mapTokenToNamespace( XML_NAMESPACE_PRESENTATION_SO52,XML_NP_PRESENTATION, XML_N_PRESENTATION_OLD );
2073 mapTokenToNamespace( XML_NAMESPACE_PRESENTATION_OOO, XML_NP_PRESENTATION, XML_N_PRESENTATION_OOO );
2074 mapTokenToNamespace( XML_NAMESPACE_PRESENTATION_OASIS, XML_NP_PRESENTATION, XML_N_PRESENTATION_OASIS );
2075 mapTokenToNamespace( XML_NAMESPACE_SVG, XML_NP_SVG, XML_N_SVG );
2076 mapTokenToNamespace( XML_NAMESPACE_SVG_COMPAT, XML_NP_SVG, XML_N_SVG_COMPAT );
2077 mapTokenToNamespace( XML_NAMESPACE_CHART, XML_NP_CHART, XML_N_CHART );
2078 mapTokenToNamespace( XML_NAMESPACE_CHART_SO52, XML_NP_CHART, XML_N_CHART_OLD );
2079 mapTokenToNamespace( XML_NAMESPACE_CHART_OOO, XML_NP_CHART, XML_N_CHART_OOO );
2080 mapTokenToNamespace( XML_NAMESPACE_DR3D, XML_NP_DR3D, XML_N_DR3D );
2081 mapTokenToNamespace( XML_NAMESPACE_DR3D_OOO, XML_NP_DR3D, XML_N_DR3D_OOO );
2082 mapTokenToNamespace( XML_NAMESPACE_MATH, XML_NP_MATH, XML_N_MATH );
2083 mapTokenToNamespace( XML_NAMESPACE_VERSIONS_LIST, XML_NP_VERSIONS_LIST, XML_N_VERSIONS_LIST );
2084 mapTokenToNamespace( XML_NAMESPACE_FORM, XML_NP_FORM, XML_N_FORM );
2085 mapTokenToNamespace( XML_NAMESPACE_FORM_OOO, XML_NP_FORM, XML_N_FORM_OOO );
2086 mapTokenToNamespace( XML_NAMESPACE_SCRIPT, XML_NP_SCRIPT, XML_N_SCRIPT );
2087 mapTokenToNamespace( XML_NAMESPACE_SCRIPT_OOO, XML_NP_SCRIPT, XML_N_SCRIPT_OOO );
2088 mapTokenToNamespace( XML_NAMESPACE_BLOCKLIST, XML_NP_BLOCK_LIST, XML_N_BLOCK_LIST );
2089 mapTokenToNamespace( XML_NAMESPACE_CONFIG, XML_NP_CONFIG, XML_N_CONFIG );
2090 mapTokenToNamespace( XML_NAMESPACE_CONFIG_OOO, XML_NP_CONFIG, XML_N_CONFIG_OOO );
2091 mapTokenToNamespace( XML_NAMESPACE_OOO, XML_NP_OOO, XML_N_OOO );
2092 mapTokenToNamespace( XML_NAMESPACE_OOOW, XML_NP_OOOW, XML_N_OOOW );
2093 mapTokenToNamespace( XML_NAMESPACE_OOOC, XML_NP_OOOC, XML_N_OOOC );
2094 mapTokenToNamespace( XML_NAMESPACE_DOM, XML_NP_DOM, XML_N_DOM );
2095 mapTokenToNamespace( XML_NAMESPACE_DB, XML_NP_DB, XML_N_DB );
2096 mapTokenToNamespace( XML_NAMESPACE_DB_OASIS, XML_NP_DB, XML_N_DB_OASIS );
2097 mapTokenToNamespace( XML_NAMESPACE_DLG, XML_NP_DLG, XML_N_DLG );
2098 mapTokenToNamespace( XML_NAMESPACE_XFORMS, XML_NP_XFORMS_1_0, XML_N_XFORMS_1_0 );
2099 mapTokenToNamespace( XML_NAMESPACE_XSD, XML_NP_XSD, XML_N_XSD );
2100 mapTokenToNamespace( XML_NAMESPACE_XSI, XML_NP_XSI, XML_N_XSI );
2101 mapTokenToNamespace( XML_NAMESPACE_SMIL, XML_NP_SMIL, XML_N_SMIL );
2102 mapTokenToNamespace( XML_NAMESPACE_SMIL_SO52, XML_NP_SMIL, XML_N_SMIL_OLD );
2103 mapTokenToNamespace( XML_NAMESPACE_SMIL_COMPAT, XML_NP_SMIL, XML_N_SMIL_COMPAT );
2104 mapTokenToNamespace( XML_NAMESPACE_ANIMATION, XML_NP_ANIMATION, XML_N_ANIMATION );
2105 mapTokenToNamespace( XML_NAMESPACE_ANIMATION_OOO, XML_NP_ANIMATION, XML_N_ANIMATION_OOO );
2106 mapTokenToNamespace( XML_NAMESPACE_REPORT, XML_NP_RPT, XML_N_RPT );
2107 mapTokenToNamespace( XML_NAMESPACE_REPORT_OASIS, XML_NP_RPT, XML_N_RPT_OASIS );
2108 mapTokenToNamespace( XML_NAMESPACE_OF, XML_NP_OF, XML_N_OF );
2109 mapTokenToNamespace( XML_NAMESPACE_XHTML, XML_NP_XHTML, XML_N_XHTML );
2110 mapTokenToNamespace( XML_NAMESPACE_GRDDL, XML_NP_GRDDL, XML_N_GRDDL );
2111 mapTokenToNamespace( XML_NAMESPACE_OFFICE_EXT, XML_NP_OFFICE_EXT, XML_N_OFFICE_EXT );
2112 mapTokenToNamespace( XML_NAMESPACE_TABLE_EXT, XML_NP_TABLE_EXT, XML_N_TABLE_EXT );
2113 mapTokenToNamespace( XML_NAMESPACE_CHART_EXT, XML_NP_CHART_EXT, XML_N_CHART_EXT );
2114 mapTokenToNamespace( XML_NAMESPACE_DRAW_EXT, XML_NP_DRAW_EXT, XML_N_DRAW_EXT );
2115 mapTokenToNamespace( XML_NAMESPACE_CALC_EXT, XML_NP_CALC_EXT, XML_N_CALC_EXT );
2116 mapTokenToNamespace( XML_NAMESPACE_LO_EXT, XML_NP_LO_EXT, XML_N_LO_EXT );
2117 mapTokenToNamespace( XML_NAMESPACE_CSS3TEXT, XML_NP_CSS3TEXT, XML_N_CSS3TEXT );
2118 mapTokenToNamespace( XML_NAMESPACE_FIELD, XML_NP_FIELD, XML_N_FIELD );
2119 mapTokenToNamespace( XML_NAMESPACE_FORMX, XML_NP_FORMX, XML_N_FORMX );
2122 void SvXMLImport::registerNamespaces()
2124 for( auto const &aNamespaceEntry : aNamespaceMap )
2126 // aNamespaceMap = { Token : ( NamespacePrefix, NamespaceURI ) }
2127 registerNamespace( aNamespaceEntry.second.second, aNamespaceEntry.first << NMSP_SHIFT );
2131 void SvXMLImport::NotifyMacroEventRead()
2133 if (mbNotifyMacroEventRead)
2134 return;
2136 comphelper::DocumentInfo::notifyMacroEventRead(mxModel);
2138 mbNotifyMacroEventRead = true;
2141 SvXMLImportFastNamespaceHandler::SvXMLImportFastNamespaceHandler()
2145 void SvXMLImportFastNamespaceHandler::addNSDeclAttributes( rtl::Reference < comphelper::AttributeList > const & rAttrList )
2147 for(const auto& aNamespaceDefine : m_aNamespaceDefines)
2149 const OUString& rPrefix = aNamespaceDefine.m_aPrefix;
2150 const OUString& rNamespaceURI = aNamespaceDefine.m_aNamespaceURI;
2151 OUString sDecl;
2152 if ( rPrefix.isEmpty() )
2153 sDecl = "xmlns";
2154 else
2155 sDecl = "xmlns:" + rPrefix;
2156 rAttrList->AddAttribute( sDecl, rNamespaceURI );
2158 m_aNamespaceDefines.clear();
2161 void SvXMLImportFastNamespaceHandler::registerNamespace( const OUString& rNamespacePrefix, const OUString& rNamespaceURI )
2163 // Elements with default namespace parsed by FastParser have namespace prefix.
2164 // A default namespace needs to be registered with the prefix, to maintain the compatibility.
2165 if ( rNamespacePrefix.isEmpty() )
2166 m_aNamespaceDefines.push_back( NamespaceDefine(
2167 SvXMLImport::getNamespacePrefixFromURI( rNamespaceURI ), rNamespaceURI) );
2169 m_aNamespaceDefines.push_back( NamespaceDefine(
2170 rNamespacePrefix, rNamespaceURI) );
2173 OUString SvXMLImportFastNamespaceHandler::getNamespaceURI( const OUString&/* rNamespacePrefix */ )
2175 return OUString();
2178 SvXMLLegacyToFastDocHandler::SvXMLLegacyToFastDocHandler( rtl::Reference< SvXMLImport > xImport )
2179 : mrImport(std::move( xImport )),
2180 mxFastAttributes( new sax_fastparser::FastAttributeList( SvXMLImport::xTokenHandler.get() ) )
2184 void SAL_CALL SvXMLLegacyToFastDocHandler::setTargetDocument( const uno::Reference< lang::XComponent >& xDoc )
2186 mrImport->setTargetDocument( xDoc );
2189 void SAL_CALL SvXMLLegacyToFastDocHandler::startDocument()
2191 mrImport->startDocument();
2194 void SAL_CALL SvXMLLegacyToFastDocHandler::endDocument()
2196 mrImport->endDocument();
2199 void SAL_CALL SvXMLLegacyToFastDocHandler::startElement( const OUString& rName,
2200 const uno::Reference< xml::sax::XAttributeList >& xAttrList )
2202 sal_uInt16 nDefaultNamespace = XML_NAMESPACE_UNKNOWN;
2203 if (!maDefaultNamespaces.empty())
2204 nDefaultNamespace = maDefaultNamespaces.top();
2205 SvXMLImport::processNSAttributes(mrImport->mxNamespaceMap, mrImport.get(), xAttrList);
2206 OUString aLocalName;
2207 sal_uInt16 nPrefix = mrImport->mxNamespaceMap->GetKeyByAttrName( rName, &aLocalName );
2208 sal_Int32 mnElement = NAMESPACE_TOKEN( nPrefix ) | SvXMLImport::getTokenFromName( aLocalName );
2209 mxFastAttributes->clear();
2211 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
2212 for( sal_Int16 i=0; i < nAttrCount; i++ )
2214 const OUString& rAttrName = xAttrList->getNameByIndex( i );
2215 const OUString& rAttrValue = xAttrList->getValueByIndex( i );
2216 if (rAttrName == "xmlns")
2218 sal_uInt16 nNamespaceKey = mrImport->mxNamespaceMap->GetKeyByName(rAttrValue);
2219 if (nNamespaceKey != XML_NAMESPACE_UNKNOWN)
2221 nDefaultNamespace = nNamespaceKey;
2222 continue;
2224 assert(false && "unknown namespace");
2226 else if (rAttrName.indexOf(":") == -1 && nDefaultNamespace != XML_NAMESPACE_UNKNOWN)
2228 auto const nToken = SvXMLImport::getTokenFromName(rAttrName);
2229 if (nToken == xmloff::XML_TOKEN_INVALID)
2231 mxFastAttributes->addUnknown(mrImport->mxNamespaceMap->GetNameByKey(nDefaultNamespace),
2232 OUStringToOString(rAttrName, RTL_TEXTENCODING_UTF8),
2233 OUStringToOString(rAttrValue, RTL_TEXTENCODING_UTF8));
2235 else
2237 sal_Int32 const nAttr = NAMESPACE_TOKEN(nDefaultNamespace) | nToken;
2238 mxFastAttributes->add(nAttr, OUStringToOString(rAttrValue, RTL_TEXTENCODING_UTF8));
2240 continue;
2243 OUString aLocalAttrName;
2244 OUString aNamespace;
2245 // don't add unknown namespaces to the map
2246 sal_uInt16 const nAttrPrefix = mrImport->mxNamespaceMap->GetKeyByQName(
2247 rAttrName, nullptr, &aLocalAttrName, &aNamespace, SvXMLNamespaceMap::QNameMode::AttrValue);
2248 if( XML_NAMESPACE_XMLNS == nAttrPrefix )
2249 continue; // ignore
2250 auto const nToken = SvXMLImport::getTokenFromName(aLocalAttrName);
2251 if (XML_NAMESPACE_UNKNOWN == nAttrPrefix || nToken == xmloff::XML_TOKEN_INVALID)
2253 mxFastAttributes->addUnknown(aNamespace,
2254 OUStringToOString(rAttrName, RTL_TEXTENCODING_UTF8),
2255 OUStringToOString(rAttrValue, RTL_TEXTENCODING_UTF8));
2257 else
2259 sal_Int32 const nAttr = NAMESPACE_TOKEN(nAttrPrefix) | nToken;
2260 mxFastAttributes->add(nAttr, OUStringToOString(rAttrValue, RTL_TEXTENCODING_UTF8));
2263 mrImport->startFastElement( mnElement, mxFastAttributes );
2264 maDefaultNamespaces.push(nDefaultNamespace);
2267 void SAL_CALL SvXMLLegacyToFastDocHandler::endElement( const OUString& rName )
2269 OUString aLocalName;
2270 sal_uInt16 nPrefix = mrImport->mxNamespaceMap->GetKeyByAttrName( rName, &aLocalName );
2271 sal_Int32 mnElement = NAMESPACE_TOKEN( nPrefix ) | SvXMLImport::getTokenFromName(aLocalName);
2272 mrImport->endFastElement( mnElement );
2273 maDefaultNamespaces.pop();
2276 void SAL_CALL SvXMLLegacyToFastDocHandler::characters( const OUString& aChars )
2278 mrImport->characters( aChars );
2281 void SAL_CALL SvXMLLegacyToFastDocHandler::ignorableWhitespace( const OUString& )
2285 void SAL_CALL SvXMLLegacyToFastDocHandler::processingInstruction( const OUString& aTarget,
2286 const OUString& aData)
2288 mrImport->processingInstruction( aTarget, aData );
2291 void SAL_CALL SvXMLLegacyToFastDocHandler::setDocumentLocator( const uno::Reference< xml::sax::XLocator >& rLocator )
2293 mrImport->setDocumentLocator( rLocator );
2298 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */