Subversion Repositories DevTools

Rev

Blame | Last modification | View Log | RSS feed

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

#include <vcl.h>
#include <IniFiles.hpp> // Pascal unit
#pragma hdrstop

#include "TXMLSchema.h"
#include "XMLSchemaHandles.h"
#include "XMLSchemaProxyDatatypes.h"

#include "ISchemaElement.h"
#include "ISchemaValidationObserver.h"

#include "IXmlSchemaWrapperFactory.h"
#include "IXmlSchemaWrapperHandle.h"
#include "IXmlSchemaWrapperQualification.h"
#include "IXmlSchemaWrapperSchema.h"
#include "IXmlSchemaWrapperStream.h"
#include "IXmlSchemaWrapperString.h"
#include "IXmlSchemaWrapperStringCollection.h"

using namespace XMLSchema;

#pragma package(smart_init)

class nullValidationObserver : public virtual ISchemaValidationObserver
{
public:
        virtual void validationFailure( const XMLSchema::ISchemaElement & schemaElement,
                                                                        const char *constraint,
                                                                        const char *message )
        {
        }

        virtual void validationSuccess( const XMLSchema::ISchemaElement& schemaElement,
                                                                        const char *constraint,
                                                                        const char *message )
        {
        }
};


//---------------------------------------------------------------------------
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
//

static inline void ValidCtrCheck(TXMLSchema *)
{
        new TXMLSchema(NULL);
}
//---------------------------------------------------------------------------
__fastcall TXMLSchema::TXMLSchema(TComponent* Owner)
                : TComponent(Owner),
                  m_xmlSchemaWrapper( 0 ),
                  m_getXmlSchemaWrapperFactory( 0 ),
                  m_xmlSchemaWrapperFactory( 0 ),
                  m_xmlSchema( 0 )
{
        setProfile( "XMLSchema.ini" );
        readProfile();
}
//---------------------------------------------------------------------------
namespace Xmlschema
{
        void __fastcall PACKAGE Register()
        {
        TComponentClass classes[1] = {__classid(TXMLSchema)};
        RegisterComponents("XML Schema", classes, 0);
    }
}
//------------------------------------------------------------------------------


//------------------------------------------------------------------------------
void __fastcall TXMLSchema::setProfile( const AnsiString & profile )
{
        m_profile = profile;
}


//------------------------------------------------------------------------------
AnsiString & __fastcall TXMLSchema::prependMassConfig( AnsiString & string, const AnsiString & filename )
{
        // any absolute path characters at start of filename implies we ignore MASS_CONFIG
        switch ( filename[ 1 ] )
        {
                case '.':
                case '/':
                case '\\':
                case 0:         // save checking length == 0 for next test
                        return ( string = filename );
        }

        // check if drive letter at start of filename
        if ( filename.Length() >= 3
                        && isalpha( filename[ 1 ] ) != 0                        // a-z or A-Z
                        && filename[ 2 ] == ':'                                         // :
                        && strchr( "/\\", filename[ 3 ] ) != 0 )        // / or \\
        {
                return ( string = filename );
        }

        char path[ 1024 ];
        if ( GetEnvironmentVariable( "CONFIGPATH", path, sizeof( path ) ) )
        {
                string = path;
        }
        else
        {
                string = "";
        }

        // make sure we have the path delimiter
        if ( !string.IsEmpty() &&
                 strchr( "/\\", string[ string.Length() ] ) == 0 )
        {
                string += "\\";
        }
        string += filename;
        
        return ( string );
}


//------------------------------------------------------------------------------
void __fastcall TXMLSchema::readProfile()
{
        TIniFile * profile = 0;
        try
        {
                AnsiString file;

                profile = new TIniFile( prependMassConfig( file, m_profile ) );

                m_xmlSchemaWrapperLibrary = profile->ReadString( "Init", "Wrapper", "XmlSchemaWrapperD.dll" );

                if ( m_xmlSchemaWrapperLibrary.IsEmpty() )
                {
                        Application->MessageBox(
                                "Attribute \"Wrapper\" in section \"Init\" is empty.  Cannot load XML Schema Wrapper.",
                                "TXMLSchema",
                                MB_OK );
                }
        }
        __finally
        {
                delete profile;
                profile = 0;
        }
}


//------------------------------------------------------------------------------
void __fastcall TXMLSchema::SetActive(bool Value)
{
        if ( Value == false )
        {
                m_active = false;

                if ( m_xmlSchemaWrapperFactory )
                {
                        if ( m_xmlSchema )
                        {
                                m_xmlSchema->close();

                                m_xmlSchemaWrapperFactory->destroySchema( *m_xmlSchema );
                                m_xmlSchema = 0;
                        }

                        m_xmlSchemaWrapperFactory->stop();
                        m_xmlSchemaWrapperFactory = 0;
                }
                m_getXmlSchemaWrapperFactory = 0;
                if ( m_xmlSchemaWrapper )
                {
                        ::FreeLibrary( m_xmlSchemaWrapper );
                        m_xmlSchemaWrapper = 0;
                }
        }
        else
        {
                if ( !m_xmlSchemaWrapperLibrary.IsEmpty() )
                {
                        m_xmlSchemaWrapper = ::LoadLibrary( m_xmlSchemaWrapperLibrary.c_str() );
                        if ( m_xmlSchemaWrapper )
                        {
                                m_getXmlSchemaWrapperFactory = ( getXmlSchemaWrapperFactory_t )::GetProcAddress( m_xmlSchemaWrapper, "getXmlSchemaWrapperFactory" );
                                if ( m_getXmlSchemaWrapperFactory )
                                {
                                        m_xmlSchemaWrapperFactory = &m_getXmlSchemaWrapperFactory();
                                        if ( m_xmlSchemaWrapperFactory )
                                        {
                                                if ( m_xmlSchemaWrapperFactory->start( m_profile.c_str() ) )
                                                {
                                                        m_xmlSchema = &m_xmlSchemaWrapperFactory->createSchema();
                                                        m_xmlSchema->open();

                                                        m_moduleName    = m_xmlSchema->getModuleName();
                                                        m_moduleVersion = m_xmlSchema->getModuleVersion();
                                                }
                                        }
                                }
                        }
                }
                else
                {
                        Application->MessageBox(
                                "Attribute \"Wrapper\" in section \"Init\" is empty.  Cannot load XML Schema Wrapper.",
                                "TXMLSchema",
                                MB_OK );
                }
    }
}

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

bool __fastcall TXMLSchema::Refresh()
{
        SetActive(false);

    SetActive(true);

        return true;
}

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

bool __fastcall TXMLSchema::GetSchemas(std::vector<std::string> &schemas)
{
        if ( m_xmlSchema )
        {
                IXmlSchemaWrapperStringCollection * collection = 0;

                try
                {
                        collection = &m_xmlSchemaWrapperFactory->createStringCollection();
                        if ( m_xmlSchema->getSchemas( *collection ) )
                        {
                                schemas.clear();
                                const unsigned int size = collection->size();
                                for ( unsigned int position = 0; position < size; ++position )
                                {
                                        schemas.push_back( collection->operator[]( position ) );
                                }
                                return ( true );
                        }
                }
                __finally
                {
                        m_xmlSchemaWrapperFactory->destroyStringCollection( *collection );
                        collection = 0;
                }
        }

        return ( false );
}

bool __fastcall TXMLSchema::GetAttributes(const std::string& handle, std::vector<std::string> &attributes, bool specificationOnly)
{
        if ( m_xmlSchema )
        {
                IXmlSchemaWrapperStringCollection * collection = 0;

                try
                {
                        collection = &m_xmlSchemaWrapperFactory->createStringCollection();
                        if ( m_xmlSchema->getAttributes( handle.c_str(), *collection, specificationOnly ) )
                        {
                                attributes.clear();
                                const unsigned int size = collection->size();
                                for ( unsigned int position = 0; position < size; ++position )
                                {
                                        attributes.push_back( collection->operator[]( position ) );
                                }
                                return ( true );
                        }
                }
                __finally
                {
                        m_xmlSchemaWrapperFactory->destroyStringCollection( *collection );
                        collection = 0;
                }
        }

        return ( false );
}

bool __fastcall TXMLSchema::GetAttributeProperty(const std::string &handle, const std::string &property_name, std::string &value)
{
        if ( m_xmlSchema )
        {
                IXmlSchemaWrapperString * attributeValue = 0;

                try
                {
                        attributeValue = &m_xmlSchemaWrapperFactory->createString();
                        if ( m_xmlSchema->getAttributeProperty( handle.c_str(), "", property_name.c_str(), *attributeValue ) )
                        {
                                value = attributeValue->c_str();
                                return ( true );
                        }
                }
                __finally
                {
                        m_xmlSchemaWrapperFactory->destroyString( *attributeValue );
                        attributeValue = 0;
                }
        }

        return ( false );
}

bool __fastcall TXMLSchema::Create (const char *structure_name, unsigned short version, std::string &handle, const char *qualifier)
{
        if ( m_xmlSchema )
        {
                IXmlSchemaWrapperHandle * wrapperHandle = 0;

                try
                {
                        wrapperHandle = &m_xmlSchemaWrapperFactory->createHandle();
                        if ( m_xmlSchema->createStructure( structure_name, version, *wrapperHandle, qualifier ) )
                        {
                                handle = wrapperHandle->c_str();
                                return ( true );
                        }
                }
                __finally
                {
                        m_xmlSchemaWrapperFactory->destroyHandle( *wrapperHandle );
                        wrapperHandle = 0;
                }
        }

        return ( false );
}

bool __fastcall TXMLSchema::Create(const char *schema, const char *structure_name, unsigned short version, std::string &handle, const char *qualifier)
{
        if ( m_xmlSchema )
        {
                IXmlSchemaWrapperHandle * wrapperHandle = 0;

                try
                {
                        wrapperHandle = &m_xmlSchemaWrapperFactory->createHandle();
                        if ( m_xmlSchema->createStructure( structure_name, version, *wrapperHandle, qualifier ) )
                        {
                                handle = wrapperHandle->c_str();
                                return ( true );
                        }
                }
                __finally
                {
                        m_xmlSchemaWrapperFactory->destroyHandle( *wrapperHandle );
                        wrapperHandle = 0;
                }
        }

        return ( false );
}

bool __fastcall TXMLSchema::Destroy(std::string& handle)
{
        if ( m_xmlSchema )
        {
                return ( m_xmlSchema->destroyStructure( handle.c_str() ) );
        }

        return ( false );
}

bool __fastcall TXMLSchema::Copy (const std::string &src_handle, const std::string &dest_handle, const XMLSchema::XMLSchemaCopyArgs &copyargs)
{
        if ( m_xmlSchema )
        {
                return ( m_xmlSchema->copyStructure(
                        dest_handle.c_str(),
                        src_handle.c_str(),
                        copyargs.searchByName,
                        copyargs.searchByTag,
                        copyargs.errorOnFindFailure ) );
        }

        return ( false );
}

bool __fastcall TXMLSchema::Deserialise(const std::string& handle, const std::string& streamtype, const std::string& stream_args, int &required_alignment, const char *buffer, unsigned int bufsize, XMLSchema::StreamCallback callbackfn)
{
        if ( m_xmlSchema )
        {
                IXmlSchemaWrapperStream * stream = 0;

                try
                {
                        if ( streamtype == "XDR" )
                        {
                                stream = &m_xmlSchemaWrapperFactory->createXdrStream();
                        }
                        else if ( streamtype == "XML" )
                        {
                                stream = &m_xmlSchemaWrapperFactory->createXmlStream();
                        }
                        else
                        {
                                stream = &m_xmlSchemaWrapperFactory->createBinaryStream();
                        }

                        stream->putData( buffer, bufsize );
                        if ( callbackfn )
                        {
                                stream->setCallback( callbackfn );
                        }
                        if ( !stream_args.empty() )
                        {
                                stream->setArguments( stream_args.c_str() );
                        }

                        return ( m_xmlSchema->deserialise(
                                handle.c_str(),
                                *stream,
                                required_alignment ) );
                }
                __finally
                {
                        m_xmlSchemaWrapperFactory->destroyStream( *stream );
                        stream = 0;
                }
        }

        return ( false );
}

bool __fastcall TXMLSchema::Serialise (const std::string &handle, const std::string& streamtype, const std::string& stream_args, void *&stream, unsigned int& stream_size, XMLSchema::IXmlSchemaWrapperQualification * qualifier, const char *serialise_qualifier, unsigned char required_alignment)
{
        if ( m_xmlSchema )
        {
                IXmlSchemaWrapperStream * wrapperStream = 0;

                try
                {
                        if ( streamtype == "XDR" )
                        {
                                wrapperStream = &m_xmlSchemaWrapperFactory->createXdrStream();
                        }
                        else if ( streamtype == "XML" )
                        {
                                wrapperStream = &m_xmlSchemaWrapperFactory->createXmlStream();
                        }
                        else
                        {
                                wrapperStream = &m_xmlSchemaWrapperFactory->createBinaryStream();
                        }

                        if ( !stream_args.empty() )
                        {
                                wrapperStream->setArguments( stream_args.c_str() );
                        }

                        const bool serialised = m_xmlSchema->serialise(
                                handle.c_str(),
                                *wrapperStream,
                                qualifier,
                                serialise_qualifier,
                                required_alignment );

                        void *                  buffer = 0;
                        unsigned int    length = 0;

                        if ( wrapperStream->getData( buffer, length ) )
                        {
                                stream_size = length;
                                stream = malloc( stream_size );
                                memcpy( stream, buffer, stream_size );
                        }
                        else
                        {
                                stream_size = 0;
                                stream = 0;
                        }

                        return ( serialised );
                }
                __finally
                {
                        m_xmlSchemaWrapperFactory->destroyStream( *wrapperStream );
                        wrapperStream = 0;
                }
        }

        return ( false );
}

bool __fastcall TXMLSchema::SetUDTArgs(const char *udtName, int argc, const char** argv)
{
        if ( m_xmlSchema )
        {
                return ( m_xmlSchema->setUdtArguments( udtName, argc, argv ) );
        }

        return ( false );
}

bool __fastcall TXMLSchema::GetAttributeValue(const std::string &handle, const std::string& attribute_path, std::string &value)
{
        if ( m_xmlSchema )
        {
                IXmlSchemaWrapperString * attributeValue = 0;

                try
                {
                        attributeValue = &m_xmlSchemaWrapperFactory->createString();
                        if ( m_xmlSchema->getAttributeString( handle.c_str(), attribute_path.c_str(), *attributeValue ) )
                        {
                                value = attributeValue->c_str();
                                return ( true );
                        }
                }
                __finally
                {
                        m_xmlSchemaWrapperFactory->destroyString( *attributeValue );
                        attributeValue = 0;
                }
        }

        return ( false );
}

bool __fastcall TXMLSchema::GetAttributeValue(const std::string &handle, const std::string& attribute_path, int &value)
{
        if ( m_xmlSchema )
        {
                return ( m_xmlSchema->getAttributeInteger32( handle.c_str(), attribute_path.c_str(), value ) );
        }

        return ( false );
}

bool __fastcall TXMLSchema::GetAttributeValue(const std::string &handle, const std::string& attribute_path, AnsiString &value)
{
        std::string string_value;

        bool result = GetAttributeValue(handle, attribute_path, string_value);

    if (result)
    {
        value = string_value.c_str();
    }

    return result;
}

bool __fastcall TXMLSchema::SetAttributeValue (const std::string &handle, const std::string& attribute_path, const char *value)
{
        if ( m_xmlSchema )
        {
                return ( m_xmlSchema->setAttributeString( handle.c_str(), attribute_path.c_str(), value ) );
        }

        return ( false );
}

bool __fastcall TXMLSchema::SetAttributeValue (const std::string &handle, const std::string& attribute_path, const int &value)
{
        if ( m_xmlSchema )
        {
                return ( m_xmlSchema->setAttributeInteger32( handle.c_str(), attribute_path.c_str(), value ) );
        }

        return ( false );
}

bool __fastcall TXMLSchema::SetAttributeValue (const std::string &handle, const std::string& attribute_path, void *value, unsigned int len)
{
        if ( m_xmlSchema )
        {
                return ( m_xmlSchema->setAttributeByteArray( handle.c_str(), attribute_path.c_str(), value, len ) );
        }

        return ( false );
}

bool __fastcall TXMLSchema::AddRepeatEntry (const std::string &handle, const unsigned int entry)
{
        if ( m_xmlSchema )
        {
                return ( m_xmlSchema->addRepeatEntry( handle.c_str(), entry ) );
        }

        return ( false );
}

bool __fastcall TXMLSchema::RemoveRepeatEntry (const std::string &handle, const unsigned int entry)
{
        if ( m_xmlSchema )
        {
                return ( m_xmlSchema->removeRepeatEntry( handle.c_str(), entry ) );
        }

        return ( false );
}

bool __fastcall TXMLSchema::Sort(const std::string &handle, const std::string &repeat_name, std::vector<std::string> &sort_fields )
{
        if ( m_xmlSchema )
        {
                IXmlSchemaWrapperStringCollection * collection = 0;

                try
                {
                        collection = &m_xmlSchemaWrapperFactory->createStringCollection();
                        for ( std::vector< std::string >::iterator
                                        where = sort_fields.begin();
                                  where != sort_fields.end();
                                  ++where )
                        {
                                collection->push_back( where->c_str() );
                        }
                        return ( m_xmlSchema->sort( handle.c_str(), repeat_name.c_str(), *collection ) );
                }
                __finally
                {
                        m_xmlSchemaWrapperFactory->destroyStringCollection( *collection );
                        collection = 0;
                }
        }

        return ( false );
}

bool __fastcall TXMLSchema::SetAttributeValue (const std::string &handle, const std::string& attribute_path, const AnsiString &value)
{
        return SetAttributeValue( handle, attribute_path, value.c_str() );
}

bool __fastcall TXMLSchema::GetEnumerationValues (const std::string &handle, const char *enumeration, std::vector<std::string> &values)
{
        if ( m_xmlSchema )
        {
                IXmlSchemaWrapperStringCollection * collection = 0;

                try
                {
                        collection = &m_xmlSchemaWrapperFactory->createStringCollection();
                        if ( m_xmlSchema->getEnumerationValues( handle.c_str(), enumeration, *collection ) )
                        {
                                values.clear();
                                const unsigned int size = collection->size();
                                for ( unsigned int position = 0; position < size; ++position )
                                {
                                        values.push_back( collection->operator[]( position ) );
                                }
                                return ( true );
                        }
                }
                __finally
                {
                        m_xmlSchemaWrapperFactory->destroyStringCollection( *collection );
                        collection = 0;
                }
        }

        return ( false );
}

bool __fastcall TXMLSchema::GetEnumerationIdValue (const std::string &handle, const char *enumeration, const char *id, std::string &value)
{
        if ( m_xmlSchema )
        {
                IXmlSchemaWrapperString * enumerationValue = 0;

                try
                {
                        enumerationValue = &m_xmlSchemaWrapperFactory->createString();
                        if ( m_xmlSchema->getEnumerationIdValue( handle.c_str(), enumeration, id, *enumerationValue ) )
                        {
                                value = enumerationValue->c_str();
                                return ( true );
                        }
                }
                __finally
                {
                        m_xmlSchemaWrapperFactory->destroyString( *enumerationValue );
                        enumerationValue = 0;
                }
        }

        return ( false );
}


void __fastcall TXMLSchema::GetVersionInfo(AnsiString &module_name, AnsiString &module_version)
{
        module_name     = m_moduleName;
    module_version      = m_moduleVersion;
}

bool __fastcall TXMLSchema::Validate (const std::string &handle)
{
        if ( m_xmlSchema )
        {
                nullValidationObserver observer;

                return ( m_xmlSchema->validate( handle.c_str(), observer ) );
        }

        return ( false );
}

XMLSchema::IXmlSchemaWrapperFactory * TXMLSchema::GetSchemaWrapperFactory( void )
{
        return ( m_xmlSchemaWrapperFactory );
}

XMLSchema::IXmlSchemaWrapperSchema * TXMLSchema::GetSchema( void )
{
        return ( m_xmlSchema );
}

XMLSchema::IXmlSchemaWrapperElement * TXMLSchema::CreateSchemaElementAccess( const std::string & handle, const std::string & attribute_path ) const
{
        if ( m_xmlSchema )
        {
                return ( m_xmlSchema->createSchemaElement( handle.c_str(), attribute_path.c_str() ) );
        }

        return ( 0 );
}

void TXMLSchema::DestroySchemaElementAccess( const XMLSchema::IXmlSchemaWrapperElement& instance ) const
{
        if ( m_xmlSchema )
        {
                m_xmlSchema->destroySchemaElement( instance );
        }
}