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