Index: ActiviteitenOpvolging/ActiviteitenOpvolging/enums/ActivityStateEnum.vb
===================================================================
diff -u -r1666 -r1671
--- ActiviteitenOpvolging/ActiviteitenOpvolging/enums/ActivityStateEnum.vb (.../ActivityStateEnum.vb) (revision 1666)
+++ ActiviteitenOpvolging/ActiviteitenOpvolging/enums/ActivityStateEnum.vb (.../ActivityStateEnum.vb) (revision 1671)
@@ -6,3 +6,30 @@
AllFinished
Zero
End Enum
+
+Public Module ActivityStateEnumMapper
+ '''
+ ''' Gets the corresponding enum value from the ActivityStateEnum with a string value.
+ '''
+ ''' The string value
+ '''
+ Public Function GetEnumValueFromString(activityStateValue As String) As ActivityStateEnum
+ Select Case activityStateValue.ToLower()
+ Case "defaulted"
+ Return ActivityStateEnum.Defaulted
+ Case "pauzed"
+ Return ActivityStateEnum.Pauzed
+ Case "started"
+ Return ActivityStateEnum.Started
+ Case "finished"
+ Return ActivityStateEnum.Finished
+ Case "allfinished"
+ Return ActivityStateEnum.AllFinished
+ Case "zero"
+ Return ActivityStateEnum.Zero
+ Case Else
+ Throw New Exception($"The activity state value is unknown for getting a corresponding enum value: '{activityStateValue}'.")
+ End Select
+ End Function
+
+End Module
Index: ActiviteitenOpvolging/ActiviteitenOpvolging/configs/ConfigsLoader.vb
===================================================================
diff -u -r1669 -r1671
--- ActiviteitenOpvolging/ActiviteitenOpvolging/configs/ConfigsLoader.vb (.../ConfigsLoader.vb) (revision 1669)
+++ ActiviteitenOpvolging/ActiviteitenOpvolging/configs/ConfigsLoader.vb (.../ConfigsLoader.vb) (revision 1671)
@@ -1,10 +1,12 @@
Imports System.IO
Imports System.Security.Policy
+Imports System.Text.RegularExpressions
Namespace configs
Public Module ConfigsLoader
Const MaxNumberOfGrids As Integer = 4
Const MaxNumberOfUsers As Integer = 4
+ Const MaxIntervalSeconds As Integer = 3600 'Max of 6 hours
Sub New()
Try
@@ -14,32 +16,15 @@
LoadDynamicConfigLines(configsTextMapper.GetAllValues(Path.Combine(My.Application.Info.DirectoryPath, "DynamicConfigs.txt")))
ValidateDynamicConfigs()
'Load the general configs.
- Dim generalConfigLines = configsTextMapper.GetAllValues("c:\users\test.txt")
+ LoadGeneralConfigLines(configsTextMapper.GetAllValues(Path.Combine(My.Application.Info.DirectoryPath, "GeneralConfigs.txt")))
+ ValidateGeneralConfigs()
Catch ex As Exception
'Show error message, it's just easier to handle it here.
MessageBox.Show(ex.Message, "An error occured...", MessageBoxButtons.OK, MessageBoxIcon.Error)
Application.Exit()
End Try
End Sub
-#Region "General config properties"
- Property RefreshIntervalMiliseconds As Integer
- Property RefreshTimeStart As DateTime
- Property RefreshTimeEnd As DateTime
- Property CacheWebserviceUrl As Url
-#Region "Colors"
-
- Property AgColorBatch As Color
- Property AgColorProductGroup As Color
- Property AgColorTo As Color
-
- Property ColorsDueOut As New Dictionary(Of DueOutStateEnum, Color)
- Property ActivityColors As New Dictionary(Of ActivityStateEnum, Color)
- Property ActivityColorsReadonly As New Dictionary(Of ActivityStateEnum, Color)
- Property UserColors As New List(Of Integer)
-#End Region
-#End Region
-
#Region "Help functions"
'''
''' Extract the identification of the config from the line. Example => 'identification'=600
@@ -68,6 +53,20 @@
Throw New Exception($"Invalid configuration entry. Can't extract the value for the config (the part after the '='): '{configLine}'.")
End Try
End Function
+
+ '''
+ ''' Get the color corresponding to the hexadecimal string code. In seperate function for error handling.
+ '''
+ '''
+ '''
+ Private Function GetColorFromHexStringValue(hexadecimalColorCode As String) As Color
+ Try
+ 'Convert to color and return.
+ Return ColorTranslator.FromHtml(hexadecimalColorCode)
+ Catch ex As Exception
+ Throw New ConfigurationException($"The value '{hexadecimalColorCode}' cannot be converted to a color.")
+ End Try
+ End Function
#End Region
#Region "Dynamic configs"
@@ -96,9 +95,12 @@
'''
Private Sub LoadDynamicConfigLines(dynamicConfigLines As IReadOnlyCollection(Of String))
Try
+ 'Loop through each line.
For Each line In dynamicConfigLines
+ 'Get key and value of a config entry.
Dim identifier = ExtractConfigIdentifier(line)
Dim value = ExtractConfigValue(line)
+
If identifier.Equals("AppName") Then
_AppName = value
ElseIf identifier.Equals("AppID") Then
@@ -116,7 +118,7 @@
End If
Next
Catch ex As InvalidCastException
- Throw New ConfigurationException($"One of the values is an invalid type.{vbNewLine}{ex.Message}")
+ Throw New ConfigurationException($"One of the dynamic config values has an invalid type.{vbNewLine}{ex.Message}")
End Try
End Sub
@@ -158,5 +160,221 @@
End If
End Sub
#End Region
+
+#Region "General configs"
+#Region "Properties"
+ Public ReadOnly Property RefreshIntervalSeconds As Integer
+ Public ReadOnly Property RefreshTimeStart As TimeSpan
+ Public ReadOnly Property RefreshTimeEnd As TimeSpan
+ Public ReadOnly Property CacheWebserviceUrl As Url
+#Region "Colors"
+ Public ReadOnly Property AgColorBatch As Color
+ Public ReadOnly Property AgColorProductGroup As Color
+ Public ReadOnly Property AgColorTo As Color
+ Private ReadOnly Property _colorsDueOut As New Dictionary(Of DueOutStateEnum, Color)
+ Public ReadOnly Property ColorsDueOut As Dictionary(Of DueOutStateEnum, Color)
+ Get
+ Return New Dictionary(Of DueOutStateEnum, Color)(_colorsDueOut)
+ End Get
+ End Property
+ Private ReadOnly Property _colorsActivities As New Dictionary(Of ActivityStateEnum, Color)
+ Public ReadOnly Property ColorsActivities As Dictionary(Of ActivityStateEnum, Color)
+ Get
+ Return New Dictionary(Of ActivityStateEnum, Color)(_colorsActivities)
+ End Get
+ End Property
+ Private ReadOnly Property _colorsActivityReadOnly As New Dictionary(Of ActivityStateEnum, Color)
+ Public ReadOnly Property ColorsActivitiesReadOnly As Dictionary(Of ActivityStateEnum, Color)
+ Get
+ Return New Dictionary(Of ActivityStateEnum, Color)(_colorsActivityReadOnly)
+ End Get
+ End Property
+ Private ReadOnly _colorsUsers As New List(Of Color)
+ Public ReadOnly Property ColorsUsers As List(Of Color)
+ Get
+ Return New List(Of Color)(_colorsUsers)
+ End Get
+ End Property
+#End Region
+#End Region
+ '''
+ ''' Loads in all the general configs.
+ '''
+ '''
+ Private Sub LoadGeneralConfigLines(generalConfigLines As IReadOnlyCollection(Of String))
+ Try
+ 'Loop through each line.
+ For Each line In generalConfigLines
+ 'Get key and value of a config entry.
+ Dim identifier = ExtractConfigIdentifier(line)
+ Dim value = ExtractConfigValue(line)
+
+ If identifier.Equals("RefreshFrequence") Then
+ _RefreshIntervalSeconds = value
+ ElseIf identifier.Equals("RefreshTimeStart") Then
+ _RefreshTimeStart = TimeSpan.FromHours(value)
+ ElseIf identifier.Equals("RefreshTimeEnd") Then
+ _RefreshTimeEnd = TimeSpan.FromHours(value)
+ ElseIf identifier.Equals("CacheWebserviceURL") Then
+ _CacheWebserviceUrl = New Url(value)
+ ElseIf identifier.Equals("AgColorBatch") Then
+ _AgColorBatch = GetColorFromHexStringValue(value)
+ ElseIf identifier.Equals("AgColorProductGroup") Then
+ _AgColorProductGroup = GetColorFromHexStringValue(value)
+ ElseIf identifier.Equals("AgColorTo") Then
+ _AgColorTo = GetColorFromHexStringValue(value)
+ ElseIf identifier.Contains("AgColorDueOut") Then
+ AddColorDueOut(identifier, value)
+ ElseIf identifier.Contains("AgColorActivityReadOnly") Then
+ AddColorActivity(identifier, value, True)
+ ElseIf identifier.Contains("AgColorActivity") Then
+ AddColorActivity(identifier, value, False)
+ ElseIf identifier.Contains("ColorUser") Then
+ _colorsUsers.Add(GetColorFromHexStringValue(value))
+ Else
+ Throw New Exception($"Unknown configuration: '{line}'.")
+ End If
+ Next
+ Catch ex As InvalidCastException
+ Throw New ConfigurationException($"One of the general config values has an invalid type.{vbNewLine}{ex.Message}")
+ Catch ex As Exception
+ Throw New ConfigurationException($"One of the general config values is invalid.{vbNewLine}{ex.Message}")
+ End Try
+ End Sub
+
+ '''
+ ''' Add a color for a due out state to the dictionary.
+ '''
+ ''' The identifier of the state
+ ''' The hexadecimal string value of the color
+ Private Sub AddColorDueOut(identifier As String, value As String)
+ Try
+ 'Extract the state name.
+ 'Invoke the Match method, all text after AgColorDueOut.
+ Dim m As Match = Regex.Match(identifier, "AgColorDueOut(.*)")
+
+ If Not m.Success Then
+ 'No results.
+ Throw New ConfigurationException($"Could not get the state for assigning a color for DueOut. Identifier is '{identifier}'.")
+ End If
+
+ 'If successful, extract the state name.
+ dim stateName = m.Groups(1).Value
+
+ 'Convert string value to enum value.
+ Dim enumValue = DueOutStateEnumMapper.GetEnumValueFromString(stateName)
+
+ 'Add to library, key is the enum value, value is the color.
+ _colorsDueOut.Add(enumValue, GetColorFromHexStringValue(value))
+ Catch ex As Exception
+ Throw New ConfigurationException($"ColorDueOut with name: '{identifier}' and value '{value}' is invalid.{vbNewLine}{ex.Message}")
+ End Try
+ End Sub
+
+ '''
+ ''' Add a color for a due out state to the dictionary.
+ '''
+ ''' The identifier of the state
+ ''' The hexadecimal string value of the color
+ ''' Whether or not the activity is readonly
+ Private Sub AddColorActivity(identifier As String, value As String, isReadOnly As Boolean)
+ Try
+ 'Extract the state name.
+ 'Invoke the Match method, all text after AgColorDueOut.
+ Dim m As Match = Regex.Match(identifier, If(isReadOnly,"AgColorActivityReadOnly(.*)", "AgColorActivity(.*)"))
+
+ If Not m.Success Then
+ 'No results.
+ Throw New ConfigurationException($"Could not get the state for assigning a color for DueOut. Identifier is '{identifier}'.")
+ End If
+
+ 'If successful, extract the state name.
+ dim stateName = m.Groups(1).Value
+
+ 'Convert string value to enum value.
+ Dim enumValue = ActivityStateEnumMapper.GetEnumValueFromString(stateName)
+
+ 'Add to library, key is the enum value, value is the color.
+ If isReadOnly Then
+ 'It's readonly.
+ _colorsActivityReadOnly.Add(enumValue, GetColorFromHexStringValue(value))
+ Else
+ 'It's not.
+ _colorsActivities.Add(enumValue, GetColorFromHexStringValue(value))
+ End If
+ Catch ex As Exception
+ Throw New ConfigurationException($"Color activity with name: '{identifier}' and value '{value}' is invalid.{vbNewLine}{ex.Message}")
+ End Try
+ End Sub
+
+ '''
+ ''' Validate that all the required fields are present.
+ '''
+ Private Sub ValidateGeneralConfigs()
+ 'Refresh interval.
+ If RefreshIntervalSeconds <= 0 Then
+ Throw New ConfigurationException("The refresh interval is too low.")
+ ElseIf RefreshIntervalSeconds > MaxIntervalSeconds Then
+ Throw New ConfigurationException($"Refresh interval is above the maximum of {MaxIntervalSeconds} seconds.")
+ End If
+
+ 'Refresh time start.
+ If RefreshTimeStart = TimeSpan.Zero Then
+ Throw New ConfigurationException("Refresh time start is not defined.")
+ End If
+
+ 'Refresh time end.
+ If RefreshTimeEnd = TimeSpan.Zero Then
+ Throw New ConfigurationException("Refresh time end is not defined.")
+ End If
+
+ 'Caché webservice URL.
+ If CacheWebserviceUrl Is Nothing Then
+ Throw New ConfigurationException("The Caché webservice URL is not defined.")
+ End If
+
+ 'Ag color batch.
+ If AgColorBatch = Color.Empty Then
+ Throw New ConfigurationException("The Ag color batch is not defined.")
+ End If
+
+ 'Ag color production group.
+ If AgColorProductGroup = Color.Empty Then
+ Throw New ConfigurationException("The Ag color production group is not defined.")
+ End If
+
+ 'Caché webservice URL.
+ If AgColorTo = Color.Empty Then
+ Throw New ConfigurationException("The Ag color to is not defined.")
+ End If
+
+ 'Colors due out.
+ If _colorsDueOut.Keys.Count <> [Enum].GetValues(GetType(DueOutStateEnum)).Length Then
+ 'Amount of enum values and entries in the dictionary differ.
+ Throw New ConfigurationException($"The amount of colors defined for the different states of DueOut differs from the amount of states.
+ There are {[Enum].GetValues(GetType(DueOutStateEnum)).Length} total states and {_colorsDueOut.Keys.Count} colors are defined.")
+ End If
+
+ 'Colors activities.
+ If _colorsActivities.Keys.Count <> [Enum].GetValues(GetType(ActivityStateEnum)).Length Then
+ 'Amount of enum values and entries in the dictionary differ.
+ Throw New ConfigurationException($"The amount of colors defined for the different states of activities differs from the amount of states.
+ There are {[Enum].GetValues(GetType(ActivityStateEnum)).Length} total states and {_colorsActivities.Keys.Count} colors are defined.")
+ End If
+
+ 'Colors activities readonly.
+ If _colorsActivityReadOnly.Keys.Count <> ([Enum].GetValues(GetType(ActivityStateEnum)).Length - 2) Then
+ 'Amount of enum values and entries in the dictionary differ. ReadOnly doesn't have a color value for the 2 special activities.
+ Throw New ConfigurationException($"The amount of colors defined for the different states of readonly activities differs from the amount of states.
+ There are {[Enum].GetValues(GetType(ActivityStateEnum)).Length} total states and {_colorsActivityReadOnly.Keys.Count} colors are defined.")
+ End If
+
+ 'Colors users.
+ If _colorsUsers.Count <> MaxNumberOfUsers Then
+ Throw New ConfigurationException($"The colors for the users are not defined or differ from the required amount of {MaxNumberOfUsers}.")
+ End If
+ End Sub
+
+#End Region
End Module
End Namespace
\ No newline at end of file
Index: ActiviteitenOpvolging/ActiviteitenOpvolging/enums/DueOutStateEnum.vb
===================================================================
diff -u -r1666 -r1671
--- ActiviteitenOpvolging/ActiviteitenOpvolging/enums/DueOutStateEnum.vb (.../DueOutStateEnum.vb) (revision 1666)
+++ ActiviteitenOpvolging/ActiviteitenOpvolging/enums/DueOutStateEnum.vb (.../DueOutStateEnum.vb) (revision 1671)
@@ -4,3 +4,26 @@
Almost
Start
End Enum
+
+Public Module DueOutStateEnumMapper
+ '''
+ ''' Gets the corresponding enum value from the DueOutStateEnum with a string value.
+ '''
+ ''' The string value
+ '''
+ Public Function GetEnumValueFromString(stateValue As String) As DueOutStateEnum
+ Select Case stateValue.ToLower()
+ Case "defaulted"
+ Return DueOutStateEnum.Defaulted
+ Case "before"
+ Return DueOutStateEnum.Before
+ Case "almost"
+ Return DueOutStateEnum.Almost
+ Case "start"
+ Return DueOutStateEnum.Start
+ Case Else
+ Throw New Exception($"The due out state value is unknown for getting a corresponding enum value: '{stateValue}'.")
+ End Select
+ End Function
+
+End Module
\ No newline at end of file