private void Load(Stream stream, Dictionary<string, Delegate> additionalCustomFormulas = null) { var templateEngineSettings = FluentJdfLibrary.Settings.TemplateEngineSettings; TemplateItem parent = null; var formulaTemplateItemFactory = new FormulaTemplateItemFactory(additionalCustomFormulas); items = new TemplateItemCollection(); StreamReader reader = null; try { reader = new StreamReader(stream); } catch (Exception err) { string mess = string.Format(Messages.CouldNotOpen, name); logger.Error(mess, err); throw new TemplateApiException(mess, err); } StringBuilder staticText = new StringBuilder(100); int lineNumber = 1; int positionInLine = -1; try { States currentState = States.Text; StringBuilder varName = new StringBuilder(50); StringBuilder defaultValue = new StringBuilder(50); StringBuilder tableName = new StringBuilder(50); StringBuilder tableTag = new StringBuilder(50); char c = ' '; while (ReadNext(reader, staticText, ref lineNumber, ref positionInLine, ref c)) { switch (currentState) { case States.Text: switch (c) { case '[': if (ReadNext(reader, staticText, ref lineNumber, ref positionInLine, ref c)) { if (c == ':') { currentState = States.Var; if (staticText.Length > 0) { StaticTemplateItem item = new StaticTemplateItem(parent, "static", lineNumber, positionInLine, staticText.ToString()); if (parent == null) { items.Add(item); } } staticText.Remove(0, staticText.Length); varName.Remove(0, varName.Length); defaultValue.Remove(0, defaultValue.Length); tableName.Remove(0, tableName.Length); tableTag.Remove(0, tableName.Length); } else if (c == '%') { currentState = States.TableTag; if (staticText.Length > 0) { StaticTemplateItem item = new StaticTemplateItem(parent, "static", lineNumber, positionInLine, staticText.ToString()); if (parent == null) { items.Add(item); } } staticText.Remove(0, staticText.Length); varName.Remove(0, varName.Length); defaultValue.Remove(0, defaultValue.Length); tableName.Remove(0, tableName.Length); tableTag.Remove(0, tableTag.Length); } else { staticText.Append("["); } } break; case '<': if (ReadNext(reader, staticText, ref lineNumber, ref positionInLine, ref c)) { if (c == '!') { if (ReadNext(reader, staticText, ref lineNumber, ref positionInLine, ref c)) { if (c == '-') { if (ReadNext(reader, staticText, ref lineNumber, ref positionInLine, ref c)) { if (c == '-') { currentState = States.Comment; } else { staticText.Append("<!-"); } } else { staticText.Append("<!-"); } } else { staticText.Append("<!"); } } else { staticText.Append("<!"); } } else { staticText.Append("<"); } } else { staticText.Append("<"); } break; } if (currentState == States.Text) { staticText.Append(c); } break; case States.Comment: if (c == '-') { if (ReadNext(reader, staticText, ref lineNumber, ref positionInLine, ref c)) { if (c == '-') { if (ReadNext(reader, staticText, ref lineNumber, ref positionInLine, ref c)) { if (c == '>') { currentState = States.Text; } } else { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "Unexpected EOF. An XML comment must end with '-->'."); } } } else { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "Unexpected EOF. An XML comment must end with '-->'."); } } break; case States.TableTag: //if the character is non-blank or one non-blank was encountered in this tag if (c == '%') { if (ReadNext(reader, staticText, ref lineNumber, ref positionInLine, ref c)) { if (c != ']') { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "']' expected"); } } else { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "Unexpected EOF"); } if (tableTag.ToString() == "end table") { if (parent == null) { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "[%end table%] without corresponding [%table(<tablename>)%]"); } //tables can be nested, this "pops" the stack of parents parent = parent.Parent; currentState = States.Text; break; } else if (tableTag.ToString() == "table") { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "table requires table name parameter"); } else { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "unknown [% tag " + tableTag.ToString()); } } else if (c == '(') { if (tableTag.ToString() == "table") { currentState = States.TableName; break; } else { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "'(' not expected"); } } tableTag.Append(c); break; case States.TableName: if (c == ')') { if (ReadNext(reader, staticText, ref lineNumber, ref positionInLine, ref c)) { if (c != '%') { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "'%' expected"); } else { if (ReadNext(reader, staticText, ref lineNumber, ref positionInLine, ref c)) { if (c != ']') { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "']' expected"); } } else { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "Unexpected EOF"); } if (tableName.Length > 0) { string tName = tableName.ToString(); TemplateItem newParent = new TableTemplateItem(parent, tName, lineNumber, positionInLine, tName); if (parent == null) { items.Add(newParent); } parent = newParent; currentState = States.Text; } else { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "[%table(<table name>%} must have table name specified."); } } } else { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "Unexpected EOF"); } } tableName.Append(c); break; case States.Var: switch (c) { case ':': if (varName.Length == 0) { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "Variable name is zero length"); } if (ReadNext(reader, staticText, ref lineNumber, ref positionInLine, ref c)) { if (c != ']') { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "']' expected"); } } else { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "Unexpected EOF"); } VariableTemplateItem item = new VariableTemplateItem(parent, varName.ToString(), lineNumber, positionInLine, null); if (parent == null) { items.Add(item); } currentState = States.Text; break; case '=': if (varName.Length == 0) { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "Variable name is zero length"); } currentState = States.Val; break; default: varName.Append(c); break; } break; case States.Val: switch (c) { case ':': if (defaultValue.Length == 0) { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "Default value is zero length"); } if (ReadNext(reader, staticText, ref lineNumber, ref positionInLine, ref c)) { if (c != ']') { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "']' expected"); } } else { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "Unexpected EOF"); } string def = defaultValue.ToString().Trim(); if (def.IndexOf("(") > -1 && def.EndsWith(")")) { FormulaTemplateItem item = formulaTemplateItemFactory.CreateFormulaItem(parent, varName.ToString(), lineNumber, positionInLine, def, templateEngineSettings); if (parent == null) { items.Add(item); } } else { VariableTemplateItem item = new VariableTemplateItem(parent, varName.ToString(), lineNumber, positionInLine, def); if (parent == null) { items.Add(item); } } currentState = States.Text; break; default: defaultValue.Append(c); break; } break; } } } finally { reader.Close(); if (staticText.Length > 0) { TemplateItem item = new StaticTemplateItem(parent, "static", lineNumber, positionInLine, staticText.ToString()); if (parent == null) { items.Add(item); } } if (parent != null) { LogAndThrowTemplateApiException("One or more [%table tags is not closed with an [%end table"); } } }
private void Load(Stream stream, Dictionary <string, Delegate> additionalCustomFormulas = null) { var templateEngineSettings = FluentJdfLibrary.Settings.TemplateEngineSettings; TemplateItem parent = null; var formulaTemplateItemFactory = new FormulaTemplateItemFactory(additionalCustomFormulas); items = new TemplateItemCollection(); StreamReader reader = null; try { reader = new StreamReader(stream); } catch (Exception err) { string mess = string.Format(Messages.CouldNotOpen, name); logger.Error(mess, err); throw new TemplateApiException(mess, err); } StringBuilder staticText = new StringBuilder(100); int lineNumber = 1; int positionInLine = -1; try { States currentState = States.Text; StringBuilder varName = new StringBuilder(50); StringBuilder defaultValue = new StringBuilder(50); StringBuilder tableName = new StringBuilder(50); StringBuilder tableTag = new StringBuilder(50); char c = ' '; while (ReadNext(reader, staticText, ref lineNumber, ref positionInLine, ref c)) { switch (currentState) { case States.Text: switch (c) { case '[': if (ReadNext(reader, staticText, ref lineNumber, ref positionInLine, ref c)) { if (c == ':') { currentState = States.Var; if (staticText.Length > 0) { StaticTemplateItem item = new StaticTemplateItem(parent, "static", lineNumber, positionInLine, staticText.ToString()); if (parent == null) { items.Add(item); } } staticText.Remove(0, staticText.Length); varName.Remove(0, varName.Length); defaultValue.Remove(0, defaultValue.Length); tableName.Remove(0, tableName.Length); tableTag.Remove(0, tableName.Length); } else if (c == '%') { currentState = States.TableTag; if (staticText.Length > 0) { StaticTemplateItem item = new StaticTemplateItem(parent, "static", lineNumber, positionInLine, staticText.ToString()); if (parent == null) { items.Add(item); } } staticText.Remove(0, staticText.Length); varName.Remove(0, varName.Length); defaultValue.Remove(0, defaultValue.Length); tableName.Remove(0, tableName.Length); tableTag.Remove(0, tableTag.Length); } else { staticText.Append("["); } } break; case '<': if (ReadNext(reader, staticText, ref lineNumber, ref positionInLine, ref c)) { if (c == '!') { if (ReadNext(reader, staticText, ref lineNumber, ref positionInLine, ref c)) { if (c == '-') { if (ReadNext(reader, staticText, ref lineNumber, ref positionInLine, ref c)) { if (c == '-') { currentState = States.Comment; } else { staticText.Append("<!-"); } } else { staticText.Append("<!-"); } } else { staticText.Append("<!"); } } else { staticText.Append("<!"); } } else { staticText.Append("<"); } } else { staticText.Append("<"); } break; } if (currentState == States.Text) { staticText.Append(c); } break; case States.Comment: if (c == '-') { if (ReadNext(reader, staticText, ref lineNumber, ref positionInLine, ref c)) { if (c == '-') { if (ReadNext(reader, staticText, ref lineNumber, ref positionInLine, ref c)) { if (c == '>') { currentState = States.Text; } } else { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "Unexpected EOF. An XML comment must end with '-->'."); } } } else { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "Unexpected EOF. An XML comment must end with '-->'."); } } break; case States.TableTag: //if the character is non-blank or one non-blank was encountered in this tag if (c == '%') { if (ReadNext(reader, staticText, ref lineNumber, ref positionInLine, ref c)) { if (c != ']') { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "']' expected"); } } else { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "Unexpected EOF"); } if (tableTag.ToString() == "end table") { if (parent == null) { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "[%end table%] without corresponding [%table(<tablename>)%]"); } //tables can be nested, this "pops" the stack of parents parent = parent.Parent; currentState = States.Text; break; } else if (tableTag.ToString() == "table") { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "table requires table name parameter"); } else { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "unknown [% tag " + tableTag.ToString()); } } else if (c == '(') { if (tableTag.ToString() == "table") { currentState = States.TableName; break; } else { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "'(' not expected"); } } tableTag.Append(c); break; case States.TableName: if (c == ')') { if (ReadNext(reader, staticText, ref lineNumber, ref positionInLine, ref c)) { if (c != '%') { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "'%' expected"); } else { if (ReadNext(reader, staticText, ref lineNumber, ref positionInLine, ref c)) { if (c != ']') { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "']' expected"); } } else { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "Unexpected EOF"); } if (tableName.Length > 0) { string tName = tableName.ToString(); TemplateItem newParent = new TableTemplateItem(parent, tName, lineNumber, positionInLine, tName); if (parent == null) { items.Add(newParent); } parent = newParent; currentState = States.Text; } else { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "[%table(<table name>%} must have table name specified."); } } } else { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "Unexpected EOF"); } } tableName.Append(c); break; case States.Var: switch (c) { case ':': if (varName.Length == 0) { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "Variable name is zero length"); } if (ReadNext(reader, staticText, ref lineNumber, ref positionInLine, ref c)) { if (c != ']') { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "']' expected"); } } else { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "Unexpected EOF"); } VariableTemplateItem item = new VariableTemplateItem(parent, varName.ToString(), lineNumber, positionInLine, null); if (parent == null) { items.Add(item); } currentState = States.Text; break; case '=': if (varName.Length == 0) { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "Variable name is zero length"); } currentState = States.Val; break; default: varName.Append(c); break; } break; case States.Val: switch (c) { case ':': if (defaultValue.Length == 0) { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "Default value is zero length"); } if (ReadNext(reader, staticText, ref lineNumber, ref positionInLine, ref c)) { if (c != ']') { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "']' expected"); } } else { LogAndThrowTemplateExpansionException(lineNumber, positionInLine, "Unexpected EOF"); } string def = defaultValue.ToString().Trim(); if (def.IndexOf("(") > -1 && def.EndsWith(")")) { FormulaTemplateItem item = formulaTemplateItemFactory.CreateFormulaItem(parent, varName.ToString(), lineNumber, positionInLine, def, templateEngineSettings); if (parent == null) { items.Add(item); } } else { VariableTemplateItem item = new VariableTemplateItem(parent, varName.ToString(), lineNumber, positionInLine, def); if (parent == null) { items.Add(item); } } currentState = States.Text; break; default: defaultValue.Append(c); break; } break; } } } finally { reader.Close(); if (staticText.Length > 0) { TemplateItem item = new StaticTemplateItem(parent, "static", lineNumber, positionInLine, staticText.ToString()); if (parent == null) { items.Add(item); } } if (parent != null) { LogAndThrowTemplateApiException("One or more [%table tags is not closed with an [%end table"); } } }