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/.
11 #include <comphelper/processfactory.hxx>
12 #include <cppuhelper/factory.hxx>
13 #include <cppuhelper/implbase.hxx>
14 #include <cppuhelper/supportsservice.hxx>
15 #include <cppuhelper/weak.hxx>
16 #include <osl/diagnose.h>
17 #include <sal/log.hxx>
19 #include <sax/tools/documenthandleradapter.hxx>
21 #include <com/sun/star/lang/XServiceInfo.hpp>
23 #include <com/sun/star/beans/PropertyValue.hpp>
25 #include <com/sun/star/xml/XImportFilter.hpp>
26 #include <com/sun/star/xml/XImportFilter2.hpp>
27 #include <com/sun/star/xml/XExportFilter.hpp>
28 #include <com/sun/star/xml/sax/Parser.hpp>
29 #include <com/sun/star/xml/sax/InputSource.hpp>
30 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
31 #include <com/sun/star/xml/sax/Writer.hpp>
32 #include <com/sun/star/xml/sax/XFastParser.hpp>
34 #include <com/sun/star/io/XInputStream.hpp>
35 #include <com/sun/star/io/XOutputStream.hpp>
36 #include <com/sun/star/io/XActiveDataSource.hpp>
37 #include <com/sun/star/io/XSeekable.hpp>
38 #include <comphelper/diagnose_ex.hxx>
40 using namespace ::cppu
;
41 using namespace ::sax
;
42 using namespace ::com::sun::star::beans
;
43 using namespace ::com::sun::star::io
;
44 using namespace ::com::sun::star::uno
;
45 using namespace ::com::sun::star::lang
;
46 using namespace ::com::sun::star::xml
;
47 using namespace ::com::sun::star::xml::sax
;
49 namespace filter::odfflatxml
{
53 * OdfFlatXml export and imports ODF flat XML documents by plugging a pass-through
54 * filter implementation into XmlFilterAdaptor.
56 class OdfFlatXml
: public WeakImplHelper
<XImportFilter
, XImportFilter2
,
57 XExportFilter
, DocumentHandlerAdapter
, css::lang::XServiceInfo
>
60 Reference
< XComponentContext
> m_xContext
;
64 explicit OdfFlatXml(const Reference
<XComponentContext
> &r
) :
70 virtual sal_Bool SAL_CALL
71 importer(const Sequence
< PropertyValue
>& sourceData
,
72 const Reference
< XDocumentHandler
>& docHandler
,
73 const Sequence
< OUString
>& userData
) override
;
76 virtual sal_Bool SAL_CALL
77 importer(const Sequence
< PropertyValue
>& sourceData
,
78 const Reference
< XFastParser
>& fastParser
,
79 const Sequence
< OUString
>& userData
) override
;
82 virtual sal_Bool SAL_CALL
84 const Sequence
< PropertyValue
>& sourceData
,
85 const Sequence
< OUString
>& userData
) override
;
87 OUString SAL_CALL
getImplementationName() override
88 { return u
"com.sun.star.comp.filter.OdfFlatXml"_ustr
; }
90 sal_Bool SAL_CALL
supportsService(OUString
const & ServiceName
) override
91 { return cppu::supportsService(this, ServiceName
); }
93 css::uno::Sequence
<OUString
> SAL_CALL
getSupportedServiceNames() override
95 return css::uno::Sequence
<OUString
>{
96 u
"com.sun.star.document.ImportFilter"_ustr
,
97 u
"com.sun.star.document.ExportFilter"_ustr
};
105 using namespace ::filter::odfflatxml
;
108 OdfFlatXml::importer(
109 const Sequence
< PropertyValue
>& sourceData
,
110 const Reference
< XDocumentHandler
>& docHandler
,
111 const Sequence
< OUString
>& /* userData */)
113 // Read InputStream to read from and a URL used for the system id
114 // of the InputSource we create from the given sourceData sequence
115 Reference
<XInputStream
> inputStream
;
119 sal_Int32 paramCount
= sourceData
.getLength();
120 for (sal_Int32 paramIdx
= 0; paramIdx
< paramCount
; paramIdx
++)
122 paramName
= sourceData
[paramIdx
].Name
;
123 if ( paramName
== "InputStream" )
124 sourceData
[paramIdx
].Value
>>= inputStream
;
125 else if ( paramName
== "URL" )
126 sourceData
[paramIdx
].Value
>>= url
;
129 OSL_ASSERT(inputStream
.is());
130 if (!inputStream
.is())
133 InputSource inputSource
;
134 inputSource
.sSystemId
= url
;
135 inputSource
.sPublicId
= url
;
136 inputSource
.aInputStream
= inputStream
;
139 css::uno::Reference
< css::io::XSeekable
> xSeekable( inputStream
, css::uno::UNO_QUERY
);
140 if ( xSeekable
.is() )
141 xSeekable
->seek( 0 );
143 css::uno::Reference
< css::xml::sax::XFastParser
> xFastParser (docHandler
, UNO_QUERY
);
144 if( xFastParser
.is() )
145 xFastParser
->parseStream( inputSource
);
148 Reference
<XParser
> saxParser
= Parser::create(m_xContext
);
149 saxParser
->setDocumentHandler(docHandler
);
150 saxParser
->parseStream(inputSource
);
153 catch (const Exception
&)
155 TOOLS_WARN_EXCEPTION("filter.odfflatxml", "");
158 catch (const std::exception
&exc
)
160 SAL_WARN("filter.odfflatxml", exc
.what());
167 OdfFlatXml::importer(
168 const Sequence
< PropertyValue
>& sourceData
,
169 const Reference
< XFastParser
>& xFastParser
,
170 const Sequence
< OUString
>& /* userData */)
172 // Read InputStream to read from and a URL used for the system id
173 // of the InputSource we create from the given sourceData sequence
174 Reference
<XInputStream
> inputStream
;
178 sal_Int32 paramCount
= sourceData
.getLength();
179 for (sal_Int32 paramIdx
= 0; paramIdx
< paramCount
; paramIdx
++)
181 paramName
= sourceData
[paramIdx
].Name
;
182 if ( paramName
== "InputStream" )
183 sourceData
[paramIdx
].Value
>>= inputStream
;
184 else if ( paramName
== "URL" )
185 sourceData
[paramIdx
].Value
>>= url
;
188 OSL_ASSERT(inputStream
.is());
189 if (!inputStream
.is())
192 InputSource inputSource
;
193 inputSource
.sSystemId
= url
;
194 inputSource
.sPublicId
= url
;
195 inputSource
.aInputStream
= inputStream
;
198 css::uno::Reference
< css::io::XSeekable
> xSeekable( inputStream
, css::uno::UNO_QUERY
);
199 if ( xSeekable
.is() )
200 xSeekable
->seek( 0 );
202 xFastParser
->parseStream( inputSource
);
204 catch (const Exception
&)
206 TOOLS_WARN_EXCEPTION("filter.odfflatxml", "");
209 catch (const std::exception
&exc
)
211 SAL_WARN("filter.odfflatxml", exc
.what());
218 OdfFlatXml::exporter(const Sequence
< PropertyValue
>& sourceData
,
219 const Sequence
< OUString
>& /*msUserData*/)
222 Reference
<XOutputStream
> outputStream
;
224 // Read output stream and target URL from the parameters given in sourceData.
225 sal_Int32 paramCount
= sourceData
.getLength();
226 for (sal_Int32 paramIdx
= 0; paramIdx
< paramCount
; paramIdx
++)
228 paramName
= sourceData
[paramIdx
].Name
;
229 if ( paramName
== "OutputStream" )
230 sourceData
[paramIdx
].Value
>>= outputStream
;
233 if (!getDelegate().is())
235 Reference
< XDocumentHandler
> saxWriter
= Writer::create(m_xContext
);
236 setDelegate(saxWriter
);
238 // get data source interface ...
239 Reference
<XActiveDataSource
> dataSource(getDelegate(), UNO_QUERY
);
240 OSL_ASSERT(dataSource
.is());
241 if (!dataSource
.is())
243 OSL_ASSERT(outputStream
.is());
244 if (!outputStream
.is())
246 dataSource
->setOutputStream(outputStream
);
251 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
252 filter_OdfFlatXml_get_implementation(
253 css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const&)
255 return cppu::acquire(new OdfFlatXml(context
));
258 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */