blob: 9bd31daae9a6fc1db5b06104ea3a595977d9cf28 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_filter.hxx"
#include <iostream>
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
#include <rtl/ustring.hxx>
#include <tools/urlobj.hxx>
#include "XmlFilterAdaptor.hxx"
#include <osl/diagnose.h>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/uno/RuntimeException.hpp>
#include <com/sun/star/io/XActiveDataSource.hpp>
#include <com/sun/star/io/XOutputStream.hpp>
#include <com/sun/star/io/XInputStream.hpp>
#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
#include <com/sun/star/xml/sax/InputSource.hpp>
#include <com/sun/star/xml/sax/XParser.hpp>
#include <com/sun/star/frame/XConfigManager.hpp>
#include <com/sun/star/frame/XConfigManager.hpp>
#include <com/sun/star/xml/XImportFilter.hpp>
#include <com/sun/star/xml/XExportFilter.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/frame/XController.hpp>
#include <com/sun/star/task/XStatusIndicator.hpp>
#include <com/sun/star/task/XStatusIndicatorFactory.hpp>
#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
#include <com/sun/star/style/XStyleLoader.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <comphelper/sequenceashashmap.hxx>
#include <comphelper/mediadescriptor.hxx>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <comphelper/genericpropertyset.hxx>
#include <comphelper/propertysetinfo.hxx>
using namespace rtl;
using namespace comphelper;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::io;
using namespace com::sun::star::beans;
using namespace com::sun::star::container;
using namespace com::sun::star::document;
using namespace com::sun::star::style;
using namespace com::sun::star::xml;
using namespace com::sun::star::xml::sax;
using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::task;
#define MAP_LEN(x) x, sizeof(x) - 1
Reference< com::sun::star::frame::XModel > xModel;
sal_Bool SAL_CALL XmlFilterAdaptor::importImpl( const Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor )
throw (RuntimeException)
{
OUString udConvertClass=msUserData[0];
OUString udImport =msUserData[2];
sal_Int32 nSteps= 0;
sal_Int32 nProgressRange = 4;
comphelper::MediaDescriptor aMediaMap(aDescriptor);
Reference< XStatusIndicator > xStatusIndicator(aMediaMap.getUnpackedValueOrDefault(
comphelper::MediaDescriptor::PROP_STATUSINDICATOR(), Reference< XStatusIndicator >()));
if (xStatusIndicator.is()){
xStatusIndicator->start(OUString( RTL_CONSTASCII_USTRINGPARAM( "Loading :" )),nProgressRange);
}
OUString sXMLImportService ( udImport );
const OUString sSaxParser ( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Parser") );
Reference < XParser > xSaxParser( mxMSF->createInstance( sSaxParser ), UNO_QUERY );
Sequence< Any > aAnys(1);
OUString aBaseURI;
if (aMediaMap.find(OUString::createFromAscii("URL"))->second >>= aBaseURI)
{
INetURLObject aURLObj(aBaseURI);
// base URI in this case is the URI of the actual saving location
// aURLObj.removeSegment();
aBaseURI = aURLObj.GetMainURL(INetURLObject::NO_DECODE);
}
// create an XProperty set to configure the exporter for pretty printing
PropertyMapEntry aImportInfoMap[] =
{
{ MAP_LEN( "BaseURI" ), 0, &::getCppuType((const OUString*)0), PropertyAttribute::MAYBEVOID, 0},
{ NULL, 0, 0, NULL, 0, 0 }
};
Reference< XPropertySet > xInfoSet(
GenericPropertySet_CreateInstance( new PropertySetInfo( aImportInfoMap ) ) );
xInfoSet->setPropertyValue(
OUString::createFromAscii( "BaseURI" ), makeAny( aBaseURI ));
aAnys[0] <<= xInfoSet;
Reference < XDocumentHandler > xHandler( mxMSF->createInstanceWithArguments( sXMLImportService, aAnys ), UNO_QUERY );
if(! xHandler.is()) {
OSL_ENSURE(sal_False, "XMLReader::Read: %s Unable to create service instance xHandler\n" );
return sal_False;
}
Reference < XImporter > xImporter( xHandler, UNO_QUERY );
xImporter->setTargetDocument ( mxDoc );
if (xStatusIndicator.is()){
xStatusIndicator->setValue(nSteps++);
}
//*********************
// Creating a ConverterBridge instance
//*********************
Reference< XInterface > xConvBridge(mxMSF->createInstance( udConvertClass ), UNO_QUERY);
if(! xConvBridge.is()){
OSL_ENSURE( sal_False,"XMLReader::Read: %s service missing\n" );
return sal_False;
}
if (xStatusIndicator.is())
xStatusIndicator->setValue(nSteps++);
Reference< XImportFilter > xConverter( xConvBridge, UNO_QUERY );
//********************
//Template Loading if Required
//********************
if (!msTemplateName.equalsAscii("")){
Reference< XStyleFamiliesSupplier > xstylefamiliessupplier(mxDoc, UNO_QUERY);
Reference< XNameAccess >xName;
if(xstylefamiliessupplier.is()){
xName=xstylefamiliessupplier->getStyleFamilies();
}
Reference< XStyleLoader > xstyleLoader (xstylefamiliessupplier->getStyleFamilies(), UNO_QUERY);
if(xstyleLoader.is()){
xName=xstylefamiliessupplier->getStyleFamilies();
}
Sequence < OUString > elementNames = xName->getElementNames();
if(xstyleLoader.is()){
Sequence<com::sun::star::beans::PropertyValue> pValue=xstyleLoader->getStyleLoaderOptions();
//Load the Styles from the Template URL Supplied in the TypeDetection file
if(msTemplateName.indexOf(OUString::createFromAscii("file:"))==-1)
{
Reference< XConfigManager >xCfgMgr ( mxMSF->createInstance(
OUString::createFromAscii("com.sun.star.config.SpecialConfigManager") ), UNO_QUERY );
OUString PathString=xCfgMgr->substituteVariables(OUString::createFromAscii("$(progurl)"));
PathString=PathString.concat(OUString::createFromAscii("/"));
msTemplateName=PathString.concat(msTemplateName);
}
xstyleLoader->loadStylesFromURL(msTemplateName,pValue);
}
}
// sal_Bool xconv_ret = sal_True;
if (xStatusIndicator.is()){
xStatusIndicator->setValue(nSteps++);
}
//*********************
// Calling Filtering Component
//*********************
try {
if (!xConverter->importer(aDescriptor,xHandler,msUserData)) {
if (xStatusIndicator.is())
xStatusIndicator->end();
return sal_False;
}
}
#if OSL_DEBUG_LEVEL > 0
catch( Exception& e )
#else
catch( Exception& )
#endif
{
if (xStatusIndicator.is())
xStatusIndicator->end();
OSL_ENSURE( sal_False, ::rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US).getStr());
return sal_False;
}
if (xStatusIndicator.is()) {
xStatusIndicator->setValue(nSteps++);
xStatusIndicator->end();
}
return sal_True;
}
sal_Bool SAL_CALL XmlFilterAdaptor::exportImpl( const Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor )
throw (RuntimeException)
{
OUString udConvertClass = msUserData[0];
OUString udExport = msUserData[3];
// Status Bar
sal_Int32 nSteps= 1;
sal_Int32 nProgressRange(3);
comphelper::MediaDescriptor aMediaMap(aDescriptor);
Reference< XStatusIndicator > xStatusIndicator(aMediaMap.getUnpackedValueOrDefault(
comphelper::MediaDescriptor::PROP_STATUSINDICATOR(), Reference< XStatusIndicator >()));
if (xStatusIndicator.is())
xStatusIndicator->start(OUString( RTL_CONSTASCII_USTRINGPARAM( "Saving :" )),nProgressRange);
// Set up converter bridge.
Reference< com::sun::star::xml::XExportFilter > xConverter(mxMSF->createInstance(udConvertClass ), UNO_QUERY);
if(! xConverter.is()){
OSL_ENSURE( sal_False, "xml export sub service missing" );
return sal_False;
}
if (xStatusIndicator.is())
xStatusIndicator->setValue(nSteps++);
//put filter component into exporting state
if (!xConverter->exporter(aDescriptor, msUserData)) {
if (xStatusIndicator.is())
xStatusIndicator->end();
return sal_False;
}
if (xStatusIndicator.is())
xStatusIndicator->setValue(nSteps++);
try{
// create the xml exporter service and supply the converter component
// which implements the document handler
Sequence < Any > aAnys (2);
aAnys[0] <<= xConverter;
// pretty printing is confusing for some filters so it is disabled by default
sal_Bool bPrettyPrint =
(msUserData.getLength() > 6 && msUserData[6].equalsIgnoreAsciiCaseAscii("true"));
// --> OD 2008-11-25 #b6761284#
// export of <text:number> element for <text:list-item> elements are
// needed for certain filters.
sal_Bool bExportTextNumberElementForListItems =
( msUserData.getLength() > 7 &&
msUserData[7].equalsIgnoreAsciiCaseAscii("true") );
// <--
// get the base URI, so we can use relative links
OUString aBaseURI;
if (aMediaMap.find(OUString::createFromAscii("URL"))->second >>= aBaseURI)
{
INetURLObject aURLObj(aBaseURI);
// base URI in this case is the URI of the actual saving location
// aURLObj.removeSegment();
aBaseURI = aURLObj.GetMainURL(INetURLObject::NO_DECODE);
}
// create an XProperty set to configure the exporter for pretty printing
PropertyMapEntry aImportInfoMap[] =
{
{ MAP_LEN( "UsePrettyPrinting" ), 0, &::getCppuType((const sal_Bool*)0), PropertyAttribute::MAYBEVOID, 0},
// --> OD 2008-11-25 #b6761284#
{ MAP_LEN( "ExportTextNumberElement" ), 0, &::getCppuType((const sal_Bool*)0), PropertyAttribute::MAYBEVOID, 0},
// <--
{ MAP_LEN( "BaseURI" ), 0, &::getCppuType((const OUString*)0), PropertyAttribute::MAYBEVOID, 0},
{ NULL, 0, 0, NULL, 0, 0 }
};
Reference< XPropertySet > xInfoSet(
GenericPropertySet_CreateInstance( new PropertySetInfo( aImportInfoMap ) ) );
xInfoSet->setPropertyValue(
OUString::createFromAscii( "UsePrettyPrinting" ), makeAny( bPrettyPrint ));
// --> OD 2008-11-25 #b6761284#
xInfoSet->setPropertyValue(
OUString::createFromAscii( "ExportTextNumberElement" ),
makeAny( bExportTextNumberElementForListItems ));
// <--
xInfoSet->setPropertyValue(
OUString::createFromAscii( "BaseURI" ), makeAny( aBaseURI ));
aAnys[1] <<= xInfoSet;
Reference< XExporter > xExporter( mxMSF->createInstanceWithArguments (
udExport, aAnys ), UNO_QUERY_THROW );
// attach to source document
xExporter->setSourceDocument( mxDoc );
// get XFilter interface
Reference< XFilter > xFilter( xExporter, UNO_QUERY_THROW );
if (xStatusIndicator.is())
xStatusIndicator->setValue(nSteps++);
// call the actual filtering component
if (!xFilter->filter(aDescriptor))
{
if (xStatusIndicator.is())
xStatusIndicator->end();
return sal_False;
}
}
#if OSL_DEBUG_LEVEL > 0
catch( Exception& exE )
#else
catch( Exception& )
#endif
{
OSL_ENSURE( sal_False, ::rtl::OUStringToOString( exE.Message, RTL_TEXTENCODING_ASCII_US).getStr());
if (xStatusIndicator.is())
xStatusIndicator->end();
return sal_False;
}
// done
if (xStatusIndicator.is())
xStatusIndicator->end();
return sal_True;
}
sal_Bool SAL_CALL XmlFilterAdaptor::filter( const Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor )
throw (RuntimeException)
{
return meType == FILTER_EXPORT ? exportImpl ( aDescriptor ) : importImpl ( aDescriptor );
}
void SAL_CALL XmlFilterAdaptor::cancel( )
throw (RuntimeException)
{
}
// XExporter
void SAL_CALL XmlFilterAdaptor::setSourceDocument( const Reference< ::com::sun::star::lang::XComponent >& xDoc )
throw (::com::sun::star::lang::IllegalArgumentException, RuntimeException)
{
meType = FILTER_EXPORT;
mxDoc = xDoc;
com::sun::star::uno::Reference< com::sun::star::frame::XModel >rModel ( com::sun::star::uno::Reference< com::sun::star::frame::XModel >::query( xDoc ) );
xModel=rModel;
}
// XImporter
void SAL_CALL XmlFilterAdaptor::setTargetDocument( const Reference< ::com::sun::star::lang::XComponent >& xDoc )
throw (::com::sun::star::lang::IllegalArgumentException, RuntimeException)
{
meType = FILTER_IMPORT;
mxDoc = xDoc;
//xModel = uno::Reference< frame::XModel >::query( xDoc );
}
// XInitialization
void SAL_CALL XmlFilterAdaptor::initialize( const Sequence< Any >& aArguments )
throw (Exception, RuntimeException)
{
Sequence < PropertyValue > aAnySeq;
sal_Int32 nLength = aArguments.getLength();
if ( nLength && ( aArguments[0] >>= aAnySeq ) )
{
comphelper::SequenceAsHashMap aMap(aAnySeq);
msFilterName = aMap.getUnpackedValueOrDefault(
OUString::createFromAscii("Type"), OUString());
msUserData = aMap.getUnpackedValueOrDefault(
OUString::createFromAscii("UserData"), Sequence< OUString >());
msTemplateName = aMap.getUnpackedValueOrDefault(
OUString::createFromAscii("TemplateName"), OUString());
}
}
OUString XmlFilterAdaptor_getImplementationName ()
throw (RuntimeException)
{
return OUString ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.comp.Writer.XmlFilterAdaptor" ) );
}
#define SERVICE_NAME1 "com.sun.star.document.ExportFilter"
#define SERVICE_NAME2 "com.sun.star.document.ImportFilter"
sal_Bool SAL_CALL XmlFilterAdaptor_supportsService( const OUString& ServiceName )
throw (RuntimeException)
{
return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME1 ) ) ||
ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME2 ) );
}
Sequence< OUString > SAL_CALL XmlFilterAdaptor_getSupportedServiceNames( )
throw (RuntimeException)
{
Sequence < OUString > aRet(2);
OUString* pArray = aRet.getArray();
pArray[0] = OUString ( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME1 ) );
pArray[1] = OUString ( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME2 ) );
return aRet;
}
#undef SERVICE_NAME1
#undef SERVICE_NAME2
Reference< XInterface > SAL_CALL XmlFilterAdaptor_createInstance( const Reference< XMultiServiceFactory > & rSMgr)
throw( Exception )
{
return (cppu::OWeakObject*) new XmlFilterAdaptor( rSMgr );
}
// XServiceInfo
OUString SAL_CALL XmlFilterAdaptor::getImplementationName( )
throw (RuntimeException)
{
return XmlFilterAdaptor_getImplementationName();
}
sal_Bool SAL_CALL XmlFilterAdaptor::supportsService( const OUString& rServiceName )
throw (RuntimeException)
{
return XmlFilterAdaptor_supportsService( rServiceName );
}
Sequence< OUString > SAL_CALL XmlFilterAdaptor::getSupportedServiceNames( )
throw (RuntimeException)
{
return XmlFilterAdaptor_getSupportedServiceNames();
}