/// <summary> /// Second pass parse and validation. /// </summary> /// <param name="options">Configuration options.</param> /// <param name="doc">Document being parsed.</param> /// <param name="sqltypes">List of sql types defined.</param> /// <param name="types">List of .Net types defined.</param> /// <param name="entities">List of EntityElement objects defined.</param> /// <param name="vd">Validation delegate for error reporting.</param> /// <returns>Validated list of report extractions.</returns> public static ArrayList ParseFromXml(Configuration options, XmlDocument doc, Hashtable sqltypes, Hashtable types, IList entities, ParserValidationDelegate vd) { ArrayList reportExtractions = new ArrayList(); XmlNodeList elements = doc.DocumentElement.GetElementsByTagName("reportextraction"); foreach (XmlNode node in elements) { if (node.NodeType == XmlNodeType.Comment) { continue; } ReportExtractionElement reportExtraction = new ReportExtractionElement(); if (node.Attributes[NAME] != null) { reportExtraction.Name = node.Attributes[NAME].Value; } else { vd(ParserValidationArgs.NewError("A report extraction must have a name.")); } if (node.Attributes[HINTS] != null) { reportExtraction.Hints = (string)(node.Attributes[HINTS].Value); } if (node.Attributes[HAVING] != null) { reportExtraction.Having = (string)(node.Attributes[HAVING].Value); } reportExtraction.EntityReferences = EntityReferenceElement.ParseFromXml(options, GetChildNodeByName(node, ENTITY_REFERENCES), reportExtraction, types, sqltypes, entities, vd); XmlNode computedProperties = GetChildNodeByName(node, COMPUTED_PROPERTIES); if (computedProperties != null) { reportExtraction.ComputedProperties = PropertyElement.ParseFromXml(computedProperties, entities, reportExtraction, sqltypes, types, false, vd); } reportExtraction.ValidateFilters(vd); reportExtraction.ValidateExpressions(vd); reportExtraction.ValidateUniqueNames(vd); reportExtraction.ValidateDatabases(vd); reportExtractions.Add(reportExtraction); reportExtraction.Having = Configuration.PrepareExpression(reportExtraction.Having, reportExtraction, "having attribute in report extraction " + reportExtraction.Name, vd); // Make sure finders get prepared expressions! reportExtraction.Comparers = ComparerElement.ParseFromXml(node, entities, reportExtraction, sqltypes, types, vd); reportExtraction.Finders = ReportExtractionFinderElement.ParseFromXml(node, entities, reportExtraction, sqltypes, types, vd); } return(reportExtractions); }
/// <summary> /// Parse only method. Parses and adds all entities found in the given node and adds them to the given /// list. /// </summary> /// <param name="node">Node containing the enty reference elements.</param> /// <param name="EntityReferenceElements">returned list of entity reference elements parsed.</param> public static void ParseFromXml(XmlNode node, IList entityReferenceElements) { if (node != null && entityReferenceElements != null) { foreach (XmlNode refNode in node.ChildNodes) { if (refNode.NodeType.Equals(XmlNodeType.Element)) { EntityReferenceElement entityReferenceElement = new EntityReferenceElement(); entityReferenceElement.Name = GetAttributeValue(refNode, NAME, entityReferenceElement.Name); entityReferenceElement.Entity.Name = GetAttributeValue(refNode, ENTITY, entityReferenceElement.Entity.Name); entityReferenceElement.AliasPrefix = GetAttributeValue(refNode, ALIAS_PREFIX, entityReferenceElement.AliasPrefix); entityReferenceElement.Hints = GetAttributeValue(refNode, HINTS, entityReferenceElement.Hints); entityReferenceElement.Filter = GetAttributeValue(refNode, FILTER, entityReferenceElement.Filter); entityReferenceElement.JoinModifier = GetAttributeValue(refNode, JOIN_MODIFIER, entityReferenceElement.JoinModifier); PropertyElement.ParseFromXml(GetChildNodeByName(refNode, PROPERTY_REFERENCES), entityReferenceElement.PropertyReferences); entityReferenceElements.Add(entityReferenceElement); } } } }
/// <summary> /// Parse only method. Parses and adds all entities found in the given node and adds them to the given /// list. /// </summary> /// <param name="node">Node to look in for the report extractions.</param> /// <param name="ReportExtractionElements">List of report extractions created (returned)</param> public static void ParseFromXml(XmlNode node, IList ReportExtractionElements) { if (node != null && ReportExtractionElements != null) { foreach (XmlNode entityNode in node.ChildNodes) { if (entityNode.NodeType.Equals(XmlNodeType.Element)) { ReportExtractionElement reportExtractionElement = new ReportExtractionElement(); reportExtractionElement.Name = GetAttributeValue(entityNode, NAME, reportExtractionElement.Name); reportExtractionElement.Hints = GetAttributeValue(entityNode, HINTS, reportExtractionElement.Name); reportExtractionElement.Having = GetAttributeValue(entityNode, HAVING, reportExtractionElement.Name); EntityReferenceElement.ParseFromXml(GetChildNodeByName(entityNode, ENTITY_REFERENCES), reportExtractionElement.entityReferences); PropertyElement.ParseFromXml(GetChildNodeByName(entityNode, COMPUTED_PROPERTIES), reportExtractionElement.ComputedProperties); ComparerElement.ParseFromXml(GetChildNodeByName(entityNode, COMPARERS), reportExtractionElement.Comparers); ReportExtractionFinderElement.ParseFromXml(GetChildNodeByName(entityNode, FINDERS), reportExtractionElement.Finders); ReportExtractionElements.Add(reportExtractionElement); } } } }
/// <summary> /// Second pass parsing and validation. /// </summary> /// <param name="options">Configuration options</param> /// <param name="reportExtractionNode">Node contaiing the entity references.</param> /// <param name="reportExtraction">ReportExtraction element to contain the parsed entity references.</param> /// <param name="types">List of .Net types defined.</param> /// <param name="entities">List of entities defined.</param> /// <param name="vd">Validation delegate for error reporting.</param> /// <returns>List of entity references parsed.</returns> public static ArrayList ParseFromXml(Configuration options, XmlNode reportExtractionNode, ReportExtractionElement reportExtraction, Hashtable types, Hashtable sqltypes, IList entities, ParserValidationDelegate vd) { ArrayList entityReferences = new ArrayList(); foreach (XmlNode node in reportExtractionNode.ChildNodes) { if (node.NodeType == XmlNodeType.Comment) { continue; } EntityReferenceElement entityReference = new EntityReferenceElement(reportExtraction); if (entityReference.Name != null) { entityReference.Name = node.Attributes[NAME].Value; } else { vd(ParserValidationArgs.NewError("Entity reference specified in report extraction " + reportExtraction.Name + " with no name.")); } if (node.Attributes[ENTITY] != null) { EntityElement ee = EntityElement.FindEntityByName(entities, node.Attributes[ENTITY].Value); if (ee != null) { entityReference.Entity = ee; if (entityReference.Entity.SqlEntity.Name == String.Empty) { vd(ParserValidationArgs.NewError("Entity Reference " + entityReference.Name + " refers to entity " + node.Attributes[ENTITY].Value + " which does not have an associated SQL entity.")); } } else { vd(ParserValidationArgs.NewError("Entity Reference " + entityReference.Name + " refers to entity " + node.Attributes[ENTITY].Value + " which does not exist.")); } } else { vd(ParserValidationArgs.NewError("Entity Reference " + node.Attributes[NAME].Value + " has no entity attribute.")); } if (node.Attributes[ALIAS_PREFIX] != null) { entityReference.aliasPrefix = node.Attributes[ALIAS_PREFIX].Value; } if (node.Attributes[HINTS] != null) { entityReference.Hints = node.Attributes[HINTS].Value; } if (node.Attributes[FILTER] != null) { entityReference.Filter = node.Attributes[FILTER].Value; } if (node.Attributes[JOIN_MODIFIER] != null) { entityReference.JoinModifier = node.Attributes[JOIN_MODIFIER].Value; if (entityReference.JoinModifier.ToUpper() != JOIN_LEFT && entityReference.JoinModifier.ToUpper() != JOIN_RIGHT && entityReference.JoinModifier.ToUpper() != JOIN_FULL) { vd(ParserValidationArgs.NewError("Entity Reference " + node.Attributes[NAME].Value + " has join modifier other than left, right or full.")); } } entityReference.ReportExtraction = reportExtraction; // Note we pass entityReference.Entity because the fields refer to fields in the entity. entityReference.propertyReferences = PropertyElement.ParseFromXml(GetChildNodeByName(node, PROPERTY_REFERENCES), entities, entityReference.Entity, sqltypes, types, true, vd); entityReference.ProcessAsteriskName(vd); entityReference.AdjustSqlAlias(); entityReferences.Add(entityReference); } return(entityReferences); }
/* * /// <summary> * /// Replaces embedded property references in the string with sql cocde. * /// </summary> * /// <param name="withEmbedded">Expression to be replaced.</param> * /// <param name="idString">Id to use when reporting errors.</param> * /// <param name="vd">Validation delegate for error reporting.</param> * /// <returns>String with embedded references replaced.</returns> * private string PrepareExpression(string withEmbedded, string idString, ParserValidationDelegate vd) * { * string checkExpression = withEmbedded; * string retVal = String.Empty; * int leftBrace = 0; * int startPos = 0; * for(leftBrace=checkExpression.IndexOf("{", startPos); startPos >=0; leftBrace=checkExpression.IndexOf("{", startPos)) * { * if (leftBrace == -1) * { * // No more strings to replace. * retVal += checkExpression.Substring(startPos, checkExpression.Length - startPos); * break; * } * else * { * // Concatenate portion of string without embedded references. * retVal += checkExpression.Substring(startPos, leftBrace - startPos); * } * int rightBrace = checkExpression.IndexOf("}", leftBrace); * if (rightBrace == -1) * { * if (vd != null) * { * vd(ParserValidationArgs.NewError("The " + idString + " has a left brace({} with no corresonding right brace(}}")); * } * return ""; * } * * // Isolate the property reference. * string expression = checkExpression.Substring(leftBrace+1, rightBrace - leftBrace - 1); * * // Create list of property references seen to check for circular references. * ArrayList repeList = new ArrayList(); * * string[] parts = expression.Split('.'); * string leftPart = ""; * string rightPart = ""; * if (parts.Length == 1) * { * // Default the left part to this report extraction if not specified. * leftPart = this.Name; * rightPart = parts[0]; * } * else if (parts.Length == 2) * { * leftPart = parts[0]; * rightPart = parts[1]; * } * else * { * if (vd != null) * { * vd(ParserValidationArgs.NewError("The expression " + expression + " in the " + idString + " does not contain exactly one dot(.).")); * } * return ""; * } * * * if (leftPart.ToLower() == this.Name.ToLower()) * { * // Refers to a property in this report extraction. * ReportExtractionPropertyElement repe = this.FindComputedFieldByName(rightPart); * if (repe != null) * { * // Refers to a computed property. Check for circular references. * foreach(ReportExtractionPropertyElement repel in repeList) * { * if(repel.Name == repe.Name) * { * if (vd != null) * { * vd(ParserValidationArgs.NewError("The expression " + expression + " in the " + idString + " has a circular reference.")); * } * return ""; * } * } * * // Add in the expansion of this property.e * retVal += "(" + repe.GetSqlExpression() + ")"; * } * else * { * EntityReferencePropertyElement pre = this.FindReferenceFieldByName(rightPart); * if (pre != null) * { * // Refers to a property reference. Get the expression. * retVal += pre.GetSqlExpression(); * } * else * { * if (vd != null) * { * vd(ParserValidationArgs.NewError("The expression " + expression + " in the " + idString + " refers to a property in the report extraction that does not exist.")); * } * return ""; * } * } * } * else * { * EntityReferenceElement er = FindEntityReferenceByName(leftPart); * if (er == null) * { * if (vd != null) * { * vd(ParserValidationArgs.NewError("The expression " + expression + " in the " + idString + " refers to an entity that is not an entity reference in the extraction nor the extraction itself.")); * } * return ""; * } * else * { * // Refers to an entity reference. * EntityReferencePropertyElement pre = er.FindFieldBySqlAlias(rightPart); * if (pre != null) * { * // Refers to a property reference in the entity. * retVal += pre.GetSqlExpression(); * } * else * { * PropertyElement p = er.Entity.FindFieldByName(rightPart); * if (p != null) * { * // Refers to a property in the entity referenced that is not in the property referenced. * retVal += "[" + er.Name + "].[" + p.Column.Name + "]"; * } * else * { * if (vd != null) * { * vd(ParserValidationArgs.NewError("The expression " + expression + " in the " + idString + " refers to a property that is not in the referenced entity reference nor it's associated entity.")); * } * else * { * return ""; * } * } * } * } * } * * startPos = rightBrace + 1; * } * * return retVal; * }*/ public string GetExpressionSubstitution(string substitutionExpression, string idString, ParserValidationDelegate vd) { // Create list of property references seen to check for circular references. ArrayList repeList = new ArrayList(); string[] parts = substitutionExpression.Split('.'); string leftPart = ""; string rightPart = ""; if (parts.Length == 1) { // Default the left part to this report extraction if not specified. leftPart = this.Name; rightPart = parts[0]; } else if (parts.Length == 2) { leftPart = parts[0]; rightPart = parts[1]; } else { if (vd != null) { vd(ParserValidationArgs.NewError("The expression " + substitutionExpression + " in the " + idString + " does not contain exactly one dot(.).")); } return(""); } if (leftPart.ToLower() == this.Name.ToLower()) { // Refers to a property in this report extraction. PropertyElement repe = this.FindComputedFieldByName(rightPart); if (repe != null) { // Refers to a computed property. Check for circular references. foreach (PropertyElement repel in repeList) { if (repel.Name == repe.Name) { if (vd != null) { vd(ParserValidationArgs.NewError("The expression " + substitutionExpression + " in the " + idString + " has a circular reference.")); } return(""); } } // Add in the expansion of this property.e return("(" + repe.GetSqlExpression() + ")"); } else { PropertyElement pre = this.FindReferenceFieldByName(rightPart); if (pre != null) { // Refers to a property reference. Get the expression. return(pre.GetSqlExpression()); } else { if (vd != null) { vd(ParserValidationArgs.NewError("The expression " + substitutionExpression + " in the " + idString + " refers to a property in the report extraction that does not exist.")); } return(""); } } } else { EntityReferenceElement er = FindEntityReferenceByName(leftPart); if (er == null) { if (vd != null) { vd(ParserValidationArgs.NewError("The expression " + substitutionExpression + " in the " + idString + " refers to an entity that is not an entity reference in the extraction nor the extraction itself.")); } return(""); } else { // Refers to an entity reference. PropertyElement pre = er.FindFieldBySqlAlias(rightPart); if (pre != null) { // Refers to a property reference in the entity. return(pre.GetSqlExpression()); } else { PropertyElement p = er.Entity.FindFieldByName(rightPart); if (p != null) { // Refers to a property in the entity referenced that is not in the property referenced. return("[" + er.Name + "].[" + p.Column.Name + "]"); } else { if (vd != null) { vd(ParserValidationArgs.NewError("The expression " + substitutionExpression + " in the " + idString + " refers to a property that is not in the referenced entity reference nor it's associated entity.")); } return(""); } } } } }