//--------------------------------------------------------------------------- #include #include // 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 &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 &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 ©args) { 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 &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 &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 ); } }