private static void ProcessLinesScope(string[] lines, int startIndex, ref int endIndexExclusive, StringBuilder result, List <ContentItem> contentRoots, Stack <StackContextItem> contextStack, List <ErrorItem> errorList) { bool hasEmptyStackToBegin = contextStack.Count == 0; for (int currLineIX = startIndex; currLineIX < endIndexExclusive; currLineIX++) { string line = lines[currLineIX]; try { if (IgnoreBindingsTillEnd(line)) { break; } bool hasStackContext = ProcessLine(lines, ref currLineIX, line, result, contentRoots, contextStack, errorList); // If stack is empty and we had context to begin with, stop here if (hasStackContext == false && hasEmptyStackToBegin == false) { endIndexExclusive = currLineIX + 1; return; } } catch (Exception ex) { StackContextItem item = contextStack.Count > 0 ? contextStack.Peek() : null; ErrorItem errorItem = new ErrorItem(ex, item, line); if (item == null) { errorItem.CurrentContextName = "No active context"; } errorList.Add(errorItem); } } }
private static void ProcessLinesScope(string[] lines, int startIndex, ref int endIndexExclusive, StringBuilder result, List<ContentItem> contentRoots, Stack<StackContextItem> contextStack, List<ErrorItem> errorList) { bool hasEmptyStackToBegin = contextStack.Count == 0; for (int currLineIX = startIndex; currLineIX < endIndexExclusive; currLineIX++) { string line = lines[currLineIX]; try { if (IgnoreBindingsTillEnd(line)) { break; } bool hasStackContext = ProcessLine(lines, ref currLineIX, line, result, contentRoots, contextStack, errorList); // If stack is empty and we had context to begin with, stop here if (hasStackContext == false && hasEmptyStackToBegin == false) { endIndexExclusive = currLineIX + 1; return; } } catch (Exception ex) { StackContextItem item = contextStack.Count > 0 ? contextStack.Peek() : null; ErrorItem errorItem = new ErrorItem(ex, item, line); if (item == null) errorItem.CurrentContextName = "No active context"; errorList.Add(errorItem); } } }
private static bool ProcessLine(string[] lines, ref int currLineIx, string line, StringBuilder result, List<ContentItem> contentRoots, Stack<StackContextItem> contextStack, List<ErrorItem> errorList) { if (line.Contains(TheBallPrefix) == false && line.Contains("[!ATOM]") == false) { result.AppendLine(line); return contextStack.Count > 0; } if (line.Contains(RootTagBegin) || line.Contains(DynamicRootTagBegin)) { result.AppendLine(line); object content; StackContextItem rootItem; Match match = ContextRootRegex.Match(line); string rootType = match.Groups["rootType"].Value; string rootName = match.Groups["rootName"].Value; string bindingType = match.Groups["bindingType"].Value; bool isDynamicRoot = bindingType == "DYNAMIC"; try { //string typeName = line.Substring(RootTagLen, line.Length - RootTagsTotalLen).Trim(); content = GetOrInitiateContentObject(contentRoots, rootType, rootName, isDynamicRoot); StackContextItem parent = contextStack.Count > 0 ? contextStack.Peek() : null; rootItem = new StackContextItem(content, parent, content.GetType(), null, StackContextItemType.Root, rootName); } catch { rootItem = new StackContextItem("Invalid Stack Root Item", null, typeof(string), "INVALID", StackContextItemType.Root, ""); errorList.Add(new ErrorItem(new Exception("Invalid stack root: " + rootType), rootItem, line)); } result.AppendLine(GetSpanTag(rootItem.CurrContent, SpanTagItemBeginFormat)); // NOTE! We support multiple roots now, but root has to be first in stack //if (contextStack.Count != 0) // throw new InvalidDataException("Context stack already has a root item before: " + content.GetType().FullName); contextStack.Push(rootItem); } else if (line.Contains(CollectionTagBegin)) { result.AppendLine(line); requireExistingContext(contextStack, line); Match match = CollectionRegex.Match(line); string memberName = match.Groups["memberName"].Value; string bindingOptions = match.Groups["bindingOptions"].Value; bool isFiltered = true; if(String.IsNullOrEmpty(bindingOptions) == false) { if (bindingOptions == "Unfiltered") isFiltered = false; else throw new NotSupportedException("Collection binding option unsupported: " + bindingOptions); } Stack<StackContextItem> collStack = new Stack<StackContextItem>(); StackContextItem currCtx = contextStack.Peek(); StackContextItem collItem = null; try { Type type = GetMemberType(currCtx, memberName); object contentValue = GetPropertyValue(currCtx, memberName); StackContextItem parent = currCtx; StackContextItemType itemType = isFiltered ? StackContextItemType.CollectionFiltered : StackContextItemType.CollectionUnfiltered; collItem = new StackContextItem(contentValue, parent, type, memberName, itemType); } catch(Exception ex) { StackContextItem item = contextStack.Count > 0 ? contextStack.Peek() : null; ErrorItem errorItem = new ErrorItem(ex, item, line); if (item == null) errorItem.CurrentContextName = "No active context"; errorList.Add(errorItem); if (collItem == null) collItem = new StackContextItem("Invalid Collection Context", contextStack.Peek(), typeof(string), "INVALID", StackContextItemType.CollectionUnfiltered); } collStack.Push(collItem); int scopeStartIx = currLineIx + 1; int scopeEndIx = lines.Length; // Candidate, the lower call will adjust properly // Get scope length result.AppendLine(GetSpanTag(collItem.CollectionContainer, SpanTagCollectionBeginFormat)); ProcessLinesScope(lines, scopeStartIx, ref scopeEndIx, new StringBuilder(), contentRoots, collStack, new List<ErrorItem>()); // Scope goes to end context tag, so it pops the item back from scope - let's push it back // ... or not, commented below for a while //scopeEndIx--; //collStack.Push(collItem); bool isFirstRound = true; while (collItem.IsNotFullyProcessed) { var currErrorList = isFirstRound ? errorList : new List<ErrorItem>(); collStack.Push(collItem); string spanTag = GetSpanTag(collItem.CurrContent, SpanTagCollectionItemBeginFormat); result.AppendLine(spanTag); ProcessLinesScope(lines, scopeStartIx, ref scopeEndIx, result, contentRoots, collStack, currErrorList); //result.AppendLine(SpanTagClosing); if(collStack.Count > 0) throw new InvalidDataException("Collection stack should be empty at this point"); isFirstRound = false; collItem.CurrCollectionItem++; } result.AppendLine(SpanTagClosing); // Jump to the end tag (as the next loop will progress by one) currLineIx = scopeEndIx - 1; } else if (line.Contains(ObjectTagBegin)) { result.AppendLine(line); requireExistingContext(contextStack, line); string memberName = line.Substring(ObjTagLen, line.Length - ObjTagsTotalLen).Trim(); StackContextItem currItem = PushMemberObjectToStack(contextStack, memberName); result.AppendLine(GetSpanTag(currItem.CurrContent, SpanTagItemBeginFormat)); } else if (line.Contains(ContextTagEnd)) { result.AppendLine(SpanTagClosing); result.AppendLine(line); StackContextItem popItem = contextStack.Pop(); if (contextStack.Count == 0) return false; } else if(line.Contains(FormHiddenFieldTag)) { requireExistingContext(contextStack, line); result.AppendLine(line); /* ProcessATOMLine( "<input id=\"RootObjectRelativeLocation\" name=\"RootObjectRelativeLocation\" type=\"hidden\" value=\"[!ATOM]RelativeLocation[ATOM!]\" />", result, contextStack); ProcessATOMLine( "<input id=\"RootObjectType\" name=\"RootObjectType\" type=\"hidden\" value=\"[!ATOM]SemanticDomainName[ATOM!].[!ATOM]Name[ATOM!]\" />", result, contextStack); ProcessATOMLine( "<input id=\"RootSourceName\" name=\"RootSourceName\" type=\"hidden\" value=[!ATOM]ETag[ATOM!] />", result, contextStack);*/ StackContextItem currContext = contextStack.Peek().GetContextRoot(); result.AppendLine( String.Format( "<input id=\"RootSourceName\" name=\"RootSourceName\" type=\"hidden\" value=\"{0}\" />", currContext.RootName)); } else // ATOM line { ProcessATOMLine(line, result, contextStack); } return contextStack.Count > 0; }
private static bool ProcessLine(string[] lines, ref int currLineIx, string line, StringBuilder result, List <ContentItem> contentRoots, Stack <StackContextItem> contextStack, List <ErrorItem> errorList) { if (line.Contains(TheBallPrefix) == false && line.Contains("[!ATOM]") == false) { result.AppendLine(line); return(contextStack.Count > 0); } if (line.Contains(RootTagBegin) || line.Contains(DynamicRootTagBegin)) { result.AppendLine(line); object content; StackContextItem rootItem; Match match = ContextRootRegex.Match(line); string rootType = match.Groups["rootType"].Value; string rootName = match.Groups["rootName"].Value; string bindingType = match.Groups["bindingType"].Value; bool isDynamicRoot = bindingType == "DYNAMIC"; try { //string typeName = line.Substring(RootTagLen, line.Length - RootTagsTotalLen).Trim(); content = GetOrInitiateContentObject(contentRoots, rootType, rootName, isDynamicRoot); StackContextItem parent = contextStack.Count > 0 ? contextStack.Peek() : null; rootItem = new StackContextItem(content, parent, content.GetType(), null, StackContextItemType.Root, rootName); } catch { rootItem = new StackContextItem("Invalid Stack Root Item", null, typeof(string), "INVALID", StackContextItemType.Root, ""); errorList.Add(new ErrorItem(new Exception("Invalid stack root: " + rootType), rootItem, line)); } result.AppendLine(GetSpanTag(rootItem.CurrContent, SpanTagItemBeginFormat)); // NOTE! We support multiple roots now, but root has to be first in stack //if (contextStack.Count != 0) // throw new InvalidDataException("Context stack already has a root item before: " + content.GetType().FullName); contextStack.Push(rootItem); } else if (line.Contains(CollectionTagBegin)) { result.AppendLine(line); requireExistingContext(contextStack, line); Match match = CollectionRegex.Match(line); string memberName = match.Groups["memberName"].Value; string bindingOptions = match.Groups["bindingOptions"].Value; bool isFiltered = true; if (String.IsNullOrEmpty(bindingOptions) == false) { if (bindingOptions == "Unfiltered") { isFiltered = false; } else { throw new NotSupportedException("Collection binding option unsupported: " + bindingOptions); } } Stack <StackContextItem> collStack = new Stack <StackContextItem>(); StackContextItem currCtx = contextStack.Peek(); StackContextItem collItem = null; try { Type type = GetMemberType(currCtx, memberName); object contentValue = GetPropertyValue(currCtx, memberName); StackContextItem parent = currCtx; StackContextItemType itemType = isFiltered ? StackContextItemType.CollectionFiltered : StackContextItemType.CollectionUnfiltered; collItem = new StackContextItem(contentValue, parent, type, memberName, itemType); } catch (Exception ex) { StackContextItem item = contextStack.Count > 0 ? contextStack.Peek() : null; ErrorItem errorItem = new ErrorItem(ex, item, line); if (item == null) { errorItem.CurrentContextName = "No active context"; } errorList.Add(errorItem); if (collItem == null) { collItem = new StackContextItem("Invalid Collection Context", contextStack.Peek(), typeof(string), "INVALID", StackContextItemType.CollectionUnfiltered); } } collStack.Push(collItem); int scopeStartIx = currLineIx + 1; int scopeEndIx = lines.Length; // Candidate, the lower call will adjust properly // Get scope length result.AppendLine(GetSpanTag(collItem.CollectionContainer, SpanTagCollectionBeginFormat)); ProcessLinesScope(lines, scopeStartIx, ref scopeEndIx, new StringBuilder(), contentRoots, collStack, new List <ErrorItem>()); // Scope goes to end context tag, so it pops the item back from scope - let's push it back // ... or not, commented below for a while //scopeEndIx--; //collStack.Push(collItem); bool isFirstRound = true; while (collItem.IsNotFullyProcessed) { var currErrorList = isFirstRound ? errorList : new List <ErrorItem>(); collStack.Push(collItem); string spanTag = GetSpanTag(collItem.CurrContent, SpanTagCollectionItemBeginFormat); result.AppendLine(spanTag); ProcessLinesScope(lines, scopeStartIx, ref scopeEndIx, result, contentRoots, collStack, currErrorList); //result.AppendLine(SpanTagClosing); if (collStack.Count > 0) { throw new InvalidDataException("Collection stack should be empty at this point"); } isFirstRound = false; collItem.CurrCollectionItem++; } result.AppendLine(SpanTagClosing); // Jump to the end tag (as the next loop will progress by one) currLineIx = scopeEndIx - 1; } else if (line.Contains(ObjectTagBegin)) { result.AppendLine(line); requireExistingContext(contextStack, line); string memberName = line.Substring(ObjTagLen, line.Length - ObjTagsTotalLen).Trim(); StackContextItem currItem = PushMemberObjectToStack(contextStack, memberName); result.AppendLine(GetSpanTag(currItem.CurrContent, SpanTagItemBeginFormat)); } else if (line.Contains(ContextTagEnd)) { result.AppendLine(SpanTagClosing); result.AppendLine(line); StackContextItem popItem = contextStack.Pop(); if (contextStack.Count == 0) { return(false); } } else if (line.Contains(FormHiddenFieldTag)) { requireExistingContext(contextStack, line); result.AppendLine(line); /* * ProcessATOMLine( * "<input id=\"RootObjectRelativeLocation\" name=\"RootObjectRelativeLocation\" type=\"hidden\" value=\"[!ATOM]RelativeLocation[ATOM!]\" />", * result, contextStack); * ProcessATOMLine( * "<input id=\"RootObjectType\" name=\"RootObjectType\" type=\"hidden\" value=\"[!ATOM]SemanticDomainName[ATOM!].[!ATOM]Name[ATOM!]\" />", * result, contextStack); * ProcessATOMLine( * "<input id=\"RootSourceName\" name=\"RootSourceName\" type=\"hidden\" value=[!ATOM]ETag[ATOM!] />", * result, contextStack);*/ StackContextItem currContext = contextStack.Peek().GetContextRoot(); result.AppendLine( String.Format( "<input id=\"RootSourceName\" name=\"RootSourceName\" type=\"hidden\" value=\"{0}\" />", currContext.RootName)); } else // ATOM line { ProcessATOMLine(line, result, contextStack); } return(contextStack.Count > 0); }