LibreOffice Module filter (master) 1
OdfFlatXml.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 */
9
10
15#include <cppuhelper/weak.hxx>
16#include <osl/diagnose.h>
17#include <sal/log.hxx>
18
20
21#include <com/sun/star/lang/XServiceInfo.hpp>
22
23#include <com/sun/star/beans/PropertyValue.hpp>
24
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>
33
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>
39
40using namespace ::cppu;
41using namespace ::osl;
42using namespace ::sax;
43using namespace ::com::sun::star::beans;
44using namespace ::com::sun::star::io;
45using namespace ::com::sun::star::uno;
46using namespace ::com::sun::star::lang;
47using namespace ::com::sun::star::registry;
48using namespace ::com::sun::star::xml;
49using namespace ::com::sun::star::xml::sax;
50
52 namespace {
53
54 /*
55 * OdfFlatXml export and imports ODF flat XML documents by plugging a pass-through
56 * filter implementation into XmlFilterAdaptor.
57 */
58 class OdfFlatXml : public WeakImplHelper<XImportFilter, XImportFilter2,
59 XExportFilter, DocumentHandlerAdapter, css::lang::XServiceInfo>
60 {
61 private:
62 Reference< XComponentContext > m_xContext;
63
64 public:
65
66 explicit OdfFlatXml(const Reference<XComponentContext> &r) :
67 m_xContext(r)
68 {
69 }
70
71 // XImportFilter
72 virtual sal_Bool SAL_CALL
73 importer(const Sequence< PropertyValue >& sourceData,
74 const Reference< XDocumentHandler >& docHandler,
75 const Sequence< OUString >& userData) override;
76
77 // XImportFilter2
78 virtual sal_Bool SAL_CALL
79 importer(const Sequence< PropertyValue >& sourceData,
80 const Reference< XFastParser >& fastParser,
81 const Sequence< OUString >& userData) override;
82
83 // XExportFilter
84 virtual sal_Bool SAL_CALL
85 exporter(
86 const Sequence< PropertyValue >& sourceData,
87 const Sequence< OUString >& userData) override;
88
89 OUString SAL_CALL getImplementationName() override
90 { return "com.sun.star.comp.filter.OdfFlatXml"; }
91
92 sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override
93 { return cppu::supportsService(this, ServiceName); }
94
95 css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override
96 {
97 return css::uno::Sequence<OUString>{
98 "com.sun.star.document.ImportFilter",
99 "com.sun.star.document.ExportFilter"};
100 }
101
102 };
103
104 }
105}
106
107using namespace ::filter::odfflatxml;
108
110OdfFlatXml::importer(
111 const Sequence< PropertyValue >& sourceData,
112 const Reference< XDocumentHandler >& docHandler,
113 const Sequence< OUString >& /* userData */)
114{
115 // Read InputStream to read from and a URL used for the system id
116 // of the InputSource we create from the given sourceData sequence
117 Reference<XInputStream> inputStream;
118 OUString paramName;
119 OUString url;
120
121 sal_Int32 paramCount = sourceData.getLength();
122 for (sal_Int32 paramIdx = 0; paramIdx < paramCount; paramIdx++)
123 {
124 paramName = sourceData[paramIdx].Name;
125 if ( paramName == "InputStream" )
126 sourceData[paramIdx].Value >>= inputStream;
127 else if ( paramName == "URL" )
128 sourceData[paramIdx].Value >>= url;
129 }
130
131 OSL_ASSERT(inputStream.is());
132 if (!inputStream.is())
133 return false;
134
135 InputSource inputSource;
136 inputSource.sSystemId = url;
137 inputSource.sPublicId = url;
138 inputSource.aInputStream = inputStream;
139 try
140 {
141 css::uno::Reference< css::io::XSeekable > xSeekable( inputStream, css::uno::UNO_QUERY );
142 if ( xSeekable.is() )
143 xSeekable->seek( 0 );
144
145 css::uno::Reference< css::xml::sax::XFastParser > xFastParser (docHandler, UNO_QUERY );
146 if( xFastParser.is() )
147 xFastParser->parseStream( inputSource );
148 else
149 {
150 Reference<XParser> saxParser = Parser::create(m_xContext);
151 saxParser->setDocumentHandler(docHandler);
152 saxParser->parseStream(inputSource);
153 }
154 }
155 catch (const Exception &)
156 {
157 TOOLS_WARN_EXCEPTION("filter.odfflatxml", "");
158 return false;
159 }
160 catch (const std::exception &exc)
161 {
162 SAL_WARN("filter.odfflatxml", exc.what());
163 return false;
164 }
165 return true;
166}
167
169OdfFlatXml::importer(
170 const Sequence< PropertyValue >& sourceData,
171 const Reference< XFastParser >& xFastParser,
172 const Sequence< OUString >& /* userData */)
173{
174 // Read InputStream to read from and a URL used for the system id
175 // of the InputSource we create from the given sourceData sequence
176 Reference<XInputStream> inputStream;
177 OUString paramName;
178 OUString url;
179
180 sal_Int32 paramCount = sourceData.getLength();
181 for (sal_Int32 paramIdx = 0; paramIdx < paramCount; paramIdx++)
182 {
183 paramName = sourceData[paramIdx].Name;
184 if ( paramName == "InputStream" )
185 sourceData[paramIdx].Value >>= inputStream;
186 else if ( paramName == "URL" )
187 sourceData[paramIdx].Value >>= url;
188 }
189
190 OSL_ASSERT(inputStream.is());
191 if (!inputStream.is())
192 return false;
193
194 InputSource inputSource;
195 inputSource.sSystemId = url;
196 inputSource.sPublicId = url;
197 inputSource.aInputStream = inputStream;
198 try
199 {
200 css::uno::Reference< css::io::XSeekable > xSeekable( inputStream, css::uno::UNO_QUERY );
201 if ( xSeekable.is() )
202 xSeekable->seek( 0 );
203
204 xFastParser->parseStream( inputSource );
205 }
206 catch (const Exception &)
207 {
208 TOOLS_WARN_EXCEPTION("filter.odfflatxml", "");
209 return false;
210 }
211 catch (const std::exception &exc)
212 {
213 SAL_WARN("filter.odfflatxml", exc.what());
214 return false;
215 }
216 return true;
217}
218
220OdfFlatXml::exporter(const Sequence< PropertyValue >& sourceData,
221 const Sequence< OUString >& /*msUserData*/)
222{
223 OUString paramName;
224 Reference<XOutputStream> outputStream;
225
226 // Read output stream and target URL from the parameters given in sourceData.
227 sal_Int32 paramCount = sourceData.getLength();
228 for (sal_Int32 paramIdx = 0; paramIdx < paramCount; paramIdx++)
229 {
230 paramName = sourceData[paramIdx].Name;
231 if ( paramName == "OutputStream" )
232 sourceData[paramIdx].Value >>= outputStream;
233 }
234
235 if (!getDelegate().is())
236 {
237 Reference< XDocumentHandler > saxWriter = Writer::create(m_xContext);
238 setDelegate(saxWriter);
239 }
240 // get data source interface ...
241 Reference<XActiveDataSource> dataSource(getDelegate(), UNO_QUERY);
242 OSL_ASSERT(dataSource.is());
243 if (!dataSource.is())
244 return false;
245 OSL_ASSERT(outputStream.is());
246 if (!outputStream.is())
247 return false;
248 dataSource->setOutputStream(outputStream);
249
250 return true;
251}
252
253extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
255 css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&)
256{
257 return cppu::acquire(new OdfFlatXml(context));
258}
259
260/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * filter_OdfFlatXml_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
Definition: OdfFlatXml.cxx:254
Reference< XComponentContext > m_xContext
Definition: OdfFlatXml.cxx:62
#define TOOLS_WARN_EXCEPTION(area, stream)
#define SAL_WARN(area, stream)
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
unsigned char sal_Bool