'// Forms the meta-data for a given Java class (namely, JNI signatures for use with LS2J) and
'// writes the results to an XML file on the Windows desktop via the LSLogger class, the source
'// code for which can be found at:
'// http://www.openntf.org/Projects/codebin/codebin.nsf/CodeBySubContributor/847ADBAD668FA911862572800073A25D
'//
'// This is useful during initial "set up" and debugging of LS2J code.
'//
'// See the example below using the javax.swing.JFileChooser class
Option Declare
Uselsx "*javacon"
Sub debugJavaClass(pjSess As JavaSession, pjClass As JavaClass)
On Error Goto errorHandler
Const MODIFIER_PUBLIC& = 1
Const MODIFIER_STATIC& = 8
Const MODIFER_FINAL& = 16
Const MODIFER_VOLITILE& = 64
Const MODIFIER_TRANSIENT& = 128
Const PUBLIC_CONSTANT& = MODIFIER_PUBLIC + MODIFIER_STATIC + MODIFER_FINAL
Const LS_TYPE_STR = 8
Const LS_TYPE_BLN = 11
Const LS_TYPE_BYT = 17
Const LS_TYPE_INT = 2
Const LS_TYPE_LNG = 3
Const LS_TYPE_SNG = 4
Const LS_TYPE_DBL = 5
Const LS_TYPE_OBJ = 32
Const RT_TYPE_BYT = "B"
Const RT_TYPE_CHR = "C"
Const RT_TYPE_DBL = "D"
Const RT_TYPE_FLT = "F"
Const RT_TYPE_INT = "I"
Const RT_TYPE_LNG = "J"
Const RT_TYPE_SHT = "S"
Const RT_TYPE_BLN = "Z"
Const RT_TYPE_VOID = "V"
Dim jmClxn As JavaMethodCollection
Dim jpClxn As JavaPropertyCollection
Dim jmeth As JavaMethod
Dim jprpty As JavaProperty
Dim jObj As JavaObject
Dim logger As LSLogger
Dim lngModifier As Long
Dim lngLSType As Long
Dim i As Integer
Dim intCount As Integer
Dim strFilePath As String
Dim strSignature As String
Dim strReturn As String
'// Set up the logger.
strFilePath$ = Environ$("HOMEPATH") & "\DeskTop\JavaClass - " & Replace(pjClass.ClassName, ".", "_") & ".xml"
Set logger = New LSLogger(strFilePath$)
Call logger.ClearLog()
Call logger.AddXMLTag(True, "JavaClass")
Call logger.LogXMLTagValue(True, True, "ClassName", pjClass.ClassName)
'// Record the details of the methods of the Java class passed.
Call logger.AddXMLTag(True, "MethodDetails")
Set jmClxn = pjClass.GetClassMethods()
Set jmeth = jmClxn.GetFirst()
intCount% = jmClxn.Count
For i = 1 To intCount%
Call logger.AddXMLTag(True, "Method")
Call logger.LogXMLTagValue(True, True, "Name", jmeth.MethodName)
'// Record the "raw" LS2J signature.
strSignature$ = jmeth.Signature
Call logger.LogXMLTagValue(True, True, "LS2JSignature", strSignature$)
'// Parse the return type from the method signature.
strReturn$ = Strright(strSignature$, ")")
If Strcompare(Right(strReturn$, 1), ";") = 0 Then
strReturn$ = Strleft(strReturn$, ";")
End If
'// Convert the return value to a more understandable value if possible.
Select Case True
Case Strcompare(strReturn$, RT_TYPE_VOID, 5) = 0
strReturn$ = "void"
Case Strcompare(strReturn$, RT_TYPE_BYT, 5) = 0
strReturn$ = "byte"
Case Strcompare(strReturn$, RT_TYPE_CHR, 5) = 0
strReturn$ = "char"
Case Strcompare(strReturn$, RT_TYPE_DBL, 5) = 0
strReturn$ = "double"
Case Strcompare(strReturn$, RT_TYPE_FLT, 5) = 0
strReturn$ = "float"
Case Strcompare(strReturn$, RT_TYPE_INT, 5) = 0
strReturn$ = "int"
Case Strcompare(strReturn$, RT_TYPE_LNG, 5) = 0
strReturn$ = "long"
Case Strcompare(strReturn$, RT_TYPE_SHT, 5) = 0
strReturn$ = "short"
Case Strcompare(strReturn$, RT_TYPE_BLN, 5) = 0
strReturn$ = "boolean"
End Select
Call logger.LogXMLTagValue(True, True, "ReturnType", strReturn$)
Set jmeth = jmClxn.GetNext()
Call logger.CloseTag("Method")
Next i
'// Close the Methods tag.
Call logger.CloseTag("MethodDetails")
'// Record the details of the "properties" of the Java class passed.
Call logger.AddXMLTag(True, "PropertyDetails")
Set jpClxn = pjClass.GetClassProperties()
Set jprpty = jpClxn.GetFirst()
intCount% = jpClxn.Count
For i = 1 To intCount%
lngModifier& = jprpty.Modifier
lngLSType& = jprpty.Type
Call logger.AddXMLTag(True, "Property")
Call logger.LogXMLTagValue(True, True, "Name", jprpty.PropertyName)
Call logger.LogXMLTagValue(True, True, "Modifier", Cstr(lngModifier&))
If lngModifier& = PUBLIC_CONSTANT Then
Call logger.LogXMLTagValue(True, True, "IsConstant", "True")
If Isobject(jprpty.GetValue()) Then
Set jObj = jprpty.GetValue()
strReturn$ = jObj.getClass().getName()
strReturn$ = Replace(strReturn$, ".", "/") '// just to be conistent, convert the package separator to a forward slash
Call logger.LogXMLTagValue(True, True, "Value", "[JavaObject] " & strReturn$)
Delete jObj
Else
Call logger.LogXMLTagValue(True, True, "Value", Cstr(jprpty.GetValue()))
End If
Else
Call logger.LogXMLTagValue(True, True, "IsConstant", "False")
End If
'// Record the LS datatype as an understandable string (vs. a number).
Select Case lngLSType&
Case LS_TYPE_STR
Call logger.LogXMLTagValue(True, True, "LSDataType", "String")
Case LS_TYPE_BLN
Call logger.LogXMLTagValue(True, True, "LSDataType", "Boolean")
Case LS_TYPE_BYT
Call logger.LogXMLTagValue(True, True, "LSDataType", "Byte")
Case LS_TYPE_INT
Call logger.LogXMLTagValue(True, True, "LSDataType", "Integer")
Case LS_TYPE_LNG
Call logger.LogXMLTagValue(True, True, "LSDataType", "Long")
Case LS_TYPE_SNG
Call logger.LogXMLTagValue(True, True, "LSDataType", "Single")
Case LS_TYPE_DBL
Call logger.LogXMLTagValue(True, True, "LSDataType", "Double")
Case LS_TYPE_OBJ
Call logger.LogXMLTagValue(True, True, "LSDataType", "Java object")
Case Else
Call logger.LogXMLTagValue(True, True, "LSDataType", "unknown")
End Select
Call logger.CloseTag("Property")
Set jprpty = jpClxn.GetNext()
Next i
'// Close the Properties tag.
Call logger.CloseTag("PropertyDetails")
'// Close the Class tag.
Call logger.CloseTag("JavaClass")
Msgbox "Results saved to " & strFilePath$, , "Results . . ."
Print "Results saved to " & strFilePath$ & " . . ."
subExit:
'// Always dereference the LS2J objects in reverse order of creation.
If Not(jmeth Is Nothing) Then
Delete jmeth
End If
If Not(jprpty Is Nothing) Then
Delete jprpty
End If
If Not(jmClxn Is Nothing) Then
Delete jmClxn
End If
If Not(jpClxn Is Nothing) Then
Delete jpClxn
End If
Set logger = Nothing
Exit Sub
errorHandler:
Call showLS2JErrorDetail(pjSess)
Resume subExit
End Sub
Sub showLS2JErrorDetail(pjSess As JavaSession)
Const NL = {
}
Dim jErrObj As JavaError
Dim strErrMsg As String
'// Check the state of the JavaSession object passed and capture the error details.
If Not(pjSess Is Nothing) Then
Set jErrObj = pjSess.GetLastJavaError()
If Not(jErrObj Is Nothing) Then
strErrMsg$ = jErrObj.ErrorMsg
If Len(strErrMsg$) > 0 Then
strErrMsg$ = "JavaError encountered: " & strErrMsg$ & NL & "Stacktrace:" & NL & jErrObj.StackTrace
End If
Call pjSess.ClearJavaError()
Set jErrObj = Nothing
End If
End If
'// If an LS error has been raised, capture the details.
If Not(Err = 0) Then
If Len(strErrMsg$) > 0 Then
strErrMsg$ = "Error " & Err & ": " & Error & " encountered at line " & Erl & " of " & Getthreadinfo(10) & "." & NL & strErrMsg$
Else
strErrMsg$ = "Error " & Err & ": " & Error & " encountered at line " & Erl & " of " & Getthreadinfo(10) & "."
End If
End If
'// If an error has been recorded, display its details.
If Len(strErrMsg$) > 0 Then
Msgbox strErrMsg$, , "Error encountered . . ."
Print "Error " & Err & ": " & Error & " encountered at line " & Erl & " of " & Getthreadinfo(10) & " . . ."
End If
End Sub