Imports System.Reflection
''' -----------------------------------------------------------------------------
''' Project	 : NHenry.Exception
''' Class	 : Exception.ClsDescriptions
''' -----------------------------------------------------------------------------
''' <summary>
''' Message perso des exceptions
''' </summary>
''' -----------------------------------------------------------------------------
Public NotInheritable Class ClsDescriptions
    Implements IException
    Private ReadOnly Property VbCrLf() As String
        Get
            Return Environment.NewLine
        End Get
    End Property
#Region "méthodes implémentées"
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Récupère la description d'une exception
    ''' </summary>
    ''' <param name="pEx"></param>
    ''' <param name="pParams"></param>
    ''' <returns></returns>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[nhenry]	03/04/2006	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Function GetDescription(ByVal pEx As System.Exception, ByVal pParams As ColParams) As String Implements IException.GetDescription
        Dim lParam As SParam
        Dim lStr As String = ""

        If TypeOf pEx Is IO.IOException Then
            If pParams Is Nothing Then Return ""
            For Each lParam In pParams
                If lParam.Name.ToLower.IndexOf("filename") <> -1 Then
                    lStr = "Erreur d'accès au fichier : """ + lParam.Objet.ToString + """"
                End If
            Next
            If lStr = "" Then
                For Each lParam In pParams
                    If lParam.Name.ToLower.IndexOf("file") <> -1 Then
                        lStr = "Erreur d'accès au fichier : """ + lParam.Objet.ToString + """"
                    End If
                Next
            End If
        ElseIf TypeOf pEx Is IndexOutOfRangeException Then
            If pParams Is Nothing Then Return ""
            For Each lParam In pParams
                If lParam.Name.ToLower.IndexOf("col") <> -1 And ((TypeOf lParam.Objet Is ICollection) Or (TypeOf lParam.Objet Is IList)) Then
                    lStr = "Tentative d'accès à un élément hors du tableau : " + lParam.Name
                End If
            Next
        ElseIf TypeOf pEx Is Xml.XmlException Then
            lParam = pParams.Item("filename")
            If lParam.Objet Is Nothing Then lParam = pParams.Item("file")
            If lParam.Objet Is Nothing Then
                lStr = "Erreur dans le dowument XML"
            Else
                lStr = "Erreur dans le fichier """ + lParam.Objet.ToString + """"
            End If
            lStr += " a la ligne " + CStr(CType(pEx, Xml.XmlException).LineNumber) + " et à la colonne " + CStr(CType(pEx, Xml.XmlException).LinePosition) + VbCrLf
            lStr += "  Message : " + CType(pEx, Xml.XmlException).Message
        End If
        Return lStr
    End Function
    ''' -----------------------------------------------------------------------------
        ''' <summary>
        ''' Retourne la description d'un objet spécifique (non géré)
        ''' </summary>
        ''' <param name="pObj">Objet à décrire</param>
        ''' -----------------------------------------------------------------------------
    Public Function GetDescription(ByVal pObj As Object) As String Implements IException.GetDescription
        Dim lStr As String = ""
        Dim lObj As Object
        Dim i As Integer

        If TypeOf pObj Is String Then
            lStr = pObj.ToString()
        ElseIf TypeOf pObj Is Array Then
            lStr = "Array de " + CType(pObj, Array).GetValue(0).GetType.FullName + VbCrLf
            lStr += "    Length = " + CStr(CType(pObj, Array).Length) + VbCrLf + "    Eléments :"
            For i = 0 To CType(pObj, Array).Length - 1
                lStr += VbCrLf + "    " + CStr(i) + ":" + Description(CType(pObj, Array).GetValue(i))
            Next
        ElseIf TypeOf pObj Is ArrayList Then
            lStr = "ArrayList" + VbCrLf
            lStr += "    Count = " + CStr(CType(pObj, ArrayList).Count) + VbCrLf + "    Eléments :"
            For i = 0 To CType(pObj, ArrayList).Count - 1
                lStr += VbCrLf + "    " + CStr(i) + ":" + Description(CType(pObj, ArrayList).Item(i))
            Next
        ElseIf TypeOf pObj Is IEnumerable Then
            lStr = "IEnumerable"
            i = 0
            For Each lObj In CType(pObj, IEnumerable)
                lStr += VbCrLf + "    " + CStr(i) + " : " + Description(lObj)
                i += 1
            Next
        ElseIf TypeOf pObj Is IEnumerator Then
            lStr = "IEnumerator"
            i = 0
            CType(pObj, IEnumerator).Reset()
            Do
                lStr += VbCrLf + "    " + CStr(i) + " : " + Description(CType(pObj, IEnumerator).Current)
                i += 1
            Loop While CType(pObj, IEnumerator).MoveNext
        ElseIf TypeOf pObj Is System.Exception Then
            Description(CType(pObj, System.Exception), CType(Nothing, ColParams))
        End If
        Return lStr
    End Function
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Récupère le détail d'une exception
    ''' </summary>
    ''' <param name="pEx">Exception à traiter</param>
    ''' <param name="pParams">Paramètres de l'exception</param>
    ''' -----------------------------------------------------------------------------
    Public Function GetDetail(ByVal pEx As System.Exception, ByVal pParams As ColParams) As String Implements IException.GetDetail
        'TODOi :
        Return ""
    End Function
#End Region
#Region "Liste des assemblys"
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Retourne la description d'une exception
    ''' </summary>
    ''' <param name="pEx"></param>
    ''' <param name="pParams"></param>
    ''' <returns></returns>
    ''' -----------------------------------------------------------------------------
    Friend Shared Function Description(ByVal pEx As System.Exception, ByVal pParams As ColParams) As String
        Dim lStr As String = ""
        Dim lAssemb As [Assembly]
        'Récupération des assemblys accessibles
        Dim lAssembs As [Assembly]() = System.Threading.Thread.GetDomain().GetAssemblies()

        If pEx Is Nothing Then Return "<nothing>"

        For Each lAssemb In lAssembs
            lStr = Description(pEx, pParams, lAssemb)
            If lStr <> "" Then
                System.GC.Collect()
                Return lStr
            End If
        Next
        If lStr = "" Then
            lStr = pEx.ToString
        End If
        System.GC.Collect()
        Return lStr
    End Function
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Retourne la description d'un objet
    ''' </summary>
    ''' <param name="pObj"></param>
    ''' <returns></returns>
    ''' -----------------------------------------------------------------------------
    Friend Shared Function Description(ByVal pObj As Object) As String
        Dim lStr As String = ""
        Dim lAssemb As [Assembly]
        Dim lAssembs As [Assembly]() = System.Threading.Thread.GetDomain().GetAssemblies()

        If pObj Is Nothing Then Return "<nothing>"

        For Each lAssemb In lAssembs
            lStr = Description(pObj, lAssemb)
            If lStr <> "" Then
                System.GC.Collect()
                Return lStr
            End If
        Next
        If lStr = "" Then
            lStr = pObj.ToString
        End If
        System.GC.Collect()
        Return lStr
    End Function
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Retourne le détail d'une exception
    ''' </summary>
    ''' <param name="pEx"></param>
    ''' <param name="pParams"></param>
    ''' <returns></returns>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[nhenry]	03/04/2006	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Friend Shared Function Detail(ByVal pEx As System.Exception, ByVal pParams As ColParams) As String
        Dim lStr As String = ""
        Dim lAssemb As [Assembly]
        Dim lAssembs As [Assembly]() = System.Threading.Thread.GetDomain().GetAssemblies()

        If pEx Is Nothing Then Return "<nothing>"

        For Each lAssemb In lAssembs
            lStr = Detail(pEx, pParams, lAssemb)
            If lStr <> "" Then
                System.GC.Collect()
                Return lStr
            End If
        Next
        If lStr = "" Then
            lStr = pEx.ToString
        End If
        System.GC.Collect()
        Return lStr
    End Function
#End Region
#Region "Lecture d'un assembly"
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Retourne la description trouvée par la ou les classes implémentant IException dans un assembly spécifique
    ''' </summary>
    ''' <param name="pEx"></param>
    ''' <param name="pParams"></param>
    ''' <param name="pAssemb"></param>
    ''' <returns></returns>
    ''' -----------------------------------------------------------------------------
    Private Shared Function Description(ByVal pEx As System.Exception, ByVal pParams As ColParams, ByVal pAssemb As [Assembly]) As String
        Dim lType As Type
        Dim lStr As String = ""
        Dim lInst As IException = Nothing
        For Each lType In pAssemb.GetTypes
            If Not (lType.GetInterface("IException", True) Is Nothing) And lType.IsClass Then
                Try
                    lInst = CType(pAssemb.CreateInstance(lType.ToString), IException)
                    lStr = lInst.GetDescription(pEx, pParams)
                    lInst = Nothing
                Catch ex As System.Exception
                    lStr = ""
                End Try
                If lStr <> "" Then Return lStr
            End If
        Next
        Return ""
    End Function
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Retourne la description trouvée par la ou les classes implémentant IException dans un assembly spécifique
    ''' </summary>
    ''' <param name="pObj"></param>
    ''' <param name="pAssemb"></param>
    ''' <returns></returns>
    ''' -----------------------------------------------------------------------------
    Private Shared Function Description(ByVal pObj As Object, ByVal pAssemb As [Assembly]) As String
        Dim lType As Type
        Dim lStr As String = ""
        Dim lInst As IException = Nothing
        For Each lType In pAssemb.GetTypes
            If Not (lType.GetInterface("IException", True) Is Nothing) And lType.IsClass Then
                Try
                    lInst = CType(pAssemb.CreateInstance(lType.ToString), IException)
                    lStr = lInst.GetDescription(pObj)
                    lInst = Nothing
                Catch ex As System.Exception
                    lStr = ""
                End Try
                If lStr <> "" Then Return lStr
            End If
        Next
        Return ""
    End Function
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Retourne le détail trouvée par la ou les classes implémentant IException dans un assembly spécifique
    ''' </summary>
    ''' <param name="pEx"></param>
    ''' <param name="pParams"></param>
    ''' <param name="pAssemb"></param>
    ''' <returns></returns>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[nhenry]	03/04/2006	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Private Shared Function Detail(ByVal pEx As System.Exception, ByVal pParams As ColParams, ByVal pAssemb As [Assembly]) As String
        Dim lType As Type
        Dim lStr As String = ""
        Dim lInst As IException = Nothing
        For Each lType In pAssemb.GetTypes
            If Not (lType.GetInterface("IException", True) Is Nothing) And lType.IsClass Then
                Try
                    lInst = CType(pAssemb.CreateInstance(lType.ToString), IException)
                    lStr = lInst.GetDetail(pEx, pParams)
                    lInst = Nothing
                Catch ex As System.Exception
                    lStr = ""
                End Try
                If lStr <> "" Then Return lStr
            End If
        Next
        Return ""
    End Function
#End Region
End Class
