Imports System.Text.RegularExpressions Imports WINDREAMLib Imports DigitalData.Controls.LookupGrid ''' ''' 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} ''' Public Class clsPatterns ' Complex patterns that rely on a datasource like a Database or Windream Public Const PATTERN_WMI = "WMI" Public Const PATTERN_IDBA = "IDBA" 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 = 500 Private Shared MyRegex As Regex = New Regex("{#(\w+)#([\:\.\w\s_-]+)}+") Private Shared allPatterns As New List(Of String) From {PATTERN_WMI, PATTERN_CTRL, PATTERN_IDBA, PATTERN_USER, PATTERN_INT} Private Shared complexPatterns As New List(Of String) From {PATTERN_WMI, PATTERN_CTRL, PATTERN_IDBA} Private Shared simplePatterns As New List(Of String) From {PATTERN_USER, PATTERN_INT} ''' ''' Wraps a pattern-type and -value in the common format: {#type#value} ''' 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 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(input As String) As String Try Dim result = input ' Replace Username(s) While ContainsPatternAndValue(result, PATTERN_INT, INT_VALUE_USERNAME) result = ReplacePattern(result, PATTERN_INT, USER_USERNAME) End While ' Replace Machinename(s) While ContainsPatternAndValue(result, PATTERN_INT, INT_VALUE_MACHINE) result = ReplacePattern(result, PATTERN_INT, Environment.MachineName) End While ' Replace Domainname(s) While ContainsPatternAndValue(result, PATTERN_INT, INT_VALUE_DOMAIN) result = ReplacePattern(result, PATTERN_INT, Environment.UserDomainName) End While ' Replace CurrentDate(s) While ContainsPatternAndValue(result, PATTERN_INT, INT_VALUE_DATE) result = ReplacePattern(result, PATTERN_INT, Now.ToShortDateString) End While LOGGER.Debug("pInput AFTER ReplaceInternalValues: " & input) Return result Catch ex As Exception LOGGER.Error(ex) LOGGER.Info("Error in ReplaceInternalValues:" & ex.Message) 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, USER_PRENAME) End While While ContainsPatternAndValue(result, PATTERN_USER, USER_VALUE_USER_ID) result = ReplacePattern(result, PATTERN_USER, USER_ID) End While While ContainsPatternAndValue(result, PATTERN_USER, USER_VALUE_SURNAME) result = ReplacePattern(result, PATTERN_USER, USER_SURNAME) End While While ContainsPatternAndValue(result, PATTERN_USER, USER_VALUE_SHORTNAME) result = ReplacePattern(result, PATTERN_USER, USER_SHORTNAME) End While While ContainsPatternAndValue(result, PATTERN_USER, USER_VALUE_LANGUAGE) result = ReplacePattern(result, PATTERN_USER, USER_LANGUAGE) End While While ContainsPatternAndValue(result, PATTERN_USER, USER_VALUE_EMAIL) result = ReplacePattern(result, PATTERN_USER, USER_EMAIL) End While While ContainsPatternAndValue(result, PATTERN_USER, VALUE_PROFILE_ID) If IsNothing(CURRENT_CLICKED_PROFILE_ID) Then CURRENT_CLICKED_PROFILE_ID = 0 End If result = ReplacePattern(result, PATTERN_USER, CURRENT_CLICKED_PROFILE_ID) End While While ContainsPatternAndValue(result, PATTERN_USER, VALUE_PROFILE_TITLE) If CURRENT_CLICKED_PROFILE_TITLE Is Nothing Then CURRENT_CLICKED_PROFILE_TITLE = "NONE_TITLE" End If result = ReplacePattern(result, PATTERN_USER, CURRENT_CLICKED_PROFILE_TITLE) End While LOGGER.Debug("pInput AFTER ReplaceUserValues: " & input) Return result Catch ex As Exception LOGGER.Error(ex) LOGGER.Info("Error in ReplaceUserValues:" & ex.Message) End Try End Function Public Shared Function ReplaceControlValues(input As String, panel As Panel, IS_SQL As Boolean) As String Try Dim result = input Dim oTryCounter = 0 While ContainsPattern(result, PATTERN_CTRL) If oTryCounter > MAX_TRY_COUNT Then LOGGER.Warn($"Max tries in ReplaceControlValues exceeded - Replacing with [0]") result = ReplacePattern(result, PATTERN_CTRL, 0) Throw New Exception($"Max tries in ReplaceControlValues exceeded - Result so far [{result}].") End If Dim controlName As String = GetNextPattern(result, PATTERN_CTRL).Value Dim oControl As Control = panel.Controls.Find(controlName, False).FirstOrDefault() If oControl IsNot Nothing Then Dim oReplaceValue As String Select Case oControl.GetType.ToString Case GetType(TextBox).ToString oReplaceValue = oControl.Text Case GetType(LookupControl3).ToString Dim oLookupControl3 As LookupControl3 = oControl If oLookupControl3.Properties.SelectedValues.Count = 1 Then oReplaceValue = oLookupControl3.Properties.SelectedValues.Item(0) Else oReplaceValue = "0" End If Case GetType(ComboBox).ToString oReplaceValue = oControl.Text Case GetType(CheckBox).ToString Dim oCheckBox As CheckBox = oControl oReplaceValue = oCheckBox.Checked Case Else oReplaceValue = "0" End Select If IS_SQL = True Then LOGGER.Debug($"IS_SQL = True - oReplaceValue = {oReplaceValue}") oReplaceValue = oReplaceValue.Replace("'", "''") LOGGER.Debug($"oReplaceValue = {oReplaceValue}") End If result = ReplacePattern(result, PATTERN_CTRL, oReplaceValue) End If oTryCounter += 1 End While LOGGER.Debug("pInput AFTER ReplaceControlValues: " & input) Return result Catch ex As Exception LOGGER.Error(ex) LOGGER.Info("Error in ReplaceControlValues:" & ex.Message) End Try End Function Public Shared Function ReplaceWindreamIndicies(pInput As String, pDocument As WMObject, pIsSQL As Boolean) As String Try Dim oResult = pInput Dim oTryCounter As Integer = 0 While ContainsPattern(oResult, PATTERN_WMI) Dim oIndexName As String = GetNextPattern(oResult, PATTERN_WMI).Value Dim oWMValue As String = pDocument.GetVariableValue(oIndexName) If IsNothing(oWMValue) And oTryCounter = MAX_TRY_COUNT Then Throw New Exception("Max tries in ReplaceWindreamIndicies exceeded.") End If If oWMValue IsNot Nothing Then If pIsSQL = True Then LOGGER.Debug($"IS_SQL = True - oReplaceValue = {oWMValue}") oWMValue = oWMValue.ToString().Replace("'", "''") LOGGER.Debug($"oReplaceValue = {oWMValue}") End If oResult = ReplacePattern(oResult, PATTERN_WMI, oWMValue) End If oTryCounter += 100 End While LOGGER.Debug("sql AFTER ReplaceWindreamIndicies: " & pInput) 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 oTryCounter += 100 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