/**************************************************************
 *
 * 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_xmlscript.hxx"
#include "xmlbas_import.hxx"
#include "xmlscript/xmlns.h"
#include "xmlscript/xml_helper.hxx"
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/lang/XMultiComponentFactory.hpp>
#include <com/sun/star/script/XLibraryContainerPassword.hpp>
#include <com/sun/star/document/XEmbeddedScripts.hpp>
#include <cppuhelper/implementationentry.hxx>

using namespace ::com::sun::star;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::uno;


//.........................................................................
namespace xmlscript
{
//.........................................................................

    // =============================================================================
    // BasicElementBase
    // =============================================================================

    BasicElementBase::BasicElementBase( const ::rtl::OUString& rLocalName,
            const Reference< xml::input::XAttributes >& xAttributes,
            BasicElementBase* pParent, BasicImport* pImport )
        :m_pImport( pImport )
        ,m_pParent( pParent )
        ,m_aLocalName( rLocalName )
        ,m_xAttributes( xAttributes )
    {
        if ( m_pImport )
            m_pImport->acquire();
        if ( m_pParent )
            m_pParent->acquire();
    }

    // -----------------------------------------------------------------------------

    BasicElementBase::~BasicElementBase()
    {
        if ( m_pImport )
            m_pImport->release();
        if ( m_pParent )
            m_pParent->release();
    }

    // -----------------------------------------------------------------------------

    bool BasicElementBase::getBoolAttr( sal_Bool* pRet, const ::rtl::OUString& rAttrName,
        const ::com::sun::star::uno::Reference< ::com::sun::star::xml::input::XAttributes >& xAttributes,
        sal_Int32 nUid )
    {
        if ( xAttributes.is() )
        {
            ::rtl::OUString aValue( xAttributes->getValueByUidName( nUid, rAttrName ) );
            if ( aValue.getLength() )
            {
                if ( aValue.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "true" ) ) )
                {
                    *pRet = sal_True;
                    return true;
                }
                else if ( aValue.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "false" ) ) )
                {
                    *pRet = sal_False;
                    return true;
                }
                else
                {
                    throw xml::sax::SAXException(
                        rAttrName + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ": no boolean value (true|false)!" ) ),
                        Reference< XInterface >(), Any() );
                }
            }
        }
        return false;
    }

    // -----------------------------------------------------------------------------
    // XElement
    // -----------------------------------------------------------------------------

    Reference< xml::input::XElement > BasicElementBase::getParent()
        throw (RuntimeException)
    {
        return static_cast< xml::input::XElement* >( m_pParent );
    }

    // -----------------------------------------------------------------------------

    ::rtl::OUString BasicElementBase::getLocalName()
        throw (RuntimeException)
    {
        return m_aLocalName;
    }

    // -----------------------------------------------------------------------------

    sal_Int32 BasicElementBase::getUid()
        throw (RuntimeException)
    {
        sal_Int32 nId = -1;
        if ( m_pImport )
            nId = m_pImport->XMLNS_UID;
        return nId;
    }

    // -----------------------------------------------------------------------------

    Reference< xml::input::XAttributes > BasicElementBase::getAttributes()
        throw (RuntimeException)
    {
        return m_xAttributes;
    }

    // -----------------------------------------------------------------------------

    Reference< xml::input::XElement > BasicElementBase::startChildElement(
        sal_Int32 /*nUid*/, const ::rtl::OUString& /*rLocalName*/,
        const Reference< xml::input::XAttributes >& /*xAttributes*/ )
        throw (xml::sax::SAXException, RuntimeException)
    {
        throw xml::sax::SAXException(
            ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "unexpected element!" ) ),
            Reference< XInterface >(), Any() );
    }

    // -----------------------------------------------------------------------------

void BasicElementBase::characters( const ::rtl::OUString& /*rChars*/ )
        throw (xml::sax::SAXException, RuntimeException)
    {
        // not used, all characters ignored
    }

    // -----------------------------------------------------------------------------

void BasicElementBase::ignorableWhitespace( const ::rtl::OUString& /*rWhitespaces*/ )
        throw (xml::sax::SAXException, RuntimeException)
    {
    }

    // -----------------------------------------------------------------------------

void BasicElementBase::processingInstruction( const ::rtl::OUString& /*rTarget*/, const ::rtl::OUString& /*rData*/ )
        throw (xml::sax::SAXException, RuntimeException)
    {
    }

    // -----------------------------------------------------------------------------

    void BasicElementBase::endElement()
        throw (xml::sax::SAXException, RuntimeException)
    {
    }


    // =============================================================================
    // BasicLibrariesElement
    // =============================================================================

    BasicLibrariesElement::BasicLibrariesElement( const ::rtl::OUString& rLocalName,
            const Reference< xml::input::XAttributes >& xAttributes,
            BasicElementBase* pParent, BasicImport* pImport,
            const Reference< script::XLibraryContainer2 >& rxLibContainer )
        :BasicElementBase( rLocalName, xAttributes, pParent, pImport )
        ,m_xLibContainer( rxLibContainer )
    {
    }

    // -----------------------------------------------------------------------------
    // XElement
    // -----------------------------------------------------------------------------

    Reference< xml::input::XElement > BasicLibrariesElement::startChildElement(
            sal_Int32 nUid, const ::rtl::OUString& rLocalName,
            const Reference< xml::input::XAttributes >& xAttributes )
        throw (xml::sax::SAXException, RuntimeException)
    {
        Reference< xml::input::XElement > xElement;

        if ( nUid != m_pImport->XMLNS_UID )
        {
            throw xml::sax::SAXException(
                ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "illegal namespace!" ) ),
                Reference< XInterface >(), Any() );
        }
        else if ( rLocalName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "library-linked" ) ) )
        {
            if ( xAttributes.is() )
            {
                ::rtl::OUString aName = xAttributes->getValueByUidName(
                    m_pImport->XMLNS_UID,
                    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "name" ) ) );

                ::rtl::OUString aStorageURL = xAttributes->getValueByUidName(
                    m_pImport->XMLNS_XLINK_UID,
                    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "href" ) ) );

                sal_Bool bReadOnly = sal_False;
                getBoolAttr( &bReadOnly,
                    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "readonly" ) ),
                    xAttributes, m_pImport->XMLNS_UID );

                if ( m_xLibContainer.is() )
                {
                    try
                    {
                        Reference< container::XNameAccess > xLib(
                            m_xLibContainer->createLibraryLink( aName, aStorageURL, bReadOnly ) );
                        if ( xLib.is() )
                            xElement.set( new BasicElementBase( rLocalName, xAttributes, this, m_pImport ) );
                    }
                    catch ( container::ElementExistException& e )
                    {
                        OSL_TRACE( "BasicLibrariesElement::startChildElement: caught ElementExceptionExist reason %s",
                            ::rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).pData->buffer );
                    }
                    catch ( lang::IllegalArgumentException& e )
                    {
                        OSL_TRACE( "BasicLibrariesElement::startChildElement: caught IllegalArgumentException reason %s",
                            ::rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).pData->buffer );
                    }
                }
            }
        }
        else if ( rLocalName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "library-embedded" ) ) )
        {
            // TODO: create password protected libraries

            if ( xAttributes.is() )
            {
                ::rtl::OUString aName = xAttributes->getValueByUidName(
                    m_pImport->XMLNS_UID,
                    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "name" ) ) );

                sal_Bool bReadOnly = sal_False;
                getBoolAttr( &bReadOnly,
                    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "readonly" ) ),
                    xAttributes, m_pImport->XMLNS_UID );

                if ( m_xLibContainer.is() )
                {
                    try
                    {
                        Reference< container::XNameContainer > xLib;
                        if ( m_xLibContainer->hasByName( aName ) )
                        {
                            // Standard library
                            m_xLibContainer->getByName( aName ) >>= xLib;
                        }
                        else
                        {
                            xLib.set( m_xLibContainer->createLibrary( aName ) );
                        }

                        if ( xLib.is() )
                            xElement.set( new BasicEmbeddedLibraryElement( rLocalName, xAttributes, this, m_pImport, m_xLibContainer, aName, bReadOnly ) );
                    }
                    catch ( lang::IllegalArgumentException& e )
                    {
                        OSL_TRACE( "BasicLibrariesElement::startChildElement: caught IllegalArgumentException reason %s",
                            ::rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).pData->buffer );
                    }
                }
            }
        }
        else
        {
            throw xml::sax::SAXException(
                ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "expected library-linked or library-embedded element!" ) ),
                Reference< XInterface >(), Any() );
        }

        return xElement;
    }

    // -----------------------------------------------------------------------------

    void BasicLibrariesElement::endElement()
        throw (xml::sax::SAXException, RuntimeException)
    {
    }


    // =============================================================================
    // BasicEmbeddedLibraryElement
    // =============================================================================

    BasicEmbeddedLibraryElement::BasicEmbeddedLibraryElement( const ::rtl::OUString& rLocalName,
            const Reference< xml::input::XAttributes >& xAttributes,
            BasicElementBase* pParent, BasicImport* pImport,
            const Reference< script::XLibraryContainer2 >& rxLibContainer,
            const ::rtl::OUString& rLibName, bool bReadOnly )
        :BasicElementBase( rLocalName, xAttributes, pParent, pImport )
        ,m_xLibContainer( rxLibContainer )
        ,m_aLibName( rLibName )
        ,m_bReadOnly( bReadOnly )
    {
        try
        {
            if ( m_xLibContainer.is() && m_xLibContainer->hasByName( m_aLibName ) )
                m_xLibContainer->getByName( m_aLibName ) >>= m_xLib;
        }
        catch ( lang::WrappedTargetException& e )
        {
            OSL_TRACE( "BasicEmbeddedLibraryElement CTOR: caught WrappedTargetException reason %s",
                ::rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).pData->buffer );
        }
    }

    // -----------------------------------------------------------------------------
    // XElement
    // -----------------------------------------------------------------------------

    Reference< xml::input::XElement > BasicEmbeddedLibraryElement::startChildElement(
            sal_Int32 nUid, const ::rtl::OUString& rLocalName,
            const Reference< xml::input::XAttributes >& xAttributes )
        throw (xml::sax::SAXException, RuntimeException)
    {
        Reference< xml::input::XElement > xElement;

        if ( nUid != m_pImport->XMLNS_UID )
        {
            throw xml::sax::SAXException(
                ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "illegal namespace!" ) ),
                Reference< XInterface >(), Any() );
        }
        else if ( rLocalName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "module" ) ) )
        {
            if ( xAttributes.is() )
            {
                ::rtl::OUString aName = xAttributes->getValueByUidName(
                    m_pImport->XMLNS_UID,
                    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "name" ) ) );

                if ( m_xLib.is() && aName.getLength() )
                    xElement.set( new BasicModuleElement( rLocalName, xAttributes, this, m_pImport, m_xLib, aName ) );
            }
        }
        else
        {
            throw xml::sax::SAXException(
                ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "expected module element!" ) ),
                Reference< XInterface >(), Any() );
        }

        return xElement;
    }

    // -----------------------------------------------------------------------------

    void BasicEmbeddedLibraryElement::endElement()
        throw (xml::sax::SAXException, RuntimeException)
    {
        if ( m_xLibContainer.is() && m_xLibContainer->hasByName( m_aLibName ) && m_bReadOnly )
            m_xLibContainer->setLibraryReadOnly( m_aLibName, m_bReadOnly );
    }


    // =============================================================================
    // BasicModuleElement
    // =============================================================================

    BasicModuleElement::BasicModuleElement( const ::rtl::OUString& rLocalName,
            const Reference< xml::input::XAttributes >& xAttributes,
            BasicElementBase* pParent, BasicImport* pImport,
            const Reference< container::XNameContainer >& rxLib, const ::rtl::OUString& rName )
        :BasicElementBase( rLocalName, xAttributes, pParent, pImport )
        ,m_xLib( rxLib )
        ,m_aName( rName )
    {
    }

    // -----------------------------------------------------------------------------
    // XElement
    // -----------------------------------------------------------------------------

    Reference< xml::input::XElement > BasicModuleElement::startChildElement(
            sal_Int32 nUid, const ::rtl::OUString& rLocalName,
            const Reference< xml::input::XAttributes >& xAttributes )
        throw (xml::sax::SAXException, RuntimeException)
    {
        // TODO: <byte-code>

        Reference< xml::input::XElement > xElement;

        if ( nUid != m_pImport->XMLNS_UID )
        {
            throw xml::sax::SAXException(
                ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "illegal namespace!" ) ),
                Reference< XInterface >(), Any() );
        }
        else if ( rLocalName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "source-code" ) ) )
        {
            // TODO: password protected libraries

            if ( xAttributes.is() )
            {
                if ( m_xLib.is() && m_aName.getLength() )
                    xElement.set( new BasicSourceCodeElement( rLocalName, xAttributes, this, m_pImport, m_xLib, m_aName ) );
            }
        }
        else
        {
            throw xml::sax::SAXException(
                ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "expected source-code element!" ) ),
                Reference< XInterface >(), Any() );
        }

        return xElement;
    }

    // -----------------------------------------------------------------------------

    void BasicModuleElement::endElement()
        throw (xml::sax::SAXException, RuntimeException)
    {
    }


    // =============================================================================
    // BasicSourceCodeElement
    // =============================================================================

    BasicSourceCodeElement::BasicSourceCodeElement( const ::rtl::OUString& rLocalName,
            const Reference< xml::input::XAttributes >& xAttributes,
            BasicElementBase* pParent, BasicImport* pImport,
            const Reference< container::XNameContainer >& rxLib, const ::rtl::OUString& rName )
        :BasicElementBase( rLocalName, xAttributes, pParent, pImport )
        ,m_xLib( rxLib )
        ,m_aName( rName )
    {
    }

    // -----------------------------------------------------------------------------
    // XElement
    // -----------------------------------------------------------------------------

    void BasicSourceCodeElement::characters( const ::rtl::OUString& rChars )
        throw (xml::sax::SAXException, RuntimeException)
    {
        m_aBuffer.append( rChars );
    }

    // -----------------------------------------------------------------------------

    void BasicSourceCodeElement::endElement()
        throw (xml::sax::SAXException, RuntimeException)
    {
        try
        {
            if ( m_xLib.is() && m_aName.getLength() )
            {
                Any aElement;
		        aElement <<= m_aBuffer.makeStringAndClear();
		        m_xLib->insertByName( m_aName, aElement );
            }
        }
        catch ( container::ElementExistException& e )
        {
            OSL_TRACE( "BasicSourceCodeElement::endElement: caught ElementExceptionExist reason %s",
                ::rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).pData->buffer );
        }
        catch ( lang::IllegalArgumentException& e )
        {
            OSL_TRACE( "BasicSourceCodeElement::endElement: caught IllegalArgumentException reason %s",
                ::rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).pData->buffer );
        }
        catch ( lang::WrappedTargetException& e )
        {
            OSL_TRACE( "BasicSourceCodeElement::endElement: caught WrappedTargetException reason %s",
                ::rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).pData->buffer );
        }
    }


    // =============================================================================
    // BasicImport
    // =============================================================================

    BasicImport::BasicImport( const Reference< frame::XModel >& rxModel, sal_Bool bOasis )
        :m_xModel( rxModel )
        ,m_bOasis( bOasis )
    {
    }

    // -----------------------------------------------------------------------------

    BasicImport::~BasicImport()
    {
    }

    // -----------------------------------------------------------------------------
    // XRoot
    // -----------------------------------------------------------------------------

    void BasicImport::startDocument( const Reference< xml::input::XNamespaceMapping >& xNamespaceMapping )
        throw (xml::sax::SAXException, RuntimeException)
    {
        if ( xNamespaceMapping.is() )
        {
            ::rtl::OUString aURI;
            if ( m_bOasis )
                aURI = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_OOO_URI ) );
            else
                aURI = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_SCRIPT_URI ) );
            XMLNS_UID = xNamespaceMapping->getUidByUri( aURI );
            XMLNS_XLINK_UID = xNamespaceMapping->getUidByUri( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK_URI ) ) );
        }
    }

    // -----------------------------------------------------------------------------

    void BasicImport::endDocument()
        throw (xml::sax::SAXException, RuntimeException)
    {
    }

    // -----------------------------------------------------------------------------

void BasicImport::processingInstruction( const ::rtl::OUString& /*rTarget*/, const ::rtl::OUString& /*rData*/ )
        throw (xml::sax::SAXException, RuntimeException)
    {
    }

    // -----------------------------------------------------------------------------

void BasicImport::setDocumentLocator( const Reference< xml::sax::XLocator >& /*xLocator*/ )
        throw (xml::sax::SAXException, RuntimeException)
    {
    }

    // -----------------------------------------------------------------------------

    Reference< xml::input::XElement > BasicImport::startRootElement( sal_Int32 nUid, const ::rtl::OUString& rLocalName,
            Reference< xml::input::XAttributes > const & xAttributes )
        throw (xml::sax::SAXException, RuntimeException)
    {
        Reference< xml::input::XElement > xElement;

        if ( nUid != XMLNS_UID )
        {
            throw xml::sax::SAXException(
                ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "illegal namespace!" ) ),
                Reference< XInterface >(), Any() );
        }
        else if ( rLocalName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "libraries" ) ) )
        {
            Reference< script::XLibraryContainer2 > xLibContainer;

            // try the XEmbeddedScripts interface
            Reference< document::XEmbeddedScripts > xDocumentScripts( m_xModel, UNO_QUERY );
            if ( xDocumentScripts.is() )
                xLibContainer.set( xDocumentScripts->getBasicLibraries().get() );

            if ( !xLibContainer.is() )
            {
                // try the "BasicLibraries" property (old-style, for compatibility)
                Reference< beans::XPropertySet > xPSet( m_xModel, UNO_QUERY );
                if ( xPSet.is() )
	                xPSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BasicLibraries" ) ) ) >>= xLibContainer;
            }

            OSL_ENSURE( xLibContainer.is(), "BasicImport::startRootElement: nowhere to import to!" );

            if ( xLibContainer.is() )
            {
                xElement.set( new BasicLibrariesElement( rLocalName, xAttributes, 0, this, xLibContainer ) );
            }
        }
        else
        {
            throw xml::sax::SAXException(
                ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "illegal root element (expected libraries) given: " ) ) +
                rLocalName, Reference< XInterface >(), Any() );
        }

        return xElement;
    }


    // =============================================================================
    // component operations
    // =============================================================================

    ::rtl::OUString getImplementationName_XMLBasicImporter()
    {
        static ::rtl::OUString* pImplName = 0;
	    if ( !pImplName )
	    {
            ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
            if ( !pImplName )
		    {
                static ::rtl::OUString aImplName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.xmlscript.XMLBasicImporter" ) );
			    pImplName = &aImplName;
		    }
	    }
	    return *pImplName;
    }

    // -----------------------------------------------------------------------------

    Sequence< ::rtl::OUString > getSupportedServiceNames_XMLBasicImporter()
    {
        static Sequence< ::rtl::OUString >* pNames = 0;
	    if ( !pNames )
	    {
            ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
		    if ( !pNames )
		    {
                static Sequence< ::rtl::OUString > aNames(1);
                aNames.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.XMLBasicImporter" ) );
                pNames = &aNames;
		    }
	    }
	    return *pNames;
    }

    // -----------------------------------------------------------------------------

    ::rtl::OUString getImplementationName_XMLOasisBasicImporter()
    {
        static ::rtl::OUString* pImplName = 0;
	    if ( !pImplName )
	    {
            ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
            if ( !pImplName )
		    {
                static ::rtl::OUString aImplName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.xmlscript.XMLOasisBasicImporter" ) );
			    pImplName = &aImplName;
		    }
	    }
	    return *pImplName;
    }

    // -----------------------------------------------------------------------------

    Sequence< ::rtl::OUString > getSupportedServiceNames_XMLOasisBasicImporter()
    {
        static Sequence< ::rtl::OUString >* pNames = 0;
	    if ( !pNames )
	    {
            ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
		    if ( !pNames )
		    {
                static Sequence< ::rtl::OUString > aNames(1);
                aNames.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.XMLOasisBasicImporter" ) );
                pNames = &aNames;
		    }
	    }
	    return *pNames;
    }


    // =============================================================================
    // XMLBasicImporterBase
    // =============================================================================

    XMLBasicImporterBase::XMLBasicImporterBase( const Reference< XComponentContext >& rxContext, sal_Bool bOasis )
        :m_xContext( rxContext )
        ,m_bOasis( bOasis )
    {
    }

    // -----------------------------------------------------------------------------

    XMLBasicImporterBase::~XMLBasicImporterBase()
    {
    }

    // -----------------------------------------------------------------------------
    // XServiceInfo
    // -----------------------------------------------------------------------------

    sal_Bool XMLBasicImporterBase::supportsService( const ::rtl::OUString& rServiceName ) throw (RuntimeException)
    {
	    Sequence< ::rtl::OUString > aNames( getSupportedServiceNames() );
	    const ::rtl::OUString* pNames = aNames.getConstArray();
	    const ::rtl::OUString* pEnd = pNames + aNames.getLength();
	    for ( ; pNames != pEnd && !pNames->equals( rServiceName ); ++pNames )
		    ;

	    return pNames != pEnd;
    }

    // -----------------------------------------------------------------------------
    // XImporter
    // -----------------------------------------------------------------------------

    void XMLBasicImporterBase::setTargetDocument( const Reference< XComponent >& rxDoc )
	    throw (IllegalArgumentException, RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );

        m_xModel.set( rxDoc, UNO_QUERY );

        if ( !m_xModel.is() )
        {
            throw IllegalArgumentException(
                ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XMLBasicExporter::setTargetDocument: no document model!" ) ),
                Reference< XInterface >(), 1 );
        }

        if ( m_xContext.is() )
        {
            Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager() );
            if ( xSMgr.is() )
            {
                Reference < xml::input::XRoot > xRoot( new BasicImport( m_xModel, m_bOasis ) );
	            Sequence < Any > aArgs( 1 );
	            aArgs[0] <<= xRoot;
                m_xHandler.set( xSMgr->createInstanceWithArgumentsAndContext(
                    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.input.SaxDocumentHandler" ) ),
                    aArgs, m_xContext ), UNO_QUERY );
            }
        }
    }

    // -----------------------------------------------------------------------------
    // XDocumentHandler
    // -----------------------------------------------------------------------------

    void XMLBasicImporterBase::startDocument()
        throw (xml::sax::SAXException, RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );

        if ( m_xHandler.is() )
            m_xHandler->startDocument();
    }

    // -----------------------------------------------------------------------------

    void XMLBasicImporterBase::endDocument()
        throw (xml::sax::SAXException, RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );

        if ( m_xHandler.is() )
            m_xHandler->endDocument();
    }

    // -----------------------------------------------------------------------------

    void XMLBasicImporterBase::startElement( const ::rtl::OUString& aName,
            const Reference< xml::sax::XAttributeList >& xAttribs )
        throw (xml::sax::SAXException, RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );

        if ( m_xHandler.is() )
            m_xHandler->startElement( aName, xAttribs );
    }

    // -----------------------------------------------------------------------------

    void XMLBasicImporterBase::endElement( const ::rtl::OUString& aName )
        throw (xml::sax::SAXException, RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );

        if ( m_xHandler.is() )
            m_xHandler->endElement( aName );
    }

    // -----------------------------------------------------------------------------

    void XMLBasicImporterBase::characters( const ::rtl::OUString& aChars )
        throw (xml::sax::SAXException, RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );

        if ( m_xHandler.is() )
            m_xHandler->characters( aChars );
    }

    // -----------------------------------------------------------------------------

    void XMLBasicImporterBase::ignorableWhitespace( const ::rtl::OUString& aWhitespaces )
        throw (xml::sax::SAXException, RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );

        if ( m_xHandler.is() )
            m_xHandler->ignorableWhitespace( aWhitespaces );
    }

    // -----------------------------------------------------------------------------

    void XMLBasicImporterBase::processingInstruction( const ::rtl::OUString& aTarget,
            const ::rtl::OUString& aData )
        throw (xml::sax::SAXException, RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );

        if ( m_xHandler.is() )
            m_xHandler->processingInstruction( aTarget, aData );
    }

    // -----------------------------------------------------------------------------

    void XMLBasicImporterBase::setDocumentLocator( const Reference< xml::sax::XLocator >& xLocator )
        throw (xml::sax::SAXException, RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );

        if ( m_xHandler.is() )
            m_xHandler->setDocumentLocator( xLocator );
    }


    // =============================================================================
    // XMLBasicImporter
    // =============================================================================

    XMLBasicImporter::XMLBasicImporter( const Reference< XComponentContext >& rxContext )
        :XMLBasicImporterBase( rxContext, sal_False )
    {
    }

    // -----------------------------------------------------------------------------

    XMLBasicImporter::~XMLBasicImporter()
    {
    }

    // -----------------------------------------------------------------------------
    // XServiceInfo
    // -----------------------------------------------------------------------------

    ::rtl::OUString XMLBasicImporter::getImplementationName(  ) throw (RuntimeException)
    {
        return getImplementationName_XMLBasicImporter();
    }

    // -----------------------------------------------------------------------------

    Sequence< ::rtl::OUString > XMLBasicImporter::getSupportedServiceNames(  ) throw (RuntimeException)
    {
        return getSupportedServiceNames_XMLBasicImporter();
    }


    // =============================================================================
    // XMLOasisBasicImporter
    // =============================================================================

    XMLOasisBasicImporter::XMLOasisBasicImporter( const Reference< XComponentContext >& rxContext )
        :XMLBasicImporterBase( rxContext, sal_True )
    {
    }

    // -----------------------------------------------------------------------------

    XMLOasisBasicImporter::~XMLOasisBasicImporter()
    {
    }

    // -----------------------------------------------------------------------------
    // XServiceInfo
    // -----------------------------------------------------------------------------

    ::rtl::OUString XMLOasisBasicImporter::getImplementationName(  ) throw (RuntimeException)
    {
        return getImplementationName_XMLOasisBasicImporter();
    }

    // -----------------------------------------------------------------------------

    Sequence< ::rtl::OUString > XMLOasisBasicImporter::getSupportedServiceNames(  ) throw (RuntimeException)
    {
        return getSupportedServiceNames_XMLOasisBasicImporter();
    }


    // =============================================================================
    // component operations
    // =============================================================================

    Reference< XInterface > SAL_CALL create_XMLBasicImporter(
        Reference< XComponentContext > const & xContext )
        SAL_THROW( () )
    {
        return static_cast< lang::XTypeProvider * >( new XMLBasicImporter( xContext ) );
    }

    // -----------------------------------------------------------------------------

    Reference< XInterface > SAL_CALL create_XMLOasisBasicImporter(
        Reference< XComponentContext > const & xContext )
        SAL_THROW( () )
    {
        return static_cast< lang::XTypeProvider * >( new XMLOasisBasicImporter( xContext ) );
    }

    // -----------------------------------------------------------------------------

//.........................................................................
}	// namespace xmlscript
//.........................................................................
