public StackContextItem(object content, StackContextItem parent, Type itemType, string memberName, StackContextItemType contextitemType, string rootName = null) { bool isRoot = contextitemType == StackContextItemType.Root; bool isCollection = contextitemType == StackContextItemType.CollectionFiltered || contextitemType == StackContextItemType.CollectionUnfiltered; _content = content; Parent = parent; //TypeName = typeName; ItemType = itemType; MemberName = memberName; IsRoot = isRoot; IsCollection = isCollection; if(isCollection && content.GetType() != typeof(string)) { bool isFilteredCollection = contextitemType == StackContextItemType.CollectionFiltered; dynamic dyn = content; if (isFilteredCollection) { CurrArray = dyn.GetIDSelectedArray(); } else { dynamic collContent = dyn.CollectionContent; CurrArray = collContent.ToArray(); } ItemType = CurrArray.GetType().GetElementType(); } if (isCollection) CollectionContainer = content; RootName = rootName; }
public StackContextItem(object content, StackContextItem parent, Type itemType, string memberName, StackContextItemType contextitemType, string rootName = null) { bool isRoot = contextitemType == StackContextItemType.Root; bool isCollection = contextitemType == StackContextItemType.CollectionFiltered || contextitemType == StackContextItemType.CollectionUnfiltered; _content = content; Parent = parent; //TypeName = typeName; ItemType = itemType; MemberName = memberName; IsRoot = isRoot; IsCollection = isCollection; if (isCollection && content.GetType() != typeof(string)) { bool isFilteredCollection = contextitemType == StackContextItemType.CollectionFiltered; dynamic dyn = content; if (isFilteredCollection) { CurrArray = dyn.GetIDSelectedArray(); } else { dynamic collContent = dyn.CollectionContent; CurrArray = collContent.ToArray(); } ItemType = CurrArray.GetType().GetElementType(); } if (isCollection) { CollectionContainer = content; } RootName = rootName; }
private static void ProcessATOMLine(string line, StringBuilder result, Stack <StackContextItem> contextStack) { requireExistingContext(contextStack, line); StackContextItem currCtx = contextStack.Peek(); var contentLine = Regex.Replace(line, MemberAtomPattern, match => { string memberName = match.Groups["membername"].Value; var workCtx = currCtx; if (memberName.Contains(".")) { string[] referenceList = memberName.Split('.'); Stack <StackContextItem> workStack = new Stack <StackContextItem>(referenceList.Length); workStack.Push(currCtx); int currIx; for (currIx = 0; currIx < referenceList.Length - 1; currIx++) { PushMemberObjectToStack(workStack, referenceList[currIx]); } workCtx = workStack.Peek(); memberName = referenceList[currIx]; } object value = GetPropertyValue(workCtx, memberName); return((value ?? ("")).ToString()); }); result.AppendLine(contentLine); }
private static StackContextItem PushMemberObjectToStack(Stack <StackContextItem> contextStack, string memberName) { StackContextItem currCtx = contextStack.Peek(); if (memberName == "*") { // Put top item again to stack contextStack.Push(currCtx); } else { StackContextItem objItem = null; try { Type type = GetMemberType(currCtx, memberName); object contentValue = GetPropertyValue(currCtx, memberName); StackContextItem parent = currCtx; objItem = new StackContextItem(contentValue, parent, type, memberName, StackContextItemType.Object); } finally { if (objItem == null) { objItem = new StackContextItem("Invalid Context", contextStack.Peek(), typeof(string), "INVALID", StackContextItemType.Object); } contextStack.Push(objItem); } } return(contextStack.Peek()); }
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 Type GetMemberType(StackContextItem containingItem, string memberName) { Type containingType = containingItem.ItemType; PropertyInfo pi = containingType.GetProperty(memberName); if (pi == null) { throw new InvalidDataException("InformationObject: " + containingType.Name + " does not contain InformationItem with name: " + memberName); } return(pi.PropertyType); }
private static object GetPropertyValue(StackContextItem currCtx, string propertyName) { if (currCtx.CurrContent == null) { throw new InvalidDataException("Object: " + currCtx.MemberName + " does not have content (was retrieving value: " + propertyName + ")"); } //Type type = currCtx.ItemType; Type type = currCtx.CurrContent.GetType(); PropertyInfo pi = type.GetProperty(propertyName); if (pi == null) { throw new InvalidDataException(String.Format("No InformationItem '{0}' found in InformationObject '{1}'", propertyName, type.Name)); } return(pi.GetValue(currCtx.CurrContent, null)); }
private static StackContextItem PushMemberObjectToStack(Stack<StackContextItem> contextStack, string memberName) { StackContextItem currCtx = contextStack.Peek(); if (memberName == "*") { // Put top item again to stack contextStack.Push(currCtx); } else { StackContextItem objItem = null; try { Type type = GetMemberType(currCtx, memberName); object contentValue = GetPropertyValue(currCtx, memberName); StackContextItem parent = currCtx; objItem = new StackContextItem(contentValue, parent, type, memberName, StackContextItemType.Object); } finally { if(objItem == null) objItem = new StackContextItem("Invalid Context", contextStack.Peek(), typeof(string), "INVALID", StackContextItemType.Object); contextStack.Push(objItem); } } return contextStack.Peek(); }
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 object GetPropertyValue(StackContextItem currCtx, string propertyName) { if(currCtx.CurrContent == null) throw new InvalidDataException("Object: " + currCtx.MemberName + " does not have content (was retrieving value: " + propertyName + ")"); //Type type = currCtx.ItemType; Type type = currCtx.CurrContent.GetType(); PropertyInfo pi = type.GetProperty(propertyName); if(pi == null) throw new InvalidDataException(String.Format("No InformationItem '{0}' found in InformationObject '{1}'", propertyName, type.Name)); return pi.GetValue(currCtx.CurrContent, null); }
private static Type GetMemberType(StackContextItem containingItem, string memberName) { Type containingType = containingItem.ItemType; PropertyInfo pi = containingType.GetProperty(memberName); if(pi == null) throw new InvalidDataException("InformationObject: " + containingType.Name + " does not contain InformationItem with name: " + memberName); return pi.PropertyType; }
public ErrorItem(Exception errorException, StackContextItem currentStackItem, string currentLine) { ErrorException = errorException; CurrentStackItem = currentStackItem; CurrentLine = currentLine; }
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); }