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(); }
/// <summary> /// Parses the specified condition string and turns it into /// <see cref="ConditionExpression" /> tree. /// </summary> /// <param name="expressionText">The expression to be parsed.</param> /// <param name="configurationItemFactories"> /// Instance of <see cref="ConfigurationItemFactory" /> used to resolve references to condition methods and layout renderers. /// </param> /// <returns>The root of the expression syntax tree which can be used to get the value of the condition in a specified context.</returns> public static ConditionExpression ParseExpression(string expressionText, ConfigurationItemFactory configurationItemFactories) { if (expressionText == null) { return null; } var parser = new ConditionParser(new SimpleStringReader(expressionText), configurationItemFactories); var expression = parser.ParseExpression(); if (!parser.tokenizer.IsEOF()) { throw new ConditionParseException("Unexpected token: " + parser.tokenizer.TokenValue); } return expression; }
private static LayoutRenderer ApplyWrappers(ConfigurationItemFactory configurationItemFactory, LayoutRenderer lr, List<LayoutRenderer> orderedWrappers) { for (var i = orderedWrappers.Count - 1; i >= 0; --i) { var newRenderer = (WrapperLayoutRendererBase) orderedWrappers[i]; InternalLogger.Trace("Wrapping {0} with {1}", lr.GetType().Name, newRenderer.GetType().Name); if (CanBeConvertedToLiteral(lr)) { lr = ConvertToLiteral(lr); } newRenderer.Inner = new SimpleLayout(new[] {lr}, string.Empty, configurationItemFactory); lr = newRenderer; } return lr; }
/// <summary> /// Parses the specified condition string and turns it into /// <see cref="ConditionExpression" /> tree. /// </summary> /// <param name="stringReader">The string reader.</param> /// <param name="configurationItemFactories"> /// Instance of <see cref="ConfigurationItemFactory" /> used to resolve references to condition methods and layout renderers. /// </param> /// <returns> /// The root of the expression syntax tree which can be used to get the value of the condition in a specified context. /// </returns> internal static ConditionExpression ParseExpression(SimpleStringReader stringReader, ConfigurationItemFactory configurationItemFactories) { var parser = new ConditionParser(stringReader, configurationItemFactories); var expression = parser.ParseExpression(); return expression; }
/// <summary> /// Initializes a new instance of the <see cref="ConditionParser" /> class. /// </summary> /// <param name="stringReader">The string reader.</param> /// <param name="configurationItemFactory"> /// Instance of <see cref="ConfigurationItemFactory" /> used to resolve references to condition methods and layout renderers. /// </param> private ConditionParser(SimpleStringReader stringReader, ConfigurationItemFactory configurationItemFactory) { this.configurationItemFactory = configurationItemFactory; tokenizer = new ConditionTokenizer(stringReader); }
internal Factory(ConfigurationItemFactory parentFactory) { this.parentFactory = parentFactory; }
internal SimpleLayout(LayoutRenderer[] renderers, string text, ConfigurationItemFactory configurationItemFactory) { this.configurationItemFactory = configurationItemFactory; SetRenderers(renderers, text); }
/// <summary> /// Initializes a new instance of the <see cref="SimpleLayout" /> class. /// </summary> /// <param name="txt">The layout string to parse.</param> /// <param name="configurationItemFactory">The NLog factories to use when creating references to layout renderers.</param> public SimpleLayout(string txt, ConfigurationItemFactory configurationItemFactory) { this.configurationItemFactory = configurationItemFactory; Text = txt; }
/// <summary> /// Builds the default configuration item factory. /// </summary> /// <returns>Default factory.</returns> private static ConfigurationItemFactory BuildDefaultFactory() { var factory = new ConfigurationItemFactory(typeof (Logger).Assembly); factory.RegisterExtendedItems(); return factory; }
internal static void SetPropertyFromString(object o, string name, string value, ConfigurationItemFactory configurationItemFactory) { InternalLogger.Debug("Setting '{0}.{1}' to '{2}'", o.GetType().Name, name, value); PropertyInfo propInfo; if (!TryGetPropertyInfo(o, name, out propInfo)) { throw new NotSupportedException("Parameter " + name + " not supported on " + o.GetType().Name); } try { if (propInfo.IsDefined(typeof (ArrayParameterAttribute), false)) { throw new NotSupportedException("Parameter " + name + " of " + o.GetType().Name + " is an array and cannot be assigned a scalar value."); } object newValue; var propertyType = propInfo.PropertyType; propertyType = Nullable.GetUnderlyingType(propertyType) ?? propertyType; if (!TryNLogSpecificConversion(propertyType, value, out newValue, configurationItemFactory)) { if (!TryGetEnumValue(propertyType, value, out newValue)) { if (!TryImplicitConversion(propertyType, value, out newValue)) { if (!TrySpecialConversion(propertyType, value, out newValue)) { newValue = Convert.ChangeType(value, propertyType, CultureInfo.InvariantCulture); } } } } propInfo.SetValue(o, newValue, null); } catch (TargetInvocationException ex) { throw new NLogConfigurationException("Error when setting property '" + propInfo.Name + "' on " + o, ex.InnerException); } catch (Exception exception) { if (exception.MustBeRethrown()) { throw; } throw new NLogConfigurationException("Error when setting property '" + propInfo.Name + "' on " + o, exception); } }
private static bool TryNLogSpecificConversion(Type propertyType, string value, out object newValue, ConfigurationItemFactory configurationItemFactory) { if (propertyType == typeof (Layout) || propertyType == typeof (SimpleLayout)) { newValue = new SimpleLayout(value, configurationItemFactory); return true; } if (propertyType == typeof (ConditionExpression)) { newValue = ConditionParser.ParseExpression(value, configurationItemFactory); return true; } newValue = null; return false; }
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; }