Bump version to 6.4.0.12
[LibreOffice.git] / xmloff / source / core / xmlimp.cxx
blobbfc9d3fe819a3c3f24afb75f5615887cd7b83b10
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 <memory>
22 #include <tools/diagnose_ex.h>
23 #include <sal/log.hxx>
24 #include <com/sun/star/beans/XPropertySetInfo.hpp>
25 #include <tools/urlobj.hxx>
26 #include <vcl/graph.hxx>
27 #include <xmloff/unointerfacetouniqueidentifiermapper.hxx>
28 #include <xmloff/nmspmap.hxx>
29 #include <xmloff/xmluconv.hxx>
30 #include <xmloff/xmlnmspe.hxx>
31 #include <xmloff/xmltoken.hxx>
32 #include <xmloff/XMLFontStylesContext.hxx>
33 #include <xmloff/xmlictxt.hxx>
34 #include <xmloff/xmlimp.hxx>
35 #include <xmloff/xmlnumfi.hxx>
36 #include <XMLEventImportHelper.hxx>
37 #include <XMLStarBasicContextFactory.hxx>
38 #include <XMLScriptContextFactory.hxx>
39 #include <StyleMap.hxx>
40 #include <xmloff/ProgressBarHelper.hxx>
41 #include <xmloff/xmlerror.hxx>
42 #include <com/sun/star/container/XNameContainer.hpp>
43 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
44 #include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
45 #include <com/sun/star/io/XOutputStream.hpp>
46 #include <com/sun/star/util/MeasureUnit.hpp>
47 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
48 #include <com/sun/star/frame/XModel.hpp>
49 #include <com/sun/star/document/XBinaryStreamResolver.hpp>
50 #include <com/sun/star/document/XStorageBasedDocument.hpp>
51 #include <com/sun/star/document/XGraphicStorageHandler.hpp>
52 #include <com/sun/star/document/XEmbeddedObjectResolver.hpp>
53 #include <com/sun/star/xml/sax/XLocator.hpp>
54 #include <com/sun/star/xml/sax/FastParser.hpp>
55 #include <com/sun/star/xml/sax/SAXException.hpp>
56 #include <com/sun/star/packages/zip/ZipIOException.hpp>
57 #include <comphelper/fileformat.h>
58 #include <comphelper/namecontainer.hxx>
59 #include <comphelper/servicehelper.hxx>
60 #include <cppuhelper/implbase.hxx>
61 #include <cppuhelper/supportsservice.hxx>
62 #include <comphelper/extract.hxx>
63 #include <comphelper/documentconstants.hxx>
64 #include <comphelper/documentinfo.hxx>
65 #include <comphelper/storagehelper.hxx>
66 #include <comphelper/attributelist.hxx>
67 #include <unotools/fontcvt.hxx>
68 #include <xmloff/fasttokenhandler.hxx>
69 #include <vcl/GraphicExternalLink.hxx>
71 #include <com/sun/star/rdf/XMetadatable.hpp>
72 #include <com/sun/star/rdf/XRepositorySupplier.hpp>
73 #include <RDFaImportHelper.hxx>
75 using ::com::sun::star::beans::XPropertySetInfo;
77 using namespace ::com::sun::star;
78 using namespace ::com::sun::star::uno;
79 using namespace ::com::sun::star::util;
80 using namespace ::com::sun::star::io;
81 using namespace ::com::sun::star::container;
82 using namespace ::com::sun::star::document;
83 using namespace ::xmloff::token;
85 rtl::Reference< FastTokenHandler > SvXMLImport::xTokenHandler( new FastTokenHandler() );
86 std::unordered_map< sal_Int32, std::pair< OUString, OUString > > SvXMLImport::aNamespaceMap;
87 std::unordered_map< OUString, OUString > SvXMLImport::aNamespaceURIPrefixMap;
88 const OUString SvXMLImport::aDefaultNamespace = OUString("");
89 const OUString SvXMLImport::aNamespaceSeparator = OUString(":");
90 bool SvXMLImport::bIsNSMapsInitialized = false;
92 class SvXMLImportEventListener : public cppu::WeakImplHelper< css::lang::XEventListener >
94 private:
95 SvXMLImport* pImport;
97 public:
98 explicit SvXMLImportEventListener(SvXMLImport* pImport);
100 // XEventListener
101 virtual void SAL_CALL disposing(const lang::EventObject& rEventObject) override;
104 SvXMLImportEventListener::SvXMLImportEventListener(SvXMLImport* pTempImport)
105 : pImport(pTempImport)
109 // XEventListener
110 void SAL_CALL SvXMLImportEventListener::disposing( const lang::EventObject& )
112 if (pImport)
114 pImport->DisposingModel();
115 pImport = nullptr;
119 namespace
122 OUString
123 getBuildIdsProperty(uno::Reference<beans::XPropertySet> const& xImportInfo)
125 if (xImportInfo.is())
129 Reference< XPropertySetInfo > const xSetInfo(
130 xImportInfo->getPropertySetInfo());
131 if (xSetInfo.is() && xSetInfo->hasPropertyByName("BuildId"))
133 OUString aBuildId;
134 xImportInfo->getPropertyValue("BuildId") >>= aBuildId;
135 return aBuildId;
138 catch (Exception const&)
140 DBG_UNHANDLED_EXCEPTION("xmloff.core", "exception getting BuildId");
143 return OUString();
146 class DocumentInfo
148 private:
149 sal_uInt16 mnGeneratorVersion;
151 public:
152 explicit DocumentInfo( const SvXMLImport& rImport )
153 : mnGeneratorVersion( SvXMLImport::ProductVersionUnknown )
155 OUString const buildIds(
156 getBuildIdsProperty(rImport.getImportInfo()));
157 if (!buildIds.isEmpty())
159 sal_Int32 const ix = buildIds.indexOf(';');
160 if (-1 != ix)
162 OUString const loVersion(buildIds.copy(ix + 1));
163 if (!loVersion.isEmpty())
165 if ('3' == loVersion[0])
167 mnGeneratorVersion = SvXMLImport::LO_3x;
169 else if ('4' == loVersion[0])
171 if (loVersion.getLength() > 1
172 && (loVersion[1] == '0' || loVersion[1] == '1'))
174 mnGeneratorVersion = SvXMLImport::LO_41x; // 4.0/4.1
176 else if (loVersion.getLength() > 1 && '2' == loVersion[1])
178 mnGeneratorVersion = SvXMLImport::LO_42x; // 4.2
180 else if (loVersion.getLength() > 1 && '3' == loVersion[1])
182 mnGeneratorVersion = SvXMLImport::LO_43x; // 4.3
184 else if (loVersion.getLength() > 1 && '4' == loVersion[1])
186 mnGeneratorVersion = SvXMLImport::LO_44x; // 4.4
189 else if ('5' == loVersion[0])
191 mnGeneratorVersion = SvXMLImport::LO_5x;
193 else if ('6' == loVersion[0])
195 mnGeneratorVersion = SvXMLImport::LO_6x;
197 else
199 SAL_INFO("xmloff.core", "unknown LO version: " << loVersion);
201 return; // ignore buildIds
205 sal_Int32 nUPD, nBuild;
206 if ( rImport.getBuildIds( nUPD, nBuild ) )
208 if ( nUPD >= 640 && nUPD <= 645 )
210 mnGeneratorVersion = SvXMLImport::OOo_1x;
212 else if ( nUPD == 680 )
214 mnGeneratorVersion = SvXMLImport::OOo_2x;
216 else if ( nUPD == 300 && nBuild <= 9379 )
218 mnGeneratorVersion = SvXMLImport::OOo_30x;
220 else if ( nUPD == 310 )
222 mnGeneratorVersion = SvXMLImport::OOo_31x;
224 else if ( nUPD == 320 )
226 mnGeneratorVersion = SvXMLImport::OOo_32x;
228 else if ( nUPD == 330 )
230 mnGeneratorVersion = SvXMLImport::OOo_33x;
232 else if ( nUPD == 340 )
234 mnGeneratorVersion = SvXMLImport::OOo_34x;
236 else if (nUPD == 400 || nUPD == 401)
238 mnGeneratorVersion = SvXMLImport::AOO_40x;
240 else if (nUPD >= 410)
242 // effectively this means "latest", see use
243 // in XMLGraphicsDefaultStyle::SetDefaults()!
244 mnGeneratorVersion = SvXMLImport::AOO_4x;
249 sal_uInt16 getGeneratorVersion() const
251 return mnGeneratorVersion;
257 class SvXMLImport_Impl
259 public:
260 FontToSubsFontConverter hBatsFontConv;
261 FontToSubsFontConverter hMathFontConv;
263 bool mbOwnGraphicResolver;
264 bool mbOwnEmbeddedResolver;
265 INetURLObject aBaseURL;
266 INetURLObject aDocBase;
268 /// name of stream in package, e.g., "content.xml"
269 OUString mStreamName;
271 OUString aODFVersion;
273 bool mbIsOOoXML;
275 // Boolean, indicating that position attributes
276 // of shapes are given in horizontal left-to-right layout. This is the case
277 // for the OpenOffice.org file format. (#i28749#)
278 bool mbShapePositionInHoriL2R;
279 bool mbTextDocInOOoFileFormat;
281 const uno::Reference< uno::XComponentContext > mxComponentContext;
282 OUString const implementationName;
284 uno::Reference< embed::XStorage > mxSourceStorage;
286 std::unique_ptr< xmloff::RDFaImportHelper > mpRDFaHelper;
288 std::unique_ptr< DocumentInfo > mpDocumentInfo;
290 SvXMLImport_Impl( const uno::Reference< uno::XComponentContext >& rxContext,
291 OUString const & theImplementationName)
292 : hBatsFontConv( nullptr )
293 , hMathFontConv( nullptr )
294 , mbOwnGraphicResolver( false )
295 , mbOwnEmbeddedResolver( false )
296 , mbIsOOoXML(false)
297 // Convert drawing object positions from OOo file format to OASIS (#i28749#)
298 , mbShapePositionInHoriL2R( false )
299 , mbTextDocInOOoFileFormat( false )
300 , mxComponentContext( rxContext )
301 , implementationName(theImplementationName)
302 , mpRDFaHelper() // lazy
303 , mpDocumentInfo() // lazy
305 SAL_WARN_IF(!mxComponentContext.is(), "xmloff.core", "SvXMLImport: no ComponentContext");
306 if (!mxComponentContext.is()) throw uno::RuntimeException();
309 sal_uInt16 getGeneratorVersion( const SvXMLImport& rImport )
311 if (!mpDocumentInfo)
313 mpDocumentInfo.reset( new DocumentInfo( rImport ) );
316 return mpDocumentInfo->getGeneratorVersion();
319 ::comphelper::UnoInterfaceToUniqueIdentifierMapper maInterfaceToIdentifierMapper;
322 SvXMLImportContext *SvXMLImport::CreateDocumentContext(sal_uInt16 const nPrefix,
323 const OUString& rLocalName,
324 const uno::Reference< xml::sax::XAttributeList >& )
326 return new SvXMLImportContext( *this, nPrefix, rLocalName );
329 SvXMLImportContext *SvXMLImport::CreateFastContext( sal_Int32 /*Element*/,
330 const uno::Reference< xml::sax::XFastAttributeList >& /*xAttrList*/ )
332 return new SvXMLImportContext( *this );
335 void SvXMLImport::InitCtor_()
337 if( mnImportFlags != SvXMLImportFlags::NONE )
339 // implicit "xml" namespace prefix
340 mpNamespaceMap->Add( GetXMLToken(XML_XML), GetXMLToken(XML_N_XML), XML_NAMESPACE_XML );
341 mpNamespaceMap->Add( "_office", GetXMLToken(XML_N_OFFICE), XML_NAMESPACE_OFFICE );
342 mpNamespaceMap->Add( "_office_ooo", GetXMLToken(XML_N_OFFICE_EXT), XML_NAMESPACE_OFFICE_EXT );
343 mpNamespaceMap->Add( "_ooo", GetXMLToken(XML_N_OOO), XML_NAMESPACE_OOO );
344 mpNamespaceMap->Add( "_style", GetXMLToken(XML_N_STYLE), XML_NAMESPACE_STYLE );
345 mpNamespaceMap->Add( "_text", GetXMLToken(XML_N_TEXT), XML_NAMESPACE_TEXT );
346 mpNamespaceMap->Add( "_table", GetXMLToken(XML_N_TABLE), XML_NAMESPACE_TABLE );
347 mpNamespaceMap->Add( "_table_ooo", GetXMLToken(XML_N_TABLE_EXT), XML_NAMESPACE_TABLE_EXT );
348 mpNamespaceMap->Add( "_draw", GetXMLToken(XML_N_DRAW), XML_NAMESPACE_DRAW );
349 mpNamespaceMap->Add( "_draw_ooo", GetXMLToken(XML_N_DRAW_EXT), XML_NAMESPACE_DRAW_EXT );
350 mpNamespaceMap->Add( "_dr3d", GetXMLToken(XML_N_DR3D), XML_NAMESPACE_DR3D );
351 mpNamespaceMap->Add( "_fo", GetXMLToken(XML_N_FO_COMPAT), XML_NAMESPACE_FO );
352 mpNamespaceMap->Add( "_xlink", GetXMLToken(XML_N_XLINK), XML_NAMESPACE_XLINK );
353 mpNamespaceMap->Add( "_dc", GetXMLToken(XML_N_DC), XML_NAMESPACE_DC );
354 mpNamespaceMap->Add( "_dom", GetXMLToken(XML_N_DOM), XML_NAMESPACE_DOM );
355 mpNamespaceMap->Add( "_meta", GetXMLToken(XML_N_META), XML_NAMESPACE_META );
356 mpNamespaceMap->Add( "_number", GetXMLToken(XML_N_NUMBER), XML_NAMESPACE_NUMBER );
357 mpNamespaceMap->Add( "_svg", GetXMLToken(XML_N_SVG_COMPAT), XML_NAMESPACE_SVG );
358 mpNamespaceMap->Add( "_chart", GetXMLToken(XML_N_CHART), XML_NAMESPACE_CHART );
359 mpNamespaceMap->Add( "_math", GetXMLToken(XML_N_MATH), XML_NAMESPACE_MATH );
360 mpNamespaceMap->Add( "_form", GetXMLToken(XML_N_FORM), XML_NAMESPACE_FORM );
361 mpNamespaceMap->Add( "_script", GetXMLToken(XML_N_SCRIPT), XML_NAMESPACE_SCRIPT );
362 mpNamespaceMap->Add( "_config", GetXMLToken(XML_N_CONFIG), XML_NAMESPACE_CONFIG );
363 mpNamespaceMap->Add( "_xforms", GetXMLToken(XML_N_XFORMS_1_0), XML_NAMESPACE_XFORMS );
364 mpNamespaceMap->Add( "_formx", GetXMLToken( XML_N_FORMX ), XML_NAMESPACE_FORMX );
365 mpNamespaceMap->Add( "_xsd", GetXMLToken(XML_N_XSD), XML_NAMESPACE_XSD );
366 mpNamespaceMap->Add( "_xsi", GetXMLToken(XML_N_XSI), XML_NAMESPACE_XFORMS );
367 mpNamespaceMap->Add( "_ooow", GetXMLToken(XML_N_OOOW), XML_NAMESPACE_OOOW );
368 mpNamespaceMap->Add( "_oooc", GetXMLToken(XML_N_OOOC), XML_NAMESPACE_OOOC );
369 mpNamespaceMap->Add( "_field", GetXMLToken(XML_N_FIELD), XML_NAMESPACE_FIELD );
370 mpNamespaceMap->Add( "_of", GetXMLToken(XML_N_OF), XML_NAMESPACE_OF );
371 mpNamespaceMap->Add( "_xhtml", GetXMLToken(XML_N_XHTML), XML_NAMESPACE_XHTML );
372 mpNamespaceMap->Add( "_css3text", GetXMLToken(XML_N_CSS3TEXT), XML_NAMESPACE_CSS3TEXT );
374 mpNamespaceMap->Add( "_calc_libo", GetXMLToken(XML_N_CALC_EXT), XML_NAMESPACE_CALC_EXT);
375 mpNamespaceMap->Add( "_office_libo",
376 GetXMLToken(XML_N_LO_EXT), XML_NAMESPACE_LO_EXT);
379 if (mxNumberFormatsSupplier.is())
380 mpNumImport = std::make_unique<SvXMLNumFmtHelper>(mxNumberFormatsSupplier, GetComponentContext());
382 if (mxModel.is() && !mxEventListener.is())
384 mxEventListener.set(new SvXMLImportEventListener(this));
385 mxModel->addEventListener(mxEventListener);
389 SvXMLImport::SvXMLImport(
390 const css::uno::Reference< css::uno::XComponentContext >& xContext,
391 OUString const & implementationName, SvXMLImportFlags nImportFlags )
392 : mpImpl( new SvXMLImport_Impl(xContext, implementationName) ),
393 mpNamespaceMap( new SvXMLNamespaceMap ),
395 mpUnitConv( new SvXMLUnitConverter( xContext,
396 util::MeasureUnit::MM_100TH, util::MeasureUnit::MM_100TH) ),
398 mnImportFlags( nImportFlags ),
399 isFastContext( false ),
400 maNamespaceHandler( new SvXMLImportFastNamespaceHandler() ),
401 mbIsFormsSupported( true ),
402 mbIsTableShapeSupported( false ),
403 mbNotifyMacroEventRead( false )
405 SAL_WARN_IF( !xContext.is(), "xmloff.core", "got no service manager" );
406 InitCtor_();
407 mxParser = xml::sax::FastParser::create( xContext );
408 setNamespaceHandler( maNamespaceHandler.get() );
409 setTokenHandler( xTokenHandler.get() );
410 if ( !bIsNSMapsInitialized )
412 initializeNamespaceMaps();
413 bIsNSMapsInitialized = true;
415 registerNamespaces();
418 void SvXMLImport::cleanup() throw ()
420 if (mxEventListener.is() && mxModel.is())
421 mxModel->removeEventListener(mxEventListener);
422 // clear context stacks first in case of parse error because the context
423 // class dtors are full of application logic
424 while (!maFastContexts.empty())
426 if (SvXMLStylesContext* pStylesContext = dynamic_cast<SvXMLStylesContext*>(maFastContexts.top().get()))
427 pStylesContext->Clear();
428 maFastContexts.pop();
430 while (!maContexts.empty())
432 if (SvXMLStylesContext* pStylesContext = dynamic_cast<SvXMLStylesContext*>(maContexts.top().get()))
433 pStylesContext->Clear();
434 maContexts.pop();
436 mxTextImport.clear(); // XMLRedlineImportHelper needs model
437 DisposingModel();
440 SvXMLImport::~SvXMLImport() throw ()
442 cleanup();
445 namespace
447 class theSvXMLImportUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSvXMLImportUnoTunnelId> {};
450 const css::uno::Sequence<sal_Int8>& SvXMLImport::getUnoTunnelId() throw()
452 return theSvXMLImportUnoTunnelId::get().getSeq();
455 // XUnoTunnel
456 sal_Int64 SAL_CALL SvXMLImport::getSomething( const uno::Sequence< sal_Int8 >& rId )
458 if( isUnoTunnelId<SvXMLImport>(rId) )
460 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this));
462 return 0;
465 namespace
467 class setFastDocumentHandlerGuard
469 private:
470 css::uno::Reference<css::xml::sax::XFastParser> mxParser;
471 public:
472 setFastDocumentHandlerGuard(const css::uno::Reference<css::xml::sax::XFastParser>& Parser,
473 const css::uno::Reference<css::xml::sax::XFastDocumentHandler>& Handler)
474 : mxParser(Parser)
476 mxParser->setFastDocumentHandler(Handler);
478 //guarantee restoration of null document handler
479 ~setFastDocumentHandlerGuard()
481 mxParser->setFastDocumentHandler(nullptr);
486 // XFastParser
487 void SAL_CALL SvXMLImport::parseStream( const xml::sax::InputSource& aInputSource )
489 setFastDocumentHandlerGuard aDocumentHandlerGuard(mxParser, mxFastDocumentHandler.is() ? mxFastDocumentHandler : this);
490 mxParser->parseStream(aInputSource);
493 void SAL_CALL SvXMLImport::setFastDocumentHandler( const uno::Reference< xml::sax::XFastDocumentHandler >& Handler )
495 mxFastDocumentHandler = Handler;
498 void SAL_CALL SvXMLImport::setTokenHandler( const uno::Reference< xml::sax::XFastTokenHandler >& Handler )
500 mxParser->setTokenHandler( Handler );
503 void SAL_CALL SvXMLImport::registerNamespace( const OUString& NamespaceURL, sal_Int32 NamespaceToken )
505 mxParser->registerNamespace( NamespaceURL, NamespaceToken );
508 OUString SAL_CALL SvXMLImport::getNamespaceURL( const OUString& rPrefix )
510 return mxParser->getNamespaceURL( rPrefix );
513 void SAL_CALL SvXMLImport::setErrorHandler( const uno::Reference< xml::sax::XErrorHandler >& Handler )
515 mxParser->setErrorHandler( Handler );
518 void SAL_CALL SvXMLImport::setEntityResolver( const uno::Reference< xml::sax::XEntityResolver >& Resolver )
520 mxParser->setEntityResolver( Resolver );
523 void SAL_CALL SvXMLImport::setLocale( const lang::Locale& rLocale )
525 mxParser->setLocale( rLocale );
528 void SAL_CALL SvXMLImport::setNamespaceHandler( const uno::Reference< xml::sax::XFastNamespaceHandler >& Handler)
530 mxParser->setNamespaceHandler( Handler );
534 void SAL_CALL SvXMLImport::startDocument()
536 SAL_INFO( "xmloff.core", "{ SvXMLImport::startDocument" );
537 if (!mxGraphicStorageHandler.is() || !mxEmbeddedResolver.is())
539 Reference< lang::XMultiServiceFactory > xFactory( mxModel, UNO_QUERY );
540 if( xFactory.is() )
544 if (!mxGraphicStorageHandler.is())
546 // #99870# Import... instead of Export...
547 mxGraphicStorageHandler.set(
548 xFactory->createInstance("com.sun.star.document.ImportGraphicStorageHandler"),
549 UNO_QUERY);
550 mpImpl->mbOwnGraphicResolver = mxGraphicStorageHandler.is();
553 if( !mxEmbeddedResolver.is() )
555 // #99870# Import... instead of Export...
556 mxEmbeddedResolver.set(
557 xFactory->createInstance("com.sun.star.document.ImportEmbeddedObjectResolver"),
558 UNO_QUERY);
559 mpImpl->mbOwnEmbeddedResolver = mxEmbeddedResolver.is();
562 catch( css::uno::Exception& )
569 void SAL_CALL SvXMLImport::endDocument()
571 SAL_INFO( "xmloff.core", "} SvXMLImport::endDocument" );
572 // #i9518# All the stuff that accesses the document has to be done here, not in the dtor,
573 // because the SvXMLImport dtor might not be called until after the document has been closed.
575 GetTextImport()->MapCrossRefHeadingFieldsHorribly();
577 if (mpImpl->mpRDFaHelper)
579 const uno::Reference<rdf::XRepositorySupplier> xRS(mxModel,
580 uno::UNO_QUERY);
581 if (xRS.is())
583 mpImpl->mpRDFaHelper->InsertRDFa( xRS );
587 mpNumImport.reset();
588 if (mxImportInfo.is())
590 uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = mxImportInfo->getPropertySetInfo();
591 if (xPropertySetInfo.is())
593 if (bool(mpProgressBarHelper))
595 OUString sProgressMax(XML_PROGRESSMAX);
596 OUString sProgressCurrent(XML_PROGRESSCURRENT);
597 OUString sRepeat(XML_PROGRESSREPEAT);
598 if (xPropertySetInfo->hasPropertyByName(sProgressMax) &&
599 xPropertySetInfo->hasPropertyByName(sProgressCurrent))
601 sal_Int32 nProgressMax(mpProgressBarHelper->GetReference());
602 sal_Int32 nProgressCurrent(mpProgressBarHelper->GetValue());
603 mxImportInfo->setPropertyValue(sProgressMax, uno::Any(nProgressMax));
604 mxImportInfo->setPropertyValue(sProgressCurrent, uno::Any(nProgressCurrent));
606 if (xPropertySetInfo->hasPropertyByName(sRepeat))
607 mxImportInfo->setPropertyValue(sRepeat, css::uno::makeAny(mpProgressBarHelper->GetRepeat()));
608 // pProgressBarHelper is deleted in dtor
610 OUString sNumberStyles(XML_NUMBERSTYLES);
611 if (mxNumberStyles.is() && xPropertySetInfo->hasPropertyByName(sNumberStyles))
613 mxImportInfo->setPropertyValue(sNumberStyles, Any(mxNumberStyles));
618 if( mxFontDecls.is() )
619 static_cast<SvXMLStylesContext *>(mxFontDecls.get())->Clear();
620 if( mxStyles.is() )
621 static_cast<SvXMLStylesContext *>(mxStyles.get())->Clear();
622 if( mxAutoStyles.is() )
623 static_cast<SvXMLStylesContext *>(mxAutoStyles.get())->Clear();
624 if( mxMasterStyles.is() )
625 static_cast<SvXMLStylesContext *>(mxMasterStyles.get())->Clear();
627 // possible form-layer related knittings which can only be done when
628 // the whole document exists
629 if ( mxFormImport.is() )
630 mxFormImport->documentDone();
632 // The shape import helper does the z-order sorting in the dtor,
633 // so it must be deleted here, too.
634 mxShapeImport = nullptr;
636 if( mpImpl->mbOwnGraphicResolver )
638 Reference<lang::XComponent> xComp(mxGraphicStorageHandler, UNO_QUERY);
639 xComp->dispose();
642 if( mpImpl->mbOwnEmbeddedResolver )
644 Reference< lang::XComponent > xComp( mxEmbeddedResolver, UNO_QUERY );
645 xComp->dispose();
647 mpStyleMap.clear();
649 if ( bool( mpXMLErrors ) )
651 mpXMLErrors->ThrowErrorAsSAXException( XMLERROR_FLAG_SEVERE );
655 std::unique_ptr<SvXMLNamespaceMap> SvXMLImport::processNSAttributes(
656 std::unique_ptr<SvXMLNamespaceMap> & rpNamespaceMap,
657 SvXMLImport *const pImport, // TODO???
658 const uno::Reference< xml::sax::XAttributeList >& xAttrList)
660 std::unique_ptr<SvXMLNamespaceMap> pRewindMap;
661 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
662 for( sal_Int16 i=0; i < nAttrCount; i++ )
664 const OUString& rAttrName = xAttrList->getNameByIndex( i );
665 if (pImport && rAttrName == "office:version")
667 pImport->mpImpl->aODFVersion = xAttrList->getValueByIndex( i );
669 // the ODF version in content.xml and manifest.xml must be the same starting from ODF1.2
670 if (pImport->mpImpl->mStreamName == "content.xml"
671 && !pImport->IsODFVersionConsistent(pImport->mpImpl->aODFVersion))
673 throw xml::sax::SAXException("Inconsistent ODF versions in content.xml and manifest.xml!",
674 uno::Reference< uno::XInterface >(),
675 uno::makeAny(
676 packages::zip::ZipIOException("Inconsistent ODF versions in content.xml and manifest.xml!" ) ) );
679 else if( ( rAttrName.getLength() >= 5 ) &&
680 ( rAttrName.startsWith( GetXMLToken(XML_XMLNS) ) ) &&
681 ( rAttrName.getLength() == 5 || ':' == rAttrName[5] ) )
683 if( !pRewindMap )
685 pRewindMap = std::move(rpNamespaceMap);
686 rpNamespaceMap.reset(new SvXMLNamespaceMap(*pRewindMap));
688 const OUString& rAttrValue = xAttrList->getValueByIndex( i );
690 OUString aPrefix( ( rAttrName.getLength() == 5 )
691 ? OUString()
692 : rAttrName.copy( 6 ) );
693 // Add namespace, but only if it is known.
694 sal_uInt16 nKey = rpNamespaceMap->AddIfKnown( aPrefix, rAttrValue );
695 // If namespace is unknown, try to match a name with similar
696 // TC Id and version
697 if( XML_NAMESPACE_UNKNOWN == nKey )
699 OUString aTestName( rAttrValue );
700 if( SvXMLNamespaceMap::NormalizeURI( aTestName ) )
701 nKey = rpNamespaceMap->AddIfKnown( aPrefix, aTestName );
703 // If that namespace is not known, too, add it as unknown
704 if( XML_NAMESPACE_UNKNOWN == nKey )
705 rpNamespaceMap->Add( aPrefix, rAttrValue );
709 return pRewindMap;
712 void SAL_CALL SvXMLImport::startElement( const OUString& rName,
713 const uno::Reference< xml::sax::XAttributeList >& xAttrList )
715 // SAL_INFO("svg", "startElement " << rName);
716 // Process namespace attributes. This must happen before creating the
717 // context, because namespace declaration apply to the element name itself.
718 std::unique_ptr<SvXMLNamespaceMap> pRewindMap(
719 processNSAttributes(mpNamespaceMap, this, xAttrList));
721 // Get element's namespace and local name.
722 OUString aLocalName;
723 sal_uInt16 nPrefix =
724 mpNamespaceMap->GetKeyByAttrName( rName, &aLocalName );
726 // If there are contexts already, call a CreateChildContext at the topmost
727 // context. Otherwise, create a default context.
728 SvXMLImportContextRef xContext;
729 if(!maContexts.empty())
731 xContext = maContexts.top()->CreateChildContext(nPrefix, aLocalName, xAttrList);
732 SAL_WARN_IF( !xContext.is() || (xContext->GetPrefix() != nPrefix), "xmloff.core",
733 "SvXMLImport::startElement: created context has wrong prefix" );
735 else
737 xContext.set(CreateDocumentContext(nPrefix, aLocalName, xAttrList));
738 if( (nPrefix & XML_NAMESPACE_UNKNOWN_FLAG) != 0 &&
739 dynamic_cast< const SvXMLImportContext*>(xContext.get()) != nullptr )
741 Reference<xml::sax::XLocator> xDummyLocator;
742 Sequence < OUString > aParams { rName };
744 SetError( XMLERROR_FLAG_SEVERE|XMLERROR_UNKNOWN_ROOT,
745 aParams, "Root element unknown", xDummyLocator );
749 SAL_WARN_IF( !xContext.is(), "xmloff.core", "SvXMLImport::startElement: missing context" );
750 if( !xContext.is() )
751 xContext.set(new SvXMLImportContext( *this, nPrefix, aLocalName ));
753 // Remember old namespace map.
754 if( pRewindMap )
755 xContext->PutRewindMap(std::move(pRewindMap));
757 // Call a startElement at the new context.
758 xContext->StartElement( xAttrList );
760 // Push context on stack.
761 maContexts.push(xContext);
764 void SAL_CALL SvXMLImport::endElement( const OUString&
765 #ifdef DBG_UTIL
766 rName
767 #endif
770 if (maContexts.empty())
772 SAL_WARN("xmloff.core", "SvXMLImport::endElement: no context left");
773 return;
776 std::unique_ptr<SvXMLNamespaceMap> pRewindMap;
779 // Get topmost context and remove it from the stack.
780 SvXMLImportContextRef xContext = std::move(maContexts.top());
781 maContexts.pop();
783 #ifdef DBG_UTIL
784 // Non product only: check if endElement call matches startELement call.
785 OUString aLocalName;
786 sal_uInt16 nPrefix =
787 mpNamespaceMap->GetKeyByAttrName( rName, &aLocalName );
788 SAL_WARN_IF( xContext->GetPrefix() != nPrefix, "xmloff.core", "SvXMLImport::endElement: popped context has wrong prefix" );
789 SAL_WARN_IF( xContext->GetLocalName() != aLocalName, "xmloff.core", "SvXMLImport::endElement: popped context has wrong lname" );
790 #endif
792 // Call a EndElement at the current context.
793 xContext->EndElement();
794 // Get a namespace map to rewind.
795 pRewindMap = xContext->TakeRewindMap();
796 // note: delete xContext *before* rewinding namespace map!
799 // Rewind a namespace map.
800 if (pRewindMap)
802 mpNamespaceMap.reset();
803 mpNamespaceMap = std::move(pRewindMap);
807 void SAL_CALL SvXMLImport::characters( const OUString& rChars )
809 if ( !maFastContexts.empty() )
811 maFastContexts.top()->characters( rChars );
813 else if( !maContexts.empty() )
815 maContexts.top()->Characters( rChars );
819 void SvXMLImport::Characters( const OUString& rChars )
821 if( !maContexts.empty() )
823 maContexts.top()->Characters( rChars );
827 void SAL_CALL SvXMLImport::ignorableWhitespace( const OUString& )
831 void SAL_CALL SvXMLImport::processingInstruction( const OUString&,
832 const OUString& )
836 void SAL_CALL SvXMLImport::setDocumentLocator( const uno::Reference< xml::sax::XLocator >& rLocator )
838 mxLocator = rLocator;
841 // XFastContextHandler
842 void SAL_CALL SvXMLImport::startFastElement (sal_Int32 Element,
843 const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
845 if ( Attribs.is() )
847 sax_fastparser::FastAttributeList *pAttribList =
848 sax_fastparser::FastAttributeList::castToFastAttributeList( Attribs );
849 auto aIter( pAttribList->find( XML_ELEMENT( OFFICE, XML_VERSION ) ) );
850 if( aIter != pAttribList->end() )
852 mpImpl->aODFVersion = aIter.toString();
854 // the ODF version in content.xml and manifest.xml must be the same starting from ODF1.2
855 if ( mpImpl->mStreamName == "content.xml" && !IsODFVersionConsistent( mpImpl->aODFVersion ) )
857 throw xml::sax::SAXException("Inconsistent ODF versions in content.xml and manifest.xml!",
858 uno::Reference< uno::XInterface >(),
859 uno::makeAny(
860 packages::zip::ZipIOException("Inconsistent ODF versions in content.xml and manifest.xml!" ) ) );
865 //Namespace handling is unnecessary. It is done by the fastparser itself.
866 uno::Reference<XFastContextHandler> xContext;
867 if (!maFastContexts.empty())
869 uno::Reference<XFastContextHandler> pHandler = maFastContexts.top();
870 xContext = pHandler->createFastChildContext( Element, Attribs );
872 else
873 xContext.set( CreateFastContext( Element, Attribs ) );
875 if ( !xContext.is() )
876 xContext.set( new SvXMLImportContext( *this ) );
878 isFastContext = true;
880 // Call a startElement at the new context.
881 xContext->startFastElement( Element, Attribs );
883 if ( isFastContext )
885 if ( maNamespaceAttrList.is() )
886 maNamespaceAttrList->Clear();
887 else
888 maNamespaceAttrList = new comphelper::AttributeList;
890 maNamespaceHandler->addNSDeclAttributes( maNamespaceAttrList );
891 std::unique_ptr<SvXMLNamespaceMap> pRewindMap(
892 processNSAttributes(mpNamespaceMap, this, maNamespaceAttrList.get()));
893 assert( dynamic_cast<SvXMLImportContext*>( xContext.get() ) != nullptr );
894 SvXMLImportContext *pContext = static_cast<SvXMLImportContext*>( xContext.get() );
895 if (pRewindMap)
896 pContext->PutRewindMap(std::move(pRewindMap));
897 maContexts.push(pContext);
900 // Push context on stack.
901 maFastContexts.push(xContext);
904 void SAL_CALL SvXMLImport::startUnknownElement (const OUString & rPrefix, const OUString & rLocalName,
905 const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
907 uno::Reference<XFastContextHandler> xContext;
908 if (!maFastContexts.empty())
910 uno::Reference<XFastContextHandler> pHandler = maFastContexts.top();
911 xContext = pHandler->createUnknownChildContext( rPrefix, rLocalName, Attribs );
913 else
914 xContext.set( CreateFastContext( -1, Attribs ) );
916 if ( !xContext.is() )
917 xContext.set( new SvXMLImportContext( *this ) );
919 xContext->startUnknownElement( rPrefix, rLocalName, Attribs );
920 maFastContexts.push(xContext);
923 void SAL_CALL SvXMLImport::endFastElement (sal_Int32 Element)
925 if (!maFastContexts.empty())
927 uno::Reference<XFastContextHandler> xContext = std::move(maFastContexts.top());
928 maFastContexts.pop();
929 isFastContext = true;
930 xContext->endFastElement( Element );
931 if (isFastContext)
932 maContexts.pop();
934 xContext = nullptr;
938 void SAL_CALL SvXMLImport::endUnknownElement (const OUString & rPrefix, const OUString & rLocalName)
940 if (!maFastContexts.empty())
942 uno::Reference<XFastContextHandler> xContext = std::move(maFastContexts.top());
943 maFastContexts.pop();
944 xContext->endUnknownElement( rPrefix, rLocalName );
945 xContext = nullptr;
949 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
950 SvXMLImport::createFastChildContext (sal_Int32,
951 const uno::Reference< xml::sax::XFastAttributeList > &)
953 return this;
956 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
957 SvXMLImport::createUnknownChildContext (const OUString &, const OUString &,
958 const uno::Reference< xml::sax::XFastAttributeList > &)
960 return this;
963 // XExtendedDocumentHandler
964 void SAL_CALL SvXMLImport::startCDATA()
968 void SAL_CALL SvXMLImport::endCDATA()
972 void SAL_CALL SvXMLImport::comment( const OUString& )
976 void SAL_CALL SvXMLImport::allowLineBreak()
980 void SAL_CALL SvXMLImport::unknown( const OUString& )
984 void SvXMLImport::SetStatistics(const uno::Sequence< beans::NamedValue> &)
986 GetProgressBarHelper()->SetRepeat(false);
987 GetProgressBarHelper()->SetReference(0);
990 // XImporter
991 void SAL_CALL SvXMLImport::setTargetDocument( const uno::Reference< lang::XComponent >& xDoc )
993 mxModel.set( xDoc, UNO_QUERY );
994 if( !mxModel.is() )
995 throw lang::IllegalArgumentException();
999 uno::Reference<document::XStorageBasedDocument> const xSBDoc(mxModel, uno::UNO_QUERY);
1000 uno::Reference<embed::XStorage> const xStor(xSBDoc.is() ? xSBDoc->getDocumentStorage()
1001 : nullptr);
1002 if (xStor.is())
1004 mpImpl->mbIsOOoXML =
1005 ::comphelper::OStorageHelper::GetXStorageFormat(xStor)
1006 < SOFFICE_FILEFORMAT_8;
1009 catch (uno::Exception const&)
1011 DBG_UNHANDLED_EXCEPTION("xmloff.core");
1013 if (!mxEventListener.is())
1015 mxEventListener.set(new SvXMLImportEventListener(this));
1016 mxModel->addEventListener(mxEventListener);
1019 SAL_WARN_IF( bool(mpNumImport), "xmloff.core", "number format import already exists." );
1020 mpNumImport.reset();
1023 // XFilter
1024 sal_Bool SAL_CALL SvXMLImport::filter( const uno::Sequence< beans::PropertyValue >& )
1026 return false;
1029 void SAL_CALL SvXMLImport::cancel( )
1033 // XInitialize
1034 void SAL_CALL SvXMLImport::initialize( const uno::Sequence< uno::Any >& aArguments )
1036 for( const auto& rAny : aArguments )
1038 Reference<XInterface> xValue;
1039 rAny >>= xValue;
1041 uno::Reference<task::XStatusIndicator> xTmpStatusIndicator(
1042 xValue, UNO_QUERY );
1043 if( xTmpStatusIndicator.is() )
1044 mxStatusIndicator = xTmpStatusIndicator;
1046 uno::Reference<document::XGraphicStorageHandler> xGraphicStorageHandler(xValue, UNO_QUERY);
1047 if (xGraphicStorageHandler.is())
1048 mxGraphicStorageHandler = xGraphicStorageHandler;
1050 uno::Reference<document::XEmbeddedObjectResolver> xTmpObjectResolver(
1051 xValue, UNO_QUERY );
1052 if( xTmpObjectResolver.is() )
1053 mxEmbeddedResolver = xTmpObjectResolver;
1055 uno::Reference<beans::XPropertySet> xTmpPropSet( xValue, UNO_QUERY );
1056 if( xTmpPropSet.is() )
1058 mxImportInfo = xTmpPropSet;
1059 uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = mxImportInfo->getPropertySetInfo();
1060 if (xPropertySetInfo.is())
1062 OUString sPropName(XML_NUMBERSTYLES);
1063 if (xPropertySetInfo->hasPropertyByName(sPropName))
1065 uno::Any aAny = mxImportInfo->getPropertyValue(sPropName);
1066 aAny >>= mxNumberStyles;
1069 sPropName = "PrivateData";
1070 if (xPropertySetInfo->hasPropertyByName(sPropName))
1072 Reference < XInterface > xIfc;
1073 uno::Any aAny = mxImportInfo->getPropertyValue(sPropName);
1074 aAny >>= xIfc;
1076 StyleMap *pSMap = comphelper::getUnoTunnelImplementation<StyleMap>( xIfc );
1077 if( pSMap )
1079 mpStyleMap = pSMap;
1082 OUString sBaseURI;
1083 sPropName = "BaseURI";
1084 if (xPropertySetInfo->hasPropertyByName(sPropName))
1086 uno::Any aAny = mxImportInfo->getPropertyValue(sPropName);
1087 aAny >>= sBaseURI;
1088 mpImpl->aBaseURL.SetURL( sBaseURI );
1089 mpImpl->aDocBase.SetURL( sBaseURI );
1091 OUString sRelPath;
1092 sPropName = "StreamRelPath";
1093 if( xPropertySetInfo->hasPropertyByName(sPropName) )
1095 uno::Any aAny = mxImportInfo->getPropertyValue(sPropName);
1096 aAny >>= sRelPath;
1098 OUString sName;
1099 sPropName = "StreamName";
1100 if( xPropertySetInfo->hasPropertyByName(sPropName) )
1102 uno::Any aAny = mxImportInfo->getPropertyValue(sPropName);
1103 aAny >>= sName;
1105 if( !sBaseURI.isEmpty() && !sName.isEmpty() )
1107 if( !sRelPath.isEmpty() )
1108 mpImpl->aBaseURL.insertName( sRelPath );
1109 mpImpl->aBaseURL.insertName( sName );
1111 mpImpl->mStreamName = sName; // Note: may be empty (XSLT)
1112 // Retrieve property <ShapePositionInHoriL2R> (#i28749#)
1113 sPropName = "ShapePositionInHoriL2R";
1114 if( xPropertySetInfo->hasPropertyByName(sPropName) )
1116 uno::Any aAny = mxImportInfo->getPropertyValue(sPropName);
1117 aAny >>= mpImpl->mbShapePositionInHoriL2R;
1119 sPropName = "TextDocInOOoFileFormat";
1120 if( xPropertySetInfo->hasPropertyByName(sPropName) )
1122 uno::Any aAny = mxImportInfo->getPropertyValue(sPropName);
1123 aAny >>= mpImpl->mbTextDocInOOoFileFormat;
1126 sPropName = "SourceStorage";
1127 if( xPropertySetInfo->hasPropertyByName(sPropName) )
1128 mxImportInfo->getPropertyValue(sPropName) >>= mpImpl->mxSourceStorage;
1133 uno::Reference<lang::XInitialization> const xInit(mxParser, uno::UNO_QUERY_THROW);
1134 uno::Sequence<uno::Any> args(1);
1135 args[0] <<= OUString("IgnoreMissingNSDecl");
1136 xInit->initialize( args );
1139 // XServiceInfo
1140 OUString SAL_CALL SvXMLImport::getImplementationName()
1142 return mpImpl->implementationName;
1145 sal_Bool SAL_CALL SvXMLImport::supportsService( const OUString& rServiceName )
1147 return cppu::supportsService(this, rServiceName);
1150 uno::Sequence< OUString > SAL_CALL SvXMLImport::getSupportedServiceNames( )
1152 return { "com.sun.star.document.ImportFilter", "com.sun.star.xml.XMLImportFilter" };
1155 XMLTextImportHelper* SvXMLImport::CreateTextImport()
1157 return new XMLTextImportHelper( mxModel, *this );
1160 XMLShapeImportHelper* SvXMLImport::CreateShapeImport()
1162 return new XMLShapeImportHelper( *this, mxModel );
1165 SchXMLImportHelper* SvXMLImport::CreateChartImport()
1167 return new SchXMLImportHelper();
1170 ::xmloff::OFormLayerXMLImport* SvXMLImport::CreateFormImport()
1172 return new ::xmloff::OFormLayerXMLImport(*this);
1176 // Get or create fill/line/lineend-style-helper
1179 const Reference< container::XNameContainer > & SvXMLImport::GetGradientHelper()
1181 if( !mxGradientHelper.is() )
1183 if( mxModel.is() )
1185 Reference< lang::XMultiServiceFactory > xServiceFact( mxModel, UNO_QUERY);
1186 if( xServiceFact.is() )
1190 mxGradientHelper.set( xServiceFact->createInstance(
1191 "com.sun.star.drawing.GradientTable" ), UNO_QUERY);
1193 catch( lang::ServiceNotRegisteredException& )
1199 return mxGradientHelper;
1202 const Reference< container::XNameContainer > & SvXMLImport::GetHatchHelper()
1204 if( !mxHatchHelper.is() )
1206 if( mxModel.is() )
1208 Reference< lang::XMultiServiceFactory > xServiceFact( mxModel, UNO_QUERY);
1209 if( xServiceFact.is() )
1213 mxHatchHelper.set( xServiceFact->createInstance(
1214 "com.sun.star.drawing.HatchTable" ), UNO_QUERY);
1216 catch( lang::ServiceNotRegisteredException& )
1222 return mxHatchHelper;
1225 const Reference< container::XNameContainer > & SvXMLImport::GetBitmapHelper()
1227 if( !mxBitmapHelper.is() )
1229 if( mxModel.is() )
1231 Reference< lang::XMultiServiceFactory > xServiceFact( mxModel, UNO_QUERY);
1232 if( xServiceFact.is() )
1236 mxBitmapHelper.set( xServiceFact->createInstance(
1237 "com.sun.star.drawing.BitmapTable" ), UNO_QUERY);
1239 catch( lang::ServiceNotRegisteredException& )
1245 return mxBitmapHelper;
1248 const Reference< container::XNameContainer > & SvXMLImport::GetTransGradientHelper()
1250 if( !mxTransGradientHelper.is() )
1252 if( mxModel.is() )
1254 Reference< lang::XMultiServiceFactory > xServiceFact( mxModel, UNO_QUERY);
1255 if( xServiceFact.is() )
1259 mxTransGradientHelper.set( xServiceFact->createInstance(
1260 "com.sun.star.drawing.TransparencyGradientTable" ), UNO_QUERY);
1262 catch( lang::ServiceNotRegisteredException& )
1268 return mxTransGradientHelper;
1271 const Reference< container::XNameContainer > & SvXMLImport::GetMarkerHelper()
1273 if( !mxMarkerHelper.is() )
1275 if( mxModel.is() )
1277 Reference< lang::XMultiServiceFactory > xServiceFact( mxModel, UNO_QUERY);
1278 if( xServiceFact.is() )
1282 mxMarkerHelper.set( xServiceFact->createInstance( "com.sun.star.drawing.MarkerTable" ), UNO_QUERY);
1284 catch( lang::ServiceNotRegisteredException& )
1290 return mxMarkerHelper;
1293 const Reference< container::XNameContainer > & SvXMLImport::GetDashHelper()
1295 if( !mxDashHelper.is() && mxModel.is() )
1297 Reference< lang::XMultiServiceFactory > xServiceFact( mxModel, UNO_QUERY);
1298 if( xServiceFact.is() )
1302 mxDashHelper.set( xServiceFact->createInstance( "com.sun.star.drawing.DashTable" ), UNO_QUERY);
1304 catch( lang::ServiceNotRegisteredException& )
1309 return mxDashHelper;
1312 bool SvXMLImport::IsPackageURL( const OUString& rURL ) const
1315 // if, and only if, only parts are imported, then we're in a package
1316 const SvXMLImportFlags nTest = SvXMLImportFlags::META|SvXMLImportFlags::STYLES|SvXMLImportFlags::CONTENT|SvXMLImportFlags::SETTINGS;
1317 if( (mnImportFlags & nTest) == nTest )
1318 return false;
1320 // TODO: from this point extract to own static function
1322 // Some quick tests: Some may rely on the package structure!
1323 sal_Int32 nLen = rURL.getLength();
1324 if( nLen > 0 && '/' == rURL[0] )
1325 // RFC2396 net_path or abs_path
1326 return false;
1327 else if( nLen > 1 && '.' == rURL[0] )
1329 if( '.' == rURL[1] )
1330 // ../: We are never going up one level, so we know
1331 // it's not an external URI
1332 return false;
1333 else if( '/' == rURL[1] )
1334 // we are remaining on a level, so it's a package URI
1335 return true;
1338 // Now check for a RFC2396 schema
1339 sal_Int32 nPos = 1;
1340 while( nPos < nLen )
1342 switch( rURL[nPos] )
1344 case '/':
1345 // a relative path segment
1346 return true;
1347 case ':':
1348 // a schema
1349 return false;
1350 default:
1351 break;
1352 // we don't care about any other characters
1354 ++nPos;
1357 return true;
1360 uno::Reference<graphic::XGraphic> SvXMLImport::loadGraphicByURL(OUString const & rURL)
1362 uno::Reference<graphic::XGraphic> xGraphic;
1364 if (mxGraphicStorageHandler.is())
1366 if (IsPackageURL(rURL))
1368 xGraphic = mxGraphicStorageHandler->loadGraphic(rURL);
1370 else
1372 OUString const & rAbsoluteURL = GetAbsoluteReference(rURL);
1373 GraphicExternalLink aExternalLink(rAbsoluteURL);
1374 Graphic aGraphic(aExternalLink);
1375 xGraphic = aGraphic.GetXGraphic();
1379 return xGraphic;
1382 uno::Reference<graphic::XGraphic> SvXMLImport::loadGraphicFromBase64(uno::Reference<io::XOutputStream> const & rxOutputStream)
1384 uno::Reference<graphic::XGraphic> xGraphic;
1386 if (mxGraphicStorageHandler.is())
1388 xGraphic = mxGraphicStorageHandler->loadGraphicFromOutputStream(rxOutputStream);
1391 return xGraphic;
1394 Reference< XOutputStream > SvXMLImport::GetStreamForGraphicObjectURLFromBase64() const
1396 Reference< XOutputStream > xOStm;
1397 Reference< document::XBinaryStreamResolver > xStmResolver(mxGraphicStorageHandler, UNO_QUERY);
1399 if( xStmResolver.is() )
1400 xOStm = xStmResolver->createOutputStream();
1402 return xOStm;
1405 OUString SvXMLImport::ResolveEmbeddedObjectURL(
1406 const OUString& rURL,
1407 const OUString& rClassId )
1409 OUString sRet;
1411 if( IsPackageURL( rURL ) )
1413 if ( mxEmbeddedResolver.is() )
1415 OUString sURL( rURL );
1416 if( !rClassId.isEmpty() )
1418 sURL += "!" + rClassId;
1420 sRet = mxEmbeddedResolver->resolveEmbeddedObjectURL( sURL );
1423 else
1424 sRet = GetAbsoluteReference( rURL );
1426 return sRet;
1429 Reference< embed::XStorage > const & SvXMLImport::GetSourceStorage() const
1431 return mpImpl->mxSourceStorage;
1434 Reference < XOutputStream >
1435 SvXMLImport::GetStreamForEmbeddedObjectURLFromBase64() const
1437 Reference < XOutputStream > xOLEStream;
1439 if( mxEmbeddedResolver.is() )
1441 Reference< XNameAccess > xNA( mxEmbeddedResolver, UNO_QUERY );
1442 if( xNA.is() )
1444 Any aAny = xNA->getByName( "Obj12345678" );
1445 aAny >>= xOLEStream;
1449 return xOLEStream;
1452 OUString SvXMLImport::ResolveEmbeddedObjectURLFromBase64()
1454 OUString sRet;
1456 if( mxEmbeddedResolver.is() )
1458 sRet = mxEmbeddedResolver->resolveEmbeddedObjectURL( "Obj12345678" );
1461 return sRet;
1464 void SvXMLImport::AddStyleDisplayName( sal_uInt16 nFamily,
1465 const OUString& rName,
1466 const OUString& rDisplayName )
1468 if( !mpStyleMap.is() )
1470 mpStyleMap = new StyleMap;
1471 if( mxImportInfo.is() )
1473 OUString sPrivateData( "PrivateData" );
1474 Reference< beans::XPropertySetInfo > xPropertySetInfo =
1475 mxImportInfo->getPropertySetInfo();
1476 if( xPropertySetInfo.is() &&
1477 xPropertySetInfo->hasPropertyByName(sPrivateData) )
1479 Reference < XInterface > xIfc(
1480 static_cast< XUnoTunnel *>( mpStyleMap.get() ) );
1481 mxImportInfo->setPropertyValue( sPrivateData, Any(xIfc) );
1486 StyleMap::key_type aKey( nFamily, rName );
1487 StyleMap::value_type aValue( aKey, rDisplayName );
1488 ::std::pair<StyleMap::iterator,bool> aRes( mpStyleMap->insert( aValue ) );
1489 SAL_WARN_IF( !aRes.second,
1490 "xmloff.core",
1491 "duplicate style name of family " << nFamily << ": \"" << rName << "\"");
1495 OUString SvXMLImport::GetStyleDisplayName( sal_uInt16 nFamily,
1496 const OUString& rName ) const
1498 OUString sName( rName );
1499 if( mpStyleMap.is() && !rName.isEmpty() )
1501 StyleMap::key_type aKey( nFamily, rName );
1502 StyleMap::const_iterator aIter = mpStyleMap->find( aKey );
1503 if( aIter != mpStyleMap->end() )
1504 sName = (*aIter).second;
1506 return sName;
1509 void SvXMLImport::SetViewSettings(const css::uno::Sequence<css::beans::PropertyValue>&)
1513 void SvXMLImport::SetConfigurationSettings(const css::uno::Sequence<css::beans::PropertyValue>&)
1517 void SvXMLImport::SetDocumentSpecificSettings(const OUString&, const uno::Sequence<beans::PropertyValue>&)
1521 ProgressBarHelper* SvXMLImport::GetProgressBarHelper()
1523 if (!mpProgressBarHelper)
1525 mpProgressBarHelper = std::make_unique<ProgressBarHelper>(mxStatusIndicator, false);
1527 if (mxImportInfo.is())
1529 uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = mxImportInfo->getPropertySetInfo();
1530 if (xPropertySetInfo.is())
1532 OUString sProgressRange(XML_PROGRESSRANGE);
1533 OUString sProgressMax(XML_PROGRESSMAX);
1534 OUString sProgressCurrent(XML_PROGRESSCURRENT);
1535 OUString sRepeat(XML_PROGRESSREPEAT);
1536 if (xPropertySetInfo->hasPropertyByName(sProgressMax) &&
1537 xPropertySetInfo->hasPropertyByName(sProgressCurrent) &&
1538 xPropertySetInfo->hasPropertyByName(sProgressRange))
1540 uno::Any aAny;
1541 sal_Int32 nProgressMax(0);
1542 sal_Int32 nProgressCurrent(0);
1543 sal_Int32 nProgressRange(0);
1544 aAny = mxImportInfo->getPropertyValue(sProgressRange);
1545 if (aAny >>= nProgressRange)
1546 mpProgressBarHelper->SetRange(nProgressRange);
1547 aAny = mxImportInfo->getPropertyValue(sProgressMax);
1548 if (aAny >>= nProgressMax)
1549 mpProgressBarHelper->SetReference(nProgressMax);
1550 aAny = mxImportInfo->getPropertyValue(sProgressCurrent);
1551 if (aAny >>= nProgressCurrent)
1552 mpProgressBarHelper->SetValue(nProgressCurrent);
1554 if (xPropertySetInfo->hasPropertyByName(sRepeat))
1556 uno::Any aAny = mxImportInfo->getPropertyValue(sRepeat);
1557 if (aAny.getValueType() == cppu::UnoType<bool>::get())
1558 mpProgressBarHelper->SetRepeat(::cppu::any2bool(aAny));
1559 else {
1560 SAL_WARN( "xmloff.core", "why is it no boolean?" );
1566 return mpProgressBarHelper.get();
1569 void SvXMLImport::AddNumberStyle(sal_Int32 nKey, const OUString& rName)
1571 if (!mxNumberStyles.is())
1572 mxNumberStyles.set( comphelper::NameContainer_createInstance( ::cppu::UnoType<sal_Int32>::get()) );
1573 if (mxNumberStyles.is())
1577 mxNumberStyles->insertByName(rName, Any(nKey));
1579 catch ( uno::Exception& )
1581 DBG_UNHANDLED_EXCEPTION( "xmloff.core", "Numberformat could not be inserted");
1584 else {
1585 SAL_WARN( "xmloff.core", "not possible to create NameContainer");
1589 XMLEventImportHelper& SvXMLImport::GetEventImport()
1591 if (!mpEventImportHelper)
1593 // construct event helper and register StarBasic handler and standard
1594 // event tables
1595 mpEventImportHelper = std::make_unique<XMLEventImportHelper>();
1596 const OUString& sStarBasic(GetXMLToken(XML_STARBASIC));
1597 mpEventImportHelper->RegisterFactory(sStarBasic,
1598 std::make_unique<XMLStarBasicContextFactory>());
1599 const OUString& sScript(GetXMLToken(XML_SCRIPT));
1600 mpEventImportHelper->RegisterFactory(sScript,
1601 std::make_unique<XMLScriptContextFactory>());
1602 mpEventImportHelper->AddTranslationTable(aStandardEventTable);
1604 // register StarBasic event handler with capitalized spelling
1605 mpEventImportHelper->RegisterFactory("StarBasic",
1606 std::make_unique<XMLStarBasicContextFactory>());
1609 return *mpEventImportHelper;
1612 void SvXMLImport::SetFontDecls( XMLFontStylesContext *pFontDecls )
1614 if (mxFontDecls.is())
1615 static_cast<SvXMLStylesContext*>(mxFontDecls.get())->Clear();
1616 mxFontDecls = pFontDecls;
1619 void SvXMLImport::SetStyles( SvXMLStylesContext *pStyles )
1621 if (mxStyles.is())
1622 static_cast<SvXMLStylesContext*>(mxStyles.get())->Clear();
1623 mxStyles = pStyles;
1626 void SvXMLImport::SetAutoStyles( SvXMLStylesContext *pAutoStyles )
1628 if (pAutoStyles && mxNumberStyles.is())
1630 uno::Reference<xml::sax::XAttributeList> xAttrList;
1631 const uno::Sequence<OUString> aStyleNames = mxNumberStyles->getElementNames();
1632 for (const auto& name : aStyleNames)
1634 uno::Any aAny(mxNumberStyles->getByName(name));
1635 sal_Int32 nKey(0);
1636 if (aAny >>= nKey)
1638 SvXMLStyleContext* pContext = new SvXMLNumFormatContext(
1639 *this, XML_NAMESPACE_NUMBER, name, xAttrList, nKey,
1640 GetDataStylesImport()->GetLanguageForKey(nKey), *pAutoStyles);
1641 pAutoStyles->AddStyle(*pContext);
1645 if (mxAutoStyles.is())
1646 static_cast<SvXMLStylesContext*>(mxAutoStyles.get())->Clear();
1647 mxAutoStyles = pAutoStyles;
1648 GetTextImport()->SetAutoStyles( pAutoStyles );
1649 GetShapeImport()->SetAutoStylesContext( pAutoStyles );
1650 GetChartImport()->SetAutoStylesContext( pAutoStyles );
1651 GetFormImport()->setAutoStyleContext( pAutoStyles );
1654 void SvXMLImport::SetMasterStyles( SvXMLStylesContext *pMasterStyles )
1656 if (mxMasterStyles.is())
1657 static_cast<SvXMLStylesContext*>(mxMasterStyles.get())->Clear();
1658 mxMasterStyles = pMasterStyles;
1661 XMLFontStylesContext *SvXMLImport::GetFontDecls()
1663 return static_cast<XMLFontStylesContext *>(mxFontDecls.get());
1666 SvXMLStylesContext *SvXMLImport::GetStyles()
1668 return static_cast<SvXMLStylesContext *>(mxStyles.get());
1671 SvXMLStylesContext *SvXMLImport::GetAutoStyles()
1673 return static_cast<SvXMLStylesContext *>(mxAutoStyles.get());
1676 const XMLFontStylesContext *SvXMLImport::GetFontDecls() const
1678 return static_cast<const XMLFontStylesContext *>(mxFontDecls.get());
1681 const SvXMLStylesContext *SvXMLImport::GetStyles() const
1683 return static_cast<const SvXMLStylesContext *>(mxStyles.get());
1686 const SvXMLStylesContext *SvXMLImport::GetAutoStyles() const
1688 return static_cast<const SvXMLStylesContext *>(mxAutoStyles.get());
1691 OUString SvXMLImport::GetAbsoluteReference(const OUString& rValue) const
1693 if( rValue.isEmpty() || rValue[0] == '#' )
1694 return rValue;
1696 INetURLObject aAbsURL;
1697 if( mpImpl->aBaseURL.GetNewAbsURL( rValue, &aAbsURL ) )
1698 return aAbsURL.GetMainURL( INetURLObject::DecodeMechanism::ToIUri );
1699 else
1700 return rValue;
1703 bool SvXMLImport::IsODFVersionConsistent( const OUString& aODFVersion )
1705 // the check returns sal_False only if the storage version could be retrieved
1706 bool bResult = true;
1708 if ( !aODFVersion.isEmpty() && aODFVersion.compareTo( ODFVER_012_TEXT ) >= 0 )
1710 // check the consistency only for the ODF1.2 and later ( according to content.xml )
1711 // manifest.xml might have no version, it should be checked here and the correct version should be set
1714 uno::Reference< document::XStorageBasedDocument > xDoc( mxModel, uno::UNO_QUERY_THROW );
1715 uno::Reference< embed::XStorage > xStor = xDoc->getDocumentStorage();
1716 uno::Reference< beans::XPropertySet > xStorProps( xStor, uno::UNO_QUERY_THROW );
1718 // the check should be done only for OASIS format
1719 if (!IsOOoXML())
1721 bool bRepairPackage = false;
1724 xStorProps->getPropertyValue( "RepairPackage" )
1725 >>= bRepairPackage;
1726 } catch ( uno::Exception& )
1729 // check only if not in Repair mode
1730 if ( !bRepairPackage )
1732 OUString aStorVersion;
1733 xStorProps->getPropertyValue( "Version" )
1734 >>= aStorVersion;
1736 // if the storage version is set in manifest.xml, it must be the same as in content.xml
1737 // if not, set it explicitly to be used further ( it will work even for readonly storage )
1738 // This workaround is not nice, but I see no other way to handle it, since there are
1739 // ODF1.2 documents without version in manifest.xml
1740 if ( !aStorVersion.isEmpty() )
1741 bResult = aODFVersion == aStorVersion;
1742 else
1743 xStorProps->setPropertyValue( "Version",
1744 uno::makeAny( aODFVersion ) );
1746 if ( bResult )
1748 bool bInconsistent = false;
1749 xStorProps->getPropertyValue( "IsInconsistent" )
1750 >>= bInconsistent;
1751 bResult = !bInconsistent;
1756 catch( uno::Exception& )
1760 return bResult;
1763 void SvXMLImport::CreateNumberFormatsSupplier_()
1765 SAL_WARN_IF( mxNumberFormatsSupplier.is(), "xmloff.core", "number formats supplier already exists!" );
1766 if(mxModel.is())
1767 mxNumberFormatsSupplier =
1768 uno::Reference< util::XNumberFormatsSupplier> (mxModel, uno::UNO_QUERY);
1771 void SvXMLImport::CreateDataStylesImport_()
1773 SAL_WARN_IF( bool(mpNumImport), "xmloff.core", "data styles import already exists!" );
1774 uno::Reference<util::XNumberFormatsSupplier> xNum =
1775 GetNumberFormatsSupplier();
1776 if ( xNum.is() )
1777 mpNumImport = std::make_unique<SvXMLNumFmtHelper>(xNum, GetComponentContext() );
1780 sal_Unicode SvXMLImport::ConvStarBatsCharToStarSymbol( sal_Unicode c )
1782 sal_Unicode cNew = c;
1783 if( !mpImpl->hBatsFontConv )
1785 mpImpl->hBatsFontConv = CreateFontToSubsFontConverter( "StarBats",
1786 FontToSubsFontFlags::IMPORT );
1787 SAL_WARN_IF( !mpImpl->hBatsFontConv, "xmloff.core", "Got no symbol font converter" );
1789 if( mpImpl->hBatsFontConv )
1791 cNew = ConvertFontToSubsFontChar( mpImpl->hBatsFontConv, c );
1794 return cNew;
1797 sal_Unicode SvXMLImport::ConvStarMathCharToStarSymbol( sal_Unicode c )
1799 sal_Unicode cNew = c;
1800 if( !mpImpl->hMathFontConv )
1802 mpImpl->hMathFontConv = CreateFontToSubsFontConverter( "StarMath",
1803 FontToSubsFontFlags::IMPORT );
1804 SAL_WARN_IF( !mpImpl->hMathFontConv, "xmloff.core", "Got no symbol font converter" );
1806 if( mpImpl->hMathFontConv )
1808 cNew = ConvertFontToSubsFontChar( mpImpl->hMathFontConv, c );
1811 return cNew;
1814 void SvXMLImport::SetError(
1815 sal_Int32 nId,
1816 const Sequence<OUString>& rMsgParams,
1817 const OUString& rExceptionMessage,
1818 const Reference<xml::sax::XLocator>& rLocator )
1820 // create error list on demand
1821 if ( !mpXMLErrors )
1822 mpXMLErrors = std::make_unique<XMLErrors>();
1824 // save error information
1825 // use document locator (if none supplied)
1826 mpXMLErrors->AddRecord( nId, rMsgParams, rExceptionMessage,
1827 rLocator.is() ? rLocator : mxLocator );
1830 void SvXMLImport::SetError(
1831 sal_Int32 nId,
1832 const Sequence<OUString>& rMsgParams)
1834 SetError( nId, rMsgParams, "", nullptr );
1837 void SvXMLImport::SetError(
1838 sal_Int32 nId)
1840 Sequence<OUString> aSeq(0);
1841 SetError( nId, aSeq );
1844 void SvXMLImport::SetError(
1845 sal_Int32 nId,
1846 const OUString& rMsg1)
1848 Sequence<OUString> aSeq { rMsg1 };
1849 SetError( nId, aSeq );
1852 void SvXMLImport::SetError(
1853 sal_Int32 nId,
1854 const OUString& rMsg1,
1855 const OUString& rMsg2)
1857 Sequence<OUString> aSeq(2);
1858 OUString* pSeq = aSeq.getArray();
1859 pSeq[0] = rMsg1;
1860 pSeq[1] = rMsg2;
1861 SetError( nId, aSeq );
1864 void SvXMLImport::DisposingModel()
1866 if( mxFontDecls.is() )
1867 static_cast<SvXMLStylesContext *>(mxFontDecls.get())->Clear();
1868 if( mxStyles.is() )
1869 static_cast<SvXMLStylesContext *>(mxStyles.get())->Clear();
1870 if( mxAutoStyles.is() )
1871 static_cast<SvXMLStylesContext *>(mxAutoStyles.get())->Clear();
1872 if( mxMasterStyles.is() )
1873 static_cast<SvXMLStylesContext *>(mxMasterStyles.get())->Clear();
1875 mxModel.set(nullptr);
1876 mxEventListener.set(nullptr);
1879 ::comphelper::UnoInterfaceToUniqueIdentifierMapper& SvXMLImport::getInterfaceToIdentifierMapper()
1881 return mpImpl->maInterfaceToIdentifierMapper;
1884 uno::Reference< uno::XComponentContext > const &
1885 SvXMLImport::GetComponentContext() const
1887 return mpImpl->mxComponentContext;
1890 OUString SvXMLImport::GetBaseURL() const
1892 return mpImpl->aBaseURL.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1895 OUString SvXMLImport::GetDocumentBase() const
1897 return mpImpl->aDocBase.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1900 // Convert drawing object positions from OOo file format to OASIS (#i28749#)
1901 bool SvXMLImport::IsShapePositionInHoriL2R() const
1903 return mpImpl->mbShapePositionInHoriL2R;
1906 bool SvXMLImport::IsTextDocInOOoFileFormat() const
1908 return mpImpl->mbTextDocInOOoFileFormat;
1911 void SvXMLImport::initXForms()
1913 // dummy method; to be implemented by derived classes supporting XForms
1916 bool SvXMLImport::getBuildIds( sal_Int32& rUPD, sal_Int32& rBuild ) const
1918 bool bRet = false;
1919 OUString const aBuildId(getBuildIdsProperty(mxImportInfo));
1920 if (!aBuildId.isEmpty())
1922 sal_Int32 nIndex = aBuildId.indexOf('$');
1923 if (nIndex != -1)
1925 rUPD = aBuildId.copy( 0, nIndex ).toInt32();
1926 sal_Int32 nIndexEnd = aBuildId.indexOf(';', nIndex);
1927 rBuild = (nIndexEnd == -1)
1928 ? aBuildId.copy(nIndex + 1).toInt32()
1929 : aBuildId.copy(nIndex + 1, nIndexEnd - nIndex - 1).toInt32();
1930 bRet = true;
1933 return bRet;
1936 sal_uInt16 SvXMLImport::getGeneratorVersion() const
1938 // --> ORW
1939 return mpImpl->getGeneratorVersion( *this );
1940 // <--
1943 bool SvXMLImport::isGeneratorVersionOlderThan(
1944 sal_uInt16 const nOOoVersion, sal_uInt16 const nLOVersion)
1946 assert( (nLOVersion & LO_flag));
1947 assert(!(nOOoVersion & LO_flag));
1948 const sal_uInt16 nGeneratorVersion(getGeneratorVersion());
1949 return (nGeneratorVersion & LO_flag)
1950 ? nGeneratorVersion < nLOVersion
1951 : nGeneratorVersion < nOOoVersion;
1955 OUString const & SvXMLImport::GetODFVersion() const
1957 return mpImpl->aODFVersion;
1960 bool SvXMLImport::IsOOoXML() const
1962 return mpImpl->mbIsOOoXML;
1965 // xml:id for RDF metadata
1966 void SvXMLImport::SetXmlId(uno::Reference<uno::XInterface> const & i_xIfc,
1967 OUString const & i_rXmlId)
1969 if (!i_rXmlId.isEmpty()) {
1970 try {
1971 const uno::Reference<rdf::XMetadatable> xMeta(i_xIfc,
1972 uno::UNO_QUERY);
1973 //FIXME: not yet
1974 if (xMeta.is()) {
1975 const beans::StringPair mdref( mpImpl->mStreamName, i_rXmlId );
1976 try {
1977 xMeta->setMetadataReference(mdref);
1978 } catch (lang::IllegalArgumentException &) {
1979 // probably duplicate; ignore
1980 SAL_INFO("xmloff.core", "SvXMLImport::SetXmlId: cannot set xml:id");
1983 } catch (uno::Exception &) {
1984 TOOLS_WARN_EXCEPTION("xmloff.core","SvXMLImport::SetXmlId");
1989 ::xmloff::RDFaImportHelper &
1990 SvXMLImport::GetRDFaImportHelper()
1992 if (!mpImpl->mpRDFaHelper)
1994 mpImpl->mpRDFaHelper.reset( new ::xmloff::RDFaImportHelper(*this) );
1996 return *mpImpl->mpRDFaHelper;
1999 void
2000 SvXMLImport::AddRDFa(const uno::Reference<rdf::XMetadatable>& i_xObject,
2001 OUString const & i_rAbout,
2002 OUString const & i_rProperty,
2003 OUString const & i_rContent,
2004 OUString const & i_rDatatype)
2006 // N.B.: we only get called if i_xObject had xhtml:about attribute
2007 // (an empty attribute value is valid)
2008 ::xmloff::RDFaImportHelper & rRDFaHelper( GetRDFaImportHelper() );
2009 rRDFaHelper.ParseAndAddRDFa(i_xObject,
2010 i_rAbout, i_rProperty, i_rContent, i_rDatatype);
2013 bool SvXMLImport::embeddedFontAlreadyProcessed( const OUString& url )
2015 if( embeddedFontUrlsKnown.count( url ) != 0 )
2016 return true;
2017 embeddedFontUrlsKnown.insert( url );
2018 return false;
2021 const OUString & SvXMLImport::getNameFromToken( sal_Int32 nToken )
2023 return xTokenHandler->getIdentifier( nToken & TOKEN_MASK );
2026 OUString SvXMLImport::getPrefixAndNameFromToken( sal_Int32 nToken )
2028 return getNamespacePrefixFromToken(nToken, nullptr) + ":" + xTokenHandler->getIdentifier( nToken & TOKEN_MASK );
2031 OUString SvXMLImport::getNamespacePrefixFromToken(sal_Int32 nToken, const SvXMLNamespaceMap* pMap)
2033 sal_Int32 nNamespaceToken = ( nToken & NMSP_MASK ) >> NMSP_SHIFT;
2034 auto aIter( aNamespaceMap.find( nNamespaceToken ) );
2035 if( aIter != aNamespaceMap.end() )
2037 if (pMap)
2039 OUString sRet = pMap->GetPrefixByKey(pMap->GetKeyByName((*aIter).second.second));
2040 if (!sRet.isEmpty())
2041 return sRet;
2043 return (*aIter).second.first;
2045 else
2046 return OUString();
2049 OUString SvXMLImport::getNamespaceURIFromToken( sal_Int32 nToken )
2051 sal_Int32 nNamespaceToken = ( nToken & NMSP_MASK ) >> NMSP_SHIFT;
2052 auto aIter( aNamespaceMap.find( nNamespaceToken ) );
2053 if( aIter != aNamespaceMap.end() )
2054 return (*aIter).second.second;
2055 else
2056 return OUString();
2059 OUString SvXMLImport::getNamespacePrefixFromURI( const OUString& rURI )
2061 auto aIter( aNamespaceURIPrefixMap.find(rURI) );
2062 if( aIter != aNamespaceURIPrefixMap.end() )
2063 return (*aIter).second;
2064 else
2065 return OUString();
2068 void SvXMLImport::initializeNamespaceMaps()
2070 auto mapTokenToNamespace = [&]( sal_Int32 nToken, sal_Int32 nPrefix, sal_Int32 nNamespace )
2072 if ( nToken >= 0 )
2074 const OUString& sNamespace = GetXMLToken( static_cast<XMLTokenEnum>( nNamespace ) );
2075 const OUString& sPrefix = GetXMLToken( static_cast<XMLTokenEnum>( nPrefix ) );
2076 aNamespaceMap[ nToken + 1 ] = std::make_pair( sPrefix, sNamespace );
2077 aNamespaceURIPrefixMap.emplace( sNamespace, sPrefix );
2081 mapTokenToNamespace( XML_NAMESPACE_OFFICE, XML_NP_OFFICE, XML_N_OFFICE );
2082 mapTokenToNamespace( XML_OLD_NAMESPACE_OFFICE, XML_NP_OFFICE, XML_N_OFFICE_OLD );
2083 mapTokenToNamespace( XML_NAMESPACE_OFFICE_OOO, XML_NP_OFFICE, XML_N_OFFICE_OOO );
2084 mapTokenToNamespace( XML_NAMESPACE_STYLE, XML_NP_STYLE, XML_N_STYLE );
2085 mapTokenToNamespace( XML_OLD_NAMESPACE_STYLE, XML_NP_STYLE, XML_N_STYLE_OLD );
2086 mapTokenToNamespace( XML_NAMESPACE_STYLE_OOO, XML_NP_STYLE, XML_N_STYLE_OOO );
2087 mapTokenToNamespace( XML_NAMESPACE_TEXT, XML_NP_TEXT, XML_N_TEXT );
2088 mapTokenToNamespace( XML_OLD_NAMESPACE_TEXT, XML_NP_TEXT, XML_N_TEXT_OLD );
2089 mapTokenToNamespace( XML_NAMESPACE_TEXT_OOO, XML_NP_TEXT, XML_N_TEXT_OOO );
2090 mapTokenToNamespace( XML_NAMESPACE_TABLE, XML_NP_TABLE, XML_N_TABLE );
2091 mapTokenToNamespace( XML_OLD_NAMESPACE_TABLE, XML_NP_TABLE, XML_N_TABLE_OLD );
2092 mapTokenToNamespace( XML_NAMESPACE_TABLE_OOO, XML_NP_TABLE, XML_N_TABLE_OOO );
2093 mapTokenToNamespace( XML_NAMESPACE_DRAW, XML_NP_DRAW, XML_N_DRAW );
2094 mapTokenToNamespace( XML_OLD_NAMESPACE_DRAW, XML_NP_DRAW, XML_N_DRAW_OLD );
2095 mapTokenToNamespace( XML_NAMESPACE_DRAW_OOO, XML_NP_DRAW, XML_N_DRAW_OOO );
2096 mapTokenToNamespace( XML_NAMESPACE_FO, XML_NP_FO, XML_N_FO );
2097 mapTokenToNamespace( XML_OLD_NAMESPACE_FO, XML_NP_FO, XML_N_FO_OLD );
2098 mapTokenToNamespace( XML_NAMESPACE_FO_COMPAT, XML_NP_FO, XML_N_FO_COMPAT );
2099 mapTokenToNamespace( XML_NAMESPACE_XLINK, XML_NP_XLINK, XML_N_XLINK );
2100 mapTokenToNamespace( XML_OLD_NAMESPACE_XLINK, XML_NP_XLINK, XML_N_XLINK_OLD );
2101 mapTokenToNamespace( XML_NAMESPACE_DC, XML_NP_DC, XML_N_DC );
2102 mapTokenToNamespace( XML_NAMESPACE_META, XML_NP_META, XML_N_META );
2103 mapTokenToNamespace( XML_OLD_NAMESPACE_META, XML_NP_META, XML_N_META_OLD );
2104 mapTokenToNamespace( XML_NAMESPACE_META_OOO, XML_NP_META, XML_N_META_OOO );
2105 mapTokenToNamespace( XML_NAMESPACE_NUMBER, XML_NP_NUMBER, XML_N_NUMBER );
2106 mapTokenToNamespace( XML_OLD_NAMESPACE_NUMBER, XML_NP_NUMBER, XML_N_NUMBER_OLD );
2107 mapTokenToNamespace( XML_NAMESPACE_NUMBER_OOO, XML_NP_NUMBER, XML_N_NUMBER_OOO );
2108 mapTokenToNamespace( XML_NAMESPACE_PRESENTATION, XML_NP_PRESENTATION, XML_N_PRESENTATION );
2109 mapTokenToNamespace( XML_OLD_NAMESPACE_PRESENTATION, XML_NP_PRESENTATION, XML_N_PRESENTATION_OLD );
2110 mapTokenToNamespace( XML_NAMESPACE_PRESENTATION_OOO, XML_NP_PRESENTATION, XML_N_PRESENTATION_OOO );
2111 mapTokenToNamespace( XML_NAMESPACE_SVG, XML_NP_SVG, XML_N_SVG );
2112 mapTokenToNamespace( XML_NAMESPACE_SVG_COMPAT, XML_NP_SVG, XML_N_SVG_COMPAT );
2113 mapTokenToNamespace( XML_NAMESPACE_CHART, XML_NP_CHART, XML_N_CHART );
2114 mapTokenToNamespace( XML_OLD_NAMESPACE_CHART, XML_NP_CHART, XML_N_CHART_OLD );
2115 mapTokenToNamespace( XML_NAMESPACE_CHART_OOO, XML_NP_CHART, XML_N_CHART_OOO );
2116 mapTokenToNamespace( XML_NAMESPACE_DR3D, XML_NP_DR3D, XML_N_DR3D );
2117 mapTokenToNamespace( XML_NAMESPACE_DR3D_OOO, XML_NP_DR3D, XML_N_DR3D_OOO );
2118 mapTokenToNamespace( XML_NAMESPACE_MATH, XML_NP_MATH, XML_N_MATH );
2119 mapTokenToNamespace( XML_NAMESPACE_VERSIONS_LIST, XML_NP_VERSIONS_LIST, XML_N_VERSIONS_LIST );
2120 mapTokenToNamespace( XML_NAMESPACE_FORM, XML_NP_FORM, XML_N_FORM );
2121 mapTokenToNamespace( XML_NAMESPACE_FORM_OOO, XML_NP_FORM, XML_N_FORM_OOO );
2122 mapTokenToNamespace( XML_NAMESPACE_SCRIPT, XML_NP_SCRIPT, XML_N_SCRIPT );
2123 mapTokenToNamespace( XML_NAMESPACE_SCRIPT_OOO, XML_NP_SCRIPT, XML_N_SCRIPT_OOO );
2124 mapTokenToNamespace( XML_NAMESPACE_BLOCKLIST, XML_NP_BLOCK_LIST, XML_N_BLOCK_LIST );
2125 mapTokenToNamespace( XML_NAMESPACE_CONFIG, XML_NP_CONFIG, XML_N_CONFIG );
2126 mapTokenToNamespace( XML_NAMESPACE_CONFIG_OOO, XML_NP_CONFIG, XML_N_CONFIG_OOO );
2127 mapTokenToNamespace( XML_NAMESPACE_OOO, XML_NP_OOO, XML_N_OOO );
2128 mapTokenToNamespace( XML_NAMESPACE_OOOW, XML_NP_OOOW, XML_N_OOOW );
2129 mapTokenToNamespace( XML_NAMESPACE_OOOC, XML_NP_OOOC, XML_N_OOOC );
2130 mapTokenToNamespace( XML_NAMESPACE_DOM, XML_NP_DOM, XML_N_DOM );
2131 mapTokenToNamespace( XML_NAMESPACE_DB, XML_NP_DB, XML_N_DB );
2132 mapTokenToNamespace( XML_NAMESPACE_DB_OASIS, XML_NP_DB, XML_N_DB_OASIS );
2133 mapTokenToNamespace( XML_NAMESPACE_DLG, XML_NP_DLG, XML_N_DLG );
2134 mapTokenToNamespace( XML_NAMESPACE_XFORMS, XML_NP_XFORMS_1_0, XML_N_XFORMS_1_0 );
2135 mapTokenToNamespace( XML_NAMESPACE_XSD, XML_NP_XSD, XML_N_XSD );
2136 mapTokenToNamespace( XML_NAMESPACE_XSI, XML_NP_XSI, XML_N_XSI );
2137 mapTokenToNamespace( XML_NAMESPACE_SMIL, XML_NP_SMIL, XML_N_SMIL );
2138 mapTokenToNamespace( XML_OLD_NAMESPACE_SMIL, XML_NP_SMIL, XML_N_SMIL_OLD );
2139 mapTokenToNamespace( XML_NAMESPACE_SMIL_COMPAT, XML_NP_SMIL, XML_N_SMIL_COMPAT );
2140 mapTokenToNamespace( XML_NAMESPACE_ANIMATION, XML_NP_ANIMATION, XML_N_ANIMATION );
2141 mapTokenToNamespace( XML_NAMESPACE_REPORT, XML_NP_RPT, XML_N_RPT );
2142 mapTokenToNamespace( XML_NAMESPACE_REPORT_OASIS, XML_NP_RPT, XML_N_RPT_OASIS );
2143 mapTokenToNamespace( XML_NAMESPACE_OF, XML_NP_OF, XML_N_OF );
2144 mapTokenToNamespace( XML_NAMESPACE_XHTML, XML_NP_XHTML, XML_N_XHTML );
2145 mapTokenToNamespace( XML_NAMESPACE_GRDDL, XML_NP_GRDDL, XML_N_GRDDL );
2146 mapTokenToNamespace( XML_NAMESPACE_OFFICE_EXT, XML_NP_OFFICE_EXT, XML_N_OFFICE_EXT );
2147 mapTokenToNamespace( XML_NAMESPACE_TABLE_EXT, XML_NP_TABLE_EXT, XML_N_TABLE_EXT );
2148 mapTokenToNamespace( XML_NAMESPACE_CHART_EXT, XML_NP_CHART_EXT, XML_N_CHART_EXT );
2149 mapTokenToNamespace( XML_NAMESPACE_DRAW_EXT, XML_NP_DRAW_EXT, XML_N_DRAW_EXT );
2150 mapTokenToNamespace( XML_NAMESPACE_CALC_EXT, XML_NP_CALC_EXT, XML_N_CALC_EXT );
2151 mapTokenToNamespace( XML_NAMESPACE_LO_EXT, XML_NP_LO_EXT, XML_N_LO_EXT );
2152 mapTokenToNamespace( XML_NAMESPACE_CSS3TEXT, XML_NP_CSS3TEXT, XML_N_CSS3TEXT );
2153 mapTokenToNamespace( XML_NAMESPACE_FIELD, XML_NP_FIELD, XML_N_FIELD );
2154 mapTokenToNamespace( XML_NAMESPACE_FORMX, XML_NP_FORMX, XML_N_FORMX );
2157 void SvXMLImport::registerNamespaces()
2159 for( auto const &aNamespaceEntry : aNamespaceMap )
2161 // aNamespaceMap = { Token : ( NamespacePrefix, NamespaceURI ) }
2162 registerNamespace( aNamespaceEntry.second.second, aNamespaceEntry.first << NMSP_SHIFT );
2166 void SvXMLImport::NotifyMacroEventRead()
2168 if (mbNotifyMacroEventRead)
2169 return;
2171 comphelper::DocumentInfo::notifyMacroEventRead(mxModel);
2173 mbNotifyMacroEventRead = true;
2176 SvXMLImportFastNamespaceHandler::SvXMLImportFastNamespaceHandler()
2180 void SvXMLImportFastNamespaceHandler::addNSDeclAttributes( rtl::Reference < comphelper::AttributeList > const & rAttrList )
2182 for(const auto& aNamespaceDefine : m_aNamespaceDefines)
2184 OUString& rPrefix = aNamespaceDefine->m_aPrefix;
2185 OUString& rNamespaceURI = aNamespaceDefine->m_aNamespaceURI;
2186 OUString sDecl;
2187 if ( rPrefix.isEmpty() )
2188 sDecl = "xmlns";
2189 else
2190 sDecl = "xmlns:" + rPrefix;
2191 rAttrList->AddAttribute( sDecl, "CDATA", rNamespaceURI );
2193 m_aNamespaceDefines.clear();
2196 void SvXMLImportFastNamespaceHandler::registerNamespace( const OUString& rNamespacePrefix, const OUString& rNamespaceURI )
2198 // Elements with default namespace parsed by FastParser have namespace prefix.
2199 // A default namespace needs to be registered with the prefix, to maintain the compatibility.
2200 if ( rNamespacePrefix.isEmpty() )
2201 m_aNamespaceDefines.push_back( std::make_unique<NamespaceDefine>(
2202 SvXMLImport::getNamespacePrefixFromURI( rNamespaceURI ), rNamespaceURI) );
2204 m_aNamespaceDefines.push_back( std::make_unique<NamespaceDefine>(
2205 rNamespacePrefix, rNamespaceURI) );
2208 OUString SvXMLImportFastNamespaceHandler::getNamespaceURI( const OUString&/* rNamespacePrefix */ )
2210 return OUString();
2213 SvXMLLegacyToFastDocHandler::SvXMLLegacyToFastDocHandler( const rtl::Reference< SvXMLImport > & rImport )
2214 : mrImport( rImport ),
2215 mxFastAttributes( new sax_fastparser::FastAttributeList( SvXMLImport::xTokenHandler.get(),
2216 dynamic_cast< sax_fastparser::FastTokenHandlerBase *>( SvXMLImport::xTokenHandler.get() ) ) )
2220 void SAL_CALL SvXMLLegacyToFastDocHandler::setTargetDocument( const uno::Reference< lang::XComponent >& xDoc )
2222 mrImport->setTargetDocument( xDoc );
2225 void SAL_CALL SvXMLLegacyToFastDocHandler::startDocument()
2227 mrImport->startDocument();
2230 void SAL_CALL SvXMLLegacyToFastDocHandler::endDocument()
2232 mrImport->endDocument();
2235 void SAL_CALL SvXMLLegacyToFastDocHandler::startElement( const OUString& rName,
2236 const uno::Reference< xml::sax::XAttributeList >& xAttrList )
2238 SvXMLImport::processNSAttributes(mrImport->mpNamespaceMap, mrImport.get(), xAttrList);
2239 OUString aLocalName;
2240 sal_uInt16 nPrefix = mrImport->mpNamespaceMap->GetKeyByAttrName( rName, &aLocalName );
2241 Sequence< sal_Int8 > aLocalNameSeq( reinterpret_cast<sal_Int8 const *>(
2242 OUStringToOString( aLocalName, RTL_TEXTENCODING_UTF8 ).getStr()), aLocalName.getLength() );
2243 sal_Int32 mnElement = NAMESPACE_TOKEN( nPrefix ) | SvXMLImport::xTokenHandler->getTokenFromUTF8( aLocalNameSeq );
2244 mxFastAttributes->clear();
2246 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
2247 for( sal_Int16 i=0; i < nAttrCount; i++ )
2249 OUString aLocalAttrName;
2250 OUString aNamespace;
2251 const OUString& rAttrName = xAttrList->getNameByIndex( i );
2252 const OUString& rAttrValue = xAttrList->getValueByIndex( i );
2253 sal_uInt16 const nAttrPrefix(mrImport->mpNamespaceMap->GetKeyByAttrName(
2254 rAttrName, nullptr, &aLocalAttrName, &aNamespace));
2255 if( XML_NAMESPACE_XMLNS != nAttrPrefix )
2257 Sequence< sal_Int8 > aAttrSeq( reinterpret_cast<sal_Int8 const *>(
2258 OUStringToOString( aLocalAttrName, RTL_TEXTENCODING_UTF8 ).getStr()), aLocalAttrName.getLength() );
2259 auto const nToken(SvXMLImport::xTokenHandler->getTokenFromUTF8(aAttrSeq));
2260 if (nToken == xmloff::XML_TOKEN_INVALID)
2262 mxFastAttributes->addUnknown(aNamespace,
2263 OUStringToOString(rAttrName, RTL_TEXTENCODING_UTF8),
2264 OUStringToOString(rAttrValue, RTL_TEXTENCODING_UTF8));
2266 else
2268 sal_Int32 const nAttr = NAMESPACE_TOKEN(nAttrPrefix) | nToken;
2269 mxFastAttributes->add(nAttr, OUStringToOString(rAttrValue, RTL_TEXTENCODING_UTF8).getStr());
2273 mrImport->startFastElement( mnElement, mxFastAttributes.get() );
2276 void SAL_CALL SvXMLLegacyToFastDocHandler::endElement( const OUString& rName )
2278 OUString aLocalName;
2279 sal_uInt16 nPrefix = mrImport->mpNamespaceMap->GetKeyByAttrName( rName, &aLocalName );
2280 Sequence< sal_Int8 > aLocalNameSeq( reinterpret_cast<sal_Int8 const *>(
2281 OUStringToOString( aLocalName, RTL_TEXTENCODING_UTF8 ).getStr()), aLocalName.getLength() );
2282 sal_Int32 mnElement = NAMESPACE_TOKEN( nPrefix ) | SvXMLImport::xTokenHandler->getTokenFromUTF8( aLocalNameSeq );
2283 mrImport->endFastElement( mnElement );
2286 void SAL_CALL SvXMLLegacyToFastDocHandler::characters( const OUString& aChars )
2288 mrImport->characters( aChars );
2291 void SAL_CALL SvXMLLegacyToFastDocHandler::ignorableWhitespace( const OUString& aWhitespaces )
2293 mrImport->ignorableWhitespace( aWhitespaces );
2296 void SAL_CALL SvXMLLegacyToFastDocHandler::processingInstruction( const OUString& aTarget,
2297 const OUString& aData)
2299 mrImport->processingInstruction( aTarget, aData );
2302 void SAL_CALL SvXMLLegacyToFastDocHandler::setDocumentLocator( const uno::Reference< xml::sax::XLocator >& rLocator )
2304 mrImport->setDocumentLocator( rLocator );
2309 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */