internal static LayoutRenderer[] CompileLayout(ConfigurationItemFactory configurationItemFactory, SimpleStringReader sr, bool isNested, out string text) { var result = new List<LayoutRenderer>(); var literalBuf = new StringBuilder(); int ch; var p0 = sr.Position; while ((ch = sr.Peek()) != -1) { if (isNested && (ch == '}' || ch == ':')) { break; } sr.Read(); if (ch == '$' && sr.Peek() == '{') { if (literalBuf.Length > 0) { result.Add(new LiteralLayoutRenderer(literalBuf.ToString())); literalBuf.Length = 0; } var newLayoutRenderer = ParseLayoutRenderer(configurationItemFactory, sr); if (CanBeConvertedToLiteral(newLayoutRenderer)) { newLayoutRenderer = ConvertToLiteral(newLayoutRenderer); } // layout renderer result.Add(newLayoutRenderer); } else { literalBuf.Append((char) ch); } } if (literalBuf.Length > 0) { result.Add(new LiteralLayoutRenderer(literalBuf.ToString())); literalBuf.Length = 0; } var p1 = sr.Position; MergeLiterals(result); text = sr.Substring(p0, p1); return result.ToArray(); }
private static string ParseParameterValue(SimpleStringReader sr) { int ch; var nameBuf = new StringBuilder(); while ((ch = sr.Peek()) != -1) { if (ch == ':' || ch == '}') { break; } if (ch == '\\') { // skip the backslash sr.Read(); // append next character nameBuf.Append((char) sr.Read()); continue; } nameBuf.Append((char) ch); sr.Read(); } return nameBuf.ToString(); }
private static string ParseLayoutRendererName(SimpleStringReader sr) { int ch; var nameBuf = new StringBuilder(); while ((ch = sr.Peek()) != -1) { if (ch == ':' || ch == '}') { break; } nameBuf.Append((char) ch); sr.Read(); } return nameBuf.ToString(); }
private static string ParseParameterName(SimpleStringReader sr) { int ch; var nestLevel = 0; var nameBuf = new StringBuilder(); while ((ch = sr.Peek()) != -1) { if ((ch == '=' || ch == '}' || ch == ':') && nestLevel == 0) { break; } if (ch == '$') { sr.Read(); nameBuf.Append('$'); if (sr.Peek() == '{') { nameBuf.Append('{'); nestLevel++; sr.Read(); } continue; } if (ch == '}') { nestLevel--; } if (ch == '\\') { // skip the backslash sr.Read(); // append next character nameBuf.Append((char) sr.Read()); continue; } nameBuf.Append((char) ch); sr.Read(); } return nameBuf.ToString(); }
private static LayoutRenderer ParseLayoutRenderer(ConfigurationItemFactory configurationItemFactory, SimpleStringReader sr) { var ch = sr.Read(); Debug.Assert(ch == '{', "'{' expected in layout specification"); var name = ParseLayoutRendererName(sr); var lr = configurationItemFactory.LayoutRenderers.CreateInstance(name); var wrappers = new Dictionary<Type, LayoutRenderer>(); var orderedWrappers = new List<LayoutRenderer>(); ch = sr.Read(); while (ch != -1 && ch != '}') { var parameterName = ParseParameterName(sr).Trim(); if (sr.Peek() == '=') { sr.Read(); // skip the '=' PropertyInfo pi; var parameterTarget = lr; if (!PropertyHelper.TryGetPropertyInfo(lr, parameterName, out pi)) { Type wrapperType; if (configurationItemFactory.AmbientProperties.TryGetDefinition(parameterName, out wrapperType)) { LayoutRenderer wrapperRenderer; if (!wrappers.TryGetValue(wrapperType, out wrapperRenderer)) { wrapperRenderer = configurationItemFactory.AmbientProperties.CreateInstance(parameterName); wrappers[wrapperType] = wrapperRenderer; orderedWrappers.Add(wrapperRenderer); } if (!PropertyHelper.TryGetPropertyInfo(wrapperRenderer, parameterName, out pi)) { pi = null; } else { parameterTarget = wrapperRenderer; } } } if (pi == null) { ParseParameterValue(sr); } else { if (typeof (Layout).IsAssignableFrom(pi.PropertyType)) { var nestedLayout = new SimpleLayout(); string txt; var renderers = CompileLayout(configurationItemFactory, sr, true, out txt); nestedLayout.SetRenderers(renderers, txt); pi.SetValue(parameterTarget, nestedLayout, null); } else if (typeof (ConditionExpression).IsAssignableFrom(pi.PropertyType)) { var conditionExpression = ConditionParser.ParseExpression(sr, configurationItemFactory); pi.SetValue(parameterTarget, conditionExpression, null); } else { var value = ParseParameterValue(sr); PropertyHelper.SetPropertyFromString(parameterTarget, parameterName, value, configurationItemFactory); } } } else { // what we've just read is not a parameterName, but a value // assign it to a default property (denoted by empty string) PropertyInfo pi; if (PropertyHelper.TryGetPropertyInfo(lr, string.Empty, out pi)) { if (typeof (SimpleLayout) == pi.PropertyType) { pi.SetValue(lr, new SimpleLayout(parameterName), null); } else { var value = parameterName; PropertyHelper.SetPropertyFromString(lr, pi.Name, value, configurationItemFactory); } } else { InternalLogger.Warn("{0} has no default property", lr.GetType().FullName); } } ch = sr.Read(); } lr = ApplyWrappers(configurationItemFactory, lr, orderedWrappers); return lr; }