private Dictionary <string, CompLibSpec> specsByType; // спецификации библиотек, ключ - имя типа компонента /// <summary> /// Статический конструктор /// </summary> static CompManager() { StandardCompTypes = new Dictionary <string, Type>() { { typeof(StaticText).FullName, typeof(StaticText) }, { typeof(DynamicText).FullName, typeof(DynamicText) }, { typeof(StaticPicture).FullName, typeof(StaticPicture) }, { typeof(DynamicPicture).FullName, typeof(DynamicPicture) } }; instance = new CompManager(); }
/// <summary> /// Загрузить представление из потока /// </summary> public override void LoadFromStream(Stream stream) { // очистка представления Clear(); // загрузка XML-документа XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(stream); // проверка формата файла (потока) XmlElement rootElem = xmlDoc.DocumentElement; if (!rootElem.Name.Equals("SchemeView", StringComparison.OrdinalIgnoreCase)) { throw new ScadaException(SchemePhrases.IncorrectFileFormat); } // загрузка документа схемы XmlNode documentNode = rootElem.SelectSingleNode("Document") ?? rootElem.SelectSingleNode("Scheme"); if (documentNode != null) { SchemeDoc.LoadFromXml(documentNode); // загрузка заголовка схемы для старого формата if (SchemeDoc.Title == "") { SchemeDoc.Title = rootElem.GetAttribute("title"); } // установка заголовка представления Title = SchemeDoc.Title; // загрузка фильтра по входным каналам для старого формата XmlNode cnlsFilterNode = rootElem.SelectSingleNode("CnlsFilter"); if (cnlsFilterNode != null) { SchemeDoc.CnlFilter.ParseCnlFilter(cnlsFilterNode.InnerText); } // добавление входных каналов представления foreach (int cnlNum in SchemeDoc.CnlFilter) { AddCnlNum(cnlNum); } } // загрузка компонентов схемы XmlNode componentsNode = rootElem.SelectSingleNode("Components") ?? rootElem.SelectSingleNode("Elements"); if (componentsNode != null) { HashSet <string> errNodeNames = new HashSet <string>(); // имена узлов незагруженных компонентов CompManager compManager = CompManager.GetInstance(); LoadErrors.AddRange(compManager.LoadErrors); foreach (XmlNode compNode in componentsNode.ChildNodes) { // создание компонента string errMsg; BaseComponent component = compManager.CreateComponent(compNode, out errMsg); if (component == null) { component = new UnknownComponent() { XmlNode = compNode }; if (errNodeNames.Add(compNode.Name)) { LoadErrors.Add(errMsg); } } // загрузка компонента и добавление его в представление component.SchemeDoc = SchemeDoc; component.LoadFromXml(compNode); Components[component.ID] = component; // добавление входных каналов представления if (component is IDynamicComponent) { IDynamicComponent dynamicComponent = (IDynamicComponent)component; AddCnlNum(dynamicComponent.InCnlNum); AddCtrlCnlNum(dynamicComponent.CtrlCnlNum); } // определение макс. идентификатора компонентов if (component.ID > maxComponentID) { maxComponentID = component.ID; } } } // загрузка изображений схемы XmlNode imagesNode = rootElem.SelectSingleNode("Images"); if (imagesNode != null) { Dictionary <string, Image> images = SchemeDoc.Images; XmlNodeList imageNodes = imagesNode.SelectNodes("Image"); foreach (XmlNode imageNode in imageNodes) { Image image = new Image(); image.LoadFromXml(imageNode); if (!string.IsNullOrEmpty(image.Name)) { images[image.Name] = image; } } } }
/// <summary> /// Загрузить представление из потока. /// </summary> public override void LoadFromStream(Stream stream) { // clear the view Clear(); // load component bindings if (string.IsNullOrEmpty(templateArgs.BindingFileName)) { templateBindings = null; } else { templateBindings = new TemplateBindings(); templateBindings.Load(System.IO.Path.Combine( SchemeContext.GetInstance().AppDirs.ConfigDir, templateArgs.BindingFileName)); } // load XML document XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(stream); // check data format XmlElement rootElem = xmlDoc.DocumentElement; if (!rootElem.Name.Equals("SchemeView", StringComparison.OrdinalIgnoreCase)) { throw new ScadaException(SchemePhrases.IncorrectFileFormat); } // get channel offsets in template mode int inCnlOffset = templateArgs.InCnlOffset; int ctrlCnlOffset = templateArgs.CtrlCnlOffset; // load scheme document if (rootElem.SelectSingleNode("Scheme") is XmlNode schemeNode) { SchemeDoc.LoadFromXml(schemeNode); // установка заголовка представления Title = SchemeDoc.Title; // добавление входных каналов представления foreach (int cnlNum in SchemeDoc.CnlFilter) { if (cnlNum > 0) { AddCnlNum(cnlNum + inCnlOffset); } } } // load scheme components if (rootElem.SelectSingleNode("Components") is XmlNode componentsNode) { HashSet <string> errNodeNames = new HashSet <string>(); // имена узлов незагруженных компонентов CompManager compManager = CompManager.GetInstance(); LoadErrors.AddRange(compManager.LoadErrors); SortedDictionary <int, ComponentBinding> componentBindings = templateBindings?.ComponentBindings; foreach (XmlNode compNode in componentsNode.ChildNodes) { // создание компонента BaseComponent component = compManager.CreateComponent(compNode, out string errMsg); if (component == null) { component = new UnknownComponent { XmlNode = compNode }; if (errNodeNames.Add(compNode.Name)) { LoadErrors.Add(errMsg); } } // загрузка компонента и добавление его в представление component.SchemeView = this; component.LoadFromXml(compNode); Components[component.ID] = component; // добавление входных каналов представления if (component is IDynamicComponent dynamicComponent) { if (componentBindings != null && componentBindings.TryGetValue(component.ID, out ComponentBinding binding)) { dynamicComponent.InCnlNum = binding.InCnlNum; dynamicComponent.CtrlCnlNum = binding.CtrlCnlNum; } else { if (inCnlOffset > 0 && dynamicComponent.InCnlNum > 0) { dynamicComponent.InCnlNum += inCnlOffset; } if (ctrlCnlOffset > 0 && dynamicComponent.CtrlCnlNum > 0) { dynamicComponent.CtrlCnlNum += ctrlCnlOffset; } } AddCnlNum(dynamicComponent.InCnlNum); AddCtrlCnlNum(dynamicComponent.CtrlCnlNum); } // определение макс. идентификатора компонентов if (component.ID > maxComponentID) { maxComponentID = component.ID; } } } // load scheme images if (rootElem.SelectSingleNode("Images") is XmlNode imagesNode) { Dictionary <string, Image> images = SchemeDoc.Images; XmlNodeList imageNodes = imagesNode.SelectNodes("Image"); foreach (XmlNode imageNode in imageNodes) { Image image = new Image(); image.LoadFromXml(imageNode); if (!string.IsNullOrEmpty(image.Name)) { images[image.Name] = image; } } } }
/// <summary> /// Сохранить схему в файле /// </summary> public bool SaveToFile(string fileName, out string errMsg) { try { XmlDocument xmlDoc = new XmlDocument(); XmlDeclaration xmlDecl = xmlDoc.CreateXmlDeclaration("1.0", "utf-8", null); xmlDoc.AppendChild(xmlDecl); // запись заголовка представления XmlElement rootElem = xmlDoc.CreateElement("SchemeView"); rootElem.SetAttribute("title", SchemeDoc.Title); xmlDoc.AppendChild(rootElem); // пока используется старый формат файла // запись документа схемы XmlElement documentElem = xmlDoc.CreateElement("Scheme"); rootElem.AppendChild(documentElem); SchemeDoc.SaveToXml(documentElem); // запись компонентов схемы CompManager compManager = CompManager.GetInstance(); HashSet <string> prefixes = new HashSet <string>(); XmlElement componentsElem = xmlDoc.CreateElement("Components"); rootElem.AppendChild(componentsElem); foreach (BaseComponent component in Components.Values) { if (component is UnknownComponent) { componentsElem.AppendChild(((UnknownComponent)component).XmlNode); } else { Type compType = component.GetType(); CompLibSpec compLibSpec = compManager.GetSpecByType(compType); // добавление пространства имён if (compLibSpec != null && !prefixes.Contains(compLibSpec.XmlPrefix)) { rootElem.SetAttribute("xmlns:" + compLibSpec.XmlPrefix, compLibSpec.XmlNs); prefixes.Add(compLibSpec.XmlPrefix); } // создание XML-элемента компонента XmlElement componentElem = compLibSpec == null? xmlDoc.CreateElement(compType.Name) /*стандартный компонент*/ : xmlDoc.CreateElement(compLibSpec.XmlPrefix, compType.Name, compLibSpec.XmlNs); componentsElem.AppendChild(componentElem); component.SaveToXml(componentElem); } } // запись изображений схемы XmlElement imagesElem = xmlDoc.CreateElement("Images"); rootElem.AppendChild(imagesElem); foreach (Image image in SchemeDoc.Images.Values) { XmlElement imageElem = xmlDoc.CreateElement("Image"); imagesElem.AppendChild(imageElem); image.SaveToXml(imageElem); } // запись фильтра по входным каналам XmlElement cnlsFilterElem = xmlDoc.CreateElement("CnlsFilter"); cnlsFilterElem.InnerText = SchemeDoc.CnlFilter.CnlFilterToString(); rootElem.AppendChild(cnlsFilterElem); xmlDoc.Save(fileName); errMsg = ""; return(true); } catch (Exception ex) { errMsg = SchemePhrases.SaveSchemeViewError + ": " + ex.Message; return(false); } }
/// <summary> /// Загрузить представление из потока. /// </summary> public override void LoadFromStream(Stream stream) { // очистка представления Clear(); SchemeDoc.SchemeView = this; // загрузка XML-документа XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(stream); // проверка формата файла (потока) XmlElement rootElem = xmlDoc.DocumentElement; if (!rootElem.Name.Equals("SchemeView", StringComparison.OrdinalIgnoreCase)) { throw new ScadaException(SchemePhrases.IncorrectFileFormat); } // получение смещений каналов при работе схемы в режиме шаблона int inCnlOffset = templateArgs.InCnlOffset; int ctrlCnlOffset = templateArgs.CtrlCnlOffset; // загрузка документа схемы if (rootElem.SelectSingleNode("Scheme") is XmlNode schemeNode) { SchemeDoc.LoadFromXml(schemeNode); // установка заголовка представления Title = SchemeDoc.Title; // добавление входных каналов представления foreach (int cnlNum in SchemeDoc.CnlFilter) { if (cnlNum > 0) { AddCnlNum(cnlNum + inCnlOffset); } } } // загрузка компонентов схемы if (rootElem.SelectSingleNode("Components") is XmlNode componentsNode) { HashSet <string> errNodeNames = new HashSet <string>(); // имена узлов незагруженных компонентов CompManager compManager = CompManager.GetInstance(); LoadErrors.AddRange(compManager.LoadErrors); foreach (XmlNode compNode in componentsNode.ChildNodes) { // создание компонента BaseComponent component = compManager.CreateComponent(compNode, out string errMsg); if (component == null) { component = new UnknownComponent { XmlNode = compNode }; if (errNodeNames.Add(compNode.Name)) { LoadErrors.Add(errMsg); } } // загрузка компонента и добавление его в представление component.SchemeView = this; component.LoadFromXml(compNode); Components[component.ID] = component; // добавление входных каналов представления if (component is IDynamicComponent dynamicComponent) { if (inCnlOffset > 0 && dynamicComponent.InCnlNum > 0) { dynamicComponent.InCnlNum += inCnlOffset; } if (ctrlCnlOffset > 0 && dynamicComponent.CtrlCnlNum > 0) { dynamicComponent.CtrlCnlNum += ctrlCnlOffset; } AddCnlNum(dynamicComponent.InCnlNum); AddCtrlCnlNum(dynamicComponent.CtrlCnlNum); } // определение макс. идентификатора компонентов if (component.ID > maxComponentID) { maxComponentID = component.ID; } } } // загрузка изображений схемы XmlNode imagesNode = rootElem.SelectSingleNode("Images"); if (imagesNode != null) { Dictionary <string, Image> images = SchemeDoc.Images; XmlNodeList imageNodes = imagesNode.SelectNodes("Image"); foreach (XmlNode imageNode in imageNodes) { Image image = new Image(); image.LoadFromXml(imageNode); if (!string.IsNullOrEmpty(image.Name)) { images[image.Name] = image; } } } }