/// <summary> /// Функция пытается сопоставить данный шаблон документу doc /// </summary> /// <param name="doc">проверяемый документ</param> /// <param name="amplifyIfMatch">флаг "дополнять" разрешает заполнять недостающие части документа в соответствии с шаблоном</param> /// <returns>истина, если сопоставление успешно</returns> public bool IsMatch(DocumentClass doc, bool amplifyIfMatch = false) { //Создаем объект для хранения результата сопоставления result = new MatchResult(this, doc); if (doc == null) { return(false); } result.Success = IsIdMatch(doc, amplifyIfMatch) && IsAttributesMatch(doc, amplifyIfMatch) && IsFilesMatch(doc, amplifyIfMatch) && IsChildsMatch(doc, amplifyIfMatch); if (result.Success) { result.Text = "Проверка " + doc.Name + " по шаблону (" + this.Name + " - " + this.Id + ") успешна"; //Заполняем Id документа, в случае успеха проверки if (amplifyIfMatch && doc.Id == "") { doc.Id = this.Id; } } else { result.Text = "Документ " + doc.Name + " не прошел проверку по шаблону (" + this.Name + "-" + this.Id + ")\n" + result.Text; } return(result.Success); }
/// <summary> /// Метод загружает документ из папки. Создает дочерние документы рекурсивно в соответствии со структурой папок /// </summary> /// <param name="folderName">Полный путь для загрузки документа - эта папка соответствует создаваемому документу</param> /// <returns>созданный документ типа DocumentClass</returns> /// <exception cref="DirectoryNotFoundException">Выбрасывается в случае невозможности получить доступ к папке folderName</exception> public static DocumentClass LoadFromFolder(string folderName) { if (String.IsNullOrEmpty(folderName)) { throw new DirectoryNotFoundException("Не указана папка для загрузки документа"); } folderName = folderName.TrimEnd('\\'); folderName.Replace(@"\", @"\\"); DirectoryInfo rootFolder = new DirectoryInfo(folderName); if (!rootFolder.Exists) { throw new DirectoryNotFoundException("Не найдена папка " + folderName); } DocumentClass doc = new DocumentClass(rootFolder.Name); //Добавим описания файлов FileInfo[] files = rootFolder.GetFiles(); foreach (FileInfo file in files) { FileClass docFile = new FileClass("", file.FullName); doc.Files.Add(docFile); } //Добавим состав DirectoryInfo[] childFolders = rootFolder.GetDirectories(); foreach (DirectoryInfo childFolder in childFolders) { DocumentClass child = DocumentClass.LoadFromFolder(childFolder.FullName); child.ParentGUID = doc.GUID; doc.Childs.Add(child); } return(doc); }
private bool IsFilesMatch(DocumentClass doc, bool amplifyIfMatch = false) { bool success = true; foreach (FileClass file in doc.Files) { FilePatternClass ptrn = FilesPatterns.FirstOrDefault(f => f.IsMatch(file)); if (ptrn == null) { //В сообщение о несоответствии собираем все непустые сообщения о результатах проверки result.Text += "Несоответствие файла '" + (file.Id == "" ? "" : file.Id + ":") + file.ShortName + "'" + FilesPatterns. Where(p => p.MatchResult != ""). Select(presult => presult.MatchResult). Aggregate(":", (cur, next) => cur == ":" ? cur + next : cur + "; " + next); success = false; } else { result.Text += ptrn.MatchResult; //Дополняем описание файла, если сопоставление успешно if (amplifyIfMatch && file.Id == "") { file.Id = ptrn.Id; } } } return(success); }
public MatchResult(DocumentPatternClass _pattern, DocumentClass _document, string _text = "") { Pattern = _pattern; Document = _document; PatternName = Pattern.Name; DocumentName = Document.Name; Text = _text; Success = false; Childs = new List <MatchResult>(); }
/// <summary> /// Проверка соответствия Id документа и шаблона. Для документа с Id = "", проверка считается успешной /// </summary> /// <param name="doc"></param> /// <returns></returns> private bool IsIdMatch(DocumentClass doc, bool amplifyIfMatch = false) { if (this.Id != "" && doc.Id != "" && this.Id != doc.Id) { //result.Text += "Не совпадают Id: " + this.Id + "!=" + doc.Id; return(false); } //Пока не решено, как проверять, когда извест //if (amplifyIfMatch && doc.Id == "") doc.Id = this.Id; return(true); }
//Загрузить атрибуты в doc из attributes. Существующие атрибуты с таким же Id перезаписываются public static void SetAttributes(DocumentClass doc, IEnumerable <AttributeClass> attributes) { foreach (AttributeClass attr in attributes) { AttributeClass docAttr = doc.Attributes.FirstOrDefault(a => a.Id == attr.Id); if (docAttr == null) { doc.Attributes.Add(new AttributeClass(attr)); } else { docAttr = new AttributeClass(attr); } } }
/// <summary> /// Создается документ в который копируются все атрибуты, файлы и копии дочерних документов doc /// </summary> /// <param name="doc">документ оригинал</param> public DocumentClass(DocumentClass doc) { Id = doc.Id; GUID = doc.GUID; Name = doc.Name; ParentGUID = doc.ParentGUID; Attributes = new List <AttributeClass>(doc.Attributes); Files = new List <FileClass>(doc.Files); Childs = new List <DocumentClass>(); foreach (DocumentClass child in doc.Childs) { DocumentClass thisChild = new DocumentClass(child); thisChild.ParentGUID = this.GUID; Childs.Add(thisChild); } }
private bool IsChildsMatch(DocumentClass doc, bool amplifyIfMatch = false) { bool success = true; foreach (DocumentClass child in doc.Childs) { //Ищем первый шаблон, в списке дочерних шаблонов, которому удовлетворяет child //TODO: Вообще, подходящих шаблонов может быть несколько и, тогда нужны дополнительные данные для определения, какой шаблон правильный DocumentPatternClass ptrn = ChildsPatterns.FirstOrDefault(p => p.IsMatch(child, amplifyIfMatch)); if (ptrn == null) { result.Text += "Дочерний документ не прошел проверку " + child.Name + "\n"; //Запишем результаты неуспешных проверок дочерних шаблонов в результат проверки текущего шаблона result.Childs.AddRange(ChildsPatterns.Select(p => p.Result)); success = false; } else { //Добавим в дерево результат проверки дочернего документа result.Childs.Add(ptrn.Result); } } return(success); }
public void Add(DocumentClass child) { child.ParentGUID = GUID; Childs.Add(child); }
/// <summary> /// Функция возвращает истину, если сопоставление атрибутов документа шаблону успешно. /// Правило сопоставления зависит от значения поля AttributesCompareMode. /// Возможны варианты: /// CompareMode.ExistsInDocument - проверка наличия соответствующего атрибута для каждого шаблона атрибута; /// CompareMode.ExistsInPattern - проверка наличия шаблона атрибута для каждого атрибута документа; /// CompareMode.Equality - проверка полного соответствия атрибутов шаблонам /// </summary> /// <param name="doc">проверяемый документ</param> /// <param name="amplifyIfMatch">указывает необходимость заполнения значений</param> /// <returns></returns> private bool IsAttributesMatch(DocumentClass doc, bool amplifyIfMatch = false) { //Флаг успеха сравнения bool success = true; //Если в шаблоне документа не было заявлено атрибутов, то проверка считается успешной if (AttributesPatterns.Count == 0) { return(true); } //Временная коллекция для сравнения. Содержит существующие и предполагаемые атрибуты документа List <AttributeClass> attributes = new List <AttributeClass>(); //Если строка шаблона не пустая, то пытаемся извлечь атрибуты из имени и добавляем во временную коллецию if (AttributesPatternString != "") { attributes = AttributesFromString(doc.Name, AttributesPatternString); } //Если у документа уже есть атрибуты, то добавляем их во временную коллекцию attributes.AddRange(doc.Attributes); //Проверяем наличие в документе атрибутов, описанных в шаблоне if (AttributesCompareMode == CompareMode.ExistsInDocument) { foreach (AttributePatternClass ptrn in this.AttributesPatterns) { AttributeClass attr = attributes.FirstOrDefault(a => ptrn.IsMatch(a)); if (attr == null) { result.Text += "\nАтрибут не найден: '" + ptrn.Id + "'"; success = false; } else { result.Text += ptrn.MatchResult; } } } //Проверяем наличие в шаблоне атрибутов, описанных в документе else if (AttributesCompareMode == CompareMode.ExistsInPattern) { //Каждый из атрибутов документа проверяем на соответствие какому-либо шаблону foreach (AttributeClass attr in attributes) { //Ищем шаблон атрибута, которому удовлетворяет attr AttributePatternClass ptrn = AttributesPatterns.FirstOrDefault(a => a.IsMatch(attr)); //Если условия не выполнены if (ptrn == null) { result.Text += "\nАтрибут не предусмотрен: '" + attr.Id + "=" + attr.AsString + "' {" + AttributesPatterns. Where(p => p.MatchResult != ""). Aggregate("", (cur, next) => cur == "" ? cur + next : cur + "; " + next) + "}"; success = false; } else { result.Text += ptrn.MatchResult; } } } //Проверяем взаимнооднозначное соответствие атрибутов документа атрибутам шаблона else if (AttributesCompareMode == CompareMode.Equality) { //Временная коллекция шаблонов атрибутов List <AttributePatternClass> patterns = new List <AttributePatternClass>(this.AttributesPatterns); foreach (AttributeClass attr in attributes) { //Ищем шаблон атрибута, которому удовлетворяет attr AttributePatternClass ptrn = patterns.FirstOrDefault(a => a.IsMatch(attr)); //Если такой атрибут в шаблоне отсутствует if (ptrn == null) { result.Text += "\nАтрибут не предусмотрен: '" + attr.Id + "=" + attr.AsString + "' {" + AttributesPatterns. Where(p => p.MatchResult != ""). Aggregate("", (cur, next) => cur == "" ? cur + next : cur + "; " + next) + " }"; success = false; } else { //Если шаблон атрибута найден, то при следующей проверке он не используется patterns.Remove(ptrn); } } //Если все атрибуты документа проверены и для каждого нашелся свой шаблон, то проверка успешна success = success && (patterns.Count == 0); } //Дополняем описание атрибутов, если сопоставление успешно if (amplifyIfMatch && success) { doc.Attributes = attributes; } return(success); }