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