Modules/GUIs.ZooFlow/clsPatterns.vb

484 lines
19 KiB
VB.net

Imports System.Text.RegularExpressions
Imports WINDREAMLib
Imports DigitalData.Controls.LookupGrid
Imports DevExpress.XtraGrid
Imports DevExpress.XtraGrid.Views.Grid
Imports DevExpress.XtraGrid.Columns
''' <summary>
''' Defines common Functions for Checking for and replacing placeholders.
''' This Class also includes a child class `Pattern` for passing around Patterns.
'''
''' The format of all placeholders is:
''' {#TYPE#VALUE}
'''
''' Some Examples:
''' {#INT#USERNAME}
''' {#CTRL#CMB_2}
''' {#WMI#String 39}
''' </summary>
Public Class clsPatterns
' Complex patterns that rely on a datasource like a Database or Windream
Public Const PATTERN_ZFATTRIBUTE = "ATTR"
Public Const PATTERN_ATTR_AUTO = "ATTR_A"
Public Const PATTERN_ATTR_MAN = "ATTR_M"
Public Const PATTERN_IDBA = "IDBA"
Public Const PATTERN_FILE = "FILE"
' Kinds of CTRL Placeholder
'
' Normal Control
' {#CTRL#ControlName}
'
' Summary Item from Table Column
' {#CTRL#ControlName::ColumnName}
Public Const PATTERN_CTRL = "CTRL"
' Simple patterns that only rely on .NET functions
Public Const PATTERN_INT = "INT"
' Simple patterns that rely on Data from the TBDD_USER table
Public Const PATTERN_USER = "USER"
Public Const USER_VALUE_PRENAME = "PRENAME"
Public Const USER_VALUE_SURNAME = "SURNAME"
Public Const USER_VALUE_EMAIL = "EMAIL"
Public Const USER_VALUE_SHORTNAME = "SHORTNAME"
Public Const USER_VALUE_LANGUAGE = "LANGUAGE"
Public Const USER_VALUE_USER_ID = "USER_ID"
Public Const VALUE_PROFILE_ID = "PROFILE_ID"
Public Const VALUE_PROFILE_TITLE = "PROFILE_TITLE"
Public Const INT_VALUE_USERNAME = "USERNAME"
Public Const INT_VALUE_MACHINE = "MACHINE"
Public Const INT_VALUE_DOMAIN = "DOMAIN"
Public Const INT_VALUE_DATE = "DATE"
Public Const MAX_TRY_COUNT = 50
''' <summary>
''' This value will be valid as any datatype,
''' and you can easily check against it
''' </summary>
Public Const ERROR_REPLACE_VALUE = "0"
Private Shared ReadOnly MyRegex As Regex = New Regex("{#(\w+)#([\:\.\w\s_-]+)}+")
Private Shared ReadOnly allPatterns As New List(Of String) From {PATTERN_ZFATTRIBUTE, PATTERN_ATTR_AUTO, PATTERN_ATTR_MAN, PATTERN_CTRL, PATTERN_IDBA, PATTERN_USER, PATTERN_INT}
Private Shared ReadOnly complexPatterns As New List(Of String) From {PATTERN_ZFATTRIBUTE, PATTERN_ATTR_AUTO, PATTERN_ATTR_MAN, PATTERN_CTRL, PATTERN_IDBA}
Private Shared ReadOnly simplePatterns As New List(Of String) From {PATTERN_USER, PATTERN_INT}
''' <summary>
''' Wraps a pattern-type and -value in the common format: {#type#value}
''' </summary>
Public Shared Function WrapPatternValue(type As String, value As String) As String
Return New Pattern(type, value).ToString
End Function
'Public Shared Function ReplaceAllValues(input As String, panel As Panel, is_SQL As Boolean) As String
' Try
' Dim result = input
' If Not HasAnyPatterns(result) Then
' Return result
' End If
' LOGGER.Debug($"input BEFORE replacing: [{result}]")
' result = ReplaceInternalValues(result)
' result = ReplaceControlValues(result, panel, is_SQL)
' If Not IsNothing(CURRENT_WMFILE) Then
' result = ReplaceWindreamIndicies(result, CURRENT_WMFILE, is_SQL)
' End If
' If IDB_ACTIVE = True Then
' result = ReplaceIDBAttributes(result, is_SQL)
' End If
' If Not IsNothing(result) Then
' result = ReplaceUserValues(result)
' LOGGER.Debug($"input AFTER replacing: [{result}]")
' End If
' Return result
' Catch ex As Exception
' LOGGER.Error(ex)
' LOGGER.Info("Error in ReplaceAllValues:" & ex.Message)
' Return input
' End Try
'End Function
Public Shared Function ReplaceInternalValues(pInput As String) As String
Dim oResult = pInput
Try
' Replace Username(s)
While ContainsPatternAndValue(oResult, PATTERN_INT, INT_VALUE_USERNAME)
oResult = ReplacePattern(oResult, PATTERN_INT, My.Application.User.UserName)
End While
' Replace Machinename(s)
While ContainsPatternAndValue(oResult, PATTERN_INT, INT_VALUE_MACHINE)
oResult = ReplacePattern(oResult, PATTERN_INT, Environment.MachineName)
End While
' Replace Domainname(s)
While ContainsPatternAndValue(oResult, PATTERN_INT, INT_VALUE_DOMAIN)
oResult = ReplacePattern(oResult, PATTERN_INT, Environment.UserDomainName)
End While
' Replace CurrentDate(s)
While ContainsPatternAndValue(oResult, PATTERN_INT, INT_VALUE_DATE)
oResult = ReplacePattern(oResult, PATTERN_INT, Now.ToShortDateString)
End While
Return oResult
Catch ex As Exception
LOGGER.Error(ex)
LOGGER.Info("Error in ReplaceInternalValues:" & ex.Message)
Return oResult
End Try
End Function
Public Shared Function ReplaceUserValues(input As String) As String
Try
Dim result = input
While ContainsPatternAndValue(result, PATTERN_USER, USER_VALUE_PRENAME)
result = ReplacePattern(result, PATTERN_USER, My.Application.User.GivenName)
End While
While ContainsPatternAndValue(result, PATTERN_USER, USER_VALUE_USER_ID)
result = ReplacePattern(result, PATTERN_USER, My.Application.User.UserId)
End While
While ContainsPatternAndValue(result, PATTERN_USER, USER_VALUE_SURNAME)
result = ReplacePattern(result, PATTERN_USER, My.Application.User.Surname)
End While
While ContainsPatternAndValue(result, PATTERN_USER, USER_VALUE_SHORTNAME)
result = ReplacePattern(result, PATTERN_USER, My.Application.User.ShortName)
End While
While ContainsPatternAndValue(result, PATTERN_USER, USER_VALUE_LANGUAGE)
result = ReplacePattern(result, PATTERN_USER, My.Application.User.Language)
End While
While ContainsPatternAndValue(result, PATTERN_USER, USER_VALUE_EMAIL)
result = ReplacePattern(result, PATTERN_USER, My.Application.User.Email)
End While
Return result
Catch ex As Exception
LOGGER.Error(ex)
LOGGER.Info("Error in ReplaceUserValues:" & ex.Message)
End Try
End Function
Public Shared Function ReplaceControlValues(pInput As String, oPanel As Panel, oIsSQL As Boolean) As String
Dim oResult = pInput
Try
Dim oTryCounter = 0
While ContainsPattern(oResult, PATTERN_CTRL)
If oTryCounter > MAX_TRY_COUNT Then
LOGGER.Warn($"Max tries in ReplaceControlValues exceeded - Replacing with [0]")
oResult = ReplacePattern(oResult, PATTERN_CTRL, 0)
Throw New Exception($"Max tries in ReplaceControlValues exceeded - Result so far [{oResult}].")
End If
Dim oControlName As String = GetNextPattern(oResult, PATTERN_CTRL).Value
Dim oColumnName As String = String.Empty
If oControlName.Contains("::") Then
Dim oSplitName = Split(oControlName, "::").ToList()
oControlName = oSplitName.First()
oColumnName = oSplitName.Last()
End If
LOGGER.Debug("Found placeholder for control [{0}].", oControlName)
Dim oControl As Control = oPanel.Controls.Find(oControlName, False).FirstOrDefault()
If oControl IsNot Nothing Then
Dim oReplaceValue As String
Select Case oControl.GetType
Case GetType(TextBox)
oReplaceValue = oControl.Text
Case GetType(LookupControl3)
Dim oLookupControl3 As LookupControl3 = oControl
If oLookupControl3.Properties.SelectedValues.Count = 1 Then
oReplaceValue = oLookupControl3.Properties.SelectedValues.Item(0)
Else
oReplaceValue = ERROR_REPLACE_VALUE
End If
Case GetType(ComboBox)
oReplaceValue = oControl.Text
Case GetType(CheckBox)
Dim oCheckBox As CheckBox = oControl
oReplaceValue = oCheckBox.Checked
Case GetType(GridControl)
Dim oGrid As GridControl = oControl
Dim oView As GridView = oGrid.FocusedView
If oColumnName = String.Empty Then
LOGGER.Warn("Used placeholder for Table [{0}] but without Column Name!", oControlName)
oReplaceValue = ERROR_REPLACE_VALUE
End If
Dim oColumn As GridColumn = oView.Columns.
Where(Function(c) c.FieldName = oColumnName).
SingleOrDefault()
If oColumn?.SummaryItem?.SummaryValue Is Nothing Then
LOGGER.Warn("Column [{0}] not found in Grid!", oColumnName)
oReplaceValue = ERROR_REPLACE_VALUE
Else
oReplaceValue = oColumn.SummaryItem.SummaryValue
End If
Case Else
oReplaceValue = ERROR_REPLACE_VALUE
End Select
If oIsSQL = True Then
'LOGGER.Debug($"IS_SQL = True - oReplaceValue = {oReplaceValue}")
'LOGGER.Debug($"oReplaceValue = {oReplaceValue}")
oReplaceValue = oReplaceValue.Replace("'", "''")
End If
oResult = ReplacePattern(oResult, PATTERN_CTRL, oReplaceValue)
End If
oTryCounter += 1
End While
Return oResult
Catch ex As Exception
LOGGER.Error(ex)
LOGGER.Warn("Error in ReplaceControlValues:" & ex.Message)
Return oResult
End Try
End Function
Public Shared Function ReplaceAttributes(pInput As String, pIDBOBJ_ID As Long, pIsSQL As Boolean) As String
Try
Dim oResult = pInput
Dim oTryCounter As Integer = 0
While ContainsPattern(oResult, PATTERN_ZFATTRIBUTE)
Dim oIndexName As String = GetNextPattern(oResult, PATTERN_ZFATTRIBUTE).Value
Dim oValue As String '= pDocument.GetVariableValue(oIndexName)
If IsNothing(oValue) And oTryCounter = MAX_TRY_COUNT Then
Throw New Exception("Max tries in ReplaceWindreamIndicies exceeded.")
End If
If oValue IsNot Nothing Then
If pIsSQL = True Then
LOGGER.Debug($"IS_SQL = True - oReplaceValue = {oValue}")
oValue = oValue.ToString().Replace("'", "''")
LOGGER.Debug($"oReplaceValue = {oValue}")
End If
oResult = ReplacePattern(oResult, PATTERN_ZFATTRIBUTE, oValue)
End If
' Increase counter by 10 to avoid DDOSing the Windream Service
oTryCounter += 10
End While
Return oResult
Catch ex As Exception
LOGGER.Error(ex)
LOGGER.Info("Error in ReplaceWindreamIndicies:" & ex.Message)
Return pInput
End Try
End Function
'Public Shared Function ReplaceIDBAttributes(input As String, IS_SQL As Boolean) As String
' Try
' Dim result = input
' Dim oTryCounter As Integer = 0
' While ContainsPattern(result, PATTERN_IDBA)
' Dim indexName As String = GetNextPattern(result, PATTERN_IDBA).Value
' Dim oIDBValue
' If indexName = "ObjectID" Then
' oIDBValue = CURRENT_DOC_ID
' ElseIf indexName = "OBJID" Then
' oIDBValue = CURRENT_DOC_ID
' ElseIf indexName = "DocID" Then
' oIDBValue = CURRENT_DOC_ID
' Else
' oIDBValue = IDBData.GetVariableValue(indexName)
' End If
' If IsNothing(oIDBValue) And oTryCounter = MAX_TRY_COUNT Then
' LOGGER.Warn($"Max tries for [{indexName}] in ReplaceIDBAttributes exceeded - Replacing with [0]!")
' Dim oReplaceValue = "{" + $"#{PATTERN_IDBA}#{indexName}" + "}"
' result = result.Replace(oReplaceValue, 0)
' Throw New Exception("Max tries in ReplaceIDBAttributes exceeded.")
' End If
' If oIDBValue IsNot Nothing Or Not IsDBNull(oIDBValue) Then
' Dim oReplaceValue = "{" + $"#{PATTERN_IDBA}#{indexName}" + "}"
' If IS_SQL = True Then
' LOGGER.Debug($"IS_SQL = True - oReplaceValue = [{oReplaceValue}]")
' If indexName <> "ObjectID" And indexName <> "OBJID" And indexName <> "DocID" Then
' Try
' oIDBValue = oIDBValue.Replace("'", "''")
' Catch ex As Exception
' LOGGER.Warn($"Invalid IDBValue for [{indexName}] in ReplaceIDBAttributes [{ex.Message}] - Replacing with [0]!")
' oIDBValue = 0
' End Try
' End If
' LOGGER.Debug($"oIDBValue = {oIDBValue}")
' End If
' result = result.Replace(oReplaceValue, oIDBValue)
' Else
' LOGGER.Warn($"IDBValue for [{indexName}] in ReplaceIDBAttributes is nothing or dbnull - Replacing with [0]!")
' Dim oReplaceValue = "{" + $"#{PATTERN_IDBA}#{indexName}" + "}"
' result = result.Replace(oReplaceValue, 0)
' End If
' ' Increase counter by 10 to avoid DDOSing the Database/IDB Service
' oTryCounter += 10
' End While
' LOGGER.Debug("sql after ReplaceIDBAttributes: " & input)
' Return result
' Catch ex As Exception
' LOGGER.Error(ex)
' LOGGER.Info("Error in ReplaceIDBAttributes:" & ex.Message)
' End Try
'End Function
Private Shared Function ContainsPattern(input As String, type As String) As String
Dim elements As MatchCollection = MyRegex.Matches(input)
For Each element As Match In elements
Dim t As String = element.Groups(1).Value
If t = type Then
Return True
End If
Next
Return False
End Function
Public Shared Function GetNextPattern(input As String, type As String) As Pattern
Dim elements As MatchCollection = MyRegex.Matches(input)
For Each element As Match In elements
' Pattern in pInput
Dim t As String = element.Groups(1).Value
Dim v As String = element.Groups(2).Value
If t = type Then
Return New Pattern(t, v)
End If
Next
Return Nothing
End Function
Public Shared Function GetAllPatterns(input As String) As List(Of Pattern)
Dim elements As MatchCollection = MyRegex.Matches(input)
Dim results As New List(Of Pattern)
For Each element As Match In elements
' Pattern in pInput
Dim t As String = element.Groups(1).Value
Dim v As String = element.Groups(2).Value
results.Add(New Pattern(t, v))
Next
Return results
End Function
Public Shared Function ReplacePattern(input As String, type As String, replacement As String) As String
Dim elements As MatchCollection = MyRegex.Matches(input)
If IsNothing(replacement) Then
Return input
End If
For Each element As Match In elements
' if group 1 contains the 'pattern' the replace whole group with 'replacement'
' and return it
If element.Groups(1).Value = type Then
Return Regex.Replace(input, element.Groups(0).Value, replacement)
End If
Next
' no replacement made
Return input
End Function
Private Shared Function ContainsPatternAndValue(input As String, type As String, value As String) As Boolean
Dim elements As MatchCollection = MyRegex.Matches(input)
For Each element As Match In elements
' Pattern in pInput
Dim t As String = element.Groups(1).Value
Dim v As String = element.Groups(2).Value
If t = type And v = value Then
Return True
End If
Next
Return False
End Function
Public Shared Function HasAnyPatterns(input) As Boolean
Return allPatterns.Any(Function(p)
Return HasPattern(input, p)
End Function)
End Function
Public Shared Function HasOnlySimplePatterns(input As String) As Boolean
Return Not HasComplexPatterns(input)
End Function
Public Shared Function HasComplexPatterns(input As String) As Boolean
Return complexPatterns.Any(Function(p)
Return HasPattern(input, p)
End Function)
End Function
Public Shared Function HasPattern(input As String, type As String) As Boolean
Dim matches = MyRegex.Matches(input)
For Each match As Match In matches
For Each group As Group In match.Groups
If group.Value = type Then
Return True
End If
Next
Next
Return False
End Function
Public Class Pattern
Public ReadOnly Property Type As String
Public ReadOnly Property Value As String
Public Sub New(type As String, value As String)
Me.Type = type
Me.Value = value
End Sub
Public Sub New(stringRepresentation As String)
Dim elements As MatchCollection = MyRegex.Matches(stringRepresentation)
Dim first As Match = elements.Item(0)
Dim t As String = first.Groups(1).Value
Dim v As String = first.Groups(2).Value
Type = t
Value = v
End Sub
Public Overrides Function ToString() As String
Return $"{{#{Type}#{Value}}}"
End Function
End Class
End Class