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 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <iostream>
21 : #include <stdlib.h>
22 : #include <ctype.h>
23 : #include <stdio.h>
24 : #include <rtl/ustring.hxx>
25 : #include <tools/urlobj.hxx>
26 : #include "XmlFilterAdaptor.hxx"
27 : #include <osl/diagnose.h>
28 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
29 : #include <com/sun/star/uno/RuntimeException.hpp>
30 : #include <com/sun/star/io/XActiveDataSource.hpp>
31 : #include <com/sun/star/io/XOutputStream.hpp>
32 : #include <com/sun/star/io/XInputStream.hpp>
33 : #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
34 : #include <com/sun/star/xml/sax/InputSource.hpp>
35 : #include <com/sun/star/xml/sax/Parser.hpp>
36 : #include <com/sun/star/frame/XConfigManager.hpp>
37 : #include <com/sun/star/xml/XImportFilter.hpp>
38 : #include <com/sun/star/xml/XExportFilter.hpp>
39 : #include <com/sun/star/frame/XModel.hpp>
40 : #include <com/sun/star/frame/XController.hpp>
41 : #include <com/sun/star/task/XStatusIndicator.hpp>
42 : #include <com/sun/star/task/XStatusIndicatorFactory.hpp>
43 : #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
44 : #include <com/sun/star/style/XStyleLoader.hpp>
45 : #include <com/sun/star/container/XNameAccess.hpp>
46 : #include <comphelper/processfactory.hxx>
47 : #include <comphelper/sequenceashashmap.hxx>
48 : #include <comphelper/mediadescriptor.hxx>
49 : #include <com/sun/star/beans/PropertyAttribute.hpp>
50 : #include <comphelper/genericpropertyset.hxx>
51 : #include <comphelper/propertysetinfo.hxx>
52 :
53 : using namespace comphelper;
54 : using namespace com::sun::star::uno;
55 : using namespace com::sun::star::lang;
56 : using namespace com::sun::star::io;
57 : using namespace com::sun::star::beans;
58 : using namespace com::sun::star::container;
59 : using namespace com::sun::star::document;
60 : using namespace com::sun::star::style;
61 : using namespace com::sun::star::xml;
62 : using namespace com::sun::star::xml::sax;
63 : using namespace ::com::sun::star::frame;
64 : using namespace ::com::sun::star::task;
65 :
66 : using ::rtl::OUString;
67 :
68 : #define MAP_LEN(x) x, sizeof(x) - 1
69 :
70 0 : Reference< com::sun::star::frame::XModel > xModel;
71 :
72 0 : sal_Bool SAL_CALL XmlFilterAdaptor::importImpl( const Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor )
73 : throw (RuntimeException)
74 : {
75 0 : OUString udConvertClass=msUserData[0];
76 0 : OUString udImport =msUserData[2];
77 0 : sal_Int32 nSteps= 0;
78 0 : sal_Int32 nProgressRange = 4;
79 :
80 0 : comphelper::MediaDescriptor aMediaMap(aDescriptor);
81 : Reference< XStatusIndicator > xStatusIndicator(aMediaMap.getUnpackedValueOrDefault(
82 0 : comphelper::MediaDescriptor::PROP_STATUSINDICATOR(), Reference< XStatusIndicator >()));
83 :
84 0 : if (xStatusIndicator.is()){
85 0 : xStatusIndicator->start(OUString( RTL_CONSTASCII_USTRINGPARAM( "Loading :" )),nProgressRange);
86 : }
87 :
88 0 : OUString sXMLImportService ( udImport );
89 0 : Reference < XParser > xSaxParser = Parser::create( comphelper::getComponentContext(mxMSF) );
90 :
91 0 : Sequence< Any > aAnys(1);
92 0 : OUString aBaseURI;
93 0 : if (aMediaMap.find(OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" )))->second >>= aBaseURI)
94 : {
95 0 : INetURLObject aURLObj(aBaseURI);
96 : // base URI in this case is the URI of the actual saving location
97 : // aURLObj.removeSegment();
98 0 : aBaseURI = aURLObj.GetMainURL(INetURLObject::NO_DECODE);
99 : }
100 :
101 : // create an XProperty set to configure the exporter for pretty printing
102 : PropertyMapEntry aImportInfoMap[] =
103 : {
104 0 : { MAP_LEN( "BaseURI" ), 0, &::getCppuType((const OUString*)0), PropertyAttribute::MAYBEVOID, 0},
105 : { NULL, 0, 0, NULL, 0, 0 }
106 0 : };
107 :
108 : Reference< XPropertySet > xInfoSet(
109 0 : GenericPropertySet_CreateInstance( new PropertySetInfo( aImportInfoMap ) ) );
110 0 : xInfoSet->setPropertyValue(
111 0 : OUString( RTL_CONSTASCII_USTRINGPARAM( "BaseURI" )), makeAny( aBaseURI ));
112 0 : aAnys[0] <<= xInfoSet;
113 :
114 :
115 0 : Reference < XDocumentHandler > xHandler( mxMSF->createInstanceWithArguments( sXMLImportService, aAnys ), UNO_QUERY );
116 0 : if(! xHandler.is()) {
117 : OSL_FAIL("XMLReader::Read: %s Unable to create service instance xHandler\n" );
118 0 : return sal_False;
119 : }
120 0 : Reference < XImporter > xImporter( xHandler, UNO_QUERY );
121 0 : xImporter->setTargetDocument ( mxDoc );
122 :
123 0 : if (xStatusIndicator.is()){
124 0 : xStatusIndicator->setValue(nSteps++);
125 : }
126 :
127 : //*********************
128 : // Creating a ConverterBridge instance
129 : //*********************
130 0 : Reference< XInterface > xConvBridge(mxMSF->createInstance( udConvertClass ), UNO_QUERY);
131 0 : if(! xConvBridge.is()){
132 : OSL_FAIL( "XMLReader::Read: %s service missing\n" );
133 0 : return sal_False;
134 : }
135 0 : if (xStatusIndicator.is())
136 0 : xStatusIndicator->setValue(nSteps++);
137 :
138 0 : Reference< XImportFilter > xConverter( xConvBridge, UNO_QUERY );
139 :
140 : //********************
141 : //Template Loading if Required
142 : //********************
143 0 : if (!msTemplateName.isEmpty()){
144 0 : Reference< XStyleFamiliesSupplier > xstylefamiliessupplier(mxDoc, UNO_QUERY);
145 :
146 0 : Reference< XNameAccess >xName;
147 0 : if(xstylefamiliessupplier.is()){
148 0 : xName=xstylefamiliessupplier->getStyleFamilies();
149 : }
150 0 : Reference< XStyleLoader > xstyleLoader (xstylefamiliessupplier->getStyleFamilies(), UNO_QUERY);
151 :
152 :
153 0 : if(xstyleLoader.is()){
154 0 : xName=xstylefamiliessupplier->getStyleFamilies();
155 : }
156 :
157 0 : Sequence < OUString > elementNames = xName->getElementNames();
158 0 : if(xstyleLoader.is()){
159 0 : Sequence<com::sun::star::beans::PropertyValue> pValue=xstyleLoader->getStyleLoaderOptions();
160 :
161 : //Load the Styles from the Template URL Supplied in the TypeDetection file
162 0 : if(msTemplateName.indexOf(OUString( RTL_CONSTASCII_USTRINGPARAM( "file:" )))==-1)
163 : {
164 0 : Reference< XConfigManager >xCfgMgr ( mxMSF->createInstance(
165 0 : OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.config.SpecialConfigManager" )) ), UNO_QUERY );
166 0 : OUString PathString(xCfgMgr->substituteVariables(OUString(RTL_CONSTASCII_USTRINGPARAM("$(progurl)"))));
167 0 : PathString = PathString.concat(OUString( RTL_CONSTASCII_USTRINGPARAM( "/" )));
168 0 : msTemplateName=PathString.concat(msTemplateName);
169 : }
170 :
171 0 : xstyleLoader->loadStylesFromURL(msTemplateName,pValue);
172 0 : }
173 : }
174 :
175 : // sal_Bool xconv_ret = sal_True;
176 :
177 0 : if (xStatusIndicator.is()){
178 0 : xStatusIndicator->setValue(nSteps++);
179 : }
180 : //*********************
181 : // Calling Filtering Component
182 : //*********************
183 : try {
184 0 : if (!xConverter->importer(aDescriptor,xHandler,msUserData)) {
185 0 : if (xStatusIndicator.is())
186 0 : xStatusIndicator->end();
187 0 : return sal_False;
188 : }
189 : }
190 : #if OSL_DEBUG_LEVEL > 0
191 : catch( const Exception& e )
192 : #else
193 0 : catch( const Exception& )
194 : #endif
195 : {
196 0 : if (xStatusIndicator.is())
197 0 : xStatusIndicator->end();
198 :
199 : OSL_FAIL( ::rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US).getStr());
200 0 : return sal_False;
201 : }
202 0 : if (xStatusIndicator.is()) {
203 0 : xStatusIndicator->setValue(nSteps++);
204 0 : xStatusIndicator->end();
205 : }
206 0 : return sal_True;
207 : }
208 :
209 0 : sal_Bool SAL_CALL XmlFilterAdaptor::exportImpl( const Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor )
210 : throw (RuntimeException)
211 : {
212 :
213 0 : OUString udConvertClass = msUserData[0];
214 0 : OUString udExport = msUserData[3];
215 :
216 : // Status Bar
217 0 : sal_Int32 nSteps= 1;
218 0 : sal_Int32 nProgressRange(3);
219 0 : comphelper::MediaDescriptor aMediaMap(aDescriptor);
220 : Reference< XStatusIndicator > xStatusIndicator(aMediaMap.getUnpackedValueOrDefault(
221 0 : comphelper::MediaDescriptor::PROP_STATUSINDICATOR(), Reference< XStatusIndicator >()));
222 :
223 0 : if (xStatusIndicator.is())
224 0 : xStatusIndicator->start(OUString( RTL_CONSTASCII_USTRINGPARAM( "Saving :" )),nProgressRange);
225 :
226 : // Set up converter bridge.
227 0 : Reference< com::sun::star::xml::XExportFilter > xConverter(mxMSF->createInstance(udConvertClass ), UNO_QUERY);
228 0 : if(! xConverter.is()){
229 : OSL_FAIL( "xml export sub service missing" );
230 0 : return sal_False;
231 : }
232 :
233 0 : if (xStatusIndicator.is())
234 0 : xStatusIndicator->setValue(nSteps++);
235 :
236 : //put filter component into exporting state
237 0 : if (!xConverter->exporter(aDescriptor, msUserData)) {
238 0 : if (xStatusIndicator.is())
239 0 : xStatusIndicator->end();
240 0 : return sal_False;
241 : }
242 0 : if (xStatusIndicator.is())
243 0 : xStatusIndicator->setValue(nSteps++);
244 :
245 : try{
246 : // create the xml exporter service and supply the converter component
247 : // which implements the document handler
248 0 : Sequence < Any > aAnys (2);
249 0 : aAnys[0] <<= xConverter;
250 :
251 :
252 : // pretty printing is confusing for some filters so it is disabled by default
253 : sal_Bool bPrettyPrint =
254 0 : (msUserData.getLength() > 6 && msUserData[6].equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("true")));
255 :
256 : // export of <text:number> element for <text:list-item> elements are
257 : // needed for certain filters.
258 : sal_Bool bExportTextNumberElementForListItems =
259 0 : ( msUserData.getLength() > 7 &&
260 0 : msUserData[7].equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("true")) );
261 :
262 : // get the base URI, so we can use relative links
263 0 : OUString aBaseURI;
264 0 : if (aMediaMap.find(OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" )))->second >>= aBaseURI)
265 : {
266 0 : INetURLObject aURLObj(aBaseURI);
267 : // base URI in this case is the URI of the actual saving location
268 : // aURLObj.removeSegment();
269 0 : aBaseURI = aURLObj.GetMainURL(INetURLObject::NO_DECODE);
270 : }
271 :
272 : // create an XProperty set to configure the exporter for pretty printing
273 : PropertyMapEntry aImportInfoMap[] =
274 : {
275 0 : { MAP_LEN( "UsePrettyPrinting" ), 0, &::getCppuType((const sal_Bool*)0), PropertyAttribute::MAYBEVOID, 0},
276 0 : { MAP_LEN( "ExportTextNumberElement" ), 0, &::getCppuType((const sal_Bool*)0), PropertyAttribute::MAYBEVOID, 0},
277 0 : { MAP_LEN( "BaseURI" ), 0, &::getCppuType((const OUString*)0), PropertyAttribute::MAYBEVOID, 0},
278 : { NULL, 0, 0, NULL, 0, 0 }
279 0 : };
280 :
281 : Reference< XPropertySet > xInfoSet(
282 0 : GenericPropertySet_CreateInstance( new PropertySetInfo( aImportInfoMap ) ) );
283 0 : xInfoSet->setPropertyValue(
284 0 : OUString( RTL_CONSTASCII_USTRINGPARAM( "UsePrettyPrinting" )), makeAny( bPrettyPrint ));
285 0 : xInfoSet->setPropertyValue(
286 : OUString( RTL_CONSTASCII_USTRINGPARAM( "ExportTextNumberElement" )),
287 0 : makeAny( bExportTextNumberElementForListItems ));
288 0 : xInfoSet->setPropertyValue(
289 0 : OUString( RTL_CONSTASCII_USTRINGPARAM( "BaseURI" )), makeAny( aBaseURI ));
290 0 : aAnys[1] <<= xInfoSet;
291 :
292 0 : Reference< XExporter > xExporter( mxMSF->createInstanceWithArguments (
293 0 : udExport, aAnys ), UNO_QUERY_THROW );
294 :
295 : // attach to source document
296 0 : xExporter->setSourceDocument( mxDoc );
297 :
298 : // get XFilter interface
299 0 : Reference< XFilter > xFilter( xExporter, UNO_QUERY_THROW );
300 :
301 0 : if (xStatusIndicator.is())
302 0 : xStatusIndicator->setValue(nSteps++);
303 :
304 : // call the actual filtering component
305 0 : if (!xFilter->filter(aDescriptor))
306 : {
307 0 : if (xStatusIndicator.is())
308 0 : xStatusIndicator->end();
309 0 : return sal_False;
310 0 : }
311 : }
312 : #if OSL_DEBUG_LEVEL > 0
313 : catch( const Exception& exE )
314 : #else
315 0 : catch( const Exception& )
316 : #endif
317 : {
318 : OSL_FAIL( ::rtl::OUStringToOString( exE.Message, RTL_TEXTENCODING_ASCII_US).getStr());
319 0 : if (xStatusIndicator.is())
320 0 : xStatusIndicator->end();
321 0 : return sal_False;
322 : }
323 :
324 : // done
325 0 : if (xStatusIndicator.is())
326 0 : xStatusIndicator->end();
327 0 : return sal_True;
328 : }
329 :
330 0 : sal_Bool SAL_CALL XmlFilterAdaptor::filter( const Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor )
331 : throw (RuntimeException)
332 : {
333 0 : return meType == FILTER_EXPORT ? exportImpl ( aDescriptor ) : importImpl ( aDescriptor );
334 : }
335 0 : void SAL_CALL XmlFilterAdaptor::cancel( )
336 : throw (RuntimeException)
337 : {
338 0 : }
339 : // XExporter
340 0 : void SAL_CALL XmlFilterAdaptor::setSourceDocument( const Reference< ::com::sun::star::lang::XComponent >& xDoc )
341 : throw (::com::sun::star::lang::IllegalArgumentException, RuntimeException)
342 : {
343 0 : meType = FILTER_EXPORT;
344 0 : mxDoc = xDoc;
345 0 : com::sun::star::uno::Reference< com::sun::star::frame::XModel >rModel ( com::sun::star::uno::Reference< com::sun::star::frame::XModel >::query( xDoc ) );
346 0 : xModel=rModel;
347 :
348 0 : }
349 :
350 : // XImporter
351 0 : void SAL_CALL XmlFilterAdaptor::setTargetDocument( const Reference< ::com::sun::star::lang::XComponent >& xDoc )
352 : throw (::com::sun::star::lang::IllegalArgumentException, RuntimeException)
353 : {
354 0 : meType = FILTER_IMPORT;
355 0 : mxDoc = xDoc;
356 : //xModel = uno::Reference< frame::XModel >::query( xDoc );
357 0 : }
358 : // XInitialization
359 0 : void SAL_CALL XmlFilterAdaptor::initialize( const Sequence< Any >& aArguments )
360 : throw (Exception, RuntimeException)
361 : {
362 0 : Sequence < PropertyValue > aAnySeq;
363 0 : sal_Int32 nLength = aArguments.getLength();
364 0 : if ( nLength && ( aArguments[0] >>= aAnySeq ) )
365 : {
366 0 : comphelper::SequenceAsHashMap aMap(aAnySeq);
367 : msFilterName = aMap.getUnpackedValueOrDefault(
368 0 : OUString( RTL_CONSTASCII_USTRINGPARAM( "Type" )), OUString());
369 : msUserData = aMap.getUnpackedValueOrDefault(
370 0 : OUString( RTL_CONSTASCII_USTRINGPARAM( "UserData" )), Sequence< OUString >());
371 : msTemplateName = aMap.getUnpackedValueOrDefault(
372 0 : OUString( RTL_CONSTASCII_USTRINGPARAM( "TemplateName" )), OUString());
373 0 : }
374 0 : }
375 0 : OUString XmlFilterAdaptor_getImplementationName ()
376 : throw (RuntimeException)
377 : {
378 0 : return OUString ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.comp.Writer.XmlFilterAdaptor" ) );
379 : }
380 : #define SERVICE_NAME1 "com.sun.star.document.ExportFilter"
381 : #define SERVICE_NAME2 "com.sun.star.document.ImportFilter"
382 0 : sal_Bool SAL_CALL XmlFilterAdaptor_supportsService( const OUString& ServiceName )
383 : throw (RuntimeException)
384 : {
385 0 : return ServiceName == SERVICE_NAME1 || ServiceName == SERVICE_NAME2;
386 : }
387 0 : Sequence< OUString > SAL_CALL XmlFilterAdaptor_getSupportedServiceNames( )
388 : throw (RuntimeException)
389 : {
390 0 : Sequence < OUString > aRet(2);
391 0 : OUString* pArray = aRet.getArray();
392 0 : pArray[0] = OUString ( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME1 ) );
393 0 : pArray[1] = OUString ( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME2 ) );
394 0 : return aRet;
395 : }
396 : #undef SERVICE_NAME1
397 : #undef SERVICE_NAME2
398 :
399 0 : Reference< XInterface > SAL_CALL XmlFilterAdaptor_createInstance( const Reference< XMultiServiceFactory > & rSMgr)
400 : throw( Exception )
401 : {
402 0 : return (cppu::OWeakObject*) new XmlFilterAdaptor( rSMgr );
403 : }
404 :
405 : // XServiceInfo
406 0 : OUString SAL_CALL XmlFilterAdaptor::getImplementationName( )
407 : throw (RuntimeException)
408 : {
409 0 : return XmlFilterAdaptor_getImplementationName();
410 : }
411 0 : sal_Bool SAL_CALL XmlFilterAdaptor::supportsService( const OUString& rServiceName )
412 : throw (RuntimeException)
413 : {
414 0 : return XmlFilterAdaptor_supportsService( rServiceName );
415 : }
416 0 : Sequence< OUString > SAL_CALL XmlFilterAdaptor::getSupportedServiceNames( )
417 : throw (RuntimeException)
418 : {
419 0 : return XmlFilterAdaptor_getSupportedServiceNames();
420 0 : }
421 :
422 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|