File: eaf_n_cst_xmlparser.sru
Size: 26744
Date: Tue, 22 Jan 2008 23:39:13 +0100
$PBExportHeader$eaf_n_cst_xmlparser.sru
forward
global type eaf_n_cst_xmlparser from nonvisualobject
end type
end forward

global type eaf_n_cst_xmlparser from nonvisualobject
end type
global eaf_n_cst_xmlparser eaf_n_cst_xmlparser

type variables
protected:

blob                          {200000} iblob_document
string                        is_lastelementname
long                          il_lastposition = 1
long                          il_indentationamount = 4
long                          il_currentindentation = 0

//Debugging/Error references
string                        is_lasterror = ""
boolean                       ib_trace = false
boolean                       ib_debug = false
boolean                       ib_detailed = false
boolean                       ib_warning = false
boolean                       ib_usedatabaselogging = false

//Set the default character set
string                        is_characterset

n_cst_loggingservice_base     inv_log

n_cst_constants               inv_constants

boolean                       ib_usehead = true


end variables

forward prototypes
public function long getattributelist (string axml_element, ref string as_attributenames[], ref string as_attributevalues[])
public function long encode (string as_original, ref string as_encoded)
public function long getelementlist (string as_xmldocument, string as_elememtname, ref string as_elementlist[])
public function long reset ()
public function long addelement (string as_elementname, string as_value)
public function long addelement (string as_elementname)
public function long getdocument (ref string as_xmldocument)
public function long add (string axml_data)
public function long addelement (string as_elementname, string as_value, boolean ab_cdata, boolean ab_encode)
public function long closeelement (string as_elementname)
protected function long setlasterror (string as_error)
public function long setwarning (boolean ab_state)
public function long setusedatabaselogging (boolean ab_value)
public function long settrace (boolean ab_state)
public function long setdetailed (boolean ab_state)
public function long setdebug (boolean ab_state)
public function long propagatelogsettings ()
public function string getlasterror ()
public function long setcharacterset (string as_characterset)
public function long decode (string as_original, ref string as_decoded)
public subroutine setusehead (boolean ab_usehead)
end prototypes

public function long getattributelist (string axml_element, ref string as_attributenames[], ref string as_attributevalues[]);////////////////////////////////////////////////////////////////
// Description:
//    Create array of all attribute values within an element
//
//
// Revisions
//    2.1   - Initial version
// Arguments:  
//    axml_element - The XML element to be parsed
//    REF as_attributenames - Array of attribute names
//    REF as_attributevalues - Array of attribute values
// Returns: 
//     1 - Success 
//    -1 - Failure
//     0 - No attributes found
////////////////////////////////////////////////////////////////
// Copyright © 2000 - 2007 Youngsoft, Inc.  All rights reserved.
// Any distribution of the Youngsoft, Inc. Enterprise Application Framework
// source code in whole or part by other than Youngsoft, Inc. is prohibited.
//////////////////////////////////////////////////////////////// 

constant string METHOD_NAME = "getAttributeList "

inv_log.debugLog( METHOD_NAME, inv_constants.MESSAGE_TYPE_EAF_DEBUG,  "Call was made to n_cst_xmlparser.getAttributeList() but this method has not been implemented!" )


return -1


end function

public function long encode (string as_original, ref string as_encoded);////////////////////////////////////////////////////////////////
// Description:
//    Encode the passed in string according to XML requirements 
//
// Revisions
//    2.1   - Initial version
// Arguments:  
//    as_original - original string
//    as_encoded - REF - encoded string
// Returns: 
//     1 - Success 
//    -1 - Failure
////////////////////////////////////////////////////////////////
// Copyright © 2000 - 2007 Youngsoft, Inc.  All rights reserved.
// Any distribution of the Youngsoft, Inc. Enterprise Application Framework
// source code in whole or part by other than Youngsoft, Inc. is prohibited.
//////////////////////////////////////////////////////////////// 

constant string METHOD_NAME = "encode "

n_cst_stringservice           lnv_helper

lnv_helper = create n_cst_stringservice
inv_log.propagateSettings( lnv_helper )

as_encoded = lnv_helper.globalreplace(  as_original, "&", "&", true)
as_encoded = lnv_helper.globalreplace(  as_encoded, ">", ">", true)
as_encoded = lnv_helper.globalreplace(  as_encoded, "<", "&lt;", true)
as_encoded = lnv_helper.globalreplace(  as_encoded, "'", "&apos;", true)
as_encoded = lnv_helper.globalreplace(  as_encoded, "~"", "&quot;", true)
as_encoded = lnv_helper.globalreplace(  as_encoded, "%", "&#37;", true)

destroy lnv_helper

return 1

end function

public function long getelementlist (string as_xmldocument, string as_elememtname, ref string as_elementlist[]);////////////////////////////////////////////////////////////////
// Description:
//    Create array of element values of type as_elementname from 
//    passed in XML document 
//
//
// Revisions
//    2.1   - Initial version
// Arguments:  
//    axml_document - The XML document to be parsed
//    as_elementname - Entity name requested
//    REF as_entitylist - Array to be populated with entity data
// Returns: 
//     1 - Success 
//    -1 - Failure
//     0 - No entities found
////////////////////////////////////////////////////////////////
// Copyright © 2000 - 2007 Youngsoft, Inc.  All rights reserved.
// Any distribution of the Youngsoft, Inc. Enterprise Application Framework
// source code in whole or part by other than Youngsoft, Inc. is prohibited.
//////////////////////////////////////////////////////////////// 

constant string METHOD_NAME = "getElementList (String, String, REF String )"

string                     ls_empty[]
string                     lxml_temp
long                    ll_start
long                    ll_end
long                    ll_closepos
string                     ls_close
string                  ls_decoded

//reset reference array
as_elementlist = ls_empty

lxml_temp = as_xmldocument

do while( Pos( lxml_temp, "<" + as_elememtname ) > 0 )
   ll_start = Pos( lxml_temp, "<" + as_elememtname ) + 1 + Len( as_elememtname )
   //determine if this is an empty element tag
   ll_closepos = Pos( lxml_temp, ">", ll_start)
   ls_close = Trim( Mid( lxml_temp, ll_start, ll_closepos - ll_start + 1) )
   Choose Case ls_close
      Case "/>"
         //empty element
         as_elementlist[upperBound( as_elementlist ) + 1] = ""
         lxml_temp = Mid( lxml_temp, ll_closepos + 1, Len( lxml_temp ) - ( ll_closepos + 1 ) )
      Case ">"
         ll_end = Pos( lxml_temp, "</" + as_elememtname + ">" )
         decode( Mid( lxml_temp, ll_start + 1, ll_end - ( ll_start + 1 ) ), ls_decoded )
         as_elementlist[UpperBound( as_elementlist ) + 1] = ls_decoded
         lxml_temp = Mid( lxml_temp, ll_end + 3 + Len( as_elememtname ) )
      Case Else
         //Not a correct match
         //Remove and continue
         lxml_temp = Mid( lxml_temp, ll_closepos + 1, Len( lxml_temp ) - ( ll_closepos + 1 ) )
   End Choose
loop

if ( UpperBound( as_elementlist ) = 0 ) then
   return 0
else
   return 1
end if

end function

public function long reset ();////////////////////////////////////////////////////////////////
// Description:
//    Reset all instance variables for the object 
//
//
// Revisions
//    2.1   - Initial version
// Arguments:  
//    None.
// Returns: 
//     1 - Success 
//    -1 - Failure
////////////////////////////////////////////////////////////////
// Copyright © 2000 - 2007 Youngsoft, Inc.  All rights reserved.
// Any distribution of the Youngsoft, Inc. Enterprise Application Framework
// source code in whole or part by other than Youngsoft, Inc. is prohibited.
//////////////////////////////////////////////////////////////// 

constant string METHOD_NAME = "reset "

blob                          {200000} lbl_temp

iblob_document = lbl_temp
is_lastelementname = ""
il_lastposition = 1
il_currentindentation = 0


return 1

end function

public function long addelement (string as_elementname, string as_value);////////////////////////////////////////////////////////////////
// Description:
//    Overloaded version of addElement to add an entire element without formatting
//
// Revisions
//    2.1   - Initial version
// Arguments:  
//    as_elementname - the name of the element to be added
//    as_value - Value to be placed withing the element - null causes the element to be left open
// Returns: 
//     1 - Success 
//    -1 - Failure
////////////////////////////////////////////////////////////////
// Copyright © 2000 - 2007 Youngsoft, Inc.  All rights reserved.
// Any distribution of the Youngsoft, Inc. Enterprise Application Framework
// source code in whole or part by other than Youngsoft, Inc. is prohibited.
//////////////////////////////////////////////////////////////// 

constant string METHOD_NAME = "addElement "

return addElement( as_elementname, as_value, false, false )

end function

public function long addelement (string as_elementname);////////////////////////////////////////////////////////////////
// Description:
//    Overloaded version of addElement to open a new element without data
//
// Revisions
//    3.0   - Initial version
// Arguments:  
//    as_elementname - the name of the element to be added
// Returns: 
//     1 - Success 
//    -1 - Failure
////////////////////////////////////////////////////////////////
// Copyright © 2000 - 2007 Youngsoft, Inc.  All rights reserved.
// Any distribution of the Youngsoft, Inc. Enterprise Application Framework
// source code in whole or part by other than Youngsoft, Inc. is prohibited.
//////////////////////////////////////////////////////////////// 

constant string METHOD_NAME = "addElement "

string ls_value

setNull( ls_value )

return addElement( as_elementname, ls_value, false, false )

end function

public function long getdocument (ref string as_xmldocument);////////////////////////////////////////////////////////////////
// Description:
//    Create and return the XML document in the reference string
//    with the encoding in the XML header
//
// Revisions
//    3.0   - Initial version
// Arguments:  
//    as_xmldocument - (REF) Reference variable to hold the XML document
// Returns: 
//     1 - Success 
//    -1 - Failure
////////////////////////////////////////////////////////////////
// Copyright © 2000 - 2007 Youngsoft, Inc.  All rights reserved.
// Any distribution of the Youngsoft, Inc. Enterprise Application Framework
// source code in whole or part by other than Youngsoft, Inc. is prohibited.
//////////////////////////////////////////////////////////////// 

if ib_usehead then
   as_xmldocument = "<?xml version=~"1.0~" encoding=~"" + is_characterset + "~"?>"
end if

as_xmldocument += string( iblob_document )

return 1

end function

public function long add (string axml_data);////////////////////////////////////////////////////////////////
// Description:
//    Add text to the current blob
//
// Revisions
//    2.1   - Initial version
// Arguments:  
//    as_xml - string containing the text to be added
// Returns: 
//     1 - Success 
//    -1 - Failure
////////////////////////////////////////////////////////////////
// Copyright © 2000 - 2007 Youngsoft, Inc.  All rights reserved.
// Any distribution of the Youngsoft, Inc. Enterprise Application Framework
// source code in whole or part by other than Youngsoft, Inc. is prohibited.
//////////////////////////////////////////////////////////////// 

constant string METHOD_NAME = "add "

long                       ll_pos
long                       ll_bytecount

try
   
   ll_bytecount = 2

   if il_lastposition = 1 then
      ll_pos = 1
   else
      ll_pos = il_lastposition -ll_bytecount
   end if

   il_lastposition = BlobEdit( iblob_document, ll_pos, axml_data )

   if isNull( il_lastposition ) then
      return -1
   end if
finally

end try

return 1

end function

public function long addelement (string as_elementname, string as_value, boolean ab_cdata, boolean ab_encode);////////////////////////////////////////////////////////////////
// Description:
//    Add an element to the XML document held by the parser
//
//
// Revisions
//    3.0   - Initial version
// Arguments:  
//    as_elementname - the name of the element to be added
//    as_value - Value to be placed withing the element - null causes the element to be left open
//    ab_cdata - Indicator to wrap the value in a CDATA tag
//    ab_encode - Indicator to encode the data - ab_encode and ab_cdata are mutually exclusive
// Returns: 
//     1 - Success 
//    -1 - Failure
////////////////////////////////////////////////////////////////
// Copyright © 2000 - 2007 Youngsoft, Inc.  All rights reserved.
// Any distribution of the Youngsoft, Inc. Enterprise Application Framework
// source code in whole or part by other than Youngsoft, Inc. is prohibited.
//////////////////////////////////////////////////////////////// 

constant string METHOD_NAME = "addElement (string, string, boolean, boolean )"

string                  ls_xml
string                  ls_value

//Test for mutually exclusive formatting of data
if ( ab_cdata and ab_encode ) then
   setLastError( METHOD_NAME + "ab_cdata and ab_encode are both true but are mutually exclusive" )
   return -1
end if

//Pad the element with the current indentation and add the begin element tag
//ls_xml = space( il_currentindentation ) + "<" + as_elementname + ">"
ls_xml = "<" + as_elementname + ">"

//Check to see if a data value was passed in from overloaded function
if ( isNull( as_value ) ) then
   //increase the indentation
   il_currentindentation += il_indentationamount
else
   if Len( as_value ) = 0 then
      ls_xml = "<" + as_elementname + "/>"
      if ( this.add( ls_xml ) = 1 ) then
         return 1
      else
         return -1
      end if
   end if
   //CDATA wrapping requested
   if ( ab_cdata ) then
      as_value = "<![CDATA[" + as_value + "]]>"
   end if 
   
   //Encoding requested
   if ( ab_encode ) then
      if len( trim(as_value) ) > 0 then
         ls_value = as_value
         if ( encode( as_value, ls_value ) = -1 ) then
            setLastError( METHOD_NAME + "Encoding failed for '" + ls_value + "'" )
         end if
      end if
   else
      ls_value = as_value
   end if
   
   //Concatenate string
   ls_xml += ls_value + "</" + as_elementname + ">"
end if

if ( this.add( ls_xml ) = 1 ) then
   return 1
else
   return -1
end if


end function

public function long closeelement (string as_elementname);////////////////////////////////////////////////////////////////
// Description:
//    Close the element as indicated by as_elementname
//
// Revisions
//    2.1   - Initial version
// Arguments:  
//    as_elementname - the name of the element to be added
// Returns: 
//     1 - Success 
//    -1 - Failure
////////////////////////////////////////////////////////////////
// Copyright © 2000 - 2007 Youngsoft, Inc.  All rights reserved.
// Any distribution of the Youngsoft, Inc. Enterprise Application Framework
// source code in whole or part by other than Youngsoft, Inc. is prohibited.
//////////////////////////////////////////////////////////////// 

constant string METHOD_NAME = "closeElement "

//Reduce current indentation
il_currentindentation = il_currentindentation - il_indentationamount

//if ( this.add( space( il_currentindentation ) + "</" + as_elementname + ">" ) = 1 ) then
if ( this.add( "</" + as_elementname + ">" ) = 1 ) then
   return 1
else
   return -1
end if

end function

protected function long setlasterror (string as_error);////////////////////////////////////////////////////////////////
// Description:
//    Sets the last known error.  Stored until a new error is
//    encountered.  If environment is applicable use 
//    getLastError(...) to get its value.
// Revisions
//    1.0   - Initial version
// Arguments:  
//    as_error - The actual error messsage
// Returns:
//     1 - Success
//    -1 - Failure
////////////////////////////////////////////////////////////////
// Copyright © 2000 - 2007 Youngsoft, Inc.  All rights reserved.
// Any distribution of the Youngsoft, Inc. Enterprise Application Framework
// source code in whole or part by other than Youngsoft, Inc. is prohibited.
//////////////////////////////////////////////////////////////// 

constant string METHOD_NAME = "setLastError "

// Set the attribute
is_lasterror = as_error


Return 1

end function

public function long setwarning (boolean ab_state);////////////////////////////////////////////////////////////////
// Description:
//    Sets the warning property.  If TRUE it will allow warning
//    messages to be sent to the logging service
// Revisions
//    1.0   - Initial version
// Arguments:  
//    ab_state - The switch to enable/disable the property
// Returns:
//     1 - Success
//    -1 - Failure
////////////////////////////////////////////////////////////////
// Copyright © 2000 - 2007 Youngsoft, Inc.  All rights reserved.
// Any distribution of the Youngsoft, Inc. Enterprise Application Framework
// source code in whole or part by other than Youngsoft, Inc. is prohibited.
//////////////////////////////////////////////////////////////// 

constant string METHOD_NAME = "setWarning "

ib_warning = ab_state

inv_log.setWarning( ib_warning )

Return 1
end function

public function long setusedatabaselogging (boolean ab_value);////////////////////////////////////////////////////////////////
// Description:
//    Sets the warning variable
//    Required for the LogPropagation interface
//    
// Revisions
//    1.0   - Initial version
// Arguments:  
//    as_error - The actual error messsage
// Returns:
//     1 - Success
//    -1 - Failure
////////////////////////////////////////////////////////////////
// Copyright © 2000 - 2007 Youngsoft, Inc.  All rights reserved.
// Any distribution of the Youngsoft, Inc. Enterprise Application Framework
// source code in whole or part by other than Youngsoft, Inc. is prohibited.
//////////////////////////////////////////////////////////////// 

constant string METHOD_NAME = "setUseDatabaseLogging( boolean value ) "

ib_usedatabaselogging = ab_value

inv_log.setUseDatabaseLogging( ib_usedatabaselogging )

Return 1

end function

public function long settrace (boolean ab_state);////////////////////////////////////////////////////////////////
// Description:
//    Sets the trace property.  If TRUE it will allow tracing 
//    messages to be sent to the logging service
// Revisions
//    1.0   - Initial version
// Arguments:  
//    ab_state - The switch to enable/disable the property
// Returns:
//     1 - Success
//    -1 - Failure
////////////////////////////////////////////////////////////////
// Copyright © 2000 - 2007 Youngsoft, Inc.  All rights reserved.
// Any distribution of the Youngsoft, Inc. Enterprise Application Framework
// source code in whole or part by other than Youngsoft, Inc. is prohibited.
//////////////////////////////////////////////////////////////// 

constant string METHOD_NAME = "setTrace "

ib_trace = ab_state

inv_log.setTrace( ib_trace )


Return 1
end function

public function long setdetailed (boolean ab_state);////////////////////////////////////////////////////////////////
// Description:
//    Sets the detailed property.  If TRUE it will allow detailed
//    tracing and debugging messages to be sent to the logging service
// Revisions
//    1.0   - Initial version
// Arguments:  
//    ab_state - The switch to enable/disable the property
// Returns:
//     1 - Success
//    -1 - Failure
////////////////////////////////////////////////////////////////
// Copyright © 2000 - 2007 Youngsoft, Inc.  All rights reserved.
// Any distribution of the Youngsoft, Inc. Enterprise Application Framework
// source code in whole or part by other than Youngsoft, Inc. is prohibited.
//////////////////////////////////////////////////////////////// 

constant string METHOD_NAME = "setDetailed "

// Validate arguments
If isNull(ab_state) Then
   setLastError (METHOD_NAME + "Invalid ab_state argument")
   Return -1
End If

ib_detailed = ab_state

inv_log.setDetailed( ib_detailed )


Return 1
end function

public function long setdebug (boolean ab_state);////////////////////////////////////////////////////////////////
// Description:
//    Sets the debug property.  If TRUE it will allow debugging 
//    messages to be sent to the logging service
// Revisions
//    1.0   - Initial version
// Arguments:  
//    ab_state - The switch to enable/disable the property
// Returns:
//     1 - Success
//    -1 - Failure
////////////////////////////////////////////////////////////////
// Copyright © 2000 - 2007 Youngsoft, Inc.  All rights reserved.
// Any distribution of the Youngsoft, Inc. Enterprise Application Framework
// source code in whole or part by other than Youngsoft, Inc. is prohibited.
//////////////////////////////////////////////////////////////// 

constant string METHOD_NAME = "setDebug "

// Validate arguments
If isNull(ab_state) Then
   setLastError (METHOD_NAME + "Invalid ab_state argument")
   Return -1
End If

ib_debug = ab_state

inv_log.setDebug( ib_debug )

Return 1
end function

public function long propagatelogsettings ();////////////////////////////////////////////////////////////////
// Description:
//    Stub method to signal the completion of log settings to allow propagation to continue to other loggable objects
// Revisions
//    3.0   - Initial version
// Arguments:  
//    None
// Returns:
//     1 - Success
//    -1 - Failure
////////////////////////////////////////////////////////////////
// Copyright © 2000 - 2007 Youngsoft, Inc.  All rights reserved.
// Any distribution of the Youngsoft, Inc. Enterprise Application Framework
// source code in whole or part by other than Youngsoft, Inc. is prohibited.
//////////////////////////////////////////////////////////////// 

constant string METHOD_NAME = "propagateLogSettings() "

inv_log.traceLog (METHOD_NAME, "")

inv_log.setTrace( ib_trace )
inv_log.setDebug( ib_debug )
inv_log.setDetailed( ib_detailed )
inv_log.setWarning( ib_warning )
inv_log.setUseDatabaseLogging( ib_usedatabaselogging )

return 1

end function

public function string getlasterror ();////////////////////////////////////////////////////////////////
// Description:
//    Gets the last known error. (if any) 
// Revisions
//    1.0   - Initial version
// Arguments:  
//    as_error - The actual error messsage
// Returns: 
//    The actual error messsage (if any)
////////////////////////////////////////////////////////////////
// Copyright © 2000 - 2007 Youngsoft, Inc.  All rights reserved.
// Any distribution of the Youngsoft, Inc. Enterprise Application Framework
// source code in whole or part by other than Youngsoft, Inc. is prohibited.
//////////////////////////////////////////////////////////////// 

constant string METHOD_NAME = "getLastError "

Return is_lasterror
end function

public function long setcharacterset (string as_characterset);////////////////////////////////////////////////////////////////
// Description:
//    Sets the character set for the generated XML document
// Revisions
//    3.0   - Initial version
// Arguments:  
//    as_characterset - character set
// Returns:
//     1 - Success
//    -1 - Failure
////////////////////////////////////////////////////////////////
// Copyright © 2000 - 2007 Youngsoft, Inc.  All rights reserved.
// Any distribution of the Youngsoft, Inc. Enterprise Application Framework
// source code in whole or part by other than Youngsoft, Inc. is prohibited.
//////////////////////////////////////////////////////////////// 

constant string METHOD_NAME = "setCharacterSet( String ) "

is_characterset = as_characterset


Return 1
end function

public function long decode (string as_original, ref string as_decoded);////////////////////////////////////////////////////////////////
// Description:
//    Encode the passed in string according to XML requirements 
//
// Revisions
//    2.1   - Initial version
// Arguments:  
//    as_original - original string
//    as_decoded - REF - decoded string
// Returns: 
//     1 - Success 
//    -1 - Failure
////////////////////////////////////////////////////////////////
// Copyright © 2000 - 2007 Youngsoft, Inc.  All rights reserved.
// Any distribution of the Youngsoft, Inc. Enterprise Application Framework
// source code in whole or part by other than Youngsoft, Inc. is prohibited.
//////////////////////////////////////////////////////////////// 

constant string METHOD_NAME = "decode "

n_cst_stringservice           lnv_helper

lnv_helper = create n_cst_stringservice
inv_log.propagateSettings( lnv_helper )

as_decoded = lnv_helper.globalreplace(  as_original, "&amp;","&" , true)
as_decoded = lnv_helper.globalreplace(  as_decoded, "&gt;", ">", true)
as_decoded = lnv_helper.globalreplace(  as_decoded, "&lt;", "<", true)
as_decoded = lnv_helper.globalreplace(  as_decoded, "&apos;", "'", true)
as_decoded = lnv_helper.globalreplace(  as_decoded, "&quot;", "~"", true)
as_decoded = lnv_helper.globalreplace(  as_decoded, "&#37;", "%", true)

destroy lnv_helper

return 1

end function

public subroutine setusehead (boolean ab_usehead);ib_usehead = ab_usehead
end subroutine

on eaf_n_cst_xmlparser.create
call super::create
TriggerEvent( this, "constructor" )
end on

on eaf_n_cst_xmlparser.destroy
TriggerEvent( this, "destructor" )
call super::destroy
end on

event constructor;////////////////////////////////////////////////////////////////
// Description:
//    Occurs when the object is created
// Revisions
//    1.0   - Initial version
// Arguments:  
//    None
// Returns: 
////////////////////////////////////////////////////////////////

constant string METHOD_NAME = "constructor "

// Tell the logging service who requested it
inv_log = create n_cst_loggingservice_base
inv_log.setRequestor(this)

inv_constants = create n_cst_constants

//Set the default character set to UTF-8
setCharacterSet( inv_constants.CHARACTER_SET_UTF_8 )

end event

event destructor;////////////////////////////////////////////////////////////////
// Description:
//    Occurs when the object is destroyed
// Revisions
//    1.0   - Initial version
// Arguments:  
//    None
// Returns: 
////////////////////////////////////////////////////////////////

constant string METHOD_NAME = "destructor "

if isValid( inv_log ) then
   destroy inv_log
end if

if ( isValid( inv_constants ) ) then
   destroy inv_constants
end if

end event