blob: 51d860791b7aac36c307d4b31b00db28e91be26b [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_chart2.hxx"
#include "XMLFilter.hxx"
#include "macros.hxx"
#include "MediaDescriptorHelper.hxx"
#include "ContainerHelper.hxx"
#include <comphelper/mediadescriptor.hxx>
// for ERRCODE_SFX_GENERAL etc.
// header contains only macros
#include <svtools/sfxecode.hxx>
// header for class SvtSaveOptions
#include <unotools/saveopt.hxx>
#include <comphelper/genericpropertyset.hxx>
// header for struct PropertyMapEntry
#include <comphelper/propertysetinfo.hxx>
#include <comphelper/documentconstants.hxx>
// header for class SotStorage
#include <sot/storage.hxx>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/xml/sax/InputSource.hpp>
#include <com/sun/star/lang/XMultiComponentFactory.hpp>
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
#include <com/sun/star/embed/ElementModes.hpp>
#include <com/sun/star/embed/XStorage.hpp>
#include <com/sun/star/embed/XTransactedObject.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
#include <com/sun/star/xml/sax/XParser.hpp>
#include <com/sun/star/xml/sax/SAXParseException.hpp>
#include <com/sun/star/packages/zip/ZipIOException.hpp>
#include <com/sun/star/document/XGraphicObjectResolver.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
using namespace ::com::sun::star;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Sequence;
using ::rtl::OUString;
using ::osl::MutexGuard;
// ----------------------------------------
namespace
{
#define LOCAL_CONST_STR(i, x) sal_Char __READONLY_DATA i[sizeof(x)] = x
#define MAP_LEN(x) x, sizeof(x) - 1
LOCAL_CONST_STR( sXML_metaStreamName, "meta.xml");
LOCAL_CONST_STR( sXML_styleStreamName, "styles.xml" );
LOCAL_CONST_STR( sXML_contentStreamName, "content.xml" );
LOCAL_CONST_STR( sXML_oldContentStreamName, "Content.xml" );
// soffice 6/7
// LOCAL_CONST_STR( sXML_export_chart_meta_service, "com.sun.star.comp.Chart.XMLMetaExporter" );
LOCAL_CONST_STR( sXML_export_chart_styles_service, "com.sun.star.comp.Chart.XMLStylesExporter" );
LOCAL_CONST_STR( sXML_export_chart_content_service, "com.sun.star.comp.Chart.XMLContentExporter" );
// LOCAL_CONST_STR( sXML_import_chart_meta_service, "com.sun.star.comp.Chart.XMLMetaImporter" );
LOCAL_CONST_STR( sXML_import_chart_styles_service, "com.sun.star.comp.Chart.XMLStylesImporter" );
LOCAL_CONST_STR( sXML_import_chart_content_service, "com.sun.star.comp.Chart.XMLContentImporter" );
LOCAL_CONST_STR( sXML_import_chart_old_content_service, "com.sun.star.office.sax.importer.Chart" );
// Oasis
LOCAL_CONST_STR( sXML_export_chart_oasis_styles_service, "com.sun.star.comp.Chart.XMLOasisStylesExporter" );
LOCAL_CONST_STR( sXML_export_chart_oasis_content_service, "com.sun.star.comp.Chart.XMLOasisContentExporter" );
LOCAL_CONST_STR( sXML_export_chart_oasis_meta_service, "com.sun.star.comp.Chart.XMLOasisMetaExporter" );
LOCAL_CONST_STR( sXML_import_chart_oasis_styles_service, "com.sun.star.comp.Chart.XMLOasisStylesImporter" );
LOCAL_CONST_STR( sXML_import_chart_oasis_content_service, "com.sun.star.comp.Chart.XMLOasisContentImporter" );
LOCAL_CONST_STR( sXML_import_chart_oasis_meta_service, "com.sun.star.comp.Chart.XMLOasisMetaImporter" );
uno::Reference< embed::XStorage > lcl_getWriteStorage(
const Sequence< beans::PropertyValue >& rMediaDescriptor,
const uno::Reference< uno::XComponentContext >& xContext,const ::rtl::OUString& _sMediaType)
{
uno::Reference< embed::XStorage > xStorage;
try
{
apphelper::MediaDescriptorHelper aMDHelper( rMediaDescriptor );
if( aMDHelper.ISSET_Storage )
{
xStorage = aMDHelper.Storage;
}
else
{
Reference< lang::XSingleServiceFactory > xStorageFact(
xContext->getServiceManager()->createInstanceWithContext(
C2U("com.sun.star.embed.StorageFactory"),
xContext ), uno::UNO_QUERY_THROW );
::std::vector< beans::PropertyValue > aPropertiesForStorage;
for( sal_Int32 i=rMediaDescriptor.getLength(); i--; )
{
// properties understood by storage factory
// (see package/source/xstor/xfactory.cxx for details)
if ( rMediaDescriptor[i].Name.equalsAsciiL(
RTL_CONSTASCII_STRINGPARAM( "InteractionHandler" ))
|| rMediaDescriptor[i].Name.equalsAsciiL(
RTL_CONSTASCII_STRINGPARAM( "Password" ))
|| rMediaDescriptor[i].Name.equalsAsciiL(
RTL_CONSTASCII_STRINGPARAM( "RepairPackage" ))
// || rMediaDescriptor[i].Name.equalsAsciiL(
// RTL_CONSTASCII_STRINGPARAM( "StatusIndicator" ))
// || rMediaDescriptor[i].Name.equalsAsciiL(
// RTL_CONSTASCII_STRINGPARAM( "Unpacked" ))
)
{
aPropertiesForStorage.push_back( rMediaDescriptor[i] );
}
}
if( aMDHelper.ISSET_Storage )
xStorage.set( aMDHelper.Storage );
else
{
Sequence< uno::Any > aStorageArgs( 3 );
if( aMDHelper.ISSET_OutputStream )
aStorageArgs[0] <<= aMDHelper.OutputStream;
else
aStorageArgs[0] <<= aMDHelper.URL;
aStorageArgs[1] <<= (embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE);
aStorageArgs[2] <<= ::chart::ContainerHelper::ContainerToSequence( aPropertiesForStorage );
xStorage.set(
xStorageFact->createInstanceWithArguments( aStorageArgs ),
uno::UNO_QUERY_THROW );
}
}
// set correct media type at storage
uno::Reference<beans::XPropertySet> xProp(xStorage,uno::UNO_QUERY);
OUString aMediaType;
if ( ! xProp.is() ||
! ( xProp->getPropertyValue( C2U("MediaType")) >>= aMediaType ) ||
aMediaType.isEmpty() )
{
xProp->setPropertyValue( C2U("MediaType"), uno::makeAny( _sMediaType ));
}
}
catch( uno::Exception & ex )
{
ASSERT_EXCEPTION( ex );
}
return xStorage;
}
uno::Reference< embed::XStorage > lcl_getReadStorage(
const Sequence< beans::PropertyValue >& rMediaDescriptor,
const uno::Reference< uno::XComponentContext >& xContext)
{
uno::Reference< embed::XStorage > xStorage;
try
{
apphelper::MediaDescriptorHelper aMDHelper( rMediaDescriptor );
if( aMDHelper.ISSET_Storage )
{
xStorage = aMDHelper.Storage;
}
else
{
// get XStream from MediaDescriptor
uno::Reference< io::XInputStream > xStream;
::std::vector< beans::PropertyValue > aPropertiesForStorage;
for( sal_Int32 i=rMediaDescriptor.getLength(); i--; )
{
if( rMediaDescriptor[i].Name.equalsAsciiL(
RTL_CONSTASCII_STRINGPARAM( "InputStream" )))
xStream.set( rMediaDescriptor[i].Value, uno::UNO_QUERY );
// properties understood by storage factory
// (see package/source/xstor/xfactory.cxx for details)
if ( rMediaDescriptor[i].Name.equalsAsciiL(
RTL_CONSTASCII_STRINGPARAM( "InteractionHandler" ))
|| rMediaDescriptor[i].Name.equalsAsciiL(
RTL_CONSTASCII_STRINGPARAM( "Password" ))
|| rMediaDescriptor[i].Name.equalsAsciiL(
RTL_CONSTASCII_STRINGPARAM( "RepairPackage" ))
// || rMediaDescriptor[i].Name.equalsAsciiL(
// RTL_CONSTASCII_STRINGPARAM( "StatusIndicator" ))
// || rMediaDescriptor[i].Name.equalsAsciiL(
// RTL_CONSTASCII_STRINGPARAM( "Unpacked" ))
)
{
aPropertiesForStorage.push_back( rMediaDescriptor[i] );
}
}
OSL_ENSURE( xStream.is(), "No Stream" );
if( ! xStream.is())
return xStorage;
// convert XInputStream to XStorage via the storage factory
Reference< lang::XSingleServiceFactory > xStorageFact(
xContext->getServiceManager()->createInstanceWithContext(
C2U("com.sun.star.embed.StorageFactory"),
xContext ),
uno::UNO_QUERY_THROW );
Sequence< uno::Any > aStorageArgs( 3 );
aStorageArgs[0] <<= xStream;
aStorageArgs[1] <<= (embed::ElementModes::READ | embed::ElementModes::NOCREATE);
aStorageArgs[2] <<= ::chart::ContainerHelper::ContainerToSequence( aPropertiesForStorage );
xStorage.set(
xStorageFact->createInstanceWithArguments( aStorageArgs ), uno::UNO_QUERY_THROW );
}
OSL_ENSURE( xStorage.is(), "No Storage" );
}
catch( uno::Exception & ex )
{
ASSERT_EXCEPTION( ex );
}
return xStorage;
}
} // anonymous namespace
// ----------------------------------------
namespace chart
{
XMLFilter::XMLFilter( Reference< uno::XComponentContext > const & xContext ) :
m_xContext( xContext ),
m_bCancelOperation( false )
{}
XMLFilter::~XMLFilter()
{}
// ____ XFilter ____
sal_Bool SAL_CALL XMLFilter::filter(
const Sequence< beans::PropertyValue >& aDescriptor )
throw (uno::RuntimeException)
{
bool bResult = false;
MutexGuard aGuard( m_aMutex );
// ignore cancel flag at start of function
// note: is currently ignored during import/export
if( m_bCancelOperation )
m_bCancelOperation = false;
if( m_xSourceDoc.is())
{
OSL_ENSURE( ! m_xTargetDoc.is(), "source doc is set -> target document should not be set" );
if( impl_Export( m_xSourceDoc,
aDescriptor ) == 0 )
{
m_xSourceDoc = NULL;
bResult = true;
}
}
else if( m_xTargetDoc.is())
{
if( impl_Import( m_xTargetDoc,
aDescriptor ) == 0 )
{
m_xTargetDoc = NULL;
bResult = true;
}
}
else
{
OSL_ENSURE( false, "filter() called with no document set" );
}
return bResult;
}
void SAL_CALL XMLFilter::cancel()
throw (uno::RuntimeException)
{
// if mutex is locked set "cancel state"
// note: is currently ignored in filter-method
if( ! m_aMutex.tryToAcquire())
{
m_bCancelOperation = true;
}
}
// ____ XImporter ____
void SAL_CALL XMLFilter::setTargetDocument(
const Reference< lang::XComponent >& Document )
throw (lang::IllegalArgumentException,
uno::RuntimeException)
{
MutexGuard aGuard( m_aMutex );
OSL_ENSURE( ! m_xSourceDoc.is(), "Setting target doc while source doc is set" );
m_xTargetDoc = Document;
}
// ____ XExporter ____
void SAL_CALL XMLFilter::setSourceDocument(
const Reference< lang::XComponent >& Document )
throw (lang::IllegalArgumentException,
uno::RuntimeException)
{
MutexGuard aGuard( m_aMutex );
OSL_ENSURE( ! m_xTargetDoc.is(), "Setting source doc while target doc is set" );
m_xSourceDoc = Document;
}
sal_Int32 XMLFilter::impl_Import(
const Reference< lang::XComponent > & xDocumentComp,
const Sequence< beans::PropertyValue > & rMediaDescriptor )
{
sal_Int32 nWarning = 0;
OSL_ENSURE( xDocumentComp.is(), "Import: No Model" );
OSL_ENSURE( m_xContext.is(), "Import: No ComponentContext" );
if( ! (xDocumentComp.is() &&
m_xContext.is()))
return nWarning;
try
{
Reference< lang::XServiceInfo > xServInfo( xDocumentComp, uno::UNO_QUERY_THROW );
if( ! xServInfo->supportsService( C2U( "com.sun.star.chart2.ChartDocument" )))
{
OSL_ENSURE( false, "Import: No ChartDocument" );
return ERRCODE_SFX_GENERAL;
}
Reference< lang::XMultiComponentFactory > xFactory( m_xContext->getServiceManager());
OSL_ENSURE( xFactory.is(), "Import: No Factory" );
if( ! xFactory.is())
return ERRCODE_SFX_GENERAL;
// create a sax parser
Reference< xml::sax::XParser > xSaxParser(
xFactory->createInstanceWithContext( C2U( "com.sun.star.xml.sax.Parser" ), m_xContext ),
uno::UNO_QUERY_THROW );
bool bOasis = true;
isOasisFormat( rMediaDescriptor, bOasis );
Reference< embed::XStorage > xStorage( lcl_getReadStorage( rMediaDescriptor, m_xContext));
if( ! xStorage.is())
return ERRCODE_SFX_GENERAL;
// bool bOasis = (SotStorage::GetVersion( xStorage ) > SOFFICE_FILEFORMAT_60);
Reference< document::XGraphicObjectResolver > xGraphicObjectResolver;
uno::Reference< lang::XMultiServiceFactory > xServiceFactory( xFactory, uno::UNO_QUERY);
if( xServiceFactory.is())
{
uno::Sequence< uno::Any > aArgs(1);
aArgs[0] <<= xStorage;
xGraphicObjectResolver.set(
xServiceFactory->createInstanceWithArguments(
C2U("com.sun.star.comp.Svx.GraphicImportHelper"), aArgs ), uno::UNO_QUERY );
}
// create XPropertySet with extra informatio for the filter
/** property map for import info set */
comphelper::PropertyMapEntry aImportInfoMap[] =
{
// #80365# necessary properties for XML progress bar at load time
{ MAP_LEN( "ProgressRange" ), 0, &::getCppuType((const sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
{ MAP_LEN( "ProgressMax" ), 0, &::getCppuType((const sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
{ MAP_LEN( "ProgressCurrent" ), 0, &::getCppuType((const sal_Int32*)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0},
{ MAP_LEN( "PrivateData" ), 0,
&::getCppuType( (Reference<XInterface> *)0 ),
::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
{ MAP_LEN( "BaseURI" ), 0,
&::getCppuType( (OUString *)0 ),
::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
{ MAP_LEN( "StreamRelPath" ), 0,
&::getCppuType( (OUString *)0 ),
::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
{ MAP_LEN( "StreamName" ), 0,
&::getCppuType( (OUString *)0 ),
::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
{ MAP_LEN( "BuildId" ), 0,
&::getCppuType( (OUString *)0 ),
::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 },
{ NULL, 0, 0, NULL, 0, 0 }
};
uno::Reference< beans::XPropertySet > xImportInfo(
comphelper::GenericPropertySet_CreateInstance(
new comphelper::PropertySetInfo( aImportInfoMap ) ) );
// Set base URI and Hierarchical Name
OUString aHierarchName, aBaseUri;
uno::Reference< frame::XModel > xModel( m_xSourceDoc, uno::UNO_QUERY );
if( xModel.is() )
{
uno::Sequence< beans::PropertyValue > aModProps = xModel->getArgs();
for( sal_Int32 nInd = 0; nInd < aModProps.getLength(); nInd++ )
{
if( aModProps[nInd].Name.equals( C2U( "HierarchicalDocumentName" ) ) )
{
// Actually this argument only has meaning for embedded documents
aModProps[nInd].Value >>= aHierarchName;
}
else if( aModProps[nInd].Name.equals( C2U( "DocumentBaseURL" ) ) )
{
aModProps[nInd].Value >>= aBaseUri;
}
}
}
if( !aBaseUri.isEmpty() )
xImportInfo->setPropertyValue( C2U("BaseURI"), uno::makeAny( aBaseUri ) );
if( !aHierarchName.isEmpty() )
xImportInfo->setPropertyValue( C2U("StreamRelPath"), uno::makeAny( aHierarchName ) );
// import meta information
if( bOasis )
nWarning |= impl_ImportStream(
C2U( sXML_metaStreamName ),
C2U( sXML_import_chart_oasis_meta_service ),
xStorage, xSaxParser, xFactory, xGraphicObjectResolver, xImportInfo );
// import styles
nWarning |= impl_ImportStream(
C2U( sXML_styleStreamName ),
bOasis
? C2U( sXML_import_chart_oasis_styles_service )
: C2U( sXML_import_chart_styles_service ),
xStorage, xSaxParser, xFactory, xGraphicObjectResolver, xImportInfo );
// import content
sal_Int32 nContentWarning = impl_ImportStream(
C2U( sXML_contentStreamName ),
bOasis
? C2U( sXML_import_chart_oasis_content_service )
: C2U( sXML_import_chart_content_service ),
xStorage, xSaxParser, xFactory, xGraphicObjectResolver, xImportInfo );
nWarning |= nContentWarning;
// import of "content.xml" didn't work - try old "Content.xml" stream
if( nContentWarning != 0 )
{
nWarning = impl_ImportStream(
C2U( sXML_oldContentStreamName ),
C2U( sXML_import_chart_old_content_service ),
xStorage, xSaxParser, xFactory, xGraphicObjectResolver, xImportInfo );
}
}
catch( uno::Exception & ex )
{
ASSERT_EXCEPTION( ex );
// something went awry
nWarning = ERRCODE_SFX_GENERAL;
}
return nWarning;
}
sal_Int32 XMLFilter::impl_ImportStream(
const OUString & rStreamName,
const OUString & rServiceName,
const Reference< embed::XStorage > & xStorage,
const Reference< xml::sax::XParser > & xParser,
const Reference< lang::XMultiComponentFactory > & xFactory,
const Reference< document::XGraphicObjectResolver > & xGraphicObjectResolver,
uno::Reference< beans::XPropertySet >& xImportInfo )
{
sal_Int32 nWarning = ERRCODE_SFX_GENERAL;
Reference< container::XNameAccess > xNameAcc( xStorage, uno::UNO_QUERY );
if( ! (xNameAcc.is() &&
xNameAcc->hasByName( rStreamName )))
return 0;
if( xImportInfo.is() )
xImportInfo->setPropertyValue( C2U("StreamName"), uno::makeAny( rStreamName ) );
if( xStorage.is() &&
xStorage->isStreamElement( rStreamName ) )
{
try
{
xml::sax::InputSource aParserInput;
aParserInput.aInputStream.set(
xStorage->openStreamElement(
rStreamName,
embed::ElementModes::READ | embed::ElementModes::NOCREATE ),
uno::UNO_QUERY );
// todo: encryption
if( aParserInput.aInputStream.is())
{
sal_Int32 nArgs = 0;
//if( m_xStatusIndicator.is())
// nArgs++;
if( xGraphicObjectResolver.is())
nArgs++;
if( xImportInfo.is())
nArgs++;
uno::Sequence< uno::Any > aFilterCompArgs( nArgs );
nArgs = 0;
//if( m_xStatusIndicator.is())
// aFilterCompArgs[ nArgs++ ] <<= m_xStatusIndicator;
if( xGraphicObjectResolver.is())
aFilterCompArgs[nArgs++] <<= xGraphicObjectResolver;
if( xImportInfo.is())
aFilterCompArgs[ nArgs++ ] <<= xImportInfo;
Reference< xml::sax::XDocumentHandler > xDocHandler(
xFactory->createInstanceWithArgumentsAndContext( rServiceName, aFilterCompArgs, m_xContext ),
uno::UNO_QUERY_THROW );
Reference< document::XImporter > xImporter( xDocHandler, uno::UNO_QUERY_THROW );
xImporter->setTargetDocument( Reference< lang::XComponent >( m_xTargetDoc, uno::UNO_QUERY_THROW ));
if ( !m_sDocumentHandler.isEmpty() )
{
try
{
uno::Sequence< uno::Any > aArgs(2);
beans::NamedValue aValue;
aValue.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DocumentHandler"));
aValue.Value <<= xDocHandler;
aArgs[0] <<= aValue;
aValue.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Model"));
aValue.Value <<= m_xTargetDoc;
aArgs[1] <<= aValue;
xDocHandler.set(xFactory->createInstanceWithArgumentsAndContext(m_sDocumentHandler,aArgs,m_xContext), uno::UNO_QUERY );
xImporter.set(xDocHandler,uno::UNO_QUERY);
}
catch(uno::Exception&)
{
OSL_ENSURE(0,"Exception caught!");
}
}
xParser->setDocumentHandler( xDocHandler );
xParser->parseStream( aParserInput );
}
// load was successful
nWarning = 0;
}
catch( xml::sax::SAXParseException )
{
// todo: if encrypted: ERRCODE_SFX_WRONGPASSWORD
}
catch( xml::sax::SAXException )
{
// todo: if encrypted: ERRCODE_SFX_WRONGPASSWORD
}
catch( packages::zip::ZipIOException )
{
nWarning = ERRCODE_IO_BROKENPACKAGE;
}
catch( io::IOException )
{
}
catch( uno::Exception& aEx )
{
ASSERT_EXCEPTION( aEx );
}
}
return nWarning;
}
sal_Int32 XMLFilter::impl_Export(
const Reference< lang::XComponent > & xDocumentComp,
const Sequence< beans::PropertyValue > & rMediaDescriptor )
{
//save
sal_Int32 nWarning = 0;
OSL_ENSURE( xDocumentComp.is(), "Export: No Model" );
OSL_ENSURE( m_xContext.is(), "Export: No ComponentContext" );
if( !xDocumentComp.is() || !m_xContext.is() )
return nWarning;
try
{
Reference< lang::XServiceInfo > xServInfo( xDocumentComp, uno::UNO_QUERY_THROW );
if( ! xServInfo->supportsService( C2U( "com.sun.star.chart2.ChartDocument" )))
{
OSL_ENSURE( false, "Export: No ChartDocument" );
return ERRCODE_SFX_GENERAL;
}
Reference< lang::XMultiComponentFactory > xFactory( m_xContext->getServiceManager());
OSL_ENSURE( xFactory.is(), "Export: No Factory" );
if( ! xFactory.is())
return ERRCODE_SFX_GENERAL;
uno::Reference< lang::XMultiServiceFactory > xServiceFactory( m_xContext->getServiceManager(), uno::UNO_QUERY);
if( ! xServiceFactory.is())
return ERRCODE_SFX_GENERAL;
uno::Reference< io::XActiveDataSource > xSaxWriter( xServiceFactory->createInstance(
C2U("com.sun.star.xml.sax.Writer")), uno::UNO_QUERY );
if ( !xSaxWriter.is() )
return ERRCODE_SFX_GENERAL;
bool bOasis = true;
isOasisFormat( rMediaDescriptor, bOasis );
uno::Reference< embed::XStorage > xStorage( lcl_getWriteStorage( rMediaDescriptor, m_xContext, getMediaType(bOasis) ) );
OSL_ENSURE( xStorage.is(), "No Storage" );
if( ! xStorage.is())
return ERRCODE_SFX_GENERAL;
uno::Reference< xml::sax::XDocumentHandler> xDocHandler( xSaxWriter, uno::UNO_QUERY );
if ( !m_sDocumentHandler.isEmpty() )
{
try
{
uno::Sequence< uno::Any > aArgs(2);
beans::NamedValue aValue;
aValue.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DocumentHandler"));
aValue.Value <<= xDocHandler;
aArgs[0] <<= aValue;
aValue.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Model"));
aValue.Value <<= xDocumentComp;
aArgs[1] <<= aValue;
xDocHandler.set(xServiceFactory->createInstanceWithArguments(m_sDocumentHandler,aArgs), uno::UNO_QUERY );
xSaxWriter.set(xDocHandler,uno::UNO_QUERY);
}
catch(uno::Exception&)
{
OSL_ENSURE(0,"Exception caught!");
}
}
uno::Sequence< uno::Any > aGraphicResolverArgs(1);
aGraphicResolverArgs[0] <<= xStorage;
Reference< document::XGraphicObjectResolver > xGraphicObjectResolver(
xServiceFactory->createInstanceWithArguments(
C2U("com.sun.star.comp.Svx.GraphicExportHelper"), aGraphicResolverArgs ), uno::UNO_QUERY );
uno::Reference< beans::XPropertySet > xInfoSet;
{
// property map for export info set
comphelper::PropertyMapEntry aExportInfoMap[] =
{
{ MAP_LEN("UsePrettyPrinting"), 0, &::getBooleanCppuType(), beans::PropertyAttribute::MAYBEVOID, 0},
{ MAP_LEN("BaseURI"), 0, &::getCppuType( (OUString *)0 ), beans::PropertyAttribute::MAYBEVOID, 0 },
{ MAP_LEN("StreamRelPath"), 0, &::getCppuType( (OUString *)0 ), beans::PropertyAttribute::MAYBEVOID, 0 },
{ MAP_LEN("StreamName"), 0, &::getCppuType( (OUString *)0 ), beans::PropertyAttribute::MAYBEVOID, 0 },
{ MAP_LEN("ExportTableNumberList"), 0, &::getBooleanCppuType(), beans::PropertyAttribute::MAYBEVOID, 0 },
{ NULL, 0, 0, NULL, 0, 0 }
};
xInfoSet = comphelper::GenericPropertySet_CreateInstance( new comphelper::PropertySetInfo( aExportInfoMap ) );
SvtSaveOptions aSaveOpt;
OUString sUsePrettyPrinting(RTL_CONSTASCII_USTRINGPARAM("UsePrettyPrinting"));
sal_Bool bUsePrettyPrinting( aSaveOpt.IsPrettyPrinting() );
xInfoSet->setPropertyValue( sUsePrettyPrinting, uno::makeAny( bUsePrettyPrinting ) );
if( ! bOasis )
xInfoSet->setPropertyValue( C2U("ExportTableNumberList"), uno::makeAny( true ));
}
sal_Int32 nArgs = 2;
if( xGraphicObjectResolver.is())
nArgs++;
uno::Sequence< uno::Any > aFilterProperties( nArgs );
{
nArgs = 0;
aFilterProperties[ nArgs++ ] <<= xInfoSet;
aFilterProperties[ nArgs++ ] <<= xDocHandler;
if( xGraphicObjectResolver.is())
aFilterProperties[ nArgs++ ] <<= xGraphicObjectResolver;
}
// bool bOasis = (SotStorage::GetVersion( xStorage ) > SOFFICE_FILEFORMAT_60);
// export meta information
if( bOasis )
nWarning |= impl_ExportStream(
C2U( sXML_metaStreamName ),
C2U( sXML_export_chart_oasis_meta_service ),
xStorage, xSaxWriter, xServiceFactory, aFilterProperties );
// export styles
nWarning |= impl_ExportStream(
C2U( sXML_styleStreamName ),
bOasis
? C2U( sXML_export_chart_oasis_styles_service )
: C2U( sXML_export_chart_styles_service ),
xStorage, xSaxWriter, xServiceFactory, aFilterProperties );
// export content
sal_Int32 nContentWarning = impl_ExportStream(
C2U( sXML_contentStreamName ),
bOasis
? C2U( sXML_export_chart_oasis_content_service )
: C2U( sXML_export_chart_content_service ),
xStorage, xSaxWriter, xServiceFactory, aFilterProperties );
nWarning |= nContentWarning;
Reference< lang::XComponent > xComp( xGraphicObjectResolver, uno::UNO_QUERY );
if( xComp.is())
xComp->dispose();
uno::Reference<embed::XTransactedObject> xTransact( xStorage ,uno::UNO_QUERY);
if ( xTransact.is() )
xTransact->commit();
}
catch( uno::Exception & ex )
{
ASSERT_EXCEPTION( ex );
// something went awry
nWarning = ERRCODE_SFX_GENERAL;
}
return nWarning;
}
sal_Int32 XMLFilter::impl_ExportStream(
const OUString & rStreamName,
const OUString & rServiceName,
const Reference< embed::XStorage > & xStorage,
const uno::Reference< io::XActiveDataSource >& xActiveDataSource,
const Reference< lang::XMultiServiceFactory >& xServiceFactory,
const Sequence< uno::Any > & rFilterProperties )
{
sal_Int32 nWarning = 0;
try
{
if( !xServiceFactory.is() )
return ERRCODE_SFX_GENERAL;
if( !xStorage.is() )
return ERRCODE_SFX_GENERAL;
if ( !xActiveDataSource.is() )
return ERRCODE_SFX_GENERAL;
uno::Reference< io::XStream > xStream( xStorage->openStreamElement(
rStreamName, embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE ) );
if ( !xStream.is() )
return ERRCODE_SFX_GENERAL;
uno::Reference< io::XOutputStream > xOutputStream( xStream->getOutputStream() );
if ( !xOutputStream.is() )
return ERRCODE_SFX_GENERAL;
uno::Reference< beans::XPropertySet > xStreamProp( xOutputStream, uno::UNO_QUERY );
if(xStreamProp.is()) try
{
xStreamProp->setPropertyValue( C2U("MediaType"), uno::makeAny( C2U("text/xml") ) );
xStreamProp->setPropertyValue( C2U("Compressed"), uno::makeAny( sal_True ) );//@todo?
xStreamProp->setPropertyValue( C2U("UseCommonStoragePasswordEncryption"), uno::makeAny( sal_True ) );
}
catch( uno::Exception& rEx )
{
ASSERT_EXCEPTION( rEx );
}
xActiveDataSource->setOutputStream(xOutputStream);
// set Base URL
{
uno::Reference< beans::XPropertySet > xInfoSet;
if( rFilterProperties.getLength() > 0 )
rFilterProperties.getConstArray()[0] >>= xInfoSet;
OSL_ENSURE( xInfoSet.is(), "missing infoset for export" );
if( xInfoSet.is() )
xInfoSet->setPropertyValue( C2U("StreamName"), uno::makeAny( rStreamName ) );
}
Reference< XExporter > xExporter( xServiceFactory->createInstanceWithArguments(
rServiceName, rFilterProperties ), uno::UNO_QUERY);
if ( !xExporter.is() )
return ERRCODE_SFX_GENERAL;
xExporter->setSourceDocument( m_xSourceDoc );
uno::Reference< document::XFilter > xFilter( xExporter, uno::UNO_QUERY );
if ( !xFilter.is() )
return ERRCODE_SFX_GENERAL;
uno::Sequence < beans::PropertyValue > aMediaDesc(0);
//@todo? filter properties? ... url? ...
xFilter->filter( aMediaDesc );
}
catch( uno::Exception& rEx )
{
ASSERT_EXCEPTION( rEx );
}
return nWarning;
}
// --------------------------------------------------------------------------------
Sequence< OUString > XMLFilter::getSupportedServiceNames_Static()
{
Sequence< OUString > aServices( 2 );
aServices[ 0 ] = C2U( "com.sun.star.document.ImportFilter" );
aServices[ 1 ] = C2U( "com.sun.star.document.ExportFilter" );
// todo: services are incomplete. Missing:
// XInitialization, XNamed
return aServices;
}
// -----------------------------------------------------------------------------
void XMLFilter::isOasisFormat(const Sequence< beans::PropertyValue >& _rMediaDescriptor, bool & rOutOASIS )
{
apphelper::MediaDescriptorHelper aMDHelper( _rMediaDescriptor );
if( aMDHelper.ISSET_FilterName )
rOutOASIS = aMDHelper.FilterName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("chart8"));
}
// -----------------------------------------------------------------------------
::rtl::OUString XMLFilter::getMediaType(bool _bOasis)
{
return _bOasis ? MIMETYPE_OASIS_OPENDOCUMENT_CHART : MIMETYPE_VND_SUN_XML_CHART;
}
// -----------------------------------------------------------------------------
APPHELPER_XSERVICEINFO_IMPL( XMLFilter, C2U( "com.sun.star.comp.chart2.XMLFilter" ) );
// -----------------------------------------------------------------------------
void XMLReportFilterHelper::isOasisFormat(const Sequence< beans::PropertyValue >& _rMediaDescriptor, bool & rOutOASIS )
{
apphelper::MediaDescriptorHelper aMDHelper( _rMediaDescriptor );
if( aMDHelper.ISSET_FilterName )
rOutOASIS = aMDHelper.FilterName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("StarOffice XML (Base) Report Chart"));
}
// -----------------------------------------------------------------------------
::rtl::OUString XMLReportFilterHelper::getMediaType(bool )
{
return MIMETYPE_OASIS_OPENDOCUMENT_REPORT_CHART;
}
} // namespace chart