1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
23 #include <tools/diagnose_ex.h>
24 #include <sal/log.hxx>
25 #include <com/sun/star/beans/XPropertySetInfo.hpp>
26 #include <tools/urlobj.hxx>
27 #include <vcl/graph.hxx>
28 #include <xmloff/unointerfacetouniqueidentifiermapper.hxx>
29 #include <xmloff/nmspmap.hxx>
30 #include <xmloff/xmluconv.hxx>
31 #include <xmloff/xmlnmspe.hxx>
32 #include <xmloff/xmltoken.hxx>
33 #include <xmloff/XMLFontStylesContext.hxx>
34 #include <xmloff/xmlictxt.hxx>
35 #include <xmloff/xmlimp.hxx>
36 #include <xmloff/xmlnumfi.hxx>
37 #include <XMLEventImportHelper.hxx>
38 #include <XMLStarBasicContextFactory.hxx>
39 #include <XMLScriptContextFactory.hxx>
40 #include <StyleMap.hxx>
41 #include <xmloff/ProgressBarHelper.hxx>
42 #include <xmloff/xmlerror.hxx>
43 #include <com/sun/star/container/XNameContainer.hpp>
44 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
45 #include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
46 #include <com/sun/star/io/XOutputStream.hpp>
47 #include <com/sun/star/util/MeasureUnit.hpp>
48 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
49 #include <com/sun/star/frame/XModel.hpp>
50 #include <com/sun/star/document/XBinaryStreamResolver.hpp>
51 #include <com/sun/star/document/XStorageBasedDocument.hpp>
52 #include <com/sun/star/document/XGraphicStorageHandler.hpp>
53 #include <com/sun/star/document/XEmbeddedObjectResolver.hpp>
54 #include <com/sun/star/graphic/GraphicProvider.hpp>
55 #include <com/sun/star/xml/sax/XLocator.hpp>
56 #include <com/sun/star/xml/sax/FastParser.hpp>
57 #include <com/sun/star/xml/sax/SAXException.hpp>
58 #include <com/sun/star/packages/zip/ZipIOException.hpp>
59 #include <comphelper/fileformat.h>
60 #include <comphelper/namecontainer.hxx>
61 #include <comphelper/servicehelper.hxx>
62 #include <cppuhelper/implbase.hxx>
63 #include <cppuhelper/supportsservice.hxx>
64 #include <comphelper/extract.hxx>
65 #include <comphelper/documentconstants.hxx>
66 #include <comphelper/documentinfo.hxx>
67 #include <comphelper/storagehelper.hxx>
68 #include <comphelper/attributelist.hxx>
69 #include <unotools/fontcvt.hxx>
70 #include <xmloff/fasttokenhandler.hxx>
71 #include <vcl/GraphicExternalLink.hxx>
73 #include <com/sun/star/rdf/XMetadatable.hpp>
74 #include <com/sun/star/rdf/XRepositorySupplier.hpp>
75 #include <RDFaImportHelper.hxx>
77 using ::com::sun::star::beans::XPropertySetInfo
;
79 using namespace ::com::sun::star
;
80 using namespace ::com::sun::star::uno
;
81 using namespace ::com::sun::star::util
;
82 using namespace ::com::sun::star::io
;
83 using namespace ::com::sun::star::container
;
84 using namespace ::com::sun::star::document
;
85 using namespace ::xmloff::token
;
87 css::uno::Reference
< css::xml::sax::XFastTokenHandler
> SvXMLImport::xTokenHandler( new FastTokenHandler() );
88 std::unordered_map
< sal_Int32
, std::pair
< OUString
, OUString
> > SvXMLImport::aNamespaceMap
;
89 std::unordered_map
< OUString
, OUString
> SvXMLImport::aNamespaceURIPrefixMap
;
90 const OUString
SvXMLImport::aDefaultNamespace
= OUString("");
91 const OUString
SvXMLImport::aNamespaceSeparator
= OUString(":");
92 bool SvXMLImport::bIsNSMapsInitialized
= false;
94 class SvXMLImportEventListener
: public cppu::WeakImplHelper
< css::lang::XEventListener
>
100 explicit SvXMLImportEventListener(SvXMLImport
* pImport
);
103 virtual void SAL_CALL
disposing(const lang::EventObject
& rEventObject
) override
;
106 SvXMLImportEventListener::SvXMLImportEventListener(SvXMLImport
* pTempImport
)
107 : pImport(pTempImport
)
112 void SAL_CALL
SvXMLImportEventListener::disposing( const lang::EventObject
& )
116 pImport
->DisposingModel();
125 getBuildIdsProperty(uno::Reference
<beans::XPropertySet
> const& xImportInfo
)
127 if (xImportInfo
.is())
131 Reference
< XPropertySetInfo
> const xSetInfo(
132 xImportInfo
->getPropertySetInfo());
133 if (xSetInfo
.is() && xSetInfo
->hasPropertyByName("BuildId"))
136 xImportInfo
->getPropertyValue("BuildId") >>= aBuildId
;
140 catch (Exception
const&)
142 DBG_UNHANDLED_EXCEPTION("xmloff.core", "exception getting BuildId");
151 sal_uInt16 mnGeneratorVersion
;
154 explicit DocumentInfo( const SvXMLImport
& rImport
)
155 : mnGeneratorVersion( SvXMLImport::ProductVersionUnknown
)
157 OUString
const buildIds(
158 getBuildIdsProperty(rImport
.getImportInfo()));
159 if (!buildIds
.isEmpty())
161 sal_Int32
const ix
= buildIds
.indexOf(';');
164 OUString
const loVersion(buildIds
.copy(ix
+ 1));
165 if (!loVersion
.isEmpty())
167 if ('3' == loVersion
[0])
169 mnGeneratorVersion
= SvXMLImport::LO_3x
;
171 else if ('4' == loVersion
[0])
173 if (loVersion
.getLength() > 1
174 && (loVersion
[1] == '0' || loVersion
[1] == '1'))
176 mnGeneratorVersion
= SvXMLImport::LO_41x
; // 4.0/4.1
178 else if (loVersion
.getLength() > 1 && '2' == loVersion
[1])
180 mnGeneratorVersion
= SvXMLImport::LO_42x
; // 4.2
182 else if (loVersion
.getLength() > 1 && '3' == loVersion
[1])
184 mnGeneratorVersion
= SvXMLImport::LO_43x
; // 4.3
186 else if (loVersion
.getLength() > 1 && '4' == loVersion
[1])
188 mnGeneratorVersion
= SvXMLImport::LO_44x
; // 4.4
191 else if ('5' == loVersion
[0])
193 mnGeneratorVersion
= SvXMLImport::LO_5x
;
195 else if ('6' == loVersion
[0])
197 mnGeneratorVersion
= SvXMLImport::LO_6x
;
201 SAL_INFO("xmloff.core", "unknown LO version: " << loVersion
);
203 return; // ignore buildIds
207 sal_Int32 nUPD
, nBuild
;
208 if ( rImport
.getBuildIds( nUPD
, nBuild
) )
210 if ( nUPD
>= 640 && nUPD
<= 645 )
212 mnGeneratorVersion
= SvXMLImport::OOo_1x
;
214 else if ( nUPD
== 680 )
216 mnGeneratorVersion
= SvXMLImport::OOo_2x
;
218 else if ( nUPD
== 300 && nBuild
<= 9379 )
220 mnGeneratorVersion
= SvXMLImport::OOo_30x
;
222 else if ( nUPD
== 310 )
224 mnGeneratorVersion
= SvXMLImport::OOo_31x
;
226 else if ( nUPD
== 320 )
228 mnGeneratorVersion
= SvXMLImport::OOo_32x
;
230 else if ( nUPD
== 330 )
232 mnGeneratorVersion
= SvXMLImport::OOo_33x
;
234 else if ( nUPD
== 340 )
236 mnGeneratorVersion
= SvXMLImport::OOo_34x
;
238 else if (nUPD
== 400 || nUPD
== 401)
240 mnGeneratorVersion
= SvXMLImport::AOO_40x
;
242 else if (nUPD
>= 410)
244 // effectively this means "latest", see use
245 // in XMLGraphicsDefaultStyle::SetDefaults()!
246 mnGeneratorVersion
= SvXMLImport::AOO_4x
;
251 sal_uInt16
getGeneratorVersion() const
253 return mnGeneratorVersion
;
259 class SvXMLImport_Impl
262 FontToSubsFontConverter hBatsFontConv
;
263 FontToSubsFontConverter hMathFontConv
;
265 bool mbOwnGraphicResolver
;
266 bool mbOwnEmbeddedResolver
;
267 INetURLObject aBaseURL
;
268 INetURLObject aDocBase
;
270 /// name of stream in package, e.g., "content.xml"
271 OUString mStreamName
;
273 OUString aODFVersion
;
277 // Boolean, indicating that position attributes
278 // of shapes are given in horizontal left-to-right layout. This is the case
279 // for the OpenOffice.org file format. (#i28749#)
280 bool mbShapePositionInHoriL2R
;
281 bool mbTextDocInOOoFileFormat
;
283 const uno::Reference
< uno::XComponentContext
> mxComponentContext
;
284 OUString
const implementationName
;
286 uno::Reference
< embed::XStorage
> mxSourceStorage
;
288 std::unique_ptr
< xmloff::RDFaImportHelper
> mpRDFaHelper
;
290 std::unique_ptr
< DocumentInfo
> mpDocumentInfo
;
292 SvXMLImport_Impl( const uno::Reference
< uno::XComponentContext
>& rxContext
,
293 OUString
const & theImplementationName
)
294 : hBatsFontConv( nullptr )
295 , hMathFontConv( nullptr )
296 , mbOwnGraphicResolver( false )
297 , mbOwnEmbeddedResolver( false )
299 // Convert drawing object positions from OOo file format to OASIS (#i28749#)
300 , mbShapePositionInHoriL2R( false )
301 , mbTextDocInOOoFileFormat( false )
302 , mxComponentContext( rxContext
)
303 , implementationName(theImplementationName
)
304 , mpRDFaHelper() // lazy
305 , mpDocumentInfo() // lazy
307 SAL_WARN_IF(!mxComponentContext
.is(), "xmloff.core", "SvXMLImport: no ComponentContext");
308 if (!mxComponentContext
.is()) throw uno::RuntimeException();
311 sal_uInt16
getGeneratorVersion( const SvXMLImport
& rImport
)
315 mpDocumentInfo
.reset( new DocumentInfo( rImport
) );
318 return mpDocumentInfo
->getGeneratorVersion();
321 ::comphelper::UnoInterfaceToUniqueIdentifierMapper maInterfaceToIdentifierMapper
;
324 SvXMLImportContext
*SvXMLImport::CreateDocumentContext(sal_uInt16
const nPrefix
,
325 const OUString
& rLocalName
,
326 const uno::Reference
< xml::sax::XAttributeList
>& )
328 return new SvXMLImportContext( *this, nPrefix
, rLocalName
);
331 SvXMLImportContext
*SvXMLImport::CreateFastContext( sal_Int32
/*Element*/,
332 const uno::Reference
< xml::sax::XFastAttributeList
>& /*xAttrList*/ )
334 return new SvXMLImportContext( *this );
337 void SvXMLImport::InitCtor_()
339 if( mnImportFlags
!= SvXMLImportFlags::NONE
)
341 // implicit "xml" namespace prefix
342 mpNamespaceMap
->Add( GetXMLToken(XML_XML
), GetXMLToken(XML_N_XML
), XML_NAMESPACE_XML
);
343 mpNamespaceMap
->Add( "_office", GetXMLToken(XML_N_OFFICE
), XML_NAMESPACE_OFFICE
);
344 mpNamespaceMap
->Add( "_office_ooo", GetXMLToken(XML_N_OFFICE_EXT
), XML_NAMESPACE_OFFICE_EXT
);
345 mpNamespaceMap
->Add( "_ooo", GetXMLToken(XML_N_OOO
), XML_NAMESPACE_OOO
);
346 mpNamespaceMap
->Add( "_style", GetXMLToken(XML_N_STYLE
), XML_NAMESPACE_STYLE
);
347 mpNamespaceMap
->Add( "_text", GetXMLToken(XML_N_TEXT
), XML_NAMESPACE_TEXT
);
348 mpNamespaceMap
->Add( "_table", GetXMLToken(XML_N_TABLE
), XML_NAMESPACE_TABLE
);
349 mpNamespaceMap
->Add( "_table_ooo", GetXMLToken(XML_N_TABLE_EXT
), XML_NAMESPACE_TABLE_EXT
);
350 mpNamespaceMap
->Add( "_draw", GetXMLToken(XML_N_DRAW
), XML_NAMESPACE_DRAW
);
351 mpNamespaceMap
->Add( "_draw_ooo", GetXMLToken(XML_N_DRAW_EXT
), XML_NAMESPACE_DRAW_EXT
);
352 mpNamespaceMap
->Add( "_dr3d", GetXMLToken(XML_N_DR3D
), XML_NAMESPACE_DR3D
);
353 mpNamespaceMap
->Add( "_fo", GetXMLToken(XML_N_FO_COMPAT
), XML_NAMESPACE_FO
);
354 mpNamespaceMap
->Add( "_xlink", GetXMLToken(XML_N_XLINK
), XML_NAMESPACE_XLINK
);
355 mpNamespaceMap
->Add( "_dc", GetXMLToken(XML_N_DC
), XML_NAMESPACE_DC
);
356 mpNamespaceMap
->Add( "_dom", GetXMLToken(XML_N_DOM
), XML_NAMESPACE_DOM
);
357 mpNamespaceMap
->Add( "_meta", GetXMLToken(XML_N_META
), XML_NAMESPACE_META
);
358 mpNamespaceMap
->Add( "_number", GetXMLToken(XML_N_NUMBER
), XML_NAMESPACE_NUMBER
);
359 mpNamespaceMap
->Add( "_svg", GetXMLToken(XML_N_SVG_COMPAT
), XML_NAMESPACE_SVG
);
360 mpNamespaceMap
->Add( "_chart", GetXMLToken(XML_N_CHART
), XML_NAMESPACE_CHART
);
361 mpNamespaceMap
->Add( "_math", GetXMLToken(XML_N_MATH
), XML_NAMESPACE_MATH
);
362 mpNamespaceMap
->Add( "_form", GetXMLToken(XML_N_FORM
), XML_NAMESPACE_FORM
);
363 mpNamespaceMap
->Add( "_script", GetXMLToken(XML_N_SCRIPT
), XML_NAMESPACE_SCRIPT
);
364 mpNamespaceMap
->Add( "_config", GetXMLToken(XML_N_CONFIG
), XML_NAMESPACE_CONFIG
);
365 mpNamespaceMap
->Add( "_xforms", GetXMLToken(XML_N_XFORMS_1_0
), XML_NAMESPACE_XFORMS
);
366 mpNamespaceMap
->Add( "_formx", GetXMLToken( XML_N_FORMX
), XML_NAMESPACE_FORMX
);
367 mpNamespaceMap
->Add( "_xsd", GetXMLToken(XML_N_XSD
), XML_NAMESPACE_XSD
);
368 mpNamespaceMap
->Add( "_xsi", GetXMLToken(XML_N_XSI
), XML_NAMESPACE_XFORMS
);
369 mpNamespaceMap
->Add( "_ooow", GetXMLToken(XML_N_OOOW
), XML_NAMESPACE_OOOW
);
370 mpNamespaceMap
->Add( "_oooc", GetXMLToken(XML_N_OOOC
), XML_NAMESPACE_OOOC
);
371 mpNamespaceMap
->Add( "_field", GetXMLToken(XML_N_FIELD
), XML_NAMESPACE_FIELD
);
372 mpNamespaceMap
->Add( "_of", GetXMLToken(XML_N_OF
), XML_NAMESPACE_OF
);
373 mpNamespaceMap
->Add( "_xhtml", GetXMLToken(XML_N_XHTML
), XML_NAMESPACE_XHTML
);
374 mpNamespaceMap
->Add( "_css3text", GetXMLToken(XML_N_CSS3TEXT
), XML_NAMESPACE_CSS3TEXT
);
376 mpNamespaceMap
->Add( "_calc_libo", GetXMLToken(XML_N_CALC_EXT
), XML_NAMESPACE_CALC_EXT
);
377 mpNamespaceMap
->Add( "_office_libo",
378 GetXMLToken(XML_N_LO_EXT
), XML_NAMESPACE_LO_EXT
);
381 if (mxNumberFormatsSupplier
.is())
382 mpNumImport
= std::make_unique
<SvXMLNumFmtHelper
>(mxNumberFormatsSupplier
, GetComponentContext());
384 if (mxModel
.is() && !mxEventListener
.is())
386 mxEventListener
.set(new SvXMLImportEventListener(this));
387 mxModel
->addEventListener(mxEventListener
);
391 SvXMLImport::SvXMLImport(
392 const css::uno::Reference
< css::uno::XComponentContext
>& xContext
,
393 OUString
const & implementationName
, SvXMLImportFlags nImportFlags
)
394 : mpImpl( new SvXMLImport_Impl(xContext
, implementationName
) ),
395 mpNamespaceMap( new SvXMLNamespaceMap
),
397 mpUnitConv( new SvXMLUnitConverter( xContext
,
398 util::MeasureUnit::MM_100TH
, util::MeasureUnit::MM_100TH
) ),
400 mnImportFlags( nImportFlags
),
401 isFastContext( false ),
402 maNamespaceHandler( new SvXMLImportFastNamespaceHandler() ),
403 mbIsFormsSupported( true ),
404 mbIsTableShapeSupported( false ),
405 mbNotifyMacroEventRead( false )
407 SAL_WARN_IF( !xContext
.is(), "xmloff.core", "got no service manager" );
409 mxParser
= xml::sax::FastParser::create( xContext
);
410 setNamespaceHandler( maNamespaceHandler
.get() );
411 setTokenHandler( xTokenHandler
);
412 if ( !bIsNSMapsInitialized
)
414 initializeNamespaceMaps();
415 bIsNSMapsInitialized
= true;
417 registerNamespaces();
420 void SvXMLImport::cleanup() throw ()
422 if (mxEventListener
.is() && mxModel
.is())
423 mxModel
->removeEventListener(mxEventListener
);
424 // clear context stacks first in case of parse error because the context
425 // class dtors are full of application logic
426 while (!maFastContexts
.empty())
428 if (SvXMLStylesContext
* pStylesContext
= dynamic_cast<SvXMLStylesContext
*>(maFastContexts
.top().get()))
429 pStylesContext
->Clear();
430 maFastContexts
.pop();
432 while (!maContexts
.empty())
434 if (SvXMLStylesContext
* pStylesContext
= dynamic_cast<SvXMLStylesContext
*>(maContexts
.top().get()))
435 pStylesContext
->Clear();
438 mxTextImport
.clear(); // XMLRedlineImportHelper needs model
442 SvXMLImport::~SvXMLImport() throw ()
449 class theSvXMLImportUnoTunnelId
: public rtl::Static
< UnoTunnelIdInit
, theSvXMLImportUnoTunnelId
> {};
453 sal_Int64 SAL_CALL
SvXMLImport::getSomething( const uno::Sequence
< sal_Int8
>& rId
)
455 if( rId
.getLength() == 16 &&
456 0 == memcmp( theSvXMLImportUnoTunnelId::get().getSeq().getConstArray(),
457 rId
.getConstArray(), 16 ) )
459 return sal::static_int_cast
<sal_Int64
>(reinterpret_cast<sal_uIntPtr
>(this));
466 class setFastDocumentHandlerGuard
469 css::uno::Reference
<css::xml::sax::XFastParser
> mxParser
;
471 setFastDocumentHandlerGuard(const css::uno::Reference
<css::xml::sax::XFastParser
>& Parser
,
472 const css::uno::Reference
<css::xml::sax::XFastDocumentHandler
>& Handler
)
475 mxParser
->setFastDocumentHandler(Handler
);
477 //guarantee restoration of null document handler
478 ~setFastDocumentHandlerGuard()
480 mxParser
->setFastDocumentHandler(nullptr);
486 void SAL_CALL
SvXMLImport::parseStream( const xml::sax::InputSource
& aInputSource
)
488 setFastDocumentHandlerGuard
aDocumentHandlerGuard(mxParser
, mxFastDocumentHandler
.is() ? mxFastDocumentHandler
: this);
489 mxParser
->parseStream(aInputSource
);
492 void SAL_CALL
SvXMLImport::setFastDocumentHandler( const uno::Reference
< xml::sax::XFastDocumentHandler
>& Handler
)
494 mxFastDocumentHandler
= Handler
;
497 void SAL_CALL
SvXMLImport::setTokenHandler( const uno::Reference
< xml::sax::XFastTokenHandler
>& Handler
)
499 mxParser
->setTokenHandler( Handler
);
502 void SAL_CALL
SvXMLImport::registerNamespace( const OUString
& NamespaceURL
, sal_Int32 NamespaceToken
)
504 mxParser
->registerNamespace( NamespaceURL
, NamespaceToken
);
507 OUString SAL_CALL
SvXMLImport::getNamespaceURL( const OUString
& rPrefix
)
509 return mxParser
->getNamespaceURL( rPrefix
);
512 void SAL_CALL
SvXMLImport::setErrorHandler( const uno::Reference
< xml::sax::XErrorHandler
>& Handler
)
514 mxParser
->setErrorHandler( Handler
);
517 void SAL_CALL
SvXMLImport::setEntityResolver( const uno::Reference
< xml::sax::XEntityResolver
>& Resolver
)
519 mxParser
->setEntityResolver( Resolver
);
522 void SAL_CALL
SvXMLImport::setLocale( const lang::Locale
& rLocale
)
524 mxParser
->setLocale( rLocale
);
527 void SAL_CALL
SvXMLImport::setNamespaceHandler( const uno::Reference
< xml::sax::XFastNamespaceHandler
>& Handler
)
529 mxParser
->setNamespaceHandler( Handler
);
533 void SAL_CALL
SvXMLImport::startDocument()
535 SAL_INFO( "xmloff.core", "{ SvXMLImport::startDocument" );
536 if (!mxGraphicStorageHandler
.is() || !mxEmbeddedResolver
.is())
538 Reference
< lang::XMultiServiceFactory
> xFactory( mxModel
, UNO_QUERY
);
543 if (!mxGraphicStorageHandler
.is())
545 // #99870# Import... instead of Export...
546 mxGraphicStorageHandler
.set(
547 xFactory
->createInstance("com.sun.star.document.ImportGraphicStorageHandler"),
549 mpImpl
->mbOwnGraphicResolver
= mxGraphicStorageHandler
.is();
552 if( !mxEmbeddedResolver
.is() )
554 // #99870# Import... instead of Export...
555 mxEmbeddedResolver
.set(
556 xFactory
->createInstance("com.sun.star.document.ImportEmbeddedObjectResolver"),
558 mpImpl
->mbOwnEmbeddedResolver
= mxEmbeddedResolver
.is();
561 catch( css::uno::Exception
& )
568 void SAL_CALL
SvXMLImport::endDocument()
570 SAL_INFO( "xmloff.core", "} SvXMLImport::endDocument" );
571 // #i9518# All the stuff that accesses the document has to be done here, not in the dtor,
572 // because the SvXMLImport dtor might not be called until after the document has been closed.
574 GetTextImport()->MapCrossRefHeadingFieldsHorribly();
576 if (mpImpl
->mpRDFaHelper
)
578 const uno::Reference
<rdf::XRepositorySupplier
> xRS(mxModel
,
582 mpImpl
->mpRDFaHelper
->InsertRDFa( xRS
);
587 if (mxImportInfo
.is())
589 uno::Reference
< beans::XPropertySetInfo
> xPropertySetInfo
= mxImportInfo
->getPropertySetInfo();
590 if (xPropertySetInfo
.is())
592 if (bool(mpProgressBarHelper
))
594 OUString
sProgressMax(XML_PROGRESSMAX
);
595 OUString
sProgressCurrent(XML_PROGRESSCURRENT
);
596 OUString
sRepeat(XML_PROGRESSREPEAT
);
597 if (xPropertySetInfo
->hasPropertyByName(sProgressMax
) &&
598 xPropertySetInfo
->hasPropertyByName(sProgressCurrent
))
600 sal_Int32
nProgressMax(mpProgressBarHelper
->GetReference());
601 sal_Int32
nProgressCurrent(mpProgressBarHelper
->GetValue());
602 mxImportInfo
->setPropertyValue(sProgressMax
, uno::Any(nProgressMax
));
603 mxImportInfo
->setPropertyValue(sProgressCurrent
, uno::Any(nProgressCurrent
));
605 if (xPropertySetInfo
->hasPropertyByName(sRepeat
))
606 mxImportInfo
->setPropertyValue(sRepeat
, css::uno::makeAny(mpProgressBarHelper
->GetRepeat()));
607 // pProgressBarHelper is deleted in dtor
609 OUString
sNumberStyles(XML_NUMBERSTYLES
);
610 if (mxNumberStyles
.is() && xPropertySetInfo
->hasPropertyByName(sNumberStyles
))
612 mxImportInfo
->setPropertyValue(sNumberStyles
, Any(mxNumberStyles
));
617 if( mxFontDecls
.is() )
618 static_cast<SvXMLStylesContext
*>(mxFontDecls
.get())->Clear();
620 static_cast<SvXMLStylesContext
*>(mxStyles
.get())->Clear();
621 if( mxAutoStyles
.is() )
622 static_cast<SvXMLStylesContext
*>(mxAutoStyles
.get())->Clear();
623 if( mxMasterStyles
.is() )
624 static_cast<SvXMLStylesContext
*>(mxMasterStyles
.get())->Clear();
626 // possible form-layer related knittings which can only be done when
627 // the whole document exists
628 if ( mxFormImport
.is() )
629 mxFormImport
->documentDone();
631 // The shape import helper does the z-order sorting in the dtor,
632 // so it must be deleted here, too.
633 mxShapeImport
= nullptr;
635 if( mpImpl
->mbOwnGraphicResolver
)
637 Reference
<lang::XComponent
> xComp(mxGraphicStorageHandler
, UNO_QUERY
);
641 if( mpImpl
->mbOwnEmbeddedResolver
)
643 Reference
< lang::XComponent
> xComp( mxEmbeddedResolver
, UNO_QUERY
);
648 if ( bool( mpXMLErrors
) )
650 mpXMLErrors
->ThrowErrorAsSAXException( XMLERROR_FLAG_SEVERE
);
654 std::unique_ptr
<SvXMLNamespaceMap
> SvXMLImport::processNSAttributes(
655 const uno::Reference
< xml::sax::XAttributeList
>& xAttrList
)
657 std::unique_ptr
<SvXMLNamespaceMap
> pRewindMap
;
658 sal_Int16 nAttrCount
= xAttrList
.is() ? xAttrList
->getLength() : 0;
659 for( sal_Int16 i
=0; i
< nAttrCount
; i
++ )
661 const OUString
& rAttrName
= xAttrList
->getNameByIndex( i
);
662 if ( rAttrName
== "office:version" )
664 mpImpl
->aODFVersion
= xAttrList
->getValueByIndex( i
);
666 // the ODF version in content.xml and manifest.xml must be the same starting from ODF1.2
667 if ( mpImpl
->mStreamName
== "content.xml" && !IsODFVersionConsistent( mpImpl
->aODFVersion
) )
669 throw xml::sax::SAXException("Inconsistent ODF versions in content.xml and manifest.xml!",
670 uno::Reference
< uno::XInterface
>(),
672 packages::zip::ZipIOException("Inconsistent ODF versions in content.xml and manifest.xml!" ) ) );
675 else if( ( rAttrName
.getLength() >= 5 ) &&
676 ( rAttrName
.startsWith( GetXMLToken(XML_XMLNS
) ) ) &&
677 ( rAttrName
.getLength() == 5 || ':' == rAttrName
[5] ) )
681 pRewindMap
= std::move(mpNamespaceMap
);
682 mpNamespaceMap
.reset(new SvXMLNamespaceMap(*pRewindMap
));
684 const OUString
& rAttrValue
= xAttrList
->getValueByIndex( i
);
686 OUString
aPrefix( ( rAttrName
.getLength() == 5 )
688 : rAttrName
.copy( 6 ) );
689 // Add namespace, but only if it is known.
690 sal_uInt16 nKey
= mpNamespaceMap
->AddIfKnown( aPrefix
, rAttrValue
);
691 // If namespace is unknown, try to match a name with similar
693 if( XML_NAMESPACE_UNKNOWN
== nKey
)
695 OUString
aTestName( rAttrValue
);
696 if( SvXMLNamespaceMap::NormalizeURI( aTestName
) )
697 nKey
= mpNamespaceMap
->AddIfKnown( aPrefix
, aTestName
);
699 // If that namespace is not known, too, add it as unknown
700 if( XML_NAMESPACE_UNKNOWN
== nKey
)
701 mpNamespaceMap
->Add( aPrefix
, rAttrValue
);
708 void SAL_CALL
SvXMLImport::startElement( const OUString
& rName
,
709 const uno::Reference
< xml::sax::XAttributeList
>& xAttrList
)
711 // SAL_INFO("svg", "startElement " << rName);
712 // Process namespace attributes. This must happen before creating the
713 // context, because namespace declaration apply to the element name itself.
714 std::unique_ptr
<SvXMLNamespaceMap
> pRewindMap(processNSAttributes(xAttrList
));
716 // Get element's namespace and local name.
719 mpNamespaceMap
->GetKeyByAttrName( rName
, &aLocalName
);
721 // If there are contexts already, call a CreateChildContext at the topmost
722 // context. Otherwise, create a default context.
723 SvXMLImportContextRef xContext
;
724 if(!maContexts
.empty())
726 xContext
= maContexts
.top()->CreateChildContext(nPrefix
, aLocalName
, xAttrList
);
727 SAL_WARN_IF( !xContext
.is() || (xContext
->GetPrefix() != nPrefix
), "xmloff.core",
728 "SvXMLImport::startElement: created context has wrong prefix" );
732 xContext
.set(CreateDocumentContext(nPrefix
, aLocalName
, xAttrList
));
733 if( (nPrefix
& XML_NAMESPACE_UNKNOWN_FLAG
) != 0 &&
734 dynamic_cast< const SvXMLImportContext
*>(xContext
.get()) != nullptr )
736 Reference
<xml::sax::XLocator
> xDummyLocator
;
737 Sequence
< OUString
> aParams
{ rName
};
739 SetError( XMLERROR_FLAG_SEVERE
|XMLERROR_UNKNOWN_ROOT
,
740 aParams
, "Root element unknown", xDummyLocator
);
744 SAL_WARN_IF( !xContext
.is(), "xmloff.core", "SvXMLImport::startElement: missing context" );
746 xContext
.set(new SvXMLImportContext( *this, nPrefix
, aLocalName
));
748 // Remember old namespace map.
750 xContext
->PutRewindMap(std::move(pRewindMap
));
752 // Call a startElement at the new context.
753 xContext
->StartElement( xAttrList
);
755 // Push context on stack.
756 maContexts
.push(xContext
);
759 void SAL_CALL
SvXMLImport::endElement( const OUString
&
765 if (maContexts
.empty())
767 SAL_WARN("xmloff.core", "SvXMLImport::endElement: no context left");
771 std::unique_ptr
<SvXMLNamespaceMap
> pRewindMap
;
774 // Get topmost context and remove it from the stack.
775 SvXMLImportContextRef xContext
= maContexts
.top();
779 // Non product only: check if endElement call matches startELement call.
782 mpNamespaceMap
->GetKeyByAttrName( rName
, &aLocalName
);
783 SAL_WARN_IF( xContext
->GetPrefix() != nPrefix
, "xmloff.core", "SvXMLImport::endElement: popped context has wrong prefix" );
784 SAL_WARN_IF( xContext
->GetLocalName() != aLocalName
, "xmloff.core", "SvXMLImport::endElement: popped context has wrong lname" );
787 // Call a EndElement at the current context.
788 xContext
->EndElement();
789 // Get a namespace map to rewind.
790 pRewindMap
= xContext
->TakeRewindMap();
791 // note: delete xContext *before* rewinding namespace map!
794 // Rewind a namespace map.
797 mpNamespaceMap
.reset();
798 mpNamespaceMap
= std::move(pRewindMap
);
802 void SAL_CALL
SvXMLImport::characters( const OUString
& rChars
)
804 if ( !maFastContexts
.empty() )
806 maFastContexts
.top()->characters( rChars
);
808 else if( !maContexts
.empty() )
810 maContexts
.top()->Characters( rChars
);
814 void SvXMLImport::Characters( const OUString
& rChars
)
816 if( !maContexts
.empty() )
818 maContexts
.top()->Characters( rChars
);
822 void SAL_CALL
SvXMLImport::ignorableWhitespace( const OUString
& )
826 void SAL_CALL
SvXMLImport::processingInstruction( const OUString
&,
831 void SAL_CALL
SvXMLImport::setDocumentLocator( const uno::Reference
< xml::sax::XLocator
>& rLocator
)
833 mxLocator
= rLocator
;
836 // XFastContextHandler
837 void SAL_CALL
SvXMLImport::startFastElement (sal_Int32 Element
,
838 const uno::Reference
< xml::sax::XFastAttributeList
> & Attribs
)
842 sax_fastparser::FastAttributeList
*pAttribList
=
843 sax_fastparser::FastAttributeList::castToFastAttributeList( Attribs
);
844 auto &aIter( pAttribList
->find( XML_ELEMENT( OFFICE
, XML_VERSION
) ) );
845 if( aIter
!= pAttribList
->end() )
847 mpImpl
->aODFVersion
= aIter
.toString();
849 // the ODF version in content.xml and manifest.xml must be the same starting from ODF1.2
850 if ( mpImpl
->mStreamName
== "content.xml" && !IsODFVersionConsistent( mpImpl
->aODFVersion
) )
852 throw xml::sax::SAXException("Inconsistent ODF versions in content.xml and manifest.xml!",
853 uno::Reference
< uno::XInterface
>(),
855 packages::zip::ZipIOException("Inconsistent ODF versions in content.xml and manifest.xml!" ) ) );
860 //Namespace handling is unnecessary. It is done by the fastparser itself.
861 uno::Reference
<XFastContextHandler
> xContext
;
862 if (!maFastContexts
.empty())
864 uno::Reference
<XFastContextHandler
> pHandler
= maFastContexts
.top();
865 xContext
= pHandler
->createFastChildContext( Element
, Attribs
);
868 xContext
.set( CreateFastContext( Element
, Attribs
) );
870 if ( !xContext
.is() )
871 xContext
.set( new SvXMLImportContext( *this ) );
873 isFastContext
= true;
875 // Call a startElement at the new context.
876 xContext
->startFastElement( Element
, Attribs
);
880 if ( maNamespaceAttrList
.is() )
881 maNamespaceAttrList
->Clear();
883 maNamespaceAttrList
= new comphelper::AttributeList
;
885 maNamespaceHandler
->addNSDeclAttributes( maNamespaceAttrList
);
886 std::unique_ptr
<SvXMLNamespaceMap
> pRewindMap(
887 processNSAttributes( maNamespaceAttrList
.get() ));
888 assert( dynamic_cast<SvXMLImportContext
*>( xContext
.get() ) != nullptr );
889 SvXMLImportContext
*pContext
= static_cast<SvXMLImportContext
*>( xContext
.get() );
891 pContext
->PutRewindMap(std::move(pRewindMap
));
892 maContexts
.push(pContext
);
895 // Push context on stack.
896 maFastContexts
.push(xContext
);
899 void SAL_CALL
SvXMLImport::startUnknownElement (const OUString
& rPrefix
, const OUString
& rLocalName
,
900 const uno::Reference
< xml::sax::XFastAttributeList
> & Attribs
)
902 uno::Reference
<XFastContextHandler
> xContext
;
903 if (!maFastContexts
.empty())
905 uno::Reference
<XFastContextHandler
> pHandler
= maFastContexts
.top();
906 xContext
= pHandler
->createUnknownChildContext( rPrefix
, rLocalName
, Attribs
);
909 xContext
.set( CreateFastContext( -1, Attribs
) );
911 if ( !xContext
.is() )
912 xContext
.set( new SvXMLImportContext( *this ) );
914 xContext
->startUnknownElement( rPrefix
, rLocalName
, Attribs
);
915 maFastContexts
.push(xContext
);
918 void SAL_CALL
SvXMLImport::endFastElement (sal_Int32 Element
)
920 if (!maFastContexts
.empty())
922 uno::Reference
<XFastContextHandler
> xContext
= maFastContexts
.top();
923 maFastContexts
.pop();
924 isFastContext
= true;
925 xContext
->endFastElement( Element
);
933 void SAL_CALL
SvXMLImport::endUnknownElement (const OUString
& rPrefix
, const OUString
& rLocalName
)
935 if (!maFastContexts
.empty())
937 uno::Reference
<XFastContextHandler
> xContext
= maFastContexts
.top();
938 maFastContexts
.pop();
939 xContext
->endUnknownElement( rPrefix
, rLocalName
);
944 uno::Reference
< xml::sax::XFastContextHandler
> SAL_CALL
945 SvXMLImport::createFastChildContext (sal_Int32
,
946 const uno::Reference
< xml::sax::XFastAttributeList
> &)
951 uno::Reference
< xml::sax::XFastContextHandler
> SAL_CALL
952 SvXMLImport::createUnknownChildContext (const OUString
&, const OUString
&,
953 const uno::Reference
< xml::sax::XFastAttributeList
> &)
958 // XExtendedDocumentHandler
959 void SAL_CALL
SvXMLImport::startCDATA()
963 void SAL_CALL
SvXMLImport::endCDATA()
967 void SAL_CALL
SvXMLImport::comment( const OUString
& )
971 void SAL_CALL
SvXMLImport::allowLineBreak()
975 void SAL_CALL
SvXMLImport::unknown( const OUString
& )
979 void SvXMLImport::SetStatistics(const uno::Sequence
< beans::NamedValue
> &)
981 GetProgressBarHelper()->SetRepeat(false);
982 GetProgressBarHelper()->SetReference(0);
986 void SAL_CALL
SvXMLImport::setTargetDocument( const uno::Reference
< lang::XComponent
>& xDoc
)
988 mxModel
.set( xDoc
, UNO_QUERY
);
990 throw lang::IllegalArgumentException();
994 uno::Reference
<document::XStorageBasedDocument
> const xSBDoc(mxModel
, uno::UNO_QUERY
);
995 uno::Reference
<embed::XStorage
> const xStor(xSBDoc
.is() ? xSBDoc
->getDocumentStorage()
1000 ::comphelper::OStorageHelper::GetXStorageFormat(xStor
)
1001 < SOFFICE_FILEFORMAT_8
;
1004 catch (uno::Exception
const&)
1006 DBG_UNHANDLED_EXCEPTION("xmloff.core");
1008 if (!mxEventListener
.is())
1010 mxEventListener
.set(new SvXMLImportEventListener(this));
1011 mxModel
->addEventListener(mxEventListener
);
1014 SAL_WARN_IF( bool(mpNumImport
), "xmloff.core", "number format import already exists." );
1015 mpNumImport
.reset();
1019 sal_Bool SAL_CALL
SvXMLImport::filter( const uno::Sequence
< beans::PropertyValue
>& )
1024 void SAL_CALL
SvXMLImport::cancel( )
1029 void SAL_CALL
SvXMLImport::initialize( const uno::Sequence
< uno::Any
>& aArguments
)
1031 for( const auto& rAny
: aArguments
)
1033 Reference
<XInterface
> xValue
;
1036 uno::Reference
<task::XStatusIndicator
> xTmpStatusIndicator(
1037 xValue
, UNO_QUERY
);
1038 if( xTmpStatusIndicator
.is() )
1039 mxStatusIndicator
= xTmpStatusIndicator
;
1041 uno::Reference
<document::XGraphicStorageHandler
> xGraphicStorageHandler(xValue
, UNO_QUERY
);
1042 if (xGraphicStorageHandler
.is())
1043 mxGraphicStorageHandler
= xGraphicStorageHandler
;
1045 uno::Reference
<document::XEmbeddedObjectResolver
> xTmpObjectResolver(
1046 xValue
, UNO_QUERY
);
1047 if( xTmpObjectResolver
.is() )
1048 mxEmbeddedResolver
= xTmpObjectResolver
;
1050 uno::Reference
<beans::XPropertySet
> xTmpPropSet( xValue
, UNO_QUERY
);
1051 if( xTmpPropSet
.is() )
1053 mxImportInfo
= xTmpPropSet
;
1054 uno::Reference
< beans::XPropertySetInfo
> xPropertySetInfo
= mxImportInfo
->getPropertySetInfo();
1055 if (xPropertySetInfo
.is())
1057 OUString
sPropName(XML_NUMBERSTYLES
);
1058 if (xPropertySetInfo
->hasPropertyByName(sPropName
))
1060 uno::Any aAny
= mxImportInfo
->getPropertyValue(sPropName
);
1061 aAny
>>= mxNumberStyles
;
1064 sPropName
= "PrivateData";
1065 if (xPropertySetInfo
->hasPropertyByName(sPropName
))
1067 Reference
< XInterface
> xIfc
;
1068 uno::Any aAny
= mxImportInfo
->getPropertyValue(sPropName
);
1071 StyleMap
*pSMap
= comphelper::getUnoTunnelImplementation
<StyleMap
>( xIfc
);
1078 sPropName
= "BaseURI";
1079 if (xPropertySetInfo
->hasPropertyByName(sPropName
))
1081 uno::Any aAny
= mxImportInfo
->getPropertyValue(sPropName
);
1083 mpImpl
->aBaseURL
.SetURL( sBaseURI
);
1084 mpImpl
->aDocBase
.SetURL( sBaseURI
);
1087 sPropName
= "StreamRelPath";
1088 if( xPropertySetInfo
->hasPropertyByName(sPropName
) )
1090 uno::Any aAny
= mxImportInfo
->getPropertyValue(sPropName
);
1094 sPropName
= "StreamName";
1095 if( xPropertySetInfo
->hasPropertyByName(sPropName
) )
1097 uno::Any aAny
= mxImportInfo
->getPropertyValue(sPropName
);
1100 if( !sBaseURI
.isEmpty() && !sName
.isEmpty() )
1102 if( !sRelPath
.isEmpty() )
1103 mpImpl
->aBaseURL
.insertName( sRelPath
);
1104 mpImpl
->aBaseURL
.insertName( sName
);
1106 mpImpl
->mStreamName
= sName
; // Note: may be empty (XSLT)
1107 // Retrieve property <ShapePositionInHoriL2R> (#i28749#)
1108 sPropName
= "ShapePositionInHoriL2R";
1109 if( xPropertySetInfo
->hasPropertyByName(sPropName
) )
1111 uno::Any aAny
= mxImportInfo
->getPropertyValue(sPropName
);
1112 aAny
>>= mpImpl
->mbShapePositionInHoriL2R
;
1114 sPropName
= "TextDocInOOoFileFormat";
1115 if( xPropertySetInfo
->hasPropertyByName(sPropName
) )
1117 uno::Any aAny
= mxImportInfo
->getPropertyValue(sPropName
);
1118 aAny
>>= mpImpl
->mbTextDocInOOoFileFormat
;
1121 sPropName
= "SourceStorage";
1122 if( xPropertySetInfo
->hasPropertyByName(sPropName
) )
1123 mxImportInfo
->getPropertyValue(sPropName
) >>= mpImpl
->mxSourceStorage
;
1128 uno::Reference
<lang::XInitialization
> const xInit(mxParser
, uno::UNO_QUERY_THROW
);
1129 uno::Sequence
<uno::Any
> args(1);
1130 args
[0] <<= OUString("IgnoreMissingNSDecl");
1131 xInit
->initialize( args
);
1135 OUString SAL_CALL
SvXMLImport::getImplementationName()
1137 return mpImpl
->implementationName
;
1140 sal_Bool SAL_CALL
SvXMLImport::supportsService( const OUString
& rServiceName
)
1142 return cppu::supportsService(this, rServiceName
);
1145 uno::Sequence
< OUString
> SAL_CALL
SvXMLImport::getSupportedServiceNames( )
1147 uno::Sequence
<OUString
> aSeq(2);
1148 aSeq
[0] = "com.sun.star.document.ImportFilter";
1149 aSeq
[1] = "com.sun.star.xml.XMLImportFilter";
1153 XMLTextImportHelper
* SvXMLImport::CreateTextImport()
1155 return new XMLTextImportHelper( mxModel
, *this );
1158 XMLShapeImportHelper
* SvXMLImport::CreateShapeImport()
1160 return new XMLShapeImportHelper( *this, mxModel
);
1163 SchXMLImportHelper
* SvXMLImport::CreateChartImport()
1165 return new SchXMLImportHelper();
1168 ::xmloff::OFormLayerXMLImport
* SvXMLImport::CreateFormImport()
1170 return new ::xmloff::OFormLayerXMLImport(*this);
1174 // Get or create fill/line/lineend-style-helper
1177 const Reference
< container::XNameContainer
> & SvXMLImport::GetGradientHelper()
1179 if( !mxGradientHelper
.is() )
1183 Reference
< lang::XMultiServiceFactory
> xServiceFact( mxModel
, UNO_QUERY
);
1184 if( xServiceFact
.is() )
1188 mxGradientHelper
.set( xServiceFact
->createInstance(
1189 "com.sun.star.drawing.GradientTable" ), UNO_QUERY
);
1191 catch( lang::ServiceNotRegisteredException
& )
1197 return mxGradientHelper
;
1200 const Reference
< container::XNameContainer
> & SvXMLImport::GetHatchHelper()
1202 if( !mxHatchHelper
.is() )
1206 Reference
< lang::XMultiServiceFactory
> xServiceFact( mxModel
, UNO_QUERY
);
1207 if( xServiceFact
.is() )
1211 mxHatchHelper
.set( xServiceFact
->createInstance(
1212 "com.sun.star.drawing.HatchTable" ), UNO_QUERY
);
1214 catch( lang::ServiceNotRegisteredException
& )
1220 return mxHatchHelper
;
1223 const Reference
< container::XNameContainer
> & SvXMLImport::GetBitmapHelper()
1225 if( !mxBitmapHelper
.is() )
1229 Reference
< lang::XMultiServiceFactory
> xServiceFact( mxModel
, UNO_QUERY
);
1230 if( xServiceFact
.is() )
1234 mxBitmapHelper
.set( xServiceFact
->createInstance(
1235 "com.sun.star.drawing.BitmapTable" ), UNO_QUERY
);
1237 catch( lang::ServiceNotRegisteredException
& )
1243 return mxBitmapHelper
;
1246 const Reference
< container::XNameContainer
> & SvXMLImport::GetTransGradientHelper()
1248 if( !mxTransGradientHelper
.is() )
1252 Reference
< lang::XMultiServiceFactory
> xServiceFact( mxModel
, UNO_QUERY
);
1253 if( xServiceFact
.is() )
1257 mxTransGradientHelper
.set( xServiceFact
->createInstance(
1258 "com.sun.star.drawing.TransparencyGradientTable" ), UNO_QUERY
);
1260 catch( lang::ServiceNotRegisteredException
& )
1266 return mxTransGradientHelper
;
1269 const Reference
< container::XNameContainer
> & SvXMLImport::GetMarkerHelper()
1271 if( !mxMarkerHelper
.is() )
1275 Reference
< lang::XMultiServiceFactory
> xServiceFact( mxModel
, UNO_QUERY
);
1276 if( xServiceFact
.is() )
1280 mxMarkerHelper
.set( xServiceFact
->createInstance( "com.sun.star.drawing.MarkerTable" ), UNO_QUERY
);
1282 catch( lang::ServiceNotRegisteredException
& )
1288 return mxMarkerHelper
;
1291 const Reference
< container::XNameContainer
> & SvXMLImport::GetDashHelper()
1293 if( !mxDashHelper
.is() && mxModel
.is() )
1295 Reference
< lang::XMultiServiceFactory
> xServiceFact( mxModel
, UNO_QUERY
);
1296 if( xServiceFact
.is() )
1300 mxDashHelper
.set( xServiceFact
->createInstance( "com.sun.star.drawing.DashTable" ), UNO_QUERY
);
1302 catch( lang::ServiceNotRegisteredException
& )
1307 return mxDashHelper
;
1310 bool SvXMLImport::IsPackageURL( const OUString
& rURL
) const
1313 // if, and only if, only parts are imported, then we're in a package
1314 const SvXMLImportFlags nTest
= SvXMLImportFlags::META
|SvXMLImportFlags::STYLES
|SvXMLImportFlags::CONTENT
|SvXMLImportFlags::SETTINGS
;
1315 if( (mnImportFlags
& nTest
) == nTest
)
1318 // TODO: from this point extract to own static function
1320 // Some quick tests: Some may rely on the package structure!
1321 sal_Int32 nLen
= rURL
.getLength();
1322 if( nLen
> 0 && '/' == rURL
[0] )
1323 // RFC2396 net_path or abs_path
1325 else if( nLen
> 1 && '.' == rURL
[0] )
1327 if( '.' == rURL
[1] )
1328 // ../: We are never going up one level, so we know
1329 // it's not an external URI
1331 else if( '/' == rURL
[1] )
1332 // we are remaining on a level, so it's a package URI
1336 // Now check for a RFC2396 schema
1338 while( nPos
< nLen
)
1340 switch( rURL
[nPos
] )
1343 // a relative path segment
1350 // we don't care about any other characters
1358 uno::Reference
<graphic::XGraphic
> SvXMLImport::loadGraphicByURL(OUString
const & rURL
)
1360 uno::Reference
<graphic::XGraphic
> xGraphic
;
1362 if (mxGraphicStorageHandler
.is())
1364 if (IsPackageURL(rURL
))
1366 xGraphic
= mxGraphicStorageHandler
->loadGraphic(rURL
);
1370 OUString
const & rAbsoluteURL
= GetAbsoluteReference(rURL
);
1371 GraphicExternalLink
aExternalLink(rAbsoluteURL
);
1372 Graphic
aGraphic(aExternalLink
);
1373 xGraphic
= aGraphic
.GetXGraphic();
1380 uno::Reference
<graphic::XGraphic
> SvXMLImport::loadGraphicFromBase64(uno::Reference
<io::XOutputStream
> const & rxOutputStream
)
1382 uno::Reference
<graphic::XGraphic
> xGraphic
;
1384 if (mxGraphicStorageHandler
.is())
1386 xGraphic
= mxGraphicStorageHandler
->loadGraphicFromOutputStream(rxOutputStream
);
1392 Reference
< XOutputStream
> SvXMLImport::GetStreamForGraphicObjectURLFromBase64()
1394 Reference
< XOutputStream
> xOStm
;
1395 Reference
< document::XBinaryStreamResolver
> xStmResolver(mxGraphicStorageHandler
, UNO_QUERY
);
1397 if( xStmResolver
.is() )
1398 xOStm
= xStmResolver
->createOutputStream();
1403 OUString
SvXMLImport::ResolveEmbeddedObjectURL(
1404 const OUString
& rURL
,
1405 const OUString
& rClassId
)
1409 if( IsPackageURL( rURL
) )
1411 if ( mxEmbeddedResolver
.is() )
1413 OUString
sURL( rURL
);
1414 if( !rClassId
.isEmpty() )
1416 sURL
+= "!" + rClassId
;
1418 sRet
= mxEmbeddedResolver
->resolveEmbeddedObjectURL( sURL
);
1422 sRet
= GetAbsoluteReference( rURL
);
1427 Reference
< embed::XStorage
> const & SvXMLImport::GetSourceStorage()
1429 return mpImpl
->mxSourceStorage
;
1432 Reference
< XOutputStream
>
1433 SvXMLImport::GetStreamForEmbeddedObjectURLFromBase64()
1435 Reference
< XOutputStream
> xOLEStream
;
1437 if( mxEmbeddedResolver
.is() )
1439 Reference
< XNameAccess
> xNA( mxEmbeddedResolver
, UNO_QUERY
);
1442 Any aAny
= xNA
->getByName( "Obj12345678" );
1443 aAny
>>= xOLEStream
;
1450 OUString
SvXMLImport::ResolveEmbeddedObjectURLFromBase64()
1454 if( mxEmbeddedResolver
.is() )
1456 sRet
= mxEmbeddedResolver
->resolveEmbeddedObjectURL( "Obj12345678" );
1462 void SvXMLImport::AddStyleDisplayName( sal_uInt16 nFamily
,
1463 const OUString
& rName
,
1464 const OUString
& rDisplayName
)
1466 if( !mpStyleMap
.is() )
1468 mpStyleMap
= new StyleMap
;
1469 if( mxImportInfo
.is() )
1471 OUString
sPrivateData( "PrivateData" );
1472 Reference
< beans::XPropertySetInfo
> xPropertySetInfo
=
1473 mxImportInfo
->getPropertySetInfo();
1474 if( xPropertySetInfo
.is() &&
1475 xPropertySetInfo
->hasPropertyByName(sPrivateData
) )
1477 Reference
< XInterface
> xIfc(
1478 static_cast< XUnoTunnel
*>( mpStyleMap
.get() ) );
1479 mxImportInfo
->setPropertyValue( sPrivateData
, Any(xIfc
) );
1484 StyleMap::key_type
aKey( nFamily
, rName
);
1485 StyleMap::value_type
aValue( aKey
, rDisplayName
);
1486 ::std::pair
<StyleMap::iterator
,bool> aRes( mpStyleMap
->insert( aValue
) );
1487 SAL_WARN_IF( !aRes
.second
,
1489 "duplicate style name of family " << nFamily
<< ": \"" << rName
<< "\"");
1493 OUString
SvXMLImport::GetStyleDisplayName( sal_uInt16 nFamily
,
1494 const OUString
& rName
) const
1496 OUString
sName( rName
);
1497 if( mpStyleMap
.is() && !rName
.isEmpty() )
1499 StyleMap::key_type
aKey( nFamily
, rName
);
1500 StyleMap::const_iterator aIter
= mpStyleMap
->find( aKey
);
1501 if( aIter
!= mpStyleMap
->end() )
1502 sName
= (*aIter
).second
;
1507 void SvXMLImport::SetViewSettings(const css::uno::Sequence
<css::beans::PropertyValue
>&)
1511 void SvXMLImport::SetConfigurationSettings(const css::uno::Sequence
<css::beans::PropertyValue
>&)
1515 void SvXMLImport::SetDocumentSpecificSettings(const OUString
&, const uno::Sequence
<beans::PropertyValue
>&)
1519 ProgressBarHelper
* SvXMLImport::GetProgressBarHelper()
1521 if (!mpProgressBarHelper
)
1523 mpProgressBarHelper
= std::make_unique
<ProgressBarHelper
>(mxStatusIndicator
, false);
1525 if (mxImportInfo
.is())
1527 uno::Reference
< beans::XPropertySetInfo
> xPropertySetInfo
= mxImportInfo
->getPropertySetInfo();
1528 if (xPropertySetInfo
.is())
1530 OUString
sProgressRange(XML_PROGRESSRANGE
);
1531 OUString
sProgressMax(XML_PROGRESSMAX
);
1532 OUString
sProgressCurrent(XML_PROGRESSCURRENT
);
1533 OUString
sRepeat(XML_PROGRESSREPEAT
);
1534 if (xPropertySetInfo
->hasPropertyByName(sProgressMax
) &&
1535 xPropertySetInfo
->hasPropertyByName(sProgressCurrent
) &&
1536 xPropertySetInfo
->hasPropertyByName(sProgressRange
))
1539 sal_Int32
nProgressMax(0);
1540 sal_Int32
nProgressCurrent(0);
1541 sal_Int32
nProgressRange(0);
1542 aAny
= mxImportInfo
->getPropertyValue(sProgressRange
);
1543 if (aAny
>>= nProgressRange
)
1544 mpProgressBarHelper
->SetRange(nProgressRange
);
1545 aAny
= mxImportInfo
->getPropertyValue(sProgressMax
);
1546 if (aAny
>>= nProgressMax
)
1547 mpProgressBarHelper
->SetReference(nProgressMax
);
1548 aAny
= mxImportInfo
->getPropertyValue(sProgressCurrent
);
1549 if (aAny
>>= nProgressCurrent
)
1550 mpProgressBarHelper
->SetValue(nProgressCurrent
);
1552 if (xPropertySetInfo
->hasPropertyByName(sRepeat
))
1554 uno::Any aAny
= mxImportInfo
->getPropertyValue(sRepeat
);
1555 if (aAny
.getValueType() == cppu::UnoType
<bool>::get())
1556 mpProgressBarHelper
->SetRepeat(::cppu::any2bool(aAny
));
1558 SAL_WARN( "xmloff.core", "why is it no boolean?" );
1564 return mpProgressBarHelper
.get();
1567 void SvXMLImport::AddNumberStyle(sal_Int32 nKey
, const OUString
& rName
)
1569 if (!mxNumberStyles
.is())
1570 mxNumberStyles
.set( comphelper::NameContainer_createInstance( ::cppu::UnoType
<sal_Int32
>::get()) );
1571 if (mxNumberStyles
.is())
1575 mxNumberStyles
->insertByName(rName
, Any(nKey
));
1577 catch ( uno::Exception
& )
1579 DBG_UNHANDLED_EXCEPTION( "xmloff.core", "Numberformat could not be inserted");
1583 SAL_WARN( "xmloff.core", "not possible to create NameContainer");
1587 XMLEventImportHelper
& SvXMLImport::GetEventImport()
1589 if (!mpEventImportHelper
)
1591 // construct event helper and register StarBasic handler and standard
1593 mpEventImportHelper
= std::make_unique
<XMLEventImportHelper
>();
1594 const OUString
& sStarBasic(GetXMLToken(XML_STARBASIC
));
1595 mpEventImportHelper
->RegisterFactory(sStarBasic
,
1596 std::make_unique
<XMLStarBasicContextFactory
>());
1597 const OUString
& sScript(GetXMLToken(XML_SCRIPT
));
1598 mpEventImportHelper
->RegisterFactory(sScript
,
1599 std::make_unique
<XMLScriptContextFactory
>());
1600 mpEventImportHelper
->AddTranslationTable(aStandardEventTable
);
1602 // register StarBasic event handler with capitalized spelling
1603 mpEventImportHelper
->RegisterFactory("StarBasic",
1604 std::make_unique
<XMLStarBasicContextFactory
>());
1607 return *mpEventImportHelper
;
1610 void SvXMLImport::SetFontDecls( XMLFontStylesContext
*pFontDecls
)
1612 if (mxFontDecls
.is())
1613 static_cast<SvXMLStylesContext
*>(mxFontDecls
.get())->Clear();
1614 mxFontDecls
= pFontDecls
;
1617 void SvXMLImport::SetStyles( SvXMLStylesContext
*pStyles
)
1620 static_cast<SvXMLStylesContext
*>(mxStyles
.get())->Clear();
1624 void SvXMLImport::SetAutoStyles( SvXMLStylesContext
*pAutoStyles
)
1626 if (pAutoStyles
&& mxNumberStyles
.is() && (mnImportFlags
& SvXMLImportFlags::CONTENT
) )
1628 uno::Reference
<xml::sax::XAttributeList
> xAttrList
;
1629 for (const auto& name
: mxNumberStyles
->getElementNames())
1631 uno::Any
aAny(mxNumberStyles
->getByName(name
));
1635 SvXMLStyleContext
* pContext
= new SvXMLNumFormatContext(
1636 *this, XML_NAMESPACE_NUMBER
, name
, xAttrList
, nKey
, *pAutoStyles
);
1637 pAutoStyles
->AddStyle(*pContext
);
1641 if (mxAutoStyles
.is())
1642 static_cast<SvXMLStylesContext
*>(mxAutoStyles
.get())->Clear();
1643 mxAutoStyles
= pAutoStyles
;
1644 GetTextImport()->SetAutoStyles( pAutoStyles
);
1645 GetShapeImport()->SetAutoStylesContext( pAutoStyles
);
1646 GetChartImport()->SetAutoStylesContext( pAutoStyles
);
1647 GetFormImport()->setAutoStyleContext( pAutoStyles
);
1650 void SvXMLImport::SetMasterStyles( SvXMLStylesContext
*pMasterStyles
)
1652 if (mxMasterStyles
.is())
1653 static_cast<SvXMLStylesContext
*>(mxMasterStyles
.get())->Clear();
1654 mxMasterStyles
= pMasterStyles
;
1657 XMLFontStylesContext
*SvXMLImport::GetFontDecls()
1659 return static_cast<XMLFontStylesContext
*>(mxFontDecls
.get());
1662 SvXMLStylesContext
*SvXMLImport::GetStyles()
1664 return static_cast<SvXMLStylesContext
*>(mxStyles
.get());
1667 SvXMLStylesContext
*SvXMLImport::GetAutoStyles()
1669 return static_cast<SvXMLStylesContext
*>(mxAutoStyles
.get());
1672 const XMLFontStylesContext
*SvXMLImport::GetFontDecls() const
1674 return static_cast<const XMLFontStylesContext
*>(mxFontDecls
.get());
1677 const SvXMLStylesContext
*SvXMLImport::GetStyles() const
1679 return static_cast<const SvXMLStylesContext
*>(mxStyles
.get());
1682 const SvXMLStylesContext
*SvXMLImport::GetAutoStyles() const
1684 return static_cast<const SvXMLStylesContext
*>(mxAutoStyles
.get());
1687 OUString
SvXMLImport::GetAbsoluteReference(const OUString
& rValue
) const
1689 if( rValue
.isEmpty() || rValue
[0] == '#' )
1692 INetURLObject aAbsURL
;
1693 if( mpImpl
->aBaseURL
.GetNewAbsURL( rValue
, &aAbsURL
) )
1694 return aAbsURL
.GetMainURL( INetURLObject::DecodeMechanism::ToIUri
);
1699 bool SvXMLImport::IsODFVersionConsistent( const OUString
& aODFVersion
)
1701 // the check returns sal_False only if the storage version could be retrieved
1702 bool bResult
= true;
1704 if ( !aODFVersion
.isEmpty() && aODFVersion
.compareTo( ODFVER_012_TEXT
) >= 0 )
1706 // check the consistency only for the ODF1.2 and later ( according to content.xml )
1707 // manifest.xml might have no version, it should be checked here and the correct version should be set
1710 uno::Reference
< document::XStorageBasedDocument
> xDoc( mxModel
, uno::UNO_QUERY_THROW
);
1711 uno::Reference
< embed::XStorage
> xStor
= xDoc
->getDocumentStorage();
1712 uno::Reference
< beans::XPropertySet
> xStorProps( xStor
, uno::UNO_QUERY_THROW
);
1714 // the check should be done only for OASIS format
1717 bool bRepairPackage
= false;
1720 xStorProps
->getPropertyValue( "RepairPackage" )
1722 } catch ( uno::Exception
& )
1725 // check only if not in Repair mode
1726 if ( !bRepairPackage
)
1728 OUString aStorVersion
;
1729 xStorProps
->getPropertyValue( "Version" )
1732 // if the storage version is set in manifest.xml, it must be the same as in content.xml
1733 // if not, set it explicitly to be used further ( it will work even for readonly storage )
1734 // This workaround is not nice, but I see no other way to handle it, since there are
1735 // ODF1.2 documents without version in manifest.xml
1736 if ( !aStorVersion
.isEmpty() )
1737 bResult
= aODFVersion
== aStorVersion
;
1739 xStorProps
->setPropertyValue( "Version",
1740 uno::makeAny( aODFVersion
) );
1744 bool bInconsistent
= false;
1745 xStorProps
->getPropertyValue( "IsInconsistent" )
1747 bResult
= !bInconsistent
;
1752 catch( uno::Exception
& )
1759 void SvXMLImport::CreateNumberFormatsSupplier_()
1761 SAL_WARN_IF( mxNumberFormatsSupplier
.is(), "xmloff.core", "number formats supplier already exists!" );
1763 mxNumberFormatsSupplier
=
1764 uno::Reference
< util::XNumberFormatsSupplier
> (mxModel
, uno::UNO_QUERY
);
1767 void SvXMLImport::CreateDataStylesImport_()
1769 SAL_WARN_IF( bool(mpNumImport
), "xmloff.core", "data styles import already exists!" );
1770 uno::Reference
<util::XNumberFormatsSupplier
> xNum
=
1771 GetNumberFormatsSupplier();
1773 mpNumImport
= std::make_unique
<SvXMLNumFmtHelper
>(xNum
, GetComponentContext() );
1776 sal_Unicode
SvXMLImport::ConvStarBatsCharToStarSymbol( sal_Unicode c
)
1778 sal_Unicode cNew
= c
;
1779 if( !mpImpl
->hBatsFontConv
)
1781 mpImpl
->hBatsFontConv
= CreateFontToSubsFontConverter( "StarBats",
1782 FontToSubsFontFlags::IMPORT
);
1783 SAL_WARN_IF( !mpImpl
->hBatsFontConv
, "xmloff.core", "Got no symbol font converter" );
1785 if( mpImpl
->hBatsFontConv
)
1787 cNew
= ConvertFontToSubsFontChar( mpImpl
->hBatsFontConv
, c
);
1793 sal_Unicode
SvXMLImport::ConvStarMathCharToStarSymbol( sal_Unicode c
)
1795 sal_Unicode cNew
= c
;
1796 if( !mpImpl
->hMathFontConv
)
1798 mpImpl
->hMathFontConv
= CreateFontToSubsFontConverter( "StarMath",
1799 FontToSubsFontFlags::IMPORT
);
1800 SAL_WARN_IF( !mpImpl
->hMathFontConv
, "xmloff.core", "Got no symbol font converter" );
1802 if( mpImpl
->hMathFontConv
)
1804 cNew
= ConvertFontToSubsFontChar( mpImpl
->hMathFontConv
, c
);
1810 void SvXMLImport::SetError(
1812 const Sequence
<OUString
>& rMsgParams
,
1813 const OUString
& rExceptionMessage
,
1814 const Reference
<xml::sax::XLocator
>& rLocator
)
1816 // create error list on demand
1818 mpXMLErrors
= std::make_unique
<XMLErrors
>();
1820 // save error information
1821 // use document locator (if none supplied)
1822 mpXMLErrors
->AddRecord( nId
, rMsgParams
, rExceptionMessage
,
1823 rLocator
.is() ? rLocator
: mxLocator
);
1826 void SvXMLImport::SetError(
1828 const Sequence
<OUString
>& rMsgParams
)
1830 SetError( nId
, rMsgParams
, "", nullptr );
1833 void SvXMLImport::SetError(
1836 Sequence
<OUString
> aSeq(0);
1837 SetError( nId
, aSeq
);
1840 void SvXMLImport::SetError(
1842 const OUString
& rMsg1
)
1844 Sequence
<OUString
> aSeq
{ rMsg1
};
1845 SetError( nId
, aSeq
);
1848 void SvXMLImport::SetError(
1850 const OUString
& rMsg1
,
1851 const OUString
& rMsg2
)
1853 Sequence
<OUString
> aSeq(2);
1854 OUString
* pSeq
= aSeq
.getArray();
1857 SetError( nId
, aSeq
);
1860 void SvXMLImport::DisposingModel()
1862 if( mxFontDecls
.is() )
1863 static_cast<SvXMLStylesContext
*>(mxFontDecls
.get())->Clear();
1865 static_cast<SvXMLStylesContext
*>(mxStyles
.get())->Clear();
1866 if( mxAutoStyles
.is() )
1867 static_cast<SvXMLStylesContext
*>(mxAutoStyles
.get())->Clear();
1868 if( mxMasterStyles
.is() )
1869 static_cast<SvXMLStylesContext
*>(mxMasterStyles
.get())->Clear();
1871 mxModel
.set(nullptr);
1872 mxEventListener
.set(nullptr);
1875 ::comphelper::UnoInterfaceToUniqueIdentifierMapper
& SvXMLImport::getInterfaceToIdentifierMapper()
1877 return mpImpl
->maInterfaceToIdentifierMapper
;
1880 uno::Reference
< uno::XComponentContext
> const &
1881 SvXMLImport::GetComponentContext() const
1883 return mpImpl
->mxComponentContext
;
1886 OUString
SvXMLImport::GetBaseURL() const
1888 return mpImpl
->aBaseURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
1891 OUString
SvXMLImport::GetDocumentBase() const
1893 return mpImpl
->aDocBase
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
1896 // Convert drawing object positions from OOo file format to OASIS (#i28749#)
1897 bool SvXMLImport::IsShapePositionInHoriL2R() const
1899 return mpImpl
->mbShapePositionInHoriL2R
;
1902 bool SvXMLImport::IsTextDocInOOoFileFormat() const
1904 return mpImpl
->mbTextDocInOOoFileFormat
;
1907 void SvXMLImport::initXForms()
1909 // dummy method; to be implemented by derived classes supporting XForms
1912 bool SvXMLImport::getBuildIds( sal_Int32
& rUPD
, sal_Int32
& rBuild
) const
1915 OUString
const aBuildId(getBuildIdsProperty(mxImportInfo
));
1916 if (!aBuildId
.isEmpty())
1918 sal_Int32 nIndex
= aBuildId
.indexOf('$');
1921 rUPD
= aBuildId
.copy( 0, nIndex
).toInt32();
1922 sal_Int32 nIndexEnd
= aBuildId
.indexOf(';', nIndex
);
1923 rBuild
= (nIndexEnd
== -1)
1924 ? aBuildId
.copy(nIndex
+ 1).toInt32()
1925 : aBuildId
.copy(nIndex
+ 1, nIndexEnd
- nIndex
- 1).toInt32();
1932 sal_uInt16
SvXMLImport::getGeneratorVersion() const
1935 return mpImpl
->getGeneratorVersion( *this );
1939 bool SvXMLImport::isGeneratorVersionOlderThan(
1940 sal_uInt16
const nOOoVersion
, sal_uInt16
const nLOVersion
)
1942 assert( (nLOVersion
& LO_flag
));
1943 assert(!(nOOoVersion
& LO_flag
));
1944 const sal_uInt16
nGeneratorVersion(getGeneratorVersion());
1945 return (nGeneratorVersion
& LO_flag
)
1946 ? nGeneratorVersion
< nLOVersion
1947 : nGeneratorVersion
< nOOoVersion
;
1951 OUString
const & SvXMLImport::GetODFVersion() const
1953 return mpImpl
->aODFVersion
;
1956 bool SvXMLImport::IsOOoXML() const
1958 return mpImpl
->mbIsOOoXML
;
1961 // xml:id for RDF metadata
1962 void SvXMLImport::SetXmlId(uno::Reference
<uno::XInterface
> const & i_xIfc
,
1963 OUString
const & i_rXmlId
)
1965 if (!i_rXmlId
.isEmpty()) {
1967 const uno::Reference
<rdf::XMetadatable
> xMeta(i_xIfc
,
1971 const beans::StringPair
mdref( mpImpl
->mStreamName
, i_rXmlId
);
1973 xMeta
->setMetadataReference(mdref
);
1974 } catch (lang::IllegalArgumentException
&) {
1975 // probably duplicate; ignore
1976 SAL_INFO("xmloff.core", "SvXMLImport::SetXmlId: cannot set xml:id");
1979 } catch (uno::Exception
&) {
1980 css::uno::Any
ex( cppu::getCaughtException() );
1981 SAL_WARN("xmloff.core","SvXMLImport::SetXmlId: exception " << exceptionToString(ex
));
1986 ::xmloff::RDFaImportHelper
&
1987 SvXMLImport::GetRDFaImportHelper()
1989 if (!mpImpl
->mpRDFaHelper
)
1991 mpImpl
->mpRDFaHelper
.reset( new ::xmloff::RDFaImportHelper(*this) );
1993 return *mpImpl
->mpRDFaHelper
;
1997 SvXMLImport::AddRDFa(const uno::Reference
<rdf::XMetadatable
>& i_xObject
,
1998 OUString
const & i_rAbout
,
1999 OUString
const & i_rProperty
,
2000 OUString
const & i_rContent
,
2001 OUString
const & i_rDatatype
)
2003 // N.B.: we only get called if i_xObject had xhtml:about attribute
2004 // (an empty attribute value is valid)
2005 ::xmloff::RDFaImportHelper
& rRDFaHelper( GetRDFaImportHelper() );
2006 rRDFaHelper
.ParseAndAddRDFa(i_xObject
,
2007 i_rAbout
, i_rProperty
, i_rContent
, i_rDatatype
);
2010 bool SvXMLImport::embeddedFontAlreadyProcessed( const OUString
& url
)
2012 if( embeddedFontUrlsKnown
.count( url
) != 0 )
2014 embeddedFontUrlsKnown
.insert( url
);
2018 const OUString
SvXMLImport::getNameFromToken( sal_Int32 nToken
)
2020 uno::Sequence
< sal_Int8
> aSeq
= xTokenHandler
->getUTF8Identifier( nToken
& TOKEN_MASK
);
2021 return OUString( reinterpret_cast< const char* >(
2022 aSeq
.getConstArray() ), aSeq
.getLength(), RTL_TEXTENCODING_UTF8
);
2025 const OUString
SvXMLImport::getNamespacePrefixFromToken(sal_Int32 nToken
, const SvXMLNamespaceMap
* pMap
)
2027 sal_Int32 nNamespaceToken
= ( nToken
& NMSP_MASK
) >> NMSP_SHIFT
;
2028 auto aIter( aNamespaceMap
.find( nNamespaceToken
) );
2029 if( aIter
!= aNamespaceMap
.end() )
2033 OUString sRet
= pMap
->GetPrefixByKey(pMap
->GetKeyByName((*aIter
).second
.second
));
2034 if (!sRet
.isEmpty())
2037 return (*aIter
).second
.first
;
2043 const OUString
SvXMLImport::getNamespaceURIFromToken( sal_Int32 nToken
)
2045 sal_Int32 nNamespaceToken
= ( nToken
& NMSP_MASK
) >> NMSP_SHIFT
;
2046 auto aIter( aNamespaceMap
.find( nNamespaceToken
) );
2047 if( aIter
!= aNamespaceMap
.end() )
2048 return (*aIter
).second
.second
;
2053 const OUString
SvXMLImport::getNamespacePrefixFromURI( const OUString
& rURI
)
2055 auto aIter( aNamespaceURIPrefixMap
.find(rURI
) );
2056 if( aIter
!= aNamespaceURIPrefixMap
.end() )
2057 return (*aIter
).second
;
2062 void SvXMLImport::initializeNamespaceMaps()
2064 auto mapTokenToNamespace
= [&]( sal_Int32 nToken
, sal_Int32 nPrefix
, sal_Int32 nNamespace
)
2068 const OUString
& sNamespace
= GetXMLToken( static_cast<XMLTokenEnum
>( nNamespace
) );
2069 const OUString
& sPrefix
= GetXMLToken( static_cast<XMLTokenEnum
>( nPrefix
) );
2070 aNamespaceMap
[ nToken
+ 1 ] = std::make_pair( sPrefix
, sNamespace
);
2071 aNamespaceURIPrefixMap
.emplace( sNamespace
, sPrefix
);
2075 mapTokenToNamespace( XML_NAMESPACE_OFFICE
, XML_NP_OFFICE
, XML_N_OFFICE
);
2076 mapTokenToNamespace( XML_OLD_NAMESPACE_OFFICE
, XML_NP_OFFICE
, XML_N_OFFICE_OLD
);
2077 mapTokenToNamespace( XML_NAMESPACE_OFFICE_OOO
, XML_NP_OFFICE
, XML_N_OFFICE_OOO
);
2078 mapTokenToNamespace( XML_NAMESPACE_STYLE
, XML_NP_STYLE
, XML_N_STYLE
);
2079 mapTokenToNamespace( XML_OLD_NAMESPACE_STYLE
, XML_NP_STYLE
, XML_N_STYLE_OLD
);
2080 mapTokenToNamespace( XML_NAMESPACE_STYLE_OOO
, XML_NP_STYLE
, XML_N_STYLE_OOO
);
2081 mapTokenToNamespace( XML_NAMESPACE_TEXT
, XML_NP_TEXT
, XML_N_TEXT
);
2082 mapTokenToNamespace( XML_OLD_NAMESPACE_TEXT
, XML_NP_TEXT
, XML_N_TEXT_OLD
);
2083 mapTokenToNamespace( XML_NAMESPACE_TEXT_OOO
, XML_NP_TEXT
, XML_N_TEXT_OOO
);
2084 mapTokenToNamespace( XML_NAMESPACE_TABLE
, XML_NP_TABLE
, XML_N_TABLE
);
2085 mapTokenToNamespace( XML_OLD_NAMESPACE_TABLE
, XML_NP_TABLE
, XML_N_TABLE_OLD
);
2086 mapTokenToNamespace( XML_NAMESPACE_TABLE_OOO
, XML_NP_TABLE
, XML_N_TABLE_OOO
);
2087 mapTokenToNamespace( XML_NAMESPACE_DRAW
, XML_NP_DRAW
, XML_N_DRAW
);
2088 mapTokenToNamespace( XML_OLD_NAMESPACE_DRAW
, XML_NP_DRAW
, XML_N_DRAW_OLD
);
2089 mapTokenToNamespace( XML_NAMESPACE_DRAW_OOO
, XML_NP_DRAW
, XML_N_DRAW_OOO
);
2090 mapTokenToNamespace( XML_NAMESPACE_FO
, XML_NP_FO
, XML_N_FO
);
2091 mapTokenToNamespace( XML_OLD_NAMESPACE_FO
, XML_NP_FO
, XML_N_FO_OLD
);
2092 mapTokenToNamespace( XML_NAMESPACE_FO_COMPAT
, XML_NP_FO
, XML_N_FO_COMPAT
);
2093 mapTokenToNamespace( XML_NAMESPACE_XLINK
, XML_NP_XLINK
, XML_N_XLINK
);
2094 mapTokenToNamespace( XML_OLD_NAMESPACE_XLINK
, XML_NP_XLINK
, XML_N_XLINK_OLD
);
2095 mapTokenToNamespace( XML_NAMESPACE_DC
, XML_NP_DC
, XML_N_DC
);
2096 mapTokenToNamespace( XML_NAMESPACE_META
, XML_NP_META
, XML_N_META
);
2097 mapTokenToNamespace( XML_OLD_NAMESPACE_META
, XML_NP_META
, XML_N_META_OLD
);
2098 mapTokenToNamespace( XML_NAMESPACE_META_OOO
, XML_NP_META
, XML_N_META_OOO
);
2099 mapTokenToNamespace( XML_NAMESPACE_NUMBER
, XML_NP_NUMBER
, XML_N_NUMBER
);
2100 mapTokenToNamespace( XML_OLD_NAMESPACE_NUMBER
, XML_NP_NUMBER
, XML_N_NUMBER_OLD
);
2101 mapTokenToNamespace( XML_NAMESPACE_NUMBER_OOO
, XML_NP_NUMBER
, XML_N_NUMBER_OOO
);
2102 mapTokenToNamespace( XML_NAMESPACE_PRESENTATION
, XML_NP_PRESENTATION
, XML_N_PRESENTATION
);
2103 mapTokenToNamespace( XML_OLD_NAMESPACE_PRESENTATION
, XML_NP_PRESENTATION
, XML_N_PRESENTATION_OLD
);
2104 mapTokenToNamespace( XML_NAMESPACE_PRESENTATION_OOO
, XML_NP_PRESENTATION
, XML_N_PRESENTATION_OOO
);
2105 mapTokenToNamespace( XML_NAMESPACE_SVG
, XML_NP_SVG
, XML_N_SVG
);
2106 mapTokenToNamespace( XML_NAMESPACE_SVG_COMPAT
, XML_NP_SVG
, XML_N_SVG_COMPAT
);
2107 mapTokenToNamespace( XML_NAMESPACE_CHART
, XML_NP_CHART
, XML_N_CHART
);
2108 mapTokenToNamespace( XML_OLD_NAMESPACE_CHART
, XML_NP_CHART
, XML_N_CHART_OLD
);
2109 mapTokenToNamespace( XML_NAMESPACE_CHART_OOO
, XML_NP_CHART
, XML_N_CHART_OOO
);
2110 mapTokenToNamespace( XML_NAMESPACE_DR3D
, XML_NP_DR3D
, XML_N_DR3D
);
2111 mapTokenToNamespace( XML_NAMESPACE_DR3D_OOO
, XML_NP_DR3D
, XML_N_DR3D_OOO
);
2112 mapTokenToNamespace( XML_NAMESPACE_MATH
, XML_NP_MATH
, XML_N_MATH
);
2113 mapTokenToNamespace( XML_NAMESPACE_VERSIONS_LIST
, XML_NP_VERSIONS_LIST
, XML_N_VERSIONS_LIST
);
2114 mapTokenToNamespace( XML_NAMESPACE_FORM
, XML_NP_FORM
, XML_N_FORM
);
2115 mapTokenToNamespace( XML_NAMESPACE_FORM_OOO
, XML_NP_FORM
, XML_N_FORM_OOO
);
2116 mapTokenToNamespace( XML_NAMESPACE_SCRIPT
, XML_NP_SCRIPT
, XML_N_SCRIPT
);
2117 mapTokenToNamespace( XML_NAMESPACE_SCRIPT_OOO
, XML_NP_SCRIPT
, XML_N_SCRIPT_OOO
);
2118 mapTokenToNamespace( XML_NAMESPACE_BLOCKLIST
, XML_NP_BLOCK_LIST
, XML_N_BLOCK_LIST
);
2119 mapTokenToNamespace( XML_NAMESPACE_CONFIG
, XML_NP_CONFIG
, XML_N_CONFIG
);
2120 mapTokenToNamespace( XML_NAMESPACE_CONFIG_OOO
, XML_NP_CONFIG
, XML_N_CONFIG_OOO
);
2121 mapTokenToNamespace( XML_NAMESPACE_OOO
, XML_NP_OOO
, XML_N_OOO
);
2122 mapTokenToNamespace( XML_NAMESPACE_OOOW
, XML_NP_OOOW
, XML_N_OOOW
);
2123 mapTokenToNamespace( XML_NAMESPACE_OOOC
, XML_NP_OOOC
, XML_N_OOOC
);
2124 mapTokenToNamespace( XML_NAMESPACE_DOM
, XML_NP_DOM
, XML_N_DOM
);
2125 mapTokenToNamespace( XML_NAMESPACE_DB
, XML_NP_DB
, XML_N_DB
);
2126 mapTokenToNamespace( XML_NAMESPACE_DB_OASIS
, XML_NP_DB
, XML_N_DB_OASIS
);
2127 mapTokenToNamespace( XML_NAMESPACE_DLG
, XML_NP_DLG
, XML_N_DLG
);
2128 mapTokenToNamespace( XML_NAMESPACE_XFORMS
, XML_NP_XFORMS_1_0
, XML_N_XFORMS_1_0
);
2129 mapTokenToNamespace( XML_NAMESPACE_XSD
, XML_NP_XSD
, XML_N_XSD
);
2130 mapTokenToNamespace( XML_NAMESPACE_XSI
, XML_NP_XSI
, XML_N_XSI
);
2131 mapTokenToNamespace( XML_NAMESPACE_SMIL
, XML_NP_SMIL
, XML_N_SMIL
);
2132 mapTokenToNamespace( XML_OLD_NAMESPACE_SMIL
, XML_NP_SMIL
, XML_N_SMIL_OLD
);
2133 mapTokenToNamespace( XML_NAMESPACE_SMIL_COMPAT
, XML_NP_SMIL
, XML_N_SMIL_COMPAT
);
2134 mapTokenToNamespace( XML_NAMESPACE_ANIMATION
, XML_NP_ANIMATION
, XML_N_ANIMATION
);
2135 mapTokenToNamespace( XML_NAMESPACE_REPORT
, XML_NP_RPT
, XML_N_RPT
);
2136 mapTokenToNamespace( XML_NAMESPACE_REPORT_OASIS
, XML_NP_RPT
, XML_N_RPT_OASIS
);
2137 mapTokenToNamespace( XML_NAMESPACE_OF
, XML_NP_OF
, XML_N_OF
);
2138 mapTokenToNamespace( XML_NAMESPACE_XHTML
, XML_NP_XHTML
, XML_N_XHTML
);
2139 mapTokenToNamespace( XML_NAMESPACE_GRDDL
, XML_NP_GRDDL
, XML_N_GRDDL
);
2140 mapTokenToNamespace( XML_NAMESPACE_OFFICE_EXT
, XML_NP_OFFICE_EXT
, XML_N_OFFICE_EXT
);
2141 mapTokenToNamespace( XML_NAMESPACE_TABLE_EXT
, XML_NP_TABLE_EXT
, XML_N_TABLE_EXT
);
2142 mapTokenToNamespace( XML_NAMESPACE_CHART_EXT
, XML_NP_CHART_EXT
, XML_N_CHART_EXT
);
2143 mapTokenToNamespace( XML_NAMESPACE_DRAW_EXT
, XML_NP_DRAW_EXT
, XML_N_DRAW_EXT
);
2144 mapTokenToNamespace( XML_NAMESPACE_CALC_EXT
, XML_NP_CALC_EXT
, XML_N_CALC_EXT
);
2145 mapTokenToNamespace( XML_NAMESPACE_LO_EXT
, XML_NP_LO_EXT
, XML_N_LO_EXT
);
2146 mapTokenToNamespace( XML_NAMESPACE_CSS3TEXT
, XML_NP_CSS3TEXT
, XML_N_CSS3TEXT
);
2147 mapTokenToNamespace( XML_NAMESPACE_FIELD
, XML_NP_FIELD
, XML_N_FIELD
);
2148 mapTokenToNamespace( XML_NAMESPACE_FORMX
, XML_NP_FORMX
, XML_N_FORMX
);
2151 void SvXMLImport::registerNamespaces()
2153 for( auto const &aNamespaceEntry
: aNamespaceMap
)
2155 // aNamespaceMap = { Token : ( NamespacePrefix, NamespaceURI ) }
2156 registerNamespace( aNamespaceEntry
.second
.second
, aNamespaceEntry
.first
<< NMSP_SHIFT
);
2160 void SvXMLImport::NotifyMacroEventRead()
2162 if (mbNotifyMacroEventRead
)
2165 comphelper::DocumentInfo::notifyMacroEventRead(mxModel
);
2167 mbNotifyMacroEventRead
= true;
2170 SvXMLImportFastNamespaceHandler::SvXMLImportFastNamespaceHandler()
2174 void SvXMLImportFastNamespaceHandler::addNSDeclAttributes( rtl::Reference
< comphelper::AttributeList
> const & rAttrList
)
2176 for(const auto& aNamespaceDefine
: m_aNamespaceDefines
)
2178 OUString
& rPrefix
= aNamespaceDefine
->m_aPrefix
;
2179 OUString
& rNamespaceURI
= aNamespaceDefine
->m_aNamespaceURI
;
2181 if ( rPrefix
.isEmpty() )
2184 sDecl
= "xmlns:" + rPrefix
;
2185 rAttrList
->AddAttribute( sDecl
, "CDATA", rNamespaceURI
);
2187 m_aNamespaceDefines
.clear();
2190 void SvXMLImportFastNamespaceHandler::registerNamespace( const OUString
& rNamespacePrefix
, const OUString
& rNamespaceURI
)
2192 // Elements with default namespace parsed by FastParser have namespace prefix.
2193 // A default namespace needs to be registered with the prefix, to maintain the compatibility.
2194 if ( rNamespacePrefix
.isEmpty() )
2195 m_aNamespaceDefines
.push_back( std::make_unique
<NamespaceDefine
>(
2196 SvXMLImport::getNamespacePrefixFromURI( rNamespaceURI
), rNamespaceURI
) );
2198 m_aNamespaceDefines
.push_back( std::make_unique
<NamespaceDefine
>(
2199 rNamespacePrefix
, rNamespaceURI
) );
2202 OUString
SvXMLImportFastNamespaceHandler::getNamespaceURI( const OUString
&/* rNamespacePrefix */ )
2207 SvXMLLegacyToFastDocHandler::SvXMLLegacyToFastDocHandler( const rtl::Reference
< SvXMLImport
> & rImport
)
2208 : mrImport( rImport
),
2209 mxFastAttributes( new sax_fastparser::FastAttributeList( SvXMLImport::xTokenHandler
.get(),
2210 dynamic_cast< sax_fastparser::FastTokenHandlerBase
*>( SvXMLImport::xTokenHandler
.get() ) ) )
2214 void SAL_CALL
SvXMLLegacyToFastDocHandler::setTargetDocument( const uno::Reference
< lang::XComponent
>& xDoc
)
2216 mrImport
->setTargetDocument( xDoc
);
2219 void SAL_CALL
SvXMLLegacyToFastDocHandler::startDocument()
2221 mrImport
->startDocument();
2224 void SAL_CALL
SvXMLLegacyToFastDocHandler::endDocument()
2226 mrImport
->endDocument();
2229 void SAL_CALL
SvXMLLegacyToFastDocHandler::startElement( const OUString
& rName
,
2230 const uno::Reference
< xml::sax::XAttributeList
>& xAttrList
)
2232 mrImport
->processNSAttributes(xAttrList
);
2233 OUString aLocalName
;
2234 sal_uInt16 nPrefix
= mrImport
->mpNamespaceMap
->GetKeyByAttrName( rName
, &aLocalName
);
2235 Sequence
< sal_Int8
> aLocalNameSeq( reinterpret_cast<sal_Int8
const *>(
2236 OUStringToOString( aLocalName
, RTL_TEXTENCODING_UTF8
).getStr()), aLocalName
.getLength() );
2237 sal_Int32 mnElement
= NAMESPACE_TOKEN( nPrefix
) | SvXMLImport::xTokenHandler
->getTokenFromUTF8( aLocalNameSeq
);
2238 mxFastAttributes
->clear();
2240 sal_Int16 nAttrCount
= xAttrList
.is() ? xAttrList
->getLength() : 0;
2241 for( sal_Int16 i
=0; i
< nAttrCount
; i
++ )
2243 OUString aLocalAttrName
;
2244 OUString aNamespace
;
2245 const OUString
& rAttrName
= xAttrList
->getNameByIndex( i
);
2246 const OUString
& rAttrValue
= xAttrList
->getValueByIndex( i
);
2247 sal_uInt16
const nAttrPrefix(mrImport
->mpNamespaceMap
->GetKeyByAttrName(
2248 rAttrName
, nullptr, &aLocalAttrName
, &aNamespace
));
2249 if( XML_NAMESPACE_XMLNS
!= nAttrPrefix
)
2251 Sequence
< sal_Int8
> aAttrSeq( reinterpret_cast<sal_Int8
const *>(
2252 OUStringToOString( aLocalAttrName
, RTL_TEXTENCODING_UTF8
).getStr()), aLocalAttrName
.getLength() );
2253 auto const nToken(SvXMLImport::xTokenHandler
->getTokenFromUTF8(aAttrSeq
));
2254 if (nToken
== xmloff::XML_TOKEN_INVALID
)
2256 mxFastAttributes
->addUnknown(aNamespace
,
2257 OUStringToOString(rAttrName
, RTL_TEXTENCODING_UTF8
),
2258 OUStringToOString(rAttrValue
, RTL_TEXTENCODING_UTF8
));
2262 sal_Int32
const nAttr
= NAMESPACE_TOKEN(nAttrPrefix
) | nToken
;
2263 mxFastAttributes
->add(nAttr
, OUStringToOString(rAttrValue
, RTL_TEXTENCODING_UTF8
).getStr());
2267 mrImport
->startFastElement( mnElement
, mxFastAttributes
.get() );
2270 void SAL_CALL
SvXMLLegacyToFastDocHandler::endElement( const OUString
& rName
)
2272 OUString aLocalName
;
2273 sal_uInt16 nPrefix
= mrImport
->mpNamespaceMap
->GetKeyByAttrName( rName
, &aLocalName
);
2274 Sequence
< sal_Int8
> aLocalNameSeq( reinterpret_cast<sal_Int8
const *>(
2275 OUStringToOString( aLocalName
, RTL_TEXTENCODING_UTF8
).getStr()), aLocalName
.getLength() );
2276 sal_Int32 mnElement
= NAMESPACE_TOKEN( nPrefix
) | SvXMLImport::xTokenHandler
->getTokenFromUTF8( aLocalNameSeq
);
2277 mrImport
->endFastElement( mnElement
);
2280 void SAL_CALL
SvXMLLegacyToFastDocHandler::characters( const OUString
& aChars
)
2282 mrImport
->characters( aChars
);
2285 void SAL_CALL
SvXMLLegacyToFastDocHandler::ignorableWhitespace( const OUString
& aWhitespaces
)
2287 mrImport
->ignorableWhitespace( aWhitespaces
);
2290 void SAL_CALL
SvXMLLegacyToFastDocHandler::processingInstruction( const OUString
& aTarget
,
2291 const OUString
& aData
)
2293 mrImport
->processingInstruction( aTarget
, aData
);
2296 void SAL_CALL
SvXMLLegacyToFastDocHandler::setDocumentLocator( const uno::Reference
< xml::sax::XLocator
>& rLocator
)
2298 mrImport
->setDocumentLocator( rLocator
);
2303 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */