Line data Source code
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 :
11 : #include <comphelper/processfactory.hxx>
12 : #include <cppuhelper/factory.hxx>
13 : #include <cppuhelper/implbase.hxx>
14 : #include <cppuhelper/supportsservice.hxx>
15 : #include <osl/diagnose.h>
16 :
17 : #include <sax/tools/documenthandleradapter.hxx>
18 :
19 : #include <com/sun/star/lang/XComponent.hpp>
20 : #include <com/sun/star/lang/XServiceInfo.hpp>
21 : #include <com/sun/star/uno/Any.hxx>
22 : #include <com/sun/star/uno/Type.hxx>
23 :
24 : #include <com/sun/star/beans/PropertyValue.hpp>
25 :
26 : #include <com/sun/star/xml/XImportFilter.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/XExtendedDocumentHandler.hpp>
32 : #include <com/sun/star/xml/sax/SAXException.hpp>
33 : #include <com/sun/star/xml/sax/Writer.hpp>
34 :
35 : #include <com/sun/star/io/XInputStream.hpp>
36 : #include <com/sun/star/io/XOutputStream.hpp>
37 : #include <com/sun/star/io/XActiveDataSource.hpp>
38 : #include <com/sun/star/io/XSeekable.hpp>
39 :
40 : using namespace ::cppu;
41 : using namespace ::osl;
42 : using namespace ::sax;
43 : using namespace ::com::sun::star::beans;
44 : using namespace ::com::sun::star::io;
45 : using namespace ::com::sun::star::uno;
46 : using namespace ::com::sun::star::lang;
47 : using namespace ::com::sun::star::registry;
48 : using namespace ::com::sun::star::xml;
49 : using namespace ::com::sun::star::xml::sax;
50 :
51 : namespace filter {
52 : namespace odfflatxml {
53 : /*
54 : * OdfFlatXml export and imports ODF flat XML documents by plugging a pass-through
55 : * filter implementation into XmlFilterAdaptor.
56 : */
57 14 : class OdfFlatXml : public WeakImplHelper<XImportFilter,
58 : XExportFilter, DocumentHandlerAdapter, css::lang::XServiceInfo>
59 : {
60 : private:
61 : Reference< XComponentContext > m_xContext;
62 :
63 : public:
64 :
65 7 : OdfFlatXml(const Reference<XComponentContext> &r) :
66 7 : m_xContext(r)
67 : {
68 7 : }
69 :
70 : // XImportFilter
71 : virtual sal_Bool SAL_CALL
72 : importer(const Sequence< PropertyValue >& sourceData,
73 : const Reference< XDocumentHandler >& docHandler,
74 : const Sequence< OUString >& userData)
75 : throw (IllegalArgumentException, RuntimeException, std::exception) SAL_OVERRIDE;
76 :
77 : // XExportFilter
78 : virtual sal_Bool SAL_CALL
79 : exporter(
80 : const Sequence< PropertyValue >& sourceData,
81 : const Sequence< OUString >& userData)
82 : throw (IllegalArgumentException,
83 : RuntimeException, std::exception) SAL_OVERRIDE;
84 :
85 1 : OUString SAL_CALL getImplementationName()
86 : throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
87 1 : { return OUString("com.sun.star.comp.filter.OdfFlatXml"); }
88 :
89 0 : sal_Bool SAL_CALL supportsService(OUString const & ServiceName)
90 : throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
91 0 : { return cppu::supportsService(this, ServiceName); }
92 :
93 1 : css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames()
94 : throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
95 : {
96 : return css::uno::Sequence<OUString>{
97 : "com.sun.star.document.ImportFilter",
98 1 : "com.sun.star.document.ExportFilter"};
99 : }
100 :
101 : // UNO component helper methods
102 :
103 : static OUString impl_getImplementationName();
104 :
105 : static Sequence< OUString > impl_getSupportedServiceNames();
106 :
107 : static Reference< XInterface > impl_createInstance(const Reference< XMultiServiceFactory >& fact);
108 : };
109 : }
110 : }
111 :
112 : using namespace ::filter::odfflatxml;
113 :
114 : sal_Bool
115 13 : OdfFlatXml::importer(
116 : const Sequence< PropertyValue >& sourceData,
117 : const Reference< XDocumentHandler >& docHandler,
118 : const Sequence< OUString >& /* userData */)
119 : throw (IllegalArgumentException, RuntimeException, std::exception)
120 : {
121 : // Read InputStream to read from and an URL used for the system id
122 : // of the InputSource we create from the given sourceData sequence
123 13 : Reference<XInputStream> inputStream;
124 26 : OUString paramName;
125 26 : OUString url;
126 :
127 13 : sal_Int32 paramCount = sourceData.getLength();
128 156 : for (sal_Int32 paramIdx = 0; paramIdx < paramCount; paramIdx++)
129 : {
130 143 : paramName = sourceData[paramIdx].Name;
131 143 : if ( paramName == "InputStream" )
132 13 : sourceData[paramIdx].Value >>= inputStream;
133 130 : else if ( paramName == "URL" )
134 13 : sourceData[paramIdx].Value >>= url;
135 : }
136 :
137 : OSL_ASSERT(inputStream.is());
138 13 : if (!inputStream.is())
139 0 : return sal_False;
140 :
141 26 : Reference<XParser> saxParser = Parser::create(m_xContext);
142 :
143 26 : InputSource inputSource;
144 13 : inputSource.sSystemId = url;
145 13 : inputSource.sPublicId = url;
146 13 : inputSource.aInputStream = inputStream;
147 13 : saxParser->setDocumentHandler(docHandler);
148 : try
149 : {
150 13 : saxParser->parseStream(inputSource);
151 : }
152 0 : catch (const Exception &exc)
153 : {
154 : SAL_WARN(
155 : "filter.odfflatxml",
156 : "caught exception \"" << exc.Message << "\"");
157 0 : return sal_False;
158 : }
159 26 : return sal_True;
160 : }
161 :
162 : sal_Bool
163 0 : OdfFlatXml::exporter(const Sequence< PropertyValue >& sourceData,
164 : const Sequence< OUString >& /*msUserData*/)
165 : throw (IllegalArgumentException, RuntimeException, std::exception)
166 : {
167 0 : OUString paramName;
168 0 : OUString targetURL;
169 0 : Reference<XOutputStream> outputStream;
170 :
171 : // Read output stream and target URL from the parameters given in sourceData.
172 0 : sal_Int32 paramCount = sourceData.getLength();
173 0 : for (sal_Int32 paramIdx = 0; paramIdx < paramCount; paramIdx++)
174 : {
175 0 : paramName = sourceData[paramIdx].Name;
176 0 : if ( paramName == "OutputStream" )
177 0 : sourceData[paramIdx].Value >>= outputStream;
178 0 : else if ( paramName == "URL" )
179 0 : sourceData[paramIdx].Value >>= targetURL;
180 : }
181 :
182 0 : if (!getDelegate().is())
183 : {
184 0 : Reference< XDocumentHandler > saxWriter = Writer::create(m_xContext);
185 0 : setDelegate(saxWriter);
186 : }
187 : // get data source interface ...
188 0 : Reference<XActiveDataSource> dataSource(getDelegate(), UNO_QUERY);
189 : OSL_ASSERT(dataSource.is());
190 0 : if (!dataSource.is())
191 0 : return sal_False;
192 : OSL_ASSERT(outputStream.is());
193 0 : if (!outputStream.is())
194 0 : return sal_False;
195 0 : dataSource->setOutputStream(outputStream);
196 :
197 0 : return sal_True;
198 : }
199 :
200 :
201 14 : OUString OdfFlatXml::impl_getImplementationName()
202 : {
203 14 : return OUString("com.sun.star.comp.filter.OdfFlatXml");
204 : }
205 :
206 7 : Sequence< OUString > OdfFlatXml::impl_getSupportedServiceNames()
207 : {
208 7 : Sequence< OUString > lServiceNames(2);
209 7 : lServiceNames[0] = "com.sun.star.document.ImportFilter";
210 7 : lServiceNames[1] = "com.sun.star.document.ExportFilter";
211 7 : return lServiceNames;
212 : }
213 :
214 7 : Reference< XInterface > SAL_CALL OdfFlatXml::impl_createInstance(const Reference< XMultiServiceFactory >& fact)
215 : {
216 7 : return Reference<XInterface> (static_cast<OWeakObject *>(new OdfFlatXml( comphelper::getComponentContext(fact) )));
217 :
218 : }
219 :
220 : extern "C" SAL_DLLPUBLIC_EXPORT void* SAL_CALL
221 7 : odfflatxml_component_getFactory( const sal_Char* pImplementationName,
222 : void* pServiceManager,
223 : void* /* pRegistryKey */ )
224 : {
225 7 : if ((!pImplementationName) || (!pServiceManager))
226 0 : return NULL;
227 :
228 : com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
229 7 : xSMGR = static_cast< com::sun::star::lang::XMultiServiceFactory* >(pServiceManager);
230 14 : com::sun::star::uno::Reference< com::sun::star::lang::XSingleServiceFactory > xFactory;
231 14 : OUString sImplName = OUString::createFromAscii(pImplementationName);
232 :
233 7 : if (OdfFlatXml::impl_getImplementationName() == sImplName)
234 14 : xFactory = cppu::createOneInstanceFactory( xSMGR,
235 : OdfFlatXml::impl_getImplementationName(),
236 : OdfFlatXml::impl_createInstance,
237 7 : OdfFlatXml::impl_getSupportedServiceNames() );
238 :
239 7 : if (xFactory.is())
240 : {
241 7 : xFactory->acquire();
242 7 : return xFactory.get();
243 : }
244 :
245 7 : return NULL;
246 : }
247 :
248 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|