private static EntityDefinition CreateEntityDefinition( XElement element, EntityDefinition baseEntity = null, ExtendedKeyedCollection <string, PropertyDefinition> properties = null, ExtendedKeyedCollection <string, Variable> variables = null) { string name = element.GetAttributeValueOrThrow(AttributeNames.Name); if (baseEntity != null && properties != null) { foreach (PropertyDefinition property in properties) { if (baseEntity.FindProperty(property.Name) != null) { ThrowInvalidOperation(ErrorMessages.PropertyAlreadyDefined(property.Name, name), element); } } } return(new EntityDefinition(name, baseEntity ?? EntityDefinition.Global, properties, variables)); }
public void ReadAll() { _documentElement = Document.FirstElement(); if (_documentElement == null || !DefaultComparer.NameEquals(_documentElement, ElementNames.Document)) { ThrowInvalidOperation(ErrorMessages.MissingElement(ElementNames.Document)); } string versionText = _documentElement.AttributeValueOrDefault(AttributeNames.Version); if (versionText != null) { if (!Version.TryParse(versionText, out Version version)) { ThrowInvalidOperation(ErrorMessages.InvalidDocumentVersion()); } else if (version > Pihrtsoft.Records.Document.SchemaVersion) { ThrowInvalidOperation(ErrorMessages.DocumentVersionIsNotSupported(version, Pihrtsoft.Records.Document.SchemaVersion)); } } foreach (XElement element in _documentElement.Elements()) { switch (element.Kind()) { case ElementKind.Entities: { if (_entitiesElement != null) { ThrowOnMultipleElementsWithEqualName(element); } _entitiesElement = element; break; } default: { ThrowOnUnknownElement(element); break; } } } if (_entitiesElement == null) { return; } _entities.Enqueue(new EntitiesInfo(_entitiesElement)); while (_entities.Count > 0) { EntitiesInfo entities = _entities.Dequeue(); foreach (XElement element in entities.Element.Elements()) { if (element.Kind() != ElementKind.Entity) { ThrowOnUnknownElement(element); } _entityElement = element; ScanEntity(); ExtendedKeyedCollection <string, PropertyDefinition> properties = null; ExtendedKeyedCollection <string, Variable> variables = null; if (_declarationsElement != null) { ScanDeclarations(out properties, out variables); } _entityDefinition = CreateEntityDefinition(_entityElement, baseEntity: entities.BaseEntity, properties, variables); if (_recordsElement != null) { if (_withElement != null) { _withRecords?.Clear(); _state = State.WithRecords; ReadRecords(_withElement); } _state = State.Records; ReadRecords(_recordsElement); _state = State.None; } if (_childEntitiesElement != null) { _entities.Enqueue(new EntitiesInfo(_childEntitiesElement, _entityDefinition)); } _entityDefinition = null; _entityElement = null; _declarationsElement = null; _withElement = null; _recordsElement = null; _childEntitiesElement = null; } } }
private void ScanDeclarations(out ExtendedKeyedCollection <string, PropertyDefinition> properties, out ExtendedKeyedCollection <string, Variable> variables) { properties = null; variables = null; foreach (XElement element in _declarationsElement.Elements()) { switch (element.Kind()) { case ElementKind.Variable: { variables ??= new ExtendedKeyedCollection <string, Variable>(DefaultComparer.StringComparer); string variableName = element.GetAttributeValueOrThrow(AttributeNames.Name); if (variables.Contains(variableName)) { Throw(ErrorMessages.ItemAlreadyDefined(ElementNames.Variable, variableName), element); } var variable = new Variable( variableName, element.GetAttributeValueOrThrow(AttributeNames.Value)); variables.Add(variable); break; } case ElementKind.Property: { properties ??= new ExtendedKeyedCollection <string, PropertyDefinition>(); string name = null; bool isCollection = false; bool isRequired = false; string defaultValue = null; string description = null; char[] separators = PropertyDefinition.Tags.SeparatorsArray; foreach (XAttribute attribute in element.Attributes()) { switch (attribute.LocalName()) { case AttributeNames.Name: { name = attribute.Value; break; } case AttributeNames.IsCollection: { isCollection = bool.Parse(attribute.Value); break; } case AttributeNames.IsRequired: { isRequired = bool.Parse(attribute.Value); break; } case AttributeNames.DefaultValue: { defaultValue = attribute.Value; break; } case AttributeNames.Description: { description = attribute.Value; break; } case AttributeNames.Separators: { separators = ParseHelpers.ParseSeparators(attribute.Value); break; } default: { Throw(ErrorMessages.UnknownAttribute(attribute), element); break; } } } if (properties.Contains(name)) { Throw(ErrorMessages.ItemAlreadyDefined(ElementNames.Property, name), element); } if (isCollection && defaultValue != null) { Throw(ErrorMessages.CollectionPropertyCannotDefineDefaultValue(), element); } if (PropertyDefinition.IsReservedName(name)) { ThrowInvalidOperation(ErrorMessages.PropertyNameIsReserved(name), element); } var property = new PropertyDefinition( name, isCollection, isRequired, defaultValue, description, separators); properties.Add(property); break; } default: { ThrowOnUnknownElement(element); break; } } } }