using System; using System.Collections.Generic; using System.Linq; using System.Windows; using DTS.Common.Base; using DTS.Common.DataModel; using DTS.Common.ISO; namespace DataPROWin7.DataModel { public class TestObjectTemplate : BasePropertyChanged, IComparable { #region enums and constants public enum Tags { ChannelCountText, PossibleChannelCountText, TemplateName, TemplateDescription, TestObject, TestObjectType, TemplateAllUIChannels, TemplateZones, AvailableTestObjectTypes, TestObjectIndex, TestObjectTypeIndex, CurrentZone, CurrentZoneIndex, AreZoneControlsEnabled, TemplateAllChannels, RequiredChannels } private enum GroupTemplateChannelFields { TestObjectNumber, NameOfTheChannel, LaboratoryChannelCode, CustomerChannelCode, Comments1, Location, Dimension, Direction, ChannelFrequencyClass, Unit, ReferenceSystem, TransducerType, TransducerId, PreFilterType, CutOffFrequency, ChannelAmplitudeClass, ReferenceChannel, ReferenceChannelName, DataSource, DataStatus, SamplingInterval, BitResolution, TimeOfFirstSample, NumberOfSamples, OffsetPostTest, TransducerNaturalFrequency, TransducerDampingRatio, Comments, FirstGlobalMaximumValue, TimeOfMaximumValue, FirstGlobalMinimumValue, TimeOfMinimumValue, StartOffsetInterval, EndOffsetInterval, MMEChannelId, MMEChannelType, Required, DisplayOrder, LocalOnly } private enum GroupTemplateFields { TemplateName, Icon, Description, LocalOnly, Version, LastModifiedBy, LastModified, CRC32, TestObjectType, TestObject, ParentTemplate, SysBuilt, OriginalTemplateName, Embedded }; #endregion #region properties private string _lastModifiedBy = "N/A"; public string LastModifiedBy { get => _lastModifiedBy; set => SetProperty(ref _lastModifiedBy, value, "LastModifiedBy"); } private DateTime _lastModified = (DateTime)System.Data.SqlTypes.SqlDateTime.MinValue; public DateTime LastModified { get => _lastModified; set => SetProperty(ref _lastModified, value, "LastModified"); } private DTS.Common.ISO.TestObjectTemplate _template; private List _requiredChannels = new List(); public List RequiredChannels { get => _requiredChannels; set { _requiredChannels = value; OnPropertyChanged("RequiredChannels"); } } private string _templateParent = ""; public string TemplateParent { get => _templateParent; set => SetProperty(ref _templateParent, value, "TemplateParent"); } private bool _sysBuilt; public bool SysBuilt { get => _sysBuilt; set => SetProperty(ref _sysBuilt, value, "SysBuilt"); } private bool _embedded; public bool Embedded { get => _embedded; set { _embedded = value; if (null != _template) { _template.Embedded = value; } } } private string _originalTemplateName = ""; public string OriginalTemplateName { get => _originalTemplateName; set { _originalTemplateName = value; if (null != _template) { _template.OriginalTemplateName = value; } } } private string _name; public string TemplateName { get => _name; set => SetProperty(ref _name, value, Tags.TemplateName.ToString()); } private string _desc; public string TemplateDescription { get => _desc; set => SetProperty(ref _desc, value, Tags.TemplateDescription.ToString()); } private bool _bLocalOnly; public bool IsLocalOnly { get => _bLocalOnly; set => SetProperty(ref _bLocalOnly, value, "IsLocalOnly"); } private MMETestObjects _testObject; public MMETestObjects TestObject { get => _testObject; set { SetProperty(ref _testObject, value, Tags.TestObject.ToString()); if (null == _testObject) return; AvailableTestObjectTypes = ApplicationProperties.IsoDb.GetUniquePossibleChannelTypes(TestObjectTemplateChannel.NONISOCHANNELTYPE); if (AvailableTestObjectTypes.Length > 0) { TestObjectTypeIndex = 0; } else { TestObjectTypeIndex = -1; } } } private string _testObjectType; public string TestObjectType { get => _testObjectType; set { SetProperty(ref _testObjectType, value, Tags.TestObjectType.ToString()); _channels = new List(ApplicationProperties.IsoDb.GetPossibleChannelsForType(_testObjectType)); TemplateAllChannels = _channels.Select(pc => new TestObjectTemplateChannel(new TestObjectTemplateChannel(pc), /*ref db,*/ _template)).ToArray(); AssignOrders(); OnPropertyChanged(Tags.PossibleChannelCountText.ToString()); OnPropertyChanged(Tags.ChannelCountText.ToString()); OnPropertyChanged(Tags.TestObjectTypeIndex.ToString()); } } public void AssignOrders() { var allChannels = TemplateAllChannels.ToList(); if (!allChannels.Any()) { return; } allChannels.Sort(); var maxDisplayOrder = (from ch in allChannels select ch.DisplayOrder).Max(); foreach (var ch in allChannels) { if (-1 == ch.DisplayOrder) { ch.DisplayOrder = ++maxDisplayOrder; } } } private List _channels = new List(); //11287 Out of memory exception when importing large CSV Test Setup files //reduced one collection of channels to refer to channel super class members public TestObjectTemplateChannel[] TemplateAllChannels { get { var channels = (from ch in _allUIChannels select ch.Channel).ToArray(); return channels; } set { TemplateAllUIChannels = value.Select(c => new TemplateChannelUI(c)).ToArray(); } } private List _allUIChannels = new List(); public TemplateChannelUI[] TemplateAllUIChannels { get => _allUIChannels.ToArray(); set => SetProperty(ref _allUIChannels, new List(value), Tags.TemplateAllUIChannels.ToString()); } private List _testObjects = new List(); private List _availableTestObjectTypes = null; public string[] AvailableTestObjectTypes { get { if (null != _availableTestObjectTypes) return _availableTestObjectTypes.ToArray(); if (null == TestObject) { return new string[0]; } _availableTestObjectTypes = new List(ApplicationProperties.IsoDb.GetTestObjectTypeForTestObject(TestObject.Test_Object)); return _availableTestObjectTypes.ToArray(); } set => SetProperty(ref _availableTestObjectTypes, new List(value), Tags.AvailableTestObjectTypes.ToString()); } private int _testObjectTypeIndex = -1; public int TestObjectTypeIndex { get { if (string.IsNullOrEmpty(TestObjectType)) { return -1; } return _availableTestObjectTypes.IndexOf(TestObjectType); } set { TestObjectType = value >= 0 ? _availableTestObjectTypes[value] : null; SetProperty(ref _testObjectTypeIndex, value, Tags.TestObjectTypeIndex.ToString()); TemplateAllChannels = _channels.Select(pc => new TestObjectTemplateChannel(new TestObjectTemplateChannel(pc), /*ref db,*/ _template)).ToArray(); AssignOrders(); } } #endregion #region methods public void MarkChanged(string tag) { OnPropertyChanged(tag); } public int CompareTo(TestObjectTemplate rhs) { if (null == rhs) { return 1; } return this == rhs ? 0 : string.Compare(TemplateName, rhs.TemplateName, StringComparison.Ordinal); } public override string ToString() { return Embedded ? OriginalTemplateName : TemplateName; } public DTS.Common.ISO.TestObjectTemplate ToISOTestObjectTemplate() { var template = new DTS.Common.ISO.TestObjectTemplate(TemplateName, IsLocalOnly) { Description = TemplateDescription, OriginalTemplateName = OriginalTemplateName, Embedded = Embedded, Icon = "", LocalOnly = IsLocalOnly, TestObject = TestObject.Test_Object, TestObjectType = TestObjectType }; template.TemplateParent = TemplateParent; template.Channels = TemplateAllChannels; template.SysBuilt = SysBuilt; return template; } #endregion #region constructors and initialization public TestObjectTemplate(TestObjectTemplate copy, ref ISO13499FileDb db) { if (null != copy._template) { _template = new DTS.Common.ISO.TestObjectTemplate(copy._template, ref db); } TemplateDescription = copy.TemplateDescription; TemplateParent = copy.TemplateParent; TemplateName = copy.TemplateName; LastModified = copy.LastModified; LastModifiedBy = copy.LastModifiedBy; TestObject = copy.TestObject; TestObjectType = copy.TestObjectType; foreach (var c in copy.RequiredChannels) { RequiredChannels.Add(new TestObjectTemplateChannel(c, /*ref db,*/ _template)); } TemplateAllChannels = copy.TemplateAllChannels.Select(c => new TestObjectTemplateChannel(c, /*ref db,*/ _template)).ToArray(); SysBuilt = copy.SysBuilt; Embedded = copy.Embedded; OriginalTemplateName = copy.OriginalTemplateName; } public TestObjectTemplate(DTS.Common.ISO.TestObjectTemplate template, ref ISO13499FileDb db) { Initialize(template, ref db, null); } public TestObjectTemplate(DTS.Common.ISO.TestObjectTemplate template, ref ISO13499FileDb db, List testObjects) { Initialize(template, ref db, testObjects); } private void Initialize(DTS.Common.ISO.TestObjectTemplate template, ref ISO13499FileDb db, List testObjects) { _template = template; TemplateDescription = template.Description; TemplateName = template.TemplateName; LastModified = template.LastModified; LastModifiedBy = template.LastModifiedBy; //if a list of test objects is provided, check if the test object we wish is in the list, if so use it var bFoundTestObject = false; if (null != testObjects) { var matches = from to in testObjects where to.Test_Object == template.TestObject select to; var mmeTestObjectses = matches as MMETestObjects[] ?? matches.ToArray(); if (mmeTestObjectses.Any()) { TestObject = mmeTestObjectses[0]; bFoundTestObject = true; } } if (!bFoundTestObject) { TestObject = ApplicationProperties.IsoDb.GetTestObjectByIso(template.TestObject); } TestObjectType = template.TestObjectType; OriginalTemplateName = template.OriginalTemplateName; Embedded = template.Embedded; TemplateAllChannels = template.Channels.Select(c => new TestObjectTemplateChannel(c, /*ref db,*/ _template)).ToArray(); TemplateParent = template.TemplateParent; SysBuilt = template.SysBuilt; } public TestObjectTemplate() { TemplateName = string.Empty; TemplateDescription = string.Empty; TemplateParent = string.Empty; TestObject = ApplicationProperties.IsoDb.GetTestObjects(false).FirstOrDefault(); } #endregion #region XML Serialization public static DTS.Common.ISO.TestObjectTemplate ReadXML(System.Xml.XmlElement root, Dictionary importChannels) { var template = new DTS.Common.ISO.TestObjectTemplate("", false); foreach (var node in root.ChildNodes) { if (node is System.Xml.XmlElement) { ProcessXMLElement(node as System.Xml.XmlElement, ref template, importChannels); } } return template; } private static void ProcessXMLElement(System.Xml.XmlElement node, ref DTS.Common.ISO.TestObjectTemplate template, Dictionary importChannels) { if (Enum.TryParse(node.Name, out GroupTemplateFields field)) { switch (field) { case GroupTemplateFields.CRC32: template.CRC32 = Convert.ToInt32(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; case GroupTemplateFields.Description: template.Description = node.InnerText; break; case GroupTemplateFields.Icon: template.Icon = node.InnerText; break; case GroupTemplateFields.LastModified: template.LastModified = DateTime.Parse(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; case GroupTemplateFields.LastModifiedBy: template.LastModifiedBy = node.InnerText; break; case GroupTemplateFields.LocalOnly: template.LocalOnly = Convert.ToBoolean(node.InnerText); break; case GroupTemplateFields.ParentTemplate: template.TemplateParent = node.InnerText; break; case GroupTemplateFields.SysBuilt: template.SysBuilt = Convert.ToBoolean(node.InnerText); break; case GroupTemplateFields.TemplateName: template.TemplateName = node.InnerText.Trim(); break; case GroupTemplateFields.TestObject: template.TestObject = node.InnerText; break; case GroupTemplateFields.TestObjectType: template.TestObjectType = node.InnerText; break; case GroupTemplateFields.Version: template.Version = Convert.ToInt32(node.InnerText, System.Globalization.CultureInfo.InvariantCulture); break; case GroupTemplateFields.OriginalTemplateName: template.OriginalTemplateName = node.InnerText; break; case GroupTemplateFields.Embedded: template.Embedded = Convert.ToBoolean(node.InnerText); break; default: throw new NotSupportedException("TestObjectTemplate::ProcessXMLElement unknown field: " + field.ToString()); } } else if (node.Name == "TemplateChannels") { foreach (var child in node.ChildNodes) { ProcessChannelXMLNode(child as System.Xml.XmlElement, ref template, importChannels); } var channels = new List(template.Channels); channels.Sort(); template.Channels = channels.ToArray(); } } private static void ProcessChannelXMLNode(System.Xml.XmlElement root, ref DTS.Common.ISO.TestObjectTemplate template, Dictionary importChannels) { var existingChannels = new List(template.Channels); var values = new Dictionary(); foreach (var child in root.ChildNodes) { var node = child as System.Xml.XmlElement; if (null == node) { continue; } if (Enum.TryParse(node.Name, out GroupTemplateChannelFields field)) { values[field] = node.InnerText; } } if (!values.ContainsKey(GroupTemplateChannelFields.MMEChannelId) || !values.ContainsKey(GroupTemplateChannelFields.MMEChannelType)) { return; } if (!long.TryParse(values[GroupTemplateChannelFields.MMEChannelId], System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out long id)) { return; } if (!int.TryParse(values[GroupTemplateChannelFields.MMEChannelType], System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out int cType)) { return; } MMEPossibleChannels mChannel; if (cType == (int)MMEPossibleChannels.MMEChannelTypes.SQL && importChannels.ContainsKey(id)) { mChannel = importChannels[id]; } else { mChannel = ApplicationProperties.IsoDb.GetPossibleChannel(id, cType); } if (null == mChannel) { return; } var channel = new TestObjectTemplateChannel(mChannel); using (var enumeratorGroupChannelFieldSettings = values.GetEnumerator()) { while (enumeratorGroupChannelFieldSettings.MoveNext()) { switch (enumeratorGroupChannelFieldSettings.Current.Key) { case GroupTemplateChannelFields.BitResolution: break; case GroupTemplateChannelFields.ChannelAmplitudeClass: break; case GroupTemplateChannelFields.ChannelFrequencyClass: break; case GroupTemplateChannelFields.Comments: break; case GroupTemplateChannelFields.Comments1: break; case GroupTemplateChannelFields.CustomerChannelCode: break; case GroupTemplateChannelFields.CutOffFrequency: break; case GroupTemplateChannelFields.DataSource: break; case GroupTemplateChannelFields.DataStatus: break; case GroupTemplateChannelFields.Dimension: break; case GroupTemplateChannelFields.Direction: break; case GroupTemplateChannelFields.DisplayOrder: channel.DisplayOrder = Convert.ToInt32(enumeratorGroupChannelFieldSettings.Current.Value, System.Globalization.CultureInfo.InvariantCulture); break; case GroupTemplateChannelFields.EndOffsetInterval: break; case GroupTemplateChannelFields.FirstGlobalMaximumValue: break; case GroupTemplateChannelFields.FirstGlobalMinimumValue: break; case GroupTemplateChannelFields.LaboratoryChannelCode: break; case GroupTemplateChannelFields.LocalOnly: channel.LocalOnly = Convert.ToBoolean(enumeratorGroupChannelFieldSettings.Current.Value); break; case GroupTemplateChannelFields.Location: break; case GroupTemplateChannelFields.MMEChannelId: break; case GroupTemplateChannelFields.MMEChannelType: break; case GroupTemplateChannelFields.NameOfTheChannel: channel.NameOfTheChannel = enumeratorGroupChannelFieldSettings.Current.Value; break; case GroupTemplateChannelFields.NumberOfSamples: break; case GroupTemplateChannelFields.OffsetPostTest: break; case GroupTemplateChannelFields.PreFilterType: break; case GroupTemplateChannelFields.ReferenceChannel: break; case GroupTemplateChannelFields.ReferenceChannelName: break; case GroupTemplateChannelFields.ReferenceSystem: break; case GroupTemplateChannelFields.Required: channel.Required = Convert.ToBoolean(enumeratorGroupChannelFieldSettings.Current.Value); break; case GroupTemplateChannelFields.SamplingInterval: break; case GroupTemplateChannelFields.StartOffsetInterval: break; case GroupTemplateChannelFields.TestObjectNumber: break; case GroupTemplateChannelFields.TimeOfFirstSample: break; case GroupTemplateChannelFields.TimeOfMaximumValue: break; case GroupTemplateChannelFields.TimeOfMinimumValue: break; case GroupTemplateChannelFields.TransducerDampingRatio: break; case GroupTemplateChannelFields.TransducerId: break; case GroupTemplateChannelFields.TransducerNaturalFrequency: break; case GroupTemplateChannelFields.TransducerType: break; case GroupTemplateChannelFields.Unit: break; default: throw new NotSupportedException( "TestObjectTemplate::ProcessChannelXMLNode unsupported field: " + enumeratorGroupChannelFieldSettings.Current.Key); } } } existingChannels.Add(channel); var maxDisplayOrder = (from ch in existingChannels select ch.DisplayOrder).Max(); foreach (var ch in existingChannels) { if (-1 == ch.DisplayOrder) { ch.DisplayOrder = ++maxDisplayOrder; } } template.Channels = existingChannels.ToArray(); } #endregion } }