blob: 409da4e1ff0d932502c9604f0e2d8497a4f8e27d [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 <com/sun/star/xml/sax/InputSource.hpp>
#include <com/sun/star/xml/sax/XParser.hpp>
#include <com/sun/star/xml/sax/XAttributeList.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <tools/debug.hxx>
#include "typedetectionimport.hxx"
#include "xmlfiltersettingsdialog.hxx"
using namespace com::sun::star::lang;
using namespace com::sun::star::uno;
using namespace com::sun::star::io;
using namespace com::sun::star::beans;
using namespace com::sun::star::xml::sax;
using namespace com::sun::star;
using namespace rtl;
using namespace std;
TypeDetectionImporter::TypeDetectionImporter( Reference< XMultiServiceFactory >& xMSF )
: mxMSF(xMSF),
sRootNode( RTL_CONSTASCII_USTRINGPARAM( "oor:component-data" ) ),
sNode( RTL_CONSTASCII_USTRINGPARAM( "node" ) ),
sName( RTL_CONSTASCII_USTRINGPARAM( "oor:name" ) ),
sProp( RTL_CONSTASCII_USTRINGPARAM( "prop" ) ),
sValue( RTL_CONSTASCII_USTRINGPARAM( "value" ) ),
sUIName( RTL_CONSTASCII_USTRINGPARAM( "UIName" ) ),
sData( RTL_CONSTASCII_USTRINGPARAM( "Data" ) ),
sFilters( RTL_CONSTASCII_USTRINGPARAM( "Filters" ) ),
sTypes( RTL_CONSTASCII_USTRINGPARAM( "Types" ) ),
sFilterAdaptorService( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.comp.Writer.XmlFilterAdaptor" ) ),
sXSLTFilterService( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.documentconversion.XSLTFilter" ) ),
sCdataAttribute( RTL_CONSTASCII_USTRINGPARAM( "CDATA" ) ),
sWhiteSpace( RTL_CONSTASCII_USTRINGPARAM( " " ) )
{
}
TypeDetectionImporter::~TypeDetectionImporter (void )
{
}
void TypeDetectionImporter::doImport( Reference< XMultiServiceFactory >& xMSF, Reference< XInputStream > xIS, XMLFilterVector& rFilters )
{
try
{
Reference< XParser > xParser( xMSF->createInstance(OUString::createFromAscii( "com.sun.star.xml.sax.Parser" ) ), UNO_QUERY );
if( xParser.is() )
{
TypeDetectionImporter* pImporter = new TypeDetectionImporter( xMSF );
Reference < XDocumentHandler > xDocHandler( pImporter );
xParser->setDocumentHandler( xDocHandler );
InputSource source;
source.aInputStream = xIS;
// start parsing
xParser->parseStream( source );
pImporter->fillFilterVector( rFilters );
}
}
catch( Exception& /* e */ )
{
DBG_ERROR( "TypeDetectionImporter::doImport exception catched!" );
}
}
void TypeDetectionImporter::fillFilterVector( XMLFilterVector& rFilters )
{
// create filter infos from imported filter nodes
NodeVector::iterator aIter = maFilterNodes.begin();
while( aIter != maFilterNodes.end() )
{
filter_info_impl* pFilter = createFilterForNode( (*aIter) );
if( pFilter )
rFilters.push_back( pFilter );
delete (*aIter++);
}
// now delete type nodes
aIter = maTypeNodes.begin();
while( aIter != maTypeNodes.end() )
delete (*aIter++);
}
static OUString getSubdata( int index, sal_Unicode delimeter, const OUString& rData )
{
sal_Int32 nLastIndex = 0;
sal_Int32 nNextIndex = rData.indexOf( delimeter );
OUString aSubdata;
while( index )
{
nLastIndex = nNextIndex + 1;
nNextIndex = rData.indexOf( delimeter, nLastIndex );
index--;
if( (index > 0) && (nLastIndex == 0) )
return aSubdata;
}
if( nNextIndex == -1 )
{
aSubdata = rData.copy( nLastIndex );
}
else
{
aSubdata = rData.copy( nLastIndex, nNextIndex - nLastIndex );
}
return aSubdata;
}
Node* TypeDetectionImporter::findTypeNode( const OUString& rType )
{
// now delete type nodes
NodeVector::iterator aIter = maTypeNodes.begin();
while( aIter != maTypeNodes.end() )
{
if( (*aIter)->maName == rType )
return (*aIter);
aIter++;
}
return NULL;
}
filter_info_impl* TypeDetectionImporter::createFilterForNode( Node * pNode )
{
filter_info_impl* pFilter = new filter_info_impl;
pFilter->maFilterName = pNode->maName;
pFilter->maInterfaceName = pNode->maPropertyMap[sUIName];
OUString aData = pNode->maPropertyMap[sData];
sal_Unicode aComma(',');
pFilter->maType = getSubdata( 1, aComma, aData );
pFilter->maDocumentService = getSubdata( 2, aComma, aData );
OUString aFilterService( getSubdata( 3, aComma, aData ) );
pFilter->maFlags = getSubdata( 4, aComma, aData ).toInt32();
// parse filter user data
sal_Unicode aDelim(';');
OUString aFilterUserData( getSubdata( 5, aComma, aData ) );
OUString aAdapterService( getSubdata( 0, aDelim, aFilterUserData ) );
//Import/ExportService
pFilter->maImportService = getSubdata( 2, aDelim, aFilterUserData );
pFilter->maExportService = getSubdata( 3, aDelim, aFilterUserData );
pFilter->maImportXSLT = getSubdata( 4, aDelim, aFilterUserData );
pFilter->maExportXSLT = getSubdata( 5, aDelim, aFilterUserData );
pFilter->maDTD = getSubdata( 6, aDelim, aFilterUserData );
pFilter->maComment = getSubdata( 7, aDelim, aFilterUserData );
pFilter->maImportTemplate = getSubdata( 7, aComma, aData );
Node* pTypeNode = findTypeNode( pFilter->maType );
if( pTypeNode )
{
OUString aTypeUserData( pTypeNode->maPropertyMap[sData] );
pFilter->maDocType = getSubdata( 2, aComma, aTypeUserData );
pFilter->maExtension = getSubdata( 4, aComma, aTypeUserData );
pFilter->mnDocumentIconID = getSubdata( 5, aComma, aTypeUserData ).toInt32();
}
bool bOk = true;
if( pTypeNode == NULL )
bOk = false;
if( pFilter->maFilterName.getLength() == 0 )
bOk = false;
if( pFilter->maInterfaceName.getLength() == 0 )
bOk = false;
if( pFilter->maType.getLength() == 0 )
bOk = false;
if( pFilter->maFlags == 0 )
bOk = false;
if( aFilterService != sFilterAdaptorService )
bOk = false;
if( aAdapterService != sXSLTFilterService )
bOk = false;
if( pFilter->maExtension.getLength() == 0 )
bOk = false;
if( !bOk )
{
delete pFilter;
pFilter = NULL;
}
return pFilter;
}
void SAL_CALL TypeDetectionImporter::startDocument( )
throw(xml::sax::SAXException, uno::RuntimeException)
{
}
void SAL_CALL TypeDetectionImporter::endDocument( )
throw(xml::sax::SAXException, uno::RuntimeException)
{
}
void SAL_CALL TypeDetectionImporter::startElement( const OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs )
throw(xml::sax::SAXException, uno::RuntimeException)
{
ImportState eNewState = e_Unknown;
if( maStack.empty() )
{
// #109668# support legacy name as well on import
if( aName == sRootNode || aName.equalsAscii("oor:node") )
{
eNewState = e_Root;
}
}
else if( maStack.top() == e_Root )
{
if( aName == sNode )
{
OUString aNodeName( xAttribs->getValueByName( sName ) );
if( aNodeName == sFilters )
{
eNewState = e_Filters;
}
else if( aNodeName == sTypes )
{
eNewState = e_Types;
}
}
}
else if( (maStack.top() == e_Filters) || (maStack.top() == e_Types) )
{
if( aName == sNode )
{
maNodeName = xAttribs->getValueByName( sName );
eNewState = (maStack.top() == e_Filters) ? e_Filter : e_Type;
}
}
else if( (maStack.top() == e_Filter) || (maStack.top() == e_Type))
{
if( aName == sProp )
{
maPropertyName = xAttribs->getValueByName( sName );
eNewState = e_Property;
}
}
else if( maStack.top() == e_Property )
{
if( aName == sValue )
{
eNewState = e_Value;
maValue = OUString();
}
}
maStack.push( eNewState );
}
void SAL_CALL TypeDetectionImporter::endElement( const OUString& /* aName */ )
throw(xml::sax::SAXException, uno::RuntimeException)
{
if( !maStack.empty() )
{
ImportState eCurrentState = maStack.top();
switch( eCurrentState )
{
case e_Filter:
case e_Type:
{
Node* pNode = new Node;
pNode->maName = maNodeName;
pNode->maPropertyMap = maPropertyMap;
maPropertyMap.clear();
if( eCurrentState == e_Filter )
{
maFilterNodes.push_back( pNode );
}
else
{
maTypeNodes.push_back( pNode );
}
}
break;
case e_Property:
maPropertyMap[ maPropertyName ] = maValue;
break;
default: break;
}
maStack.pop();
}
}
void SAL_CALL TypeDetectionImporter::characters( const OUString& aChars )
throw(xml::sax::SAXException, uno::RuntimeException)
{
if( !maStack.empty() && maStack.top() == e_Value )
{
maValue += aChars;
}
}
void SAL_CALL TypeDetectionImporter::ignorableWhitespace( const OUString& /* aWhitespaces */ )
throw(xml::sax::SAXException, uno::RuntimeException)
{
}
void SAL_CALL TypeDetectionImporter::processingInstruction( const OUString& /* aTarget */, const OUString& /* aData */ )
throw(xml::sax::SAXException, uno::RuntimeException)
{
}
void SAL_CALL TypeDetectionImporter::setDocumentLocator( const uno::Reference< xml::sax::XLocator >& /* xLocator */ )
throw(xml::sax::SAXException, uno::RuntimeException)
{
}