xref: /AOO41X/main/filter/source/xmlfilteradaptor/XmlFilterAdaptor.cxx (revision 9e0fc027f109ec4ffcb6033aeec742a099701108)
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