From 29b61f9b8acc4f81dd268fb29117a1385d85d3b2 Mon Sep 17 00:00:00 2001 From: Markus Quaritsch <markus.quaritsch@tugraz.at> Date: Wed, 13 Sep 2017 09:26:05 +0200 Subject: [PATCH] refactoring: use common model for validating job and results, full job-file validation when validating results --- HashingTool/HashingTool.csproj | 2 + HashingTool/Helper/HashingHelper.cs | 126 ++++++++++++++++++ HashingTool/ViewModel/ComponentEntry.cs | 11 ++ .../ViewModel/HashComponentDataViewModel.cs | 3 +- HashingTool/ViewModel/HashedXMLFile.cs | 123 +++++++++++++++-- HashingTool/ViewModel/ObservableObject.cs | 74 +--------- HashingTool/ViewModel/UserControl/XMLFile.cs | 7 +- .../VerifyComponentInputDataViewModel.cs | 3 +- .../ViewModel/VerifyJobInputDataViewModel.cs | 113 +--------------- .../ViewModel/VerifyResultDataViewModel.cs | 61 ++------- .../UserControl/VectoXMLFileSelector.xaml | 2 +- HashingTool/Views/VerifyJobInputData.xaml | 4 +- HashingTool/Views/VerifyResults.xaml | 107 ++++++++++----- 13 files changed, 349 insertions(+), 287 deletions(-) create mode 100644 HashingTool/Helper/HashingHelper.cs create mode 100644 HashingTool/ViewModel/ComponentEntry.cs diff --git a/HashingTool/HashingTool.csproj b/HashingTool/HashingTool.csproj index 96af1fa2fc..98d705e197 100644 --- a/HashingTool/HashingTool.csproj +++ b/HashingTool/HashingTool.csproj @@ -67,6 +67,7 @@ <SubType>Designer</SubType> </ApplicationDefinition> <Compile Include="Helper\CollectionConverter.cs" /> + <Compile Include="Helper\HashingHelper.cs" /> <Compile Include="Helper\IOService.cs" /> <Compile Include="Properties\Annotations.cs" /> <Compile Include="Properties\Version.cs"> @@ -74,6 +75,7 @@ <AutoGen>True</AutoGen> <DesignTime>True</DesignTime> </Compile> + <Compile Include="ViewModel\ComponentEntry.cs" /> <Compile Include="ViewModel\HashedXMLFile.cs" /> <Compile Include="ViewModel\HomeViewModel.cs" /> <Compile Include="ViewModel\IMainView.cs" /> diff --git a/HashingTool/Helper/HashingHelper.cs b/HashingTool/Helper/HashingHelper.cs new file mode 100644 index 0000000000..5206674c70 --- /dev/null +++ b/HashingTool/Helper/HashingHelper.cs @@ -0,0 +1,126 @@ +using System; +using System.Collections.ObjectModel; +using System.Linq; +using System.Xml; +using HashingTool.ViewModel; +using TUGraz.VectoCommon.Resources; +using TUGraz.VectoHashing; + +namespace HashingTool.Helper +{ + public static class HashingHelper + { + public const string ToolTipInvalidFileType = "Invalid File type!"; + public const string ToolTipXMLValidationFailed = "XML validation failed!"; + public const string ToolTipOk = "Correct file selected"; + public const string ToolTipHashInvalid = "Incorrect digest value!"; + public const string ToolTipNone = ""; + public static string ToolTipComponentHashInvalid = "Job-Data validation failed!"; + + public static bool? IsManufacturerReport(XmlDocument x, Collection<string> errorLog) + { + if (x == null || x.DocumentElement == null) { + return null; + } + var valid = x.DocumentElement.LocalName == XMLNames.VectoManufacturerReport; + if (!valid) { + errorLog.Add(String.Format("Invalid XML file given ({0}). Expected Manufacturer Report XML ({1})!", + x.DocumentElement.LocalName, XMLNames.VectoManufacturerReport)); + } + return valid; + } + + public static bool? IsCustomerReport(XmlDocument x, Collection<string> errorLog) + { + if (x == null || x.DocumentElement == null) { + return null; + } + var valid = x.DocumentElement != null && x.DocumentElement.LocalName == XMLNames.VectoCustomerReport; + if (!valid) { + errorLog.Add(String.Format("Invalid XML file given ({0}). Expected Customer Report XML ({1})!", + x.DocumentElement.LocalName, XMLNames.VectoCustomerReport)); + } + return valid; + } + + public static bool? IsJobFile(XmlDocument x, Collection<string> errorLog) + { + if (x == null || x.DocumentElement == null) { + return null; + } + var valid = x.DocumentElement.LocalName == XMLNames.VectoInputDeclaration && + x.DocumentElement.FirstChild.LocalName == XMLNames.Component_Vehicle; + if (!valid) { + errorLog.Add(String.Format("Invalid XML file given ({0}/{1}). Expected Vehicle XML ({2}/{3})!", + x.DocumentElement.LocalName, x.DocumentElement.FirstChild.LocalName, XMLNames.VectoInputDeclaration, + XMLNames.Component_Vehicle)); + } + return valid; + } + + public static bool? IsComponentFile(XmlDocument x, Collection<string> errorLog) + { + if (x.DocumentElement == null) { + return null; + } + + if (x.DocumentElement.LocalName != XMLNames.VectoInputDeclaration) { + errorLog.Add(String.Format("Invalid XML file given ({0}). Expected Component XML ({1})!", + x.DocumentElement.LocalName, XMLNames.VectoInputDeclaration)); + + return false; + } + + var localName = x.DocumentElement.FirstChild.LocalName; + var components = new[] { + VectoComponents.Engine, VectoComponents.Airdrag, VectoComponents.Angledrive, VectoComponents.Axlegear, + VectoComponents.Gearbox, VectoComponents.Retarder, VectoComponents.TorqueConverter, VectoComponents.Tyre + }; + var valid = components.Where(c => c.XMLElementName() == localName).Any(); + if (!valid) { + errorLog.Add(String.Format("Invalid XML file given ({0}). Expected Component XML ({1})!", + localName, String.Join(", ", components.Select(c => c.XMLElementName())))); + } + return valid; + } + + + public static void HashJobFile(XmlDocument xml, VectoXMLFile xmlViewModel) + { + try { + var h = VectoHash.Load(xml); + xmlViewModel.DigestValueComputed = h.ComputeHash(); + } catch (Exception e) { + xmlViewModel.XMLFile.XMLValidationErrors.Add(e.Message); + xmlViewModel.DigestValueComputed = ""; + } + } + + public static void ValidateDocumentHash(XmlDocument xml, VectoXMLFile xmlViewModel) + { + var report = xmlViewModel as ReportXMLFile; + if (report == null) { + return; + } + try { + var h = VectoHash.Load(xml); + try { + report.DigestValueRead = h.ReadHash(); + } catch { + report.DigestValueRead = ""; + } + try { + report.DigestValueComputed = h.ComputeHash(); + } catch { + report.DigestValueComputed = ""; + } + var valid = h.ValidateHash(); + report.ValidTooltip = valid ? ToolTipOk : ToolTipHashInvalid; + report.Valid = valid; + } catch (Exception e) { + report.XMLFile.XMLValidationErrors.Add(e.Message); + report.Valid = false; + } + } + } +} diff --git a/HashingTool/ViewModel/ComponentEntry.cs b/HashingTool/ViewModel/ComponentEntry.cs new file mode 100644 index 0000000000..8c1e45e9b6 --- /dev/null +++ b/HashingTool/ViewModel/ComponentEntry.cs @@ -0,0 +1,11 @@ +namespace HashingTool.ViewModel +{ + public class ComponentEntry + { + public string Component { get; set; } + public string DigestValueRead { get; set; } + public string DigestValueComputed { get; set; } + public string[] CanonicalizationMethod { get; set; } + public bool Valid { get; set; } + } +} diff --git a/HashingTool/ViewModel/HashComponentDataViewModel.cs b/HashingTool/ViewModel/HashComponentDataViewModel.cs index 7fee6dd53b..6828f7dfd5 100644 --- a/HashingTool/ViewModel/HashComponentDataViewModel.cs +++ b/HashingTool/ViewModel/HashComponentDataViewModel.cs @@ -8,6 +8,7 @@ using System.Windows.Input; using System.Xml; using System.Xml.Linq; using System.Xml.Schema; +using HashingTool.Helper; using HashingTool.Util; using HashingTool.ViewModel.UserControl; using TUGraz.VectoHashing; @@ -28,7 +29,7 @@ namespace HashingTool.ViewModel public HashComponentDataViewModel() { XMLValidationErrors = new ObservableCollection<string>(); - _sourceFile = new XMLFile(IoService, false, IsComponentFile); + _sourceFile = new XMLFile(IoService, false, HashingHelper.IsComponentFile); _sourceFile.PropertyChanged += SourceChanged; _saveCommand = new RelayCommand(SaveDocument, () => !_busy && ComponentDataValid != null && ComponentDataValid.Value && _result != null); diff --git a/HashingTool/ViewModel/HashedXMLFile.cs b/HashingTool/ViewModel/HashedXMLFile.cs index 4101bbf711..a691a9a660 100644 --- a/HashingTool/ViewModel/HashedXMLFile.cs +++ b/HashingTool/ViewModel/HashedXMLFile.cs @@ -1,9 +1,11 @@ using System; using System.Collections.ObjectModel; using System.ComponentModel; +using System.Linq; using System.Xml; using HashingTool.Helper; using HashingTool.ViewModel.UserControl; +using TUGraz.VectoHashing; namespace HashingTool.ViewModel { @@ -20,36 +22,39 @@ namespace HashingTool.ViewModel protected readonly Action<XmlDocument, VectoXMLFile> _validateHashes; - public VectoXMLFile(IOService ioService, string name, Func<XmlDocument, Collection<string>, bool?> contentCheck, + public VectoXMLFile(string name, Func<XmlDocument, Collection<string>, bool?> contentCheck, Action<XmlDocument, VectoXMLFile> hashValidation = null) { - IoService = ioService; _validateHashes = hashValidation; - _xmlFile = new XMLFile(IoService, true); + _xmlFile = new XMLFile(IoService, true, contentCheck); _xmlFile.PropertyChanged += FileChanged; Name = name; - _contentCheck = contentCheck; + // TODO CanonicalizationMethods = new[] { "urn:vecto:xml:2017:canonicalization", "http://www.w3.org/2001/10/xml-exc-c14n#" }; Valid = null; - ValidTooltip = VerifyResultDataViewModel.ToolTipNone; + ValidTooltip = HashingHelper.ToolTipNone; } protected virtual void FileChanged(object sender, PropertyChangedEventArgs e) { if (_xmlFile.IsValid != null && XMLFile.IsValid.HasValue && _xmlFile.IsValid.Value) { - Valid = _contentCheck(_xmlFile.Document, XMLFile.XMLValidationErrors); - if (Valid != null && Valid.Value) { - ValidTooltip = VerifyResultDataViewModel.ToolTipOk; + if (_xmlFile.HasContentValidation) { + Valid = _xmlFile.ContentValid; + if (Valid != null && Valid.Value) { + ValidTooltip = HashingHelper.ToolTipOk; + } else { + ValidTooltip = HashingHelper.ToolTipInvalidFileType; + } } else { - ValidTooltip = VerifyResultDataViewModel.ToolTipInvalidFileType; + ValidTooltip = HashingHelper.ToolTipOk; } } else { Valid = false; - ValidTooltip = VerifyResultDataViewModel.ToolTipXMLValidationFailed; + ValidTooltip = HashingHelper.ToolTipXMLValidationFailed; } if (Valid != null && Valid.Value && _validateHashes != null) { @@ -133,7 +138,7 @@ namespace HashingTool.ViewModel protected string _manufacturerDigestRead; public HashedXMLFile(IOService ioService, string name, Func<XmlDocument, Collection<string>, bool?> contentCheck, - Action<XmlDocument, VectoXMLFile> hashValidation = null) : base(ioService, name, contentCheck, hashValidation) {} + Action<XmlDocument, VectoXMLFile> hashValidation = null) : base(name, contentCheck, hashValidation) {} public string DigestValueRead { @@ -187,4 +192,100 @@ namespace HashingTool.ViewModel } } } + + public class VectoJobFile : VectoXMLFile + { + private bool _componentDataValid; + private string _jobValidToolTip; + + + public VectoJobFile(string name, Func<XmlDocument, Collection<string>, bool?> contentCheck, + Action<XmlDocument, VectoXMLFile> hashValidation = null) : base(name, contentCheck, hashValidation) + { + _xmlFile.PropertyChanged += JobFilechanged; + Components = new ObservableCollection<ComponentEntry>(); + } + + public ObservableCollection<ComponentEntry> Components { get; private set; } + + public bool JobDataValid + { + get { return _componentDataValid; } + set { + if (_componentDataValid == value) { + return; + } + _componentDataValid = value; + JobValidToolTip = value ? HashingHelper.ToolTipComponentHashInvalid : HashingHelper.ToolTipOk; + RaisePropertyChanged("JobDataValid"); + } + } + + public string JobValidToolTip + { + get { return _jobValidToolTip; } + set { + if (_jobValidToolTip == value) { + return; + } + _jobValidToolTip = value; + RaisePropertyChanged("JobValidToolTip"); + } + } + + private void JobFilechanged(object sender, PropertyChangedEventArgs e) + { + DoValidateHash(); + } + + private void DoValidateHash() + { + if (_xmlFile.Document == null || _xmlFile.ContentValid == null || !_xmlFile.ContentValid.Value) { + Components.Clear(); + DigestValueComputed = ""; + JobDataValid = false; + return; + } + try { + Components.Clear(); + _xmlFile.XMLValidationErrors.Clear(); + var h = VectoHash.Load(_xmlFile.Document); + var allValid = true; + var components = h.GetContainigComponents().GroupBy(s => s) + .Select(g => new { Entry = g.Key, Count = g.Count() }); + foreach (var component in components) { + if (component.Entry == VectoComponents.Vehicle) { + continue; + } + for (var i = 0; i < component.Count; i++) { + var entry = new ComponentEntry(); + entry.Component = component.Count == 1 + ? component.Entry.XMLElementName() + : string.Format("{0} ({1})", component.Entry.XMLElementName(), i + 1); + entry.Valid = h.ValidateHash(component.Entry, i); + entry.CanonicalizationMethod = new[] { + "urn:vecto:xml:2017:canonicalization", + "http://www.w3.org/2001/10/xml-exc-c14n#" + }; + entry.DigestValueRead = h.ReadHash(component.Entry, i); + entry.DigestValueComputed = h.ComputeHash(component.Entry, i); + if (!entry.Valid) { + _xmlFile.XMLValidationErrors.Add( + string.Format("Digest Value mismatch for component \"{0}\". Read digest value: \"{1}\", computed digest value \"{2}\"", + entry.Component, entry.DigestValueRead, entry.DigestValueComputed)); + } + Components.Add(entry); + allValid &= entry.Valid; + } + } + + DigestValueComputed = h.ComputeHash(); + JobDataValid = allValid; + } catch (Exception e) { + DigestValueComputed = ""; + JobDataValid = false; + _xmlFile.XMLValidationErrors.Add(e.Message); + } + } + } } diff --git a/HashingTool/ViewModel/ObservableObject.cs b/HashingTool/ViewModel/ObservableObject.cs index a11fd5f37e..0ff466c1c0 100644 --- a/HashingTool/ViewModel/ObservableObject.cs +++ b/HashingTool/ViewModel/ObservableObject.cs @@ -1,10 +1,5 @@ -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.Linq; -using System.Xml; +using System.ComponentModel; using HashingTool.Helper; -using TUGraz.VectoCommon.Resources; -using TUGraz.VectoHashing; namespace HashingTool.ViewModel { @@ -21,72 +16,5 @@ namespace HashingTool.ViewModel handler(this, new PropertyChangedEventArgs(propertyName)); } } - - protected bool? IsManufacturerReport(XmlDocument x, Collection<string> errorLog) - { - if (x == null || x.DocumentElement == null) { - return null; - } - var valid = x.DocumentElement.LocalName == XMLNames.VectoManufacturerReport; - if (!valid) { - errorLog.Add(string.Format("Invalid XML file given ({0}). Expected Manufacturer Report XML ({1})!", - x.DocumentElement.LocalName, XMLNames.VectoManufacturerReport)); - } - return valid; - } - - protected bool? IsCustomerReport(XmlDocument x, Collection<string> errorLog) - { - if (x == null || x.DocumentElement == null) { - return null; - } - var valid = x.DocumentElement != null && x.DocumentElement.LocalName == XMLNames.VectoCustomerReport; - if (!valid) { - errorLog.Add(string.Format("Invalid XML file given ({0}). Expected Customer Report XML ({1})!", - x.DocumentElement.LocalName, XMLNames.VectoCustomerReport)); - } - return valid; - } - - protected static bool? IsJobFile(XmlDocument x, Collection<string> errorLog) - { - if (x == null || x.DocumentElement == null) { - return null; - } - var valid = x.DocumentElement.LocalName == XMLNames.VectoInputDeclaration && - x.DocumentElement.FirstChild.LocalName == XMLNames.Component_Vehicle; - if (!valid) { - errorLog.Add(string.Format("Invalid XML file given ({0}/{1}). Expected Vehicle XML ({2}/{3})!", - x.DocumentElement.LocalName, x.DocumentElement.FirstChild.LocalName, XMLNames.VectoInputDeclaration, - XMLNames.Component_Vehicle)); - } - return valid; - } - - protected static bool? IsComponentFile(XmlDocument x, Collection<string> errorLog) - { - if (x.DocumentElement == null) { - return null; - } - - if (x.DocumentElement.LocalName != XMLNames.VectoInputDeclaration) { - errorLog.Add(string.Format("Invalid XML file given ({0}). Expected Component XML ({1})!", - x.DocumentElement.LocalName, XMLNames.VectoInputDeclaration)); - - return false; - } - - var localName = x.DocumentElement.FirstChild.LocalName; - var components = new[] { - VectoComponents.Engine, VectoComponents.Airdrag, VectoComponents.Angledrive, VectoComponents.Axlegear, - VectoComponents.Gearbox, VectoComponents.Retarder, VectoComponents.TorqueConverter, VectoComponents.Tyre - }; - var valid = components.Where(c => c.XMLElementName() == localName).Any(); - if (!valid) { - errorLog.Add(string.Format("Invalid XML file given ({0}). Expected Component XML ({1})!", - localName, string.Join(", ", components.Select(c => c.XMLElementName())))); - } - return valid; - } } } diff --git a/HashingTool/ViewModel/UserControl/XMLFile.cs b/HashingTool/ViewModel/UserControl/XMLFile.cs index 56b46ad72f..17bdf030c5 100644 --- a/HashingTool/ViewModel/UserControl/XMLFile.cs +++ b/HashingTool/ViewModel/UserControl/XMLFile.cs @@ -23,13 +23,14 @@ namespace HashingTool.ViewModel.UserControl private readonly Func<XmlDocument, Collection<string>, bool?> _postVerification; private bool? _contentValid; - public XMLFile(IOService ioservice, bool validate = false, Func<XmlDocument, Collection<string>, bool?> contentCheck = null) + public XMLFile(IOService ioservice, bool validate = false, + Func<XmlDocument, Collection<string>, bool?> contentCheck = null) { IoService = ioservice; _validate = validate; XMLValidationErrors = new ObservableCollection<string>(); HasContentValidation = contentCheck != null; - _postVerification = contentCheck ?? ((x,c) => null); + _postVerification = contentCheck ?? ((x, c) => null); Source = ""; RaisePropertyChanged("ValidateInput"); RaisePropertyChanged("HasContentValidation"); @@ -136,8 +137,8 @@ namespace HashingTool.ViewModel.UserControl var document = new XmlDocument(); var reader = XmlReader.Create(stream); document.Load(reader); - ContentValid = _postVerification(document, XMLValidationErrors); Document = document; + ContentValid = _postVerification(document, XMLValidationErrors); _busy = false; } diff --git a/HashingTool/ViewModel/VerifyComponentInputDataViewModel.cs b/HashingTool/ViewModel/VerifyComponentInputDataViewModel.cs index cc19810259..8a3758f12b 100644 --- a/HashingTool/ViewModel/VerifyComponentInputDataViewModel.cs +++ b/HashingTool/ViewModel/VerifyComponentInputDataViewModel.cs @@ -5,6 +5,7 @@ using System.IO; using System.Linq; using System.Windows; using System.Windows.Input; +using HashingTool.Helper; using HashingTool.ViewModel.UserControl; using TUGraz.VectoHashing; @@ -21,7 +22,7 @@ namespace HashingTool.ViewModel public VerifyComponentInputDataViewModel() { - _componentFile = new XMLFile(IoService, true, IsComponentFile); + _componentFile = new XMLFile(IoService, true, HashingHelper.IsComponentFile); _componentFile.PropertyChanged += ComponentFilechanged; // TODO! diff --git a/HashingTool/ViewModel/VerifyJobInputDataViewModel.cs b/HashingTool/ViewModel/VerifyJobInputDataViewModel.cs index 8eb83f3bf2..d4310d6905 100644 --- a/HashingTool/ViewModel/VerifyJobInputDataViewModel.cs +++ b/HashingTool/ViewModel/VerifyJobInputDataViewModel.cs @@ -3,37 +3,17 @@ using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; using System.Windows.Input; +using HashingTool.Helper; using HashingTool.ViewModel.UserControl; using TUGraz.VectoHashing; namespace HashingTool.ViewModel { - public class VerifyJobInputDataViewModel : ObservableObject, IMainView + public class VerifyJobInputDataViewModel : VectoJobFile, IMainView { - private string _digestValueComputed; - private bool _componentDataValid; - private readonly XMLFile _jobFile; + public VerifyJobInputDataViewModel() : base("Verify VECTO Job", HashingHelper.IsJobFile, HashingHelper.HashJobFile) {} - public VerifyJobInputDataViewModel() - { - _jobFile = new XMLFile(IoService, true, IsJobFile); - _jobFile.PropertyChanged += JobFilechanged; - - // TODO! - CanonicalizationMethods = new ObservableCollection<string>() { - "urn:vecto:xml:2017:canonicalization", - "http://www.w3.org/2001/10/xml-exc-c14n#" - }; - Components = new ObservableCollection<ComponentEntry>(); - } - - - public string Name - { - get { return "Verify VECTO Job"; } - } - public ICommand ShowHomeViewCommand { get { return ApplicationViewModel.HomeView; } @@ -41,92 +21,7 @@ namespace HashingTool.ViewModel public XMLFile JobFile { - get { return _jobFile; } + get { return _xmlFile; } } - - public ObservableCollection<ComponentEntry> Components { get; private set; } - - public ObservableCollection<string> CanonicalizationMethods { get; private set; } - - public string DigestValueComputed - { - get { return _digestValueComputed; } - set { - if (_digestValueComputed == value) { - return; - } - _digestValueComputed = value; - RaisePropertyChanged("DigestValueComputed"); - } - } - - public bool JobDataValid - { - get { return _componentDataValid; } - set { - if (_componentDataValid == value) { - return; - } - _componentDataValid = value; - RaisePropertyChanged("JobDataValid"); - } - } - - private void JobFilechanged(object sender, PropertyChangedEventArgs e) - { - if (e.PropertyName == "Document") { - DoValidateHash(); - } - } - - private void DoValidateHash() - { - if (_jobFile.ContentValid == null || !_jobFile.ContentValid.Value) { - return; - } - try { - Components.Clear(); - var h = VectoHash.Load(_jobFile.Document); - var allValid = true; - var components = h.GetContainigComponents().GroupBy(s => s) - .Select(g => new { Entry = g.Key, Count = g.Count() }); - foreach (var component in components) { - if (component.Entry == VectoComponents.Vehicle) { - continue; - } - for (var i = 0; i < component.Count; i++) { - var entry = new ComponentEntry(); - entry.Component = component.Count == 1 - ? component.Entry.XMLElementName() - : string.Format("{0} ({1})", component.Entry.XMLElementName(), i + 1); - entry.Valid = h.ValidateHash(component.Entry, i); - entry.CanonicalizationMethod = new[] { - "urn:vecto:xml:2017:canonicalization", - "http://www.w3.org/2001/10/xml-exc-c14n#" - }; - entry.DigestValueRead = h.ReadHash(component.Entry, i); - entry.DigestValueComputed = h.ComputeHash(component.Entry, i); - Components.Add(entry); - allValid &= entry.Valid; - } - } - - DigestValueComputed = h.ComputeHash(); - JobDataValid = allValid; - } catch (Exception e) { - DigestValueComputed = ""; - JobDataValid = false; - _jobFile.XMLValidationErrors.Add(e.Message); - } - } - } - - public class ComponentEntry - { - public string Component { get; set; } - public string DigestValueRead { get; set; } - public string DigestValueComputed { get; set; } - public string[] CanonicalizationMethod { get; set; } - public bool Valid { get; set; } } } diff --git a/HashingTool/ViewModel/VerifyResultDataViewModel.cs b/HashingTool/ViewModel/VerifyResultDataViewModel.cs index 4e9c83a6b8..a07397653a 100644 --- a/HashingTool/ViewModel/VerifyResultDataViewModel.cs +++ b/HashingTool/ViewModel/VerifyResultDataViewModel.cs @@ -3,28 +3,25 @@ using System.Collections.ObjectModel; using System.ComponentModel; using System.Windows.Input; using System.Xml; +using HashingTool.Helper; using TUGraz.VectoHashing; namespace HashingTool.ViewModel { public class VerifyResultDataViewModel : ObservableObject, IMainView { - private readonly VectoXMLFile _jobFile; + private readonly VectoJobFile _jobFile; private readonly ReportXMLFile _customerReport; private readonly ReportXMLFile _manufacturerReport; - public const string ToolTipInvalidFileType = "Invalid File type!"; - public const string ToolTipXMLValidationFailed = "XML validation failed!"; - public const string ToolTipOk = "Correct file selected"; - public const string ToolTipHashInvalid = "Incorrect digest value!"; - public const string ToolTipNone = ""; - public VerifyResultDataViewModel() { - _jobFile = new VectoXMLFile(IoService, "Job File", IsJobFile, HashJobFile); - _manufacturerReport = new ReportXMLFile(IoService, "Manufacturer Report", IsManufacturerReport, ValidateDocumentHash); - _customerReport = new ReportXMLFile(IoService, "Customer Report", IsCustomerReport, ValidateDocumentHash); + _jobFile = new VectoJobFile("Job File", HashingHelper.IsJobFile, HashingHelper.HashJobFile); + _manufacturerReport = new ReportXMLFile(IoService, "Manufacturer Report", HashingHelper.IsManufacturerReport, + HashingHelper.ValidateDocumentHash); + _customerReport = new ReportXMLFile(IoService, "Customer Report", HashingHelper.IsCustomerReport, + HashingHelper.ValidateDocumentHash); Files = new ObservableCollection<VectoXMLFile> { _jobFile, _manufacturerReport, _customerReport }; RaisePropertyChanged("CanonicalizationMethods"); @@ -49,18 +46,18 @@ namespace HashingTool.ViewModel get { return ApplicationViewModel.HomeView; } } - public VectoXMLFile JobFile + public VectoJobFile JobFile { get { return _jobFile; } } - public HashedXMLFile CustomerReport + public ReportXMLFile CustomerReport { get { return _customerReport; } } - public HashedXMLFile ManufacturerReport + public ReportXMLFile ManufacturerReport { get { return _manufacturerReport; } } @@ -82,43 +79,5 @@ namespace HashingTool.ViewModel _customerReport.JobDigest == _jobFile.DigestValueComputed; } } - - private void HashJobFile(XmlDocument xml, VectoXMLFile xmlViewModel) - { - try { - var h = VectoHash.Load(xml); - xmlViewModel.DigestValueComputed = h.ComputeHash(); - } catch (Exception e) { - xmlViewModel.XMLFile.XMLValidationErrors.Add(e.Message); - xmlViewModel.DigestValueComputed = ""; - } - } - - private void ValidateDocumentHash(XmlDocument xml, VectoXMLFile xmlViewModel) - { - var report = xmlViewModel as ReportXMLFile; - if (report == null) { - return; - } - try { - var h = VectoHash.Load(xml); - try { - report.DigestValueRead = h.ReadHash(); - } catch { - report.DigestValueRead = ""; - } - try { - report.DigestValueComputed = h.ComputeHash(); - } catch { - report.DigestValueComputed = ""; - } - var valid = h.ValidateHash(); - report.ValidTooltip = valid ? ToolTipOk : ToolTipHashInvalid; - report.Valid = valid; - } catch (Exception e) { - report.XMLFile.XMLValidationErrors.Add(e.Message); - report.Valid = false; - } - } } } diff --git a/HashingTool/Views/UserControl/VectoXMLFileSelector.xaml b/HashingTool/Views/UserControl/VectoXMLFileSelector.xaml index 037e2c0ee8..8b598ee9bf 100644 --- a/HashingTool/Views/UserControl/VectoXMLFileSelector.xaml +++ b/HashingTool/Views/UserControl/VectoXMLFileSelector.xaml @@ -15,7 +15,7 @@ <ContentControl DockPanel.Dock="Right" Visibility="{Binding XMLFile.HasContentValidation, Converter={StaticResource BoolToVis}}" Width="40" Height="40" - Margin="10,0,0,0"> + Margin="10,-5,5,0"> <ContentControl.LayoutTransform> <ScaleTransform ScaleX=".4" ScaleY=".4" /> </ContentControl.LayoutTransform> diff --git a/HashingTool/Views/VerifyJobInputData.xaml b/HashingTool/Views/VerifyJobInputData.xaml index 1aaaf6186e..1fffde3318 100644 --- a/HashingTool/Views/VerifyJobInputData.xaml +++ b/HashingTool/Views/VerifyJobInputData.xaml @@ -28,7 +28,7 @@ <DockPanel> <Label x:Name="lblFileSelect" DockPanel.Dock="Top" Content="Job data:" HorizontalAlignment="Left" Margin="10,0,0,0" VerticalAlignment="Top" /> - <views:VectoXMLFileSelector Margin="0,0,0,0" DockPanel.Dock="Top" VerticalAlignment="Top" XMLFile="{Binding JobFile}" + <views:VectoXMLFileSelector Margin="10,0,10,0" DockPanel.Dock="Top" VerticalAlignment="Top" XMLFile="{Binding JobFile}" Height="80" /> <Grid DockPanel.Dock="Top" Margin="0,0,0,0"> <Grid.RowDefinitions> @@ -45,7 +45,7 @@ <Label Grid.Row="1" Grid.Column="0" Content="Canonicalization methods:" /> <TextBox Grid.Row="1" Grid.Column="1" - Text="{Binding CanonicalizationMethods , Converter={StaticResource CollectionConverter}}" + Text="{Binding CanonicalizationMethods , Converter={StaticResource CollectionConverter}, Mode=OneWay}" Margin="10,2" IsReadOnly="True" /> <Label Grid.Row="2" Grid.Column="0" Content="Digest Value computed:" Style="{StaticResource DigestValueLabelStyle}" /> diff --git a/HashingTool/Views/VerifyResults.xaml b/HashingTool/Views/VerifyResults.xaml index 7849baa3b1..d908026e8d 100644 --- a/HashingTool/Views/VerifyResults.xaml +++ b/HashingTool/Views/VerifyResults.xaml @@ -16,10 +16,20 @@ <DataTemplate x:Key="ExpanderHeader" DataType="viewModel:VectoXMLFile"> <DockPanel HorizontalAlignment="Stretch" VerticalAlignment="top" MinWidth="450"> - <TextBlock DockPanel.Dock="Top" Text="{Binding Name}" FontWeight="Bold"/> + <TextBlock DockPanel.Dock="Top" Text="{Binding Name}" FontWeight="Bold" /> + + <views:VectoXMLFileSelector DockPanel.Dock="Left" Margin="0,0,35,0" VerticalAlignment="Top" + XMLFile="{Binding XMLFile}" Height="1" /> + + </DockPanel> + </DataTemplate> + + <DataTemplate x:Key="ExpanderHeaderJobFile" DataType="viewModel:VectoJobFile"> + <DockPanel HorizontalAlignment="Stretch" VerticalAlignment="top" MinWidth="450"> + <TextBlock DockPanel.Dock="Top" Text="{Binding Name}" FontWeight="Bold" /> <ContentControl DockPanel.Dock="Right" Width="35" Height="35" Margin="10,-10,10,0" - ToolTip="{Binding ValidTooltip}"> + ToolTip="{Binding JobValidToolTip}"> <ContentControl.LayoutTransform> <ScaleTransform ScaleX=".4" ScaleY=".4" /> </ContentControl.LayoutTransform> @@ -27,10 +37,10 @@ <Style TargetType="ContentControl"> <Setter Property="Content" Value="" /> <Style.Triggers> - <DataTrigger Binding="{Binding Valid}" Value="True"> + <DataTrigger Binding="{Binding JobDataValid}" Value="True"> <Setter Property="ContentTemplate" Value="{StaticResource Icon_OK}" /> </DataTrigger> - <DataTrigger Binding="{Binding Valid}" Value="False"> + <DataTrigger Binding="{Binding JobDataValid}" Value="False"> <Setter Property="ContentTemplate" Value="{StaticResource Icon_NOK}" /> </DataTrigger> </Style.Triggers> @@ -52,8 +62,8 @@ <RowDefinition /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> - <ColumnDefinition Width="Auto"/> - <ColumnDefinition Width="*"/> + <ColumnDefinition Width="Auto" /> + <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <StackPanel Orientation="Horizontal" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2"> <Label> @@ -91,9 +101,9 @@ Text="{Binding CanonicalizationMethods, Mode=OneWay , Converter={StaticResource CollectionConverter}}" Margin="10,2" IsReadOnly="True" /> - <Label Grid.Row="2" Grid.Column="0" Content="Digest Value computed:" Style="{StaticResource DigestValueLabelStyle}"/> + <Label Grid.Row="2" Grid.Column="0" Content="Digest Value computed:" Style="{StaticResource DigestValueLabelStyle}" /> <TextBox Grid.Row="2" Grid.Column="1" Text="{Binding DigestValueComputed}" - Margin="10,2" IsReadOnly="True" Style="{StaticResource DigestValueTextboxStyle}"/> + Margin="10,2" IsReadOnly="True" Style="{StaticResource DigestValueTextboxStyle}" /> </Grid> </DataTemplate> @@ -107,8 +117,8 @@ <RowDefinition /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> - <ColumnDefinition Width="Auto"/> - <ColumnDefinition Width="*"/> + <ColumnDefinition Width="Auto" /> + <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <StackPanel Orientation="Horizontal" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2"> <Label> @@ -139,47 +149,49 @@ </Button.Style> </Button> </StackPanel> - - <Label Grid.Row="1" Grid.Column="0" Content="Job Digest Value from file:" Style="{StaticResource DigestValueLabelStyle}"/> - <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding JobDigest, Mode=OneWay}" - Margin="10,2" IsReadOnly="True" Style="{StaticResource DigestValueTextboxStyle}"/> - <Label Grid.Row="2" Grid.Column="0" Content="Canonicalization methods:" /> - <TextBox Grid.Row="2" Grid.Column="1" Text="{Binding CanonicalizationMethods, Mode=OneWay , Converter={StaticResource CollectionConverter}}" - Margin="10,2" IsReadOnly="True" /> + <Label Grid.Row="1" Grid.Column="0" Content="Job Digest Value from file:" + Style="{StaticResource DigestValueLabelStyle}" /> + <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding JobDigest, Mode=OneWay}" + Margin="10,2" IsReadOnly="True" Style="{StaticResource DigestValueTextboxStyle}" /> - <Label Grid.Row="3" Grid.Column="0" Content="Digest Value read:" Style="{StaticResource DigestValueLabelStyle}" /> - <TextBox Grid.Row="3" Grid.Column="1" Text="{Binding DigestValueRead}" Margin="10,2" IsReadOnly="True" > + <Label Grid.Row="2" Grid.Column="0" Content="Canonicalization methods:" /> + <TextBox Grid.Row="2" Grid.Column="1" + Text="{Binding CanonicalizationMethods, Mode=OneWay , Converter={StaticResource CollectionConverter}}" + Margin="10,2" IsReadOnly="True" /> + + <Label Grid.Row="3" Grid.Column="0" Content="Digest Value read:" Style="{StaticResource DigestValueLabelStyle}" /> + <TextBox Grid.Row="3" Grid.Column="1" Text="{Binding DigestValueRead}" Margin="10,2" IsReadOnly="True"> <TextBox.Style> <Style TargetType="TextBox" BasedOn="{StaticResource DigestValueTextboxStyle}"> <Style.Triggers> <DataTrigger Binding="{Binding Valid}" Value="True"> - <Setter Property="Foreground" Value="{StaticResource Color.SuccessGreen}"/> + <Setter Property="Foreground" Value="{StaticResource Color.SuccessGreen}" /> </DataTrigger> <DataTrigger Binding="{Binding Valid}" Value="False"> - <Setter Property="Foreground" Value="{StaticResource Color.ErrorRed}"/> + <Setter Property="Foreground" Value="{StaticResource Color.ErrorRed}" /> </DataTrigger> </Style.Triggers> </Style> </TextBox.Style> </TextBox> - <Label Grid.Row="4" Grid.Column="0" Content="Digest Value computed:" Style="{StaticResource DigestValueLabelStyle}" /> - <TextBox Grid.Row="4" Grid.Column="1" Text="{Binding DigestValueComputed}" Margin="10,2" IsReadOnly="True" > + <Label Grid.Row="4" Grid.Column="0" Content="Digest Value computed:" Style="{StaticResource DigestValueLabelStyle}" /> + <TextBox Grid.Row="4" Grid.Column="1" Text="{Binding DigestValueComputed}" Margin="10,2" IsReadOnly="True"> <TextBox.Style> <Style TargetType="TextBox" BasedOn="{StaticResource DigestValueTextboxStyle}"> <Style.Triggers> <DataTrigger Binding="{Binding Valid}" Value="True"> - <Setter Property="Foreground" Value="{StaticResource Color.SuccessGreen}"/> + <Setter Property="Foreground" Value="{StaticResource Color.SuccessGreen}" /> </DataTrigger> <DataTrigger Binding="{Binding Valid}" Value="False"> - <Setter Property="Foreground" Value="{StaticResource Color.ErrorRed}"/> + <Setter Property="Foreground" Value="{StaticResource Color.ErrorRed}" /> </DataTrigger> </Style.Triggers> </Style> </TextBox.Style> - </TextBox> - + </TextBox> + </Grid> </DataTemplate> @@ -209,12 +221,12 @@ </Style> </ItemsControl.ItemContainerStyle> <ItemsControl.Resources> - <DataTemplate DataType="{x:Type viewModel:VectoXMLFile}"> + <DataTemplate DataType="{x:Type viewModel:VectoJobFile}"> - <Border BorderBrush="White" BorderThickness="1" CornerRadius="2"> + <Border BorderBrush="White" BorderThickness="1" CornerRadius="2" Margin="0,0,3,0"> <Expander Margin="2" Header="{Binding}" HorizontalAlignment="Stretch" Style="{DynamicResource HeaderStretchExpanderStyle}" - HeaderTemplate="{DynamicResource ExpanderHeader}" + HeaderTemplate="{DynamicResource ExpanderHeaderJobFile}" ContentTemplate="{DynamicResource ExpanderContentJobFile}" Content="{Binding}" /> </Border> @@ -240,17 +252,41 @@ <ColumnDefinition Width="*" /> <ColumnDefinition Width="50" /> <ColumnDefinition Width="*" /> + <ColumnDefinition Width="50" /> + <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> - <TextBlock Grid.Row="0" Grid.Column="0" HorizontalAlignment="Center" TextAlignment="Center" Margin="5" + <TextBlock Grid.Row="0" Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Center" + TextAlignment="Center" Margin="5" FontSize="14" FontWeight="Bold"> - Job-File digest <LineBreak /> matches<LineBreak /> Manufacturer Report + Job-File valid </TextBlock> <ContentControl Grid.Row="1" Grid.Column="0" Width="50" Height="50" Margin="10,10,10,0"> + <ContentControl.LayoutTransform> + <ScaleTransform ScaleX="1.5" ScaleY="1.5" /> + </ContentControl.LayoutTransform> + <ContentControl.Style> + <Style TargetType="ContentControl"> + <Setter Property="ContentTemplate" Value="{StaticResource Icon_NOK}" /> + <Style.Triggers> + <DataTrigger Binding="{Binding JobFile.JobDataValid}" Value="True"> + <Setter Property="ContentTemplate" Value="{StaticResource Icon_OK}" /> + </DataTrigger> + </Style.Triggers> + </Style> + </ContentControl.Style> + </ContentControl> + + <TextBlock Grid.Row="0" Grid.Column="2" HorizontalAlignment="Center" VerticalAlignment="Center" + TextAlignment="Center" Margin="5" + FontSize="14" FontWeight="Bold"> + Job-File digest <LineBreak /> matches<LineBreak /> Manufacturer Report + </TextBlock> + <ContentControl Grid.Row="1" Grid.Column="2" Width="50" Height="50" Margin="10,10,10,0"> <ContentControl.LayoutTransform> <ScaleTransform ScaleX="1.5" ScaleY="1.5" /> </ContentControl.LayoutTransform> @@ -265,11 +301,13 @@ </Style> </ContentControl.Style> </ContentControl> - <TextBlock Grid.Row="0" Grid.Column="2" HorizontalAlignment="Center" TextAlignment="Center" Margin="5" + + <TextBlock Grid.Row="0" Grid.Column="4" HorizontalAlignment="Center" VerticalAlignment="Center" + TextAlignment="Center" Margin="5" FontSize="14" FontWeight="Bold"> Job-File digest <LineBreak /> matches<LineBreak /> Customer Report </TextBlock> - <ContentControl Grid.Row="1" Grid.Column="2" Width="50" Height="50" Margin="10,10,10,0"> + <ContentControl Grid.Row="1" Grid.Column="4" Width="50" Height="50" Margin="10,10,10,0"> <ContentControl.LayoutTransform> <ScaleTransform ScaleX="1.5" ScaleY="1.5" /> </ContentControl.LayoutTransform> @@ -285,7 +323,6 @@ </ContentControl.Style> </ContentControl> - </Grid> </Grid> </DockPanel> -- GitLab