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