XmlFilterAdaptor: use the fastparser API when possible
part of the process of making SvXMLImport fastparser-only Which uncovered several bugs because I end up stacking fast and slow parsers, not once, but twice. Specifically, we have a problem here with default namespaces e.g. <math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> <semantics><mrow><mstyle mathsize="12pt"> where going from slow- to fast- parser loses this information, because there is no way to represent this in the fastparser world, so we end up with nastiness when we transition back to slow-parser, and then back-again to fast-parser. So I fixed a couple of places XMLEmbeddedObjectImportContext and in SvXMLLegacyToFastDocHandler, and then worked around some of it by introducing an new XImporter2 interface so I could strip out out one of the slowparser -> fastparser transitions. Change-Id: I491487b99271898da50dc999d3b9b9c39cbd97fd Reviewed-on: https://gerrit.libreoffice.org/c/core/+/104514 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
This commit is contained in:
@@ -32,6 +32,7 @@ $(eval $(call gb_Library_use_libraries,xmlfa,\
|
|||||||
sal \
|
sal \
|
||||||
tl \
|
tl \
|
||||||
utl \
|
utl \
|
||||||
|
xo \
|
||||||
))
|
))
|
||||||
|
|
||||||
$(eval $(call gb_Library_add_exception_objects,xmlfa,\
|
$(eval $(call gb_Library_add_exception_objects,xmlfa,\
|
||||||
|
@@ -24,6 +24,7 @@
|
|||||||
#include <com/sun/star/beans/PropertyValue.hpp>
|
#include <com/sun/star/beans/PropertyValue.hpp>
|
||||||
|
|
||||||
#include <com/sun/star/xml/XImportFilter.hpp>
|
#include <com/sun/star/xml/XImportFilter.hpp>
|
||||||
|
#include <com/sun/star/xml/XImportFilter2.hpp>
|
||||||
#include <com/sun/star/xml/XExportFilter.hpp>
|
#include <com/sun/star/xml/XExportFilter.hpp>
|
||||||
#include <com/sun/star/xml/sax/Parser.hpp>
|
#include <com/sun/star/xml/sax/Parser.hpp>
|
||||||
#include <com/sun/star/xml/sax/InputSource.hpp>
|
#include <com/sun/star/xml/sax/InputSource.hpp>
|
||||||
@@ -55,7 +56,7 @@ namespace filter::odfflatxml {
|
|||||||
* OdfFlatXml export and imports ODF flat XML documents by plugging a pass-through
|
* OdfFlatXml export and imports ODF flat XML documents by plugging a pass-through
|
||||||
* filter implementation into XmlFilterAdaptor.
|
* filter implementation into XmlFilterAdaptor.
|
||||||
*/
|
*/
|
||||||
class OdfFlatXml : public WeakImplHelper<XImportFilter,
|
class OdfFlatXml : public WeakImplHelper<XImportFilter, XImportFilter2,
|
||||||
XExportFilter, DocumentHandlerAdapter, css::lang::XServiceInfo>
|
XExportFilter, DocumentHandlerAdapter, css::lang::XServiceInfo>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@@ -74,6 +75,12 @@ namespace filter::odfflatxml {
|
|||||||
const Reference< XDocumentHandler >& docHandler,
|
const Reference< XDocumentHandler >& docHandler,
|
||||||
const Sequence< OUString >& userData) override;
|
const Sequence< OUString >& userData) override;
|
||||||
|
|
||||||
|
// XImportFilter2
|
||||||
|
virtual sal_Bool SAL_CALL
|
||||||
|
importer(const Sequence< PropertyValue >& sourceData,
|
||||||
|
const Reference< XFastParser >& fastParser,
|
||||||
|
const Sequence< OUString >& userData) override;
|
||||||
|
|
||||||
// XExportFilter
|
// XExportFilter
|
||||||
virtual sal_Bool SAL_CALL
|
virtual sal_Bool SAL_CALL
|
||||||
exporter(
|
exporter(
|
||||||
@@ -126,25 +133,76 @@ OdfFlatXml::importer(
|
|||||||
if (!inputStream.is())
|
if (!inputStream.is())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Reference<XParser> saxParser = Parser::create(m_xContext);
|
|
||||||
|
|
||||||
InputSource inputSource;
|
InputSource inputSource;
|
||||||
inputSource.sSystemId = url;
|
inputSource.sSystemId = url;
|
||||||
inputSource.sPublicId = url;
|
inputSource.sPublicId = url;
|
||||||
inputSource.aInputStream = inputStream;
|
inputSource.aInputStream = inputStream;
|
||||||
css::uno::Reference< css::xml::sax::XFastParser > xFastParser = dynamic_cast<
|
|
||||||
css::xml::sax::XFastParser* >( docHandler.get() );
|
|
||||||
saxParser->setDocumentHandler(docHandler);
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
css::uno::Reference< css::io::XSeekable > xSeekable( inputStream, css::uno::UNO_QUERY );
|
css::uno::Reference< css::io::XSeekable > xSeekable( inputStream, css::uno::UNO_QUERY );
|
||||||
if ( xSeekable.is() )
|
if ( xSeekable.is() )
|
||||||
xSeekable->seek( 0 );
|
xSeekable->seek( 0 );
|
||||||
|
|
||||||
|
css::uno::Reference< css::xml::sax::XFastParser > xFastParser (docHandler, UNO_QUERY );
|
||||||
if( xFastParser.is() )
|
if( xFastParser.is() )
|
||||||
xFastParser->parseStream( inputSource );
|
xFastParser->parseStream( inputSource );
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
Reference<XParser> saxParser = Parser::create(m_xContext);
|
||||||
|
saxParser->setDocumentHandler(docHandler);
|
||||||
saxParser->parseStream(inputSource);
|
saxParser->parseStream(inputSource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (const Exception &)
|
||||||
|
{
|
||||||
|
TOOLS_WARN_EXCEPTION("filter.odfflatxml", "");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch (const std::exception &exc)
|
||||||
|
{
|
||||||
|
SAL_WARN("filter.odfflatxml", exc.what());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
sal_Bool
|
||||||
|
OdfFlatXml::importer(
|
||||||
|
const Sequence< PropertyValue >& sourceData,
|
||||||
|
const Reference< XFastParser >& xFastParser,
|
||||||
|
const Sequence< OUString >& /* userData */)
|
||||||
|
{
|
||||||
|
// Read InputStream to read from and a URL used for the system id
|
||||||
|
// of the InputSource we create from the given sourceData sequence
|
||||||
|
Reference<XInputStream> inputStream;
|
||||||
|
OUString paramName;
|
||||||
|
OUString url;
|
||||||
|
|
||||||
|
sal_Int32 paramCount = sourceData.getLength();
|
||||||
|
for (sal_Int32 paramIdx = 0; paramIdx < paramCount; paramIdx++)
|
||||||
|
{
|
||||||
|
paramName = sourceData[paramIdx].Name;
|
||||||
|
if ( paramName == "InputStream" )
|
||||||
|
sourceData[paramIdx].Value >>= inputStream;
|
||||||
|
else if ( paramName == "URL" )
|
||||||
|
sourceData[paramIdx].Value >>= url;
|
||||||
|
}
|
||||||
|
|
||||||
|
OSL_ASSERT(inputStream.is());
|
||||||
|
if (!inputStream.is())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
InputSource inputSource;
|
||||||
|
inputSource.sSystemId = url;
|
||||||
|
inputSource.sPublicId = url;
|
||||||
|
inputSource.aInputStream = inputStream;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
css::uno::Reference< css::io::XSeekable > xSeekable( inputStream, css::uno::UNO_QUERY );
|
||||||
|
if ( xSeekable.is() )
|
||||||
|
xSeekable->seek( 0 );
|
||||||
|
|
||||||
|
xFastParser->parseStream( inputSource );
|
||||||
}
|
}
|
||||||
catch (const Exception &)
|
catch (const Exception &)
|
||||||
{
|
{
|
||||||
|
@@ -24,8 +24,9 @@
|
|||||||
#include <tools/urlobj.hxx>
|
#include <tools/urlobj.hxx>
|
||||||
#include "XmlFilterAdaptor.hxx"
|
#include "XmlFilterAdaptor.hxx"
|
||||||
#include <com/sun/star/io/XActiveDataSource.hpp>
|
#include <com/sun/star/io/XActiveDataSource.hpp>
|
||||||
#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
|
#include <com/sun/star/xml/sax/XFastDocumentHandler.hpp>
|
||||||
#include <com/sun/star/xml/XImportFilter.hpp>
|
#include <com/sun/star/xml/XImportFilter.hpp>
|
||||||
|
#include <com/sun/star/xml/XImportFilter2.hpp>
|
||||||
#include <com/sun/star/xml/XExportFilter.hpp>
|
#include <com/sun/star/xml/XExportFilter.hpp>
|
||||||
#include <com/sun/star/task/XStatusIndicator.hpp>
|
#include <com/sun/star/task/XStatusIndicator.hpp>
|
||||||
#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
|
#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
|
||||||
@@ -42,6 +43,7 @@
|
|||||||
#include <comphelper/scopeguard.hxx>
|
#include <comphelper/scopeguard.hxx>
|
||||||
#include <cppuhelper/supportsservice.hxx>
|
#include <cppuhelper/supportsservice.hxx>
|
||||||
#include <unotools/pathoptions.hxx>
|
#include <unotools/pathoptions.hxx>
|
||||||
|
#include <xmloff/xmlimp.hxx>
|
||||||
|
|
||||||
using namespace comphelper;
|
using namespace comphelper;
|
||||||
using namespace com::sun::star::uno;
|
using namespace com::sun::star::uno;
|
||||||
@@ -107,12 +109,13 @@ bool XmlFilterAdaptor::importImpl( const Sequence< css::beans::PropertyValue >&
|
|||||||
aAnys[0] <<= xInfoSet;
|
aAnys[0] <<= xInfoSet;
|
||||||
|
|
||||||
|
|
||||||
Reference < XDocumentHandler > xHandler( mxContext->getServiceManager()->createInstanceWithArgumentsAndContext( sXMLImportService, aAnys, mxContext ), UNO_QUERY );
|
// the underlying SvXMLImport implements XFastParser, XImporter, XFastDocumentHandler
|
||||||
if (!xHandler.is()) {
|
Reference < XInterface > xFilter = mxContext->getServiceManager()->createInstanceWithArgumentsAndContext( sXMLImportService, aAnys, mxContext );
|
||||||
SAL_WARN("filter.xmlfa", "XmlFilterAdaptor: unable to create service " << sXMLImportService);
|
assert(xFilter);
|
||||||
return false;
|
Reference < XFastDocumentHandler > xHandler( xFilter, UNO_QUERY );
|
||||||
}
|
assert(xHandler);
|
||||||
Reference < XImporter > xImporter( xHandler, UNO_QUERY );
|
Reference < XImporter > xImporter( xHandler, UNO_QUERY );
|
||||||
|
assert(xImporter);
|
||||||
xImporter->setTargetDocument ( mxDoc );
|
xImporter->setTargetDocument ( mxDoc );
|
||||||
|
|
||||||
if (xStatusIndicator.is()){
|
if (xStatusIndicator.is()){
|
||||||
@@ -122,7 +125,8 @@ bool XmlFilterAdaptor::importImpl( const Sequence< css::beans::PropertyValue >&
|
|||||||
|
|
||||||
// Creating a ConverterBridge instance
|
// Creating a ConverterBridge instance
|
||||||
|
|
||||||
Reference< XInterface > xConvBridge(mxContext->getServiceManager()->createInstanceWithContext(udConvertClass, mxContext), UNO_QUERY);
|
Reference< XInterface > xConvBridge(
|
||||||
|
mxContext->getServiceManager()->createInstanceWithContext(udConvertClass, mxContext), UNO_QUERY);
|
||||||
if (!xConvBridge.is()) {
|
if (!xConvBridge.is()) {
|
||||||
SAL_WARN("filter.xmlfa", "XmlFilterAdaptor: unable to create service " << udConvertClass);
|
SAL_WARN("filter.xmlfa", "XmlFilterAdaptor: unable to create service " << udConvertClass);
|
||||||
return false;
|
return false;
|
||||||
@@ -130,7 +134,8 @@ bool XmlFilterAdaptor::importImpl( const Sequence< css::beans::PropertyValue >&
|
|||||||
if (xStatusIndicator.is())
|
if (xStatusIndicator.is())
|
||||||
xStatusIndicator->setValue(nSteps++);
|
xStatusIndicator->setValue(nSteps++);
|
||||||
|
|
||||||
Reference< XImportFilter > xConverter( xConvBridge, UNO_QUERY );
|
Reference< XImportFilter > xConverter1( xConvBridge, UNO_QUERY );
|
||||||
|
Reference< XImportFilter2 > xConverter2( xConvBridge, UNO_QUERY );
|
||||||
|
|
||||||
// prevent unnecessary broadcasting when loading
|
// prevent unnecessary broadcasting when loading
|
||||||
Reference< XModel > xModel( mxDoc, UNO_QUERY );
|
Reference< XModel > xModel( mxDoc, UNO_QUERY );
|
||||||
@@ -170,10 +175,24 @@ bool XmlFilterAdaptor::importImpl( const Sequence< css::beans::PropertyValue >&
|
|||||||
// Calling Filtering Component
|
// Calling Filtering Component
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!xConverter->importer(aDescriptor,xHandler,msUserData)) {
|
auto pImport = dynamic_cast<SvXMLImport*>(xHandler.get());
|
||||||
if (xStatusIndicator.is())
|
assert(pImport);
|
||||||
xStatusIndicator->end();
|
if (xConverter2)
|
||||||
return false;
|
{
|
||||||
|
if (!xConverter2->importer(aDescriptor,pImport,msUserData)) {
|
||||||
|
if (xStatusIndicator.is())
|
||||||
|
xStatusIndicator->end();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Reference<XDocumentHandler> xDocHandler = new SvXMLLegacyToFastDocHandler(pImport);
|
||||||
|
if (!xConverter1->importer(aDescriptor,xDocHandler,msUserData)) {
|
||||||
|
if (xStatusIndicator.is())
|
||||||
|
xStatusIndicator->end();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch( const Exception& )
|
catch( const Exception& )
|
||||||
|
@@ -47,6 +47,7 @@
|
|||||||
#include <com/sun/star/xml/sax/XFastParser.hpp>
|
#include <com/sun/star/xml/sax/XFastParser.hpp>
|
||||||
#include <com/sun/star/xml/sax/Writer.hpp>
|
#include <com/sun/star/xml/sax/Writer.hpp>
|
||||||
#include <com/sun/star/xml/XImportFilter.hpp>
|
#include <com/sun/star/xml/XImportFilter.hpp>
|
||||||
|
#include <com/sun/star/xml/XImportFilter2.hpp>
|
||||||
#include <com/sun/star/xml/XExportFilter.hpp>
|
#include <com/sun/star/xml/XExportFilter.hpp>
|
||||||
|
|
||||||
#include <com/sun/star/util/theMacroExpander.hpp>
|
#include <com/sun/star/util/theMacroExpander.hpp>
|
||||||
@@ -97,7 +98,7 @@ namespace XSLT
|
|||||||
* supporting service from an extension for a specific filter; the
|
* supporting service from an extension for a specific filter; the
|
||||||
* service must support com.sun.star.xml.xslt.XSLT2Transformer.
|
* service must support com.sun.star.xml.xslt.XSLT2Transformer.
|
||||||
*/
|
*/
|
||||||
class XSLTFilter : public WeakImplHelper<XImportFilter, XExportFilter,
|
class XSLTFilter : public WeakImplHelper<XImportFilter, XImportFilter2, XExportFilter,
|
||||||
XStreamListener, ExtendedDocumentHandlerAdapter, XServiceInfo>
|
XStreamListener, ExtendedDocumentHandlerAdapter, XServiceInfo>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@@ -151,6 +152,12 @@ namespace XSLT
|
|||||||
XDocumentHandler>& xHandler,
|
XDocumentHandler>& xHandler,
|
||||||
const Sequence<OUString>& msUserData) override;
|
const Sequence<OUString>& msUserData) override;
|
||||||
|
|
||||||
|
// XImportFilter2
|
||||||
|
virtual sal_Bool SAL_CALL
|
||||||
|
importer(const Sequence<PropertyValue>& aSourceData, const css::uno::Reference<
|
||||||
|
XFastParser>& xFastParser,
|
||||||
|
const Sequence<OUString>& msUserData) override;
|
||||||
|
|
||||||
// XExportFilter
|
// XExportFilter
|
||||||
virtual sal_Bool SAL_CALL
|
virtual sal_Bool SAL_CALL
|
||||||
exporter(const Sequence<PropertyValue>& aSourceData, const Sequence<
|
exporter(const Sequence<PropertyValue>& aSourceData, const Sequence<
|
||||||
@@ -314,10 +321,6 @@ namespace XSLT
|
|||||||
if (!xInputStream.is())
|
if (!xInputStream.is())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// create SAX parser that will read the document file
|
|
||||||
// and provide events to xHandler passed to this call
|
|
||||||
css::uno::Reference<XParser> xSaxParser = Parser::create(m_xContext);
|
|
||||||
|
|
||||||
// create transformer
|
// create transformer
|
||||||
Sequence<Any> args(3);
|
Sequence<Any> args(3);
|
||||||
NamedValue nv;
|
NamedValue nv;
|
||||||
@@ -366,8 +369,6 @@ namespace XSLT
|
|||||||
aInput.sPublicId = aURL;
|
aInput.sPublicId = aURL;
|
||||||
aInput.aInputStream = pipein;
|
aInput.aInputStream = pipein;
|
||||||
|
|
||||||
// set doc handler
|
|
||||||
xSaxParser->setDocumentHandler(xHandler);
|
|
||||||
css::uno::Reference< css::xml::sax::XFastParser > xFastParser = dynamic_cast<
|
css::uno::Reference< css::xml::sax::XFastParser > xFastParser = dynamic_cast<
|
||||||
css::xml::sax::XFastParser* >( xHandler.get() );
|
css::xml::sax::XFastParser* >( xHandler.get() );
|
||||||
|
|
||||||
@@ -404,7 +405,14 @@ namespace XSLT
|
|||||||
if( xFastParser.is() )
|
if( xFastParser.is() )
|
||||||
xFastParser->parseStream( aInput );
|
xFastParser->parseStream( aInput );
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
// create SAX parser that will read the document file
|
||||||
|
// and provide events to xHandler passed to this call
|
||||||
|
css::uno::Reference<XParser> xSaxParser = Parser::create(m_xContext);
|
||||||
|
// set doc handler
|
||||||
|
xSaxParser->setDocumentHandler(xHandler);
|
||||||
xSaxParser->parseStream( aInput );
|
xSaxParser->parseStream( aInput );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
m_tcontrol->terminate();
|
m_tcontrol->terminate();
|
||||||
return !m_bError;
|
return !m_bError;
|
||||||
@@ -422,6 +430,134 @@ namespace XSLT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sal_Bool
|
||||||
|
XSLTFilter::importer(const Sequence<PropertyValue>& aSourceData,
|
||||||
|
const css::uno::Reference<XFastParser>& xFastParser, const Sequence<
|
||||||
|
OUString>& msUserData)
|
||||||
|
{
|
||||||
|
if (msUserData.getLength() < 5)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
OUString udStyleSheet = rel2abs(msUserData[4]);
|
||||||
|
|
||||||
|
// get information from media descriptor
|
||||||
|
// the input stream that represents the imported file
|
||||||
|
// is most important here since we need to supply it to
|
||||||
|
// the sax parser that drives the supplied document handler
|
||||||
|
sal_Int32 nLength = aSourceData.getLength();
|
||||||
|
OUString aName, aURL;
|
||||||
|
css::uno::Reference<XInputStream> xInputStream;
|
||||||
|
css::uno::Reference<XInteractionHandler> xInterActionHandler;
|
||||||
|
for (sal_Int32 i = 0; i < nLength; i++)
|
||||||
|
{
|
||||||
|
aName = aSourceData[i].Name;
|
||||||
|
Any value = aSourceData[i].Value;
|
||||||
|
if ( aName == "InputStream" )
|
||||||
|
value >>= xInputStream;
|
||||||
|
else if ( aName == "URL" )
|
||||||
|
value >>= aURL;
|
||||||
|
else if ( aName == "InteractionHandler" )
|
||||||
|
value >>= xInterActionHandler;
|
||||||
|
}
|
||||||
|
OSL_ASSERT(xInputStream.is());
|
||||||
|
if (!xInputStream.is())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// create transformer
|
||||||
|
Sequence<Any> args(3);
|
||||||
|
NamedValue nv;
|
||||||
|
|
||||||
|
nv.Name = "StylesheetURL";
|
||||||
|
nv.Value <<= expandUrl(udStyleSheet);
|
||||||
|
args[0] <<= nv;
|
||||||
|
nv.Name = "SourceURL";
|
||||||
|
nv.Value <<= aURL;
|
||||||
|
args[1] <<= nv;
|
||||||
|
nv.Name = "SourceBaseURL";
|
||||||
|
nv.Value <<= INetURLObject(aURL).getBase();
|
||||||
|
args[2] <<= nv;
|
||||||
|
|
||||||
|
m_tcontrol = impl_createTransformer(msUserData[1], args);
|
||||||
|
|
||||||
|
assert(xFastParser.is());
|
||||||
|
OSL_ASSERT(xInputStream.is());
|
||||||
|
OSL_ASSERT(m_tcontrol.is());
|
||||||
|
if (xFastParser.is() && xInputStream.is() && m_tcontrol.is())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
css::uno::Reference<css::io::XSeekable> xSeek(xInputStream, UNO_QUERY);
|
||||||
|
if (xSeek.is())
|
||||||
|
xSeek->seek(0);
|
||||||
|
|
||||||
|
// we want to be notified when the processing is done...
|
||||||
|
m_tcontrol->addListener(css::uno::Reference<XStreamListener> (
|
||||||
|
this));
|
||||||
|
|
||||||
|
// connect input to transformer
|
||||||
|
m_tcontrol->setInputStream(xInputStream);
|
||||||
|
|
||||||
|
// create pipe
|
||||||
|
css::uno::Reference<XOutputStream> pipeout =
|
||||||
|
Pipe::create(m_xContext);
|
||||||
|
css::uno::Reference<XInputStream> pipein(pipeout, UNO_QUERY);
|
||||||
|
|
||||||
|
//connect transformer to pipe
|
||||||
|
m_tcontrol->setOutputStream(pipeout);
|
||||||
|
|
||||||
|
// connect pipe to sax parser
|
||||||
|
InputSource aInput;
|
||||||
|
aInput.sSystemId = aURL;
|
||||||
|
aInput.sPublicId = aURL;
|
||||||
|
aInput.aInputStream = pipein;
|
||||||
|
|
||||||
|
// transform
|
||||||
|
m_tcontrol->start();
|
||||||
|
TimeValue timeout = { TRANSFORMATION_TIMEOUT_SEC, 0};
|
||||||
|
osl::Condition::Result result(m_cTransformed.wait(&timeout));
|
||||||
|
while (osl::Condition::result_timeout == result) {
|
||||||
|
if (xInterActionHandler.is()) {
|
||||||
|
Sequence<Any> excArgs(0);
|
||||||
|
css::ucb::InteractiveAugmentedIOException exc(
|
||||||
|
"Timeout!",
|
||||||
|
static_cast< OWeakObject * >( this ),
|
||||||
|
InteractionClassification_ERROR,
|
||||||
|
css::ucb::IOErrorCode_GENERAL,
|
||||||
|
excArgs);
|
||||||
|
Any r;
|
||||||
|
r <<= exc;
|
||||||
|
::comphelper::OInteractionRequest* pRequest = new ::comphelper::OInteractionRequest(r);
|
||||||
|
css::uno::Reference< XInteractionRequest > xRequest(pRequest);
|
||||||
|
::comphelper::OInteractionRetry* pRetry = new ::comphelper::OInteractionRetry;
|
||||||
|
::comphelper::OInteractionAbort* pAbort = new ::comphelper::OInteractionAbort;
|
||||||
|
pRequest->addContinuation(pRetry);
|
||||||
|
pRequest->addContinuation(pAbort);
|
||||||
|
xInterActionHandler->handle(xRequest);
|
||||||
|
if (pAbort->wasSelected()) {
|
||||||
|
m_bError = true;
|
||||||
|
m_cTransformed.set();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result = m_cTransformed.wait(&timeout);
|
||||||
|
};
|
||||||
|
if (!m_bError)
|
||||||
|
xFastParser->parseStream( aInput );
|
||||||
|
m_tcontrol->terminate();
|
||||||
|
return !m_bError;
|
||||||
|
}
|
||||||
|
catch( const Exception& )
|
||||||
|
{
|
||||||
|
// something went wrong
|
||||||
|
TOOLS_WARN_EXCEPTION("filter.xslt", "");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sal_Bool
|
sal_Bool
|
||||||
XSLTFilter::exporter(const Sequence<PropertyValue>& aSourceData,
|
XSLTFilter::exporter(const Sequence<PropertyValue>& aSourceData,
|
||||||
const Sequence<OUString>& msUserData)
|
const Sequence<OUString>& msUserData)
|
||||||
|
@@ -151,6 +151,7 @@ class XMLOFF_DLLPUBLIC SvXMLLegacyToFastDocHandler final : public ::cppu::WeakIm
|
|||||||
private:
|
private:
|
||||||
rtl::Reference< SvXMLImport > mrImport;
|
rtl::Reference< SvXMLImport > mrImport;
|
||||||
rtl::Reference< sax_fastparser::FastAttributeList > mxFastAttributes;
|
rtl::Reference< sax_fastparser::FastAttributeList > mxFastAttributes;
|
||||||
|
std::stack<sal_uInt16> maDefaultNamespaces;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SvXMLLegacyToFastDocHandler( const rtl::Reference< SvXMLImport > & rImport );
|
SvXMLLegacyToFastDocHandler( const rtl::Reference< SvXMLImport > & rImport );
|
||||||
|
@@ -4245,6 +4245,7 @@ $(eval $(call gb_UnoApi_add_idlfiles,offapi,com/sun/star/xml,\
|
|||||||
FastAttribute \
|
FastAttribute \
|
||||||
XExportFilter \
|
XExportFilter \
|
||||||
XImportFilter \
|
XImportFilter \
|
||||||
|
XImportFilter2 \
|
||||||
))
|
))
|
||||||
$(eval $(call gb_UnoApi_add_idlfiles,offapi,com/sun/star/xml/crypto,\
|
$(eval $(call gb_UnoApi_add_idlfiles,offapi,com/sun/star/xml/crypto,\
|
||||||
CipherID \
|
CipherID \
|
||||||
|
71
offapi/com/sun/star/xml/XImportFilter2.idl
Normal file
71
offapi/com/sun/star/xml/XImportFilter2.idl
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||||
|
/*
|
||||||
|
* This file is part of the LibreOffice project.
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*
|
||||||
|
* This file incorporates work covered by the following license notice:
|
||||||
|
*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed
|
||||||
|
* with this work for additional information regarding copyright
|
||||||
|
* ownership. The ASF licenses this file to you under the Apache
|
||||||
|
* License, Version 2.0 (the "License"); you may not use this file
|
||||||
|
* except in compliance with the License. You may obtain a copy of
|
||||||
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _COM_SUN_STAR_XML_XIMPORTFILTER2_IDL__
|
||||||
|
#define _COM_SUN_STAR_XML_XIMPORTFILTER2_IDL__
|
||||||
|
|
||||||
|
#include <com/sun/star/uno/RuntimeException.idl>
|
||||||
|
#include <com/sun/star/uno/XInterface.idl>
|
||||||
|
#include <com/sun/star/beans/PropertyValue.idl>
|
||||||
|
#include <com/sun/star/xml/sax/XFastParser.idl>
|
||||||
|
#include <com/sun/star/lang/IllegalArgumentException.idl>
|
||||||
|
|
||||||
|
|
||||||
|
module com { module sun { module star { module xml {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** interface to implement for an XML-based import filter.
|
||||||
|
Enhanced vs XImportFilter to take a XFastDocumentHandler.
|
||||||
|
|
||||||
|
@since LibreOffice 7.1
|
||||||
|
*/
|
||||||
|
interface XImportFilter2: com::sun::star::uno::XInterface
|
||||||
|
{
|
||||||
|
/** performs the import.
|
||||||
|
|
||||||
|
<p>The source data (location indicated by <var>aSourceData</var>),
|
||||||
|
and the XML representation of the document must be generated by calls
|
||||||
|
to xocHandler (???) methods.
|
||||||
|
|
||||||
|
@param aSourceData
|
||||||
|
com::sun::star::document::MediaDescriptor
|
||||||
|
which defines the data source
|
||||||
|
|
||||||
|
@param msUserData
|
||||||
|
Sequence of strings which contains the user data defined in the
|
||||||
|
TypeDetection.xml
|
||||||
|
|
||||||
|
@param xFastParser
|
||||||
|
the fast parser for the XML document, i.e. an SvXMLImport subclass
|
||||||
|
|
||||||
|
@returns
|
||||||
|
`TRUE` if import process is successful
|
||||||
|
*/
|
||||||
|
boolean importer(
|
||||||
|
[in] sequence< com::sun::star::beans::PropertyValue > aSourceData,
|
||||||
|
[in] com::sun::star::xml::sax::XFastParser xFastParser,
|
||||||
|
[in] sequence< string > msUserData )
|
||||||
|
raises( com::sun::star::lang::IllegalArgumentException );
|
||||||
|
};
|
||||||
|
|
||||||
|
}; }; }; };
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
@@ -260,7 +260,7 @@ void XMLEmbeddedObjectImportContext::StartElement(
|
|||||||
sal_uInt16 nPos = rNamespaceMap.GetFirstKey();
|
sal_uInt16 nPos = rNamespaceMap.GetFirstKey();
|
||||||
while( USHRT_MAX != nPos )
|
while( USHRT_MAX != nPos )
|
||||||
{
|
{
|
||||||
OUString aAttrName( rNamespaceMap.GetAttrNameByKey( nPos ) );
|
OUString aAttrName = "xmlns:" + rNamespaceMap.GetPrefixByKey( nPos );
|
||||||
if( xAttrList->getValueByName( aAttrName ).isEmpty() )
|
if( xAttrList->getValueByName( aAttrName ).isEmpty() )
|
||||||
{
|
{
|
||||||
pAttrList->AddAttribute( aAttrName,
|
pAttrList->AddAttribute( aAttrName,
|
||||||
|
@@ -2248,6 +2248,9 @@ void SAL_CALL SvXMLLegacyToFastDocHandler::endDocument()
|
|||||||
void SAL_CALL SvXMLLegacyToFastDocHandler::startElement( const OUString& rName,
|
void SAL_CALL SvXMLLegacyToFastDocHandler::startElement( const OUString& rName,
|
||||||
const uno::Reference< xml::sax::XAttributeList >& xAttrList )
|
const uno::Reference< xml::sax::XAttributeList >& xAttrList )
|
||||||
{
|
{
|
||||||
|
sal_uInt16 nDefaultNamespace = XML_NAMESPACE_UNKNOWN;
|
||||||
|
if (!maDefaultNamespaces.empty())
|
||||||
|
nDefaultNamespace = maDefaultNamespaces.top();
|
||||||
mrImport->processNSAttributes(xAttrList);
|
mrImport->processNSAttributes(xAttrList);
|
||||||
OUString aLocalName;
|
OUString aLocalName;
|
||||||
sal_uInt16 nPrefix = mrImport->mpNamespaceMap->GetKeyByAttrName( rName, &aLocalName );
|
sal_uInt16 nPrefix = mrImport->mpNamespaceMap->GetKeyByAttrName( rName, &aLocalName );
|
||||||
@@ -2257,30 +2260,57 @@ void SAL_CALL SvXMLLegacyToFastDocHandler::startElement( const OUString& rName,
|
|||||||
sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
|
sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
|
||||||
for( sal_Int16 i=0; i < nAttrCount; i++ )
|
for( sal_Int16 i=0; i < nAttrCount; i++ )
|
||||||
{
|
{
|
||||||
OUString aLocalAttrName;
|
|
||||||
OUString aNamespace;
|
|
||||||
const OUString& rAttrName = xAttrList->getNameByIndex( i );
|
const OUString& rAttrName = xAttrList->getNameByIndex( i );
|
||||||
const OUString& rAttrValue = xAttrList->getValueByIndex( i );
|
const OUString& rAttrValue = xAttrList->getValueByIndex( i );
|
||||||
// don't add unknown namespaces to the map
|
if (rAttrName == "xmlns")
|
||||||
sal_uInt16 const nAttrPrefix = mrImport->mpNamespaceMap->GetKeyByQName(
|
|
||||||
rAttrName, nullptr, &aLocalAttrName, &aNamespace, SvXMLNamespaceMap::QNameMode::AttrValue);
|
|
||||||
if( XML_NAMESPACE_XMLNS != nAttrPrefix )
|
|
||||||
{
|
{
|
||||||
auto const nToken = SvXMLImport::getTokenFromName(aLocalAttrName);
|
sal_uInt16 nNamespaceKey = mrImport->mpNamespaceMap->GetKeyByName(rAttrValue);
|
||||||
if (XML_NAMESPACE_UNKNOWN == nAttrPrefix || nToken == xmloff::XML_TOKEN_INVALID)
|
if (nNamespaceKey != XML_NAMESPACE_UNKNOWN)
|
||||||
{
|
{
|
||||||
mxFastAttributes->addUnknown(aNamespace,
|
nDefaultNamespace = nNamespaceKey;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
assert(false && "unknown namespace");
|
||||||
|
}
|
||||||
|
else if (rAttrName.indexOf(":") == -1 && nDefaultNamespace != XML_NAMESPACE_UNKNOWN)
|
||||||
|
{
|
||||||
|
auto const nToken = SvXMLImport::getTokenFromName(rAttrName);
|
||||||
|
if (nToken == xmloff::XML_TOKEN_INVALID)
|
||||||
|
{
|
||||||
|
mxFastAttributes->addUnknown(mrImport->mpNamespaceMap->GetNameByKey(nDefaultNamespace),
|
||||||
OUStringToOString(rAttrName, RTL_TEXTENCODING_UTF8),
|
OUStringToOString(rAttrName, RTL_TEXTENCODING_UTF8),
|
||||||
OUStringToOString(rAttrValue, RTL_TEXTENCODING_UTF8));
|
OUStringToOString(rAttrValue, RTL_TEXTENCODING_UTF8));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sal_Int32 const nAttr = NAMESPACE_TOKEN(nAttrPrefix) | nToken;
|
sal_Int32 const nAttr = NAMESPACE_TOKEN(nDefaultNamespace) | nToken;
|
||||||
mxFastAttributes->add(nAttr, OUStringToOString(rAttrValue, RTL_TEXTENCODING_UTF8).getStr());
|
mxFastAttributes->add(nAttr, OUStringToOString(rAttrValue, RTL_TEXTENCODING_UTF8).getStr());
|
||||||
}
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
OUString aLocalAttrName;
|
||||||
|
OUString aNamespace;
|
||||||
|
// don't add unknown namespaces to the map
|
||||||
|
sal_uInt16 const nAttrPrefix = mrImport->mpNamespaceMap->GetKeyByQName(
|
||||||
|
rAttrName, nullptr, &aLocalAttrName, &aNamespace, SvXMLNamespaceMap::QNameMode::AttrValue);
|
||||||
|
if( XML_NAMESPACE_XMLNS == nAttrPrefix )
|
||||||
|
continue; // ignore
|
||||||
|
auto const nToken = SvXMLImport::getTokenFromName(aLocalAttrName);
|
||||||
|
if (XML_NAMESPACE_UNKNOWN == nAttrPrefix || nToken == xmloff::XML_TOKEN_INVALID)
|
||||||
|
{
|
||||||
|
mxFastAttributes->addUnknown(aNamespace,
|
||||||
|
OUStringToOString(rAttrName, RTL_TEXTENCODING_UTF8),
|
||||||
|
OUStringToOString(rAttrValue, RTL_TEXTENCODING_UTF8));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sal_Int32 const nAttr = NAMESPACE_TOKEN(nAttrPrefix) | nToken;
|
||||||
|
mxFastAttributes->add(nAttr, OUStringToOString(rAttrValue, RTL_TEXTENCODING_UTF8).getStr());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mrImport->startFastElement( mnElement, mxFastAttributes.get() );
|
mrImport->startFastElement( mnElement, mxFastAttributes.get() );
|
||||||
|
maDefaultNamespaces.push(nDefaultNamespace);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SAL_CALL SvXMLLegacyToFastDocHandler::endElement( const OUString& rName )
|
void SAL_CALL SvXMLLegacyToFastDocHandler::endElement( const OUString& rName )
|
||||||
@@ -2289,6 +2319,7 @@ void SAL_CALL SvXMLLegacyToFastDocHandler::endElement( const OUString& rName )
|
|||||||
sal_uInt16 nPrefix = mrImport->mpNamespaceMap->GetKeyByAttrName( rName, &aLocalName );
|
sal_uInt16 nPrefix = mrImport->mpNamespaceMap->GetKeyByAttrName( rName, &aLocalName );
|
||||||
sal_Int32 mnElement = NAMESPACE_TOKEN( nPrefix ) | SvXMLImport::getTokenFromName(aLocalName);
|
sal_Int32 mnElement = NAMESPACE_TOKEN( nPrefix ) | SvXMLImport::getTokenFromName(aLocalName);
|
||||||
mrImport->endFastElement( mnElement );
|
mrImport->endFastElement( mnElement );
|
||||||
|
maDefaultNamespaces.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SAL_CALL SvXMLLegacyToFastDocHandler::characters( const OUString& aChars )
|
void SAL_CALL SvXMLLegacyToFastDocHandler::characters( const OUString& aChars )
|
||||||
|
Reference in New Issue
Block a user