Esempio n. 1
0
        /// <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);
            ConditionExpression expression = parser.ParseExpression();

            if (!parser.tokenizer.IsEOF())
            {
                throw new ConditionParseException("Unexpected token: " + parser.tokenizer.TokenValue);
            }

            return(expression);
        }
Esempio n. 2
0
        public void LayoutRendererThrows2()
        {
            string internalLogOutput = RunAndCaptureInternalLog(
                () =>
            {
                ConfigurationItemFactory configurationItemFactory = new ConfigurationItemFactory();
                configurationItemFactory.LayoutRenderers.RegisterDefinition("throwsException", typeof(ThrowsExceptionRenderer));

                SimpleLayout l = new SimpleLayout("xx${throwsException:msg1}yy${throwsException:msg2}zz", configurationItemFactory);
                string output  = l.Render(LogEventInfo.CreateNullEvent());
                Assert.Equal("xxyyzz", output);
            },
                LogLevel.Warn);

            Assert.True(internalLogOutput.IndexOf("msg1") >= 0, internalLogOutput);
            Assert.True(internalLogOutput.IndexOf("msg2") >= 0, internalLogOutput);
        }
Esempio n. 3
0
 private static void SetDefaultPropertyValue(ConfigurationItemFactory configurationItemFactory, LayoutRenderer layoutRenderer, string value, bool?throwConfigExceptions)
 {
     // what we've just read is not a parameterName, but a value
     // assign it to a default property (denoted by empty string)
     if (PropertyHelper.TryGetPropertyInfo(layoutRenderer, string.Empty, out var propertyInfo))
     {
         PropertyHelper.SetPropertyFromString(layoutRenderer, propertyInfo.Name, value, configurationItemFactory);
     }
     else
     {
         var configException = new NLogConfigurationException($"{layoutRenderer.GetType()} has no default property to assign value {value}");
         if (throwConfigExceptions ?? configException.MustBeRethrown())
         {
             throw configException;
         }
     }
 }
        private static LayoutRenderer ApplyWrappers(ConfigurationItemFactory configurationItemFactory, LayoutRenderer lr, List <LayoutRenderer> orderedWrappers)
        {
            for (int i = orderedWrappers.Count - 1; i >= 0; --i)
            {
                var newRenderer = (WrapperLayoutRendererBase)orderedWrappers[i];
                InternalLogger.Trace("Wrapping {0} with {1}", lr.GetType(), newRenderer.GetType());
                if (CanBeConvertedToLiteral(lr))
                {
                    lr = ConvertToLiteral(lr);
                }

                newRenderer.Inner = new SimpleLayout(new[] { lr }, string.Empty, configurationItemFactory);
                lr = newRenderer;
            }

            return(lr);
        }
Esempio n. 5
0
        private static void InitNLogConfigurationItemFactory()
        {
            // Default initialization code for ConfigurationItemFactory.Default spends
            // almost 0.5 sec in il-packed executable. (it scans whole types in assembly to find plugin types)
            // To avoid this slow-down, manual initialization is written.
            // If you need another layout-renderer, filter or anything else in NLog assembly,
            // please insert register code here.

            var factory = new ConfigurationItemFactory(new Assembly[0]);

            factory.LayoutRenderers.RegisterDefinition("time", typeof(TimeLayoutRenderer));
            factory.LayoutRenderers.RegisterDefinition("longdate", typeof(LongDateLayoutRenderer));
            factory.LayoutRenderers.RegisterDefinition("level", typeof(LevelLayoutRenderer));
            factory.LayoutRenderers.RegisterDefinition("logger", typeof(LoggerNameLayoutRenderer));
            factory.LayoutRenderers.RegisterDefinition("message", typeof(MessageLayoutRenderer));
            factory.LayoutRenderers.RegisterDefinition("exception", typeof(ExceptionLayoutRenderer));
            factory.LayoutRenderers.RegisterDefinition("uppercase", typeof(UppercaseLayoutRendererWrapper));
            ConfigurationItemFactory.Default = factory;
        }
Esempio n. 6
0
        private static LayoutRenderer GetLayoutRenderer(ConfigurationItemFactory configurationItemFactory, string name, bool?throwConfigExceptions)
        {
            LayoutRenderer layoutRenderer;

            try
            {
                layoutRenderer = configurationItemFactory.LayoutRenderers.CreateInstance(name);
            }
            catch (Exception ex)
            {
                if (throwConfigExceptions ?? LogManager.ThrowConfigExceptions ?? LogManager.ThrowExceptions)
                {
                    throw;  // TODO NLog 5.0 throw NLogConfigurationException. Maybe also include entire input layout-string (if not too long)
                }
                InternalLogger.Error(ex, "Error parsing layout {0} will be ignored.", name);
                // replace with empty values
                layoutRenderer = new LiteralLayoutRenderer(string.Empty);
            }
            return(layoutRenderer);
        }
Esempio n. 7
0
        private static LayoutRenderer GetLayoutRenderer(ConfigurationItemFactory configurationItemFactory, string name, bool?throwConfigExceptions)
        {
            LayoutRenderer layoutRenderer;

            try
            {
                layoutRenderer = configurationItemFactory.LayoutRenderers.CreateInstance(name);
            }
            catch (Exception ex)
            {
                var configException = new NLogConfigurationException(ex, $"Error parsing layout {name}");
                if (throwConfigExceptions ?? configException.MustBeRethrown())
                {
                    throw configException;
                }
                // replace with empty values
                layoutRenderer = new LiteralLayoutRenderer(string.Empty);
            }
            return(layoutRenderer);
        }
Esempio n. 8
0
        private static LayoutRenderer GetLayoutRenderer(ConfigurationItemFactory configurationItemFactory, string name)
        {
            LayoutRenderer layoutRenderer;

            try
            {
                layoutRenderer = configurationItemFactory.LayoutRenderers.CreateInstance(name);
            }
            catch (Exception ex)
            {
                if (LogManager.ThrowConfigExceptions ?? LogManager.ThrowExceptions)
                {
                    throw;
                }
                InternalLogger.Error(ex, "Error parsing layout {0} will be ignored.", name);
                //replace with emptys
                layoutRenderer = new LiteralLayoutRenderer(string.Empty);
            }
            return(layoutRenderer);
        }
Esempio n. 9
0
        private static void SetDefaultPropertyValue(ConfigurationItemFactory configurationItemFactory, LayoutRenderer layoutRenderer, string parameterName)
        {
            // what we've just read is not a parameterName, but a value
            // assign it to a default property (denoted by empty string)
            PropertyInfo propertyInfo;

            if (PropertyHelper.TryGetPropertyInfo(layoutRenderer, string.Empty, out propertyInfo))
            {
                if (typeof(SimpleLayout) == propertyInfo.PropertyType)
                {
                    propertyInfo.SetValue(layoutRenderer, new SimpleLayout(parameterName), null);
                }
                else
                {
                    string value = parameterName;
                    PropertyHelper.SetPropertyFromString(layoutRenderer, propertyInfo.Name, value, configurationItemFactory);
                }
            }
            else
            {
                InternalLogger.Warn("{0} has no default property", layoutRenderer.GetType().FullName);
            }
        }
Esempio n. 10
0
        /// <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);
            ConditionExpression expression = parser.ParseExpression();

            return(expression);
        }
Esempio n. 11
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ConditionParser" /> class.
 /// </summary>
 /// <param name="expressionText">The expression text.</param>
 /// <param name="configurationItemFactory">Instance of <see cref="ConfigurationItemFactory"/> used to resolve references to condition methods and layout renderers.</param>
 private ConditionParser(string expressionText, ConfigurationItemFactory configurationItemFactory)
 {
     this.configurationItemFactory = configurationItemFactory;
     this.tokenizer = new ConditionTokenizer(expressionText ?? string.Empty);
 }
        private static LayoutRenderer ParseLayoutRenderer(ConfigurationItemFactory configurationItemFactory, SimpleStringReader stringReader, bool?throwConfigExceptions)
        {
            int ch = stringReader.Read();

            Debug.Assert(ch == '{', "'{' expected in layout specification");

            string name           = ParseLayoutRendererName(stringReader);
            var    layoutRenderer = GetLayoutRenderer(configurationItemFactory, name, throwConfigExceptions);

            Dictionary <Type, LayoutRenderer> wrappers        = null;
            List <LayoutRenderer>             orderedWrappers = null;

            ch = stringReader.Read();
            while (ch != -1 && ch != '}')
            {
                string parameterName = ParseParameterName(stringReader).Trim();
                if (stringReader.Peek() == '=')
                {
                    stringReader.Read(); // skip the '='
                    PropertyInfo   propertyInfo;
                    LayoutRenderer parameterTarget = layoutRenderer;

                    if (!PropertyHelper.TryGetPropertyInfo(layoutRenderer, parameterName, out propertyInfo))
                    {
                        if (configurationItemFactory.AmbientProperties.TryGetDefinition(parameterName, out var wrapperType))
                        {
                            wrappers        = wrappers ?? new Dictionary <Type, LayoutRenderer>();
                            orderedWrappers = orderedWrappers ?? new List <LayoutRenderer>();
                            if (!wrappers.TryGetValue(wrapperType, out var wrapperRenderer))
                            {
                                wrapperRenderer       = configurationItemFactory.AmbientProperties.CreateInstance(parameterName);
                                wrappers[wrapperType] = wrapperRenderer;
                                orderedWrappers.Add(wrapperRenderer);
                            }

                            if (!PropertyHelper.TryGetPropertyInfo(wrapperRenderer, parameterName, out propertyInfo))
                            {
                                propertyInfo = null;
                            }
                            else
                            {
                                parameterTarget = wrapperRenderer;
                            }
                        }
                    }

                    if (propertyInfo == null)
                    {
                        var value = ParseParameterValue(stringReader);
                        if (!string.IsNullOrEmpty(parameterName) || !StringHelpers.IsNullOrWhiteSpace(value))
                        {
                            // TODO NLog 5.0 Should throw exception when invalid configuration (Check throwConfigExceptions)
                            InternalLogger.Warn("Skipping unrecognized property '{0}={1}` for ${{{2}}} ({3})", parameterName, value, name, layoutRenderer?.GetType());
                        }
                    }
                    else
                    {
                        if (typeof(Layout).IsAssignableFrom(propertyInfo.PropertyType))
                        {
                            LayoutRenderer[] renderers = CompileLayout(configurationItemFactory, stringReader, throwConfigExceptions, true, out var txt);

                            var nestedLayout = new SimpleLayout(renderers, txt, configurationItemFactory);
                            propertyInfo.SetValue(parameterTarget, nestedLayout, null);
                        }
                        else if (typeof(ConditionExpression).IsAssignableFrom(propertyInfo.PropertyType))
                        {
                            var conditionExpression = ConditionParser.ParseExpression(stringReader, configurationItemFactory);
                            propertyInfo.SetValue(parameterTarget, conditionExpression, null);
                        }
                        else
                        {
                            string value = ParseParameterValue(stringReader);
                            PropertyHelper.SetPropertyFromString(parameterTarget, parameterName, value, configurationItemFactory);
                        }
                    }
                }
                else
                {
                    SetDefaultPropertyValue(configurationItemFactory, layoutRenderer, parameterName);
                }

                ch = stringReader.Read();
            }

            if (orderedWrappers != null)
            {
                layoutRenderer = ApplyWrappers(configurationItemFactory, layoutRenderer, orderedWrappers);
            }

            return(layoutRenderer);
        }
        private static bool TryNLogSpecificConversion(Type propertyType, string value, ConfigurationItemFactory configurationItemFactory, out object newValue)
        {
            if (DefaultPropertyConversionMapper.TryGetValue(propertyType, out var objectConverter))
            {
                newValue = objectConverter.Invoke(value, configurationItemFactory);
                return(true);
            }

            newValue = null;
            return(false);
        }
Esempio n. 14
0
        private static LayoutRenderer ParseLayoutRenderer(ConfigurationItemFactory configurationItemFactory, SimpleStringReader stringReader, bool?throwConfigExceptions)
        {
            int ch = stringReader.Read();

            Debug.Assert(ch == '{', "'{' expected in layout specification");

            string name           = ParseLayoutRendererName(stringReader);
            var    layoutRenderer = GetLayoutRenderer(configurationItemFactory, name, throwConfigExceptions);

            var wrappers        = new Dictionary <Type, LayoutRenderer>();
            var orderedWrappers = new List <LayoutRenderer>();

            ch = stringReader.Read();
            while (ch != -1 && ch != '}')
            {
                string parameterName = ParseParameterName(stringReader).Trim();
                if (stringReader.Peek() == '=')
                {
                    stringReader.Read(); // skip the '='
                    PropertyInfo   propertyInfo;
                    LayoutRenderer parameterTarget = layoutRenderer;

                    if (!PropertyHelper.TryGetPropertyInfo(layoutRenderer, parameterName, out propertyInfo))
                    {
                        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 propertyInfo))
                            {
                                propertyInfo = null;
                            }
                            else
                            {
                                parameterTarget = wrapperRenderer;
                            }
                        }
                    }

                    if (propertyInfo == null)
                    {
                        ParseParameterValue(stringReader);
                    }
                    else
                    {
                        if (typeof(Layout).IsAssignableFrom(propertyInfo.PropertyType))
                        {
                            var              nestedLayout = new SimpleLayout();
                            string           txt;
                            LayoutRenderer[] renderers = CompileLayout(configurationItemFactory, stringReader, throwConfigExceptions, true, out txt);

                            nestedLayout.SetRenderers(renderers, txt);
                            propertyInfo.SetValue(parameterTarget, nestedLayout, null);
                        }
                        else if (typeof(ConditionExpression).IsAssignableFrom(propertyInfo.PropertyType))
                        {
                            var conditionExpression = ConditionParser.ParseExpression(stringReader, configurationItemFactory);
                            propertyInfo.SetValue(parameterTarget, conditionExpression, null);
                        }
                        else
                        {
                            string value = ParseParameterValue(stringReader);
                            PropertyHelper.SetPropertyFromString(parameterTarget, parameterName, value, configurationItemFactory);
                        }
                    }
                }
                else
                {
                    SetDefaultPropertyValue(configurationItemFactory, layoutRenderer, parameterName);
                }

                ch = stringReader.Read();
            }

            layoutRenderer = ApplyWrappers(configurationItemFactory, layoutRenderer, orderedWrappers);

            return(layoutRenderer);
        }
Esempio n. 15
0
 internal SimpleLayout(LayoutRenderer[] renderers, string text, ConfigurationItemFactory configurationItemFactory)
 {
     this.configurationItemFactory = configurationItemFactory;
     this.SetRenderers(renderers, text);
 }
        /// <summary>
        /// Set value parsed from string.
        /// </summary>
        /// <param name="obj">object instance to set with property <paramref name="propertyName"/></param>
        /// <param name="propertyName">name of the property on <paramref name="obj"/></param>
        /// <param name="value">The value to be parsed.</param>
        /// <param name="configurationItemFactory"></param>
        internal static void SetPropertyFromString(object obj, string propertyName, string value, ConfigurationItemFactory configurationItemFactory)
        {
            var objType = obj.GetType();

            InternalLogger.Debug("Setting '{0}.{1}' to '{2}'", objType, propertyName, value);

            if (!TryGetPropertyInfo(objType, propertyName, out var propInfo))
            {
                throw new NotSupportedException($"Parameter {propertyName} not supported on {objType.Name}");
            }

            try
            {
                Type propertyType = propInfo.PropertyType;

                if (!TryNLogSpecificConversion(propertyType, value, configurationItemFactory, out var newValue))
                {
                    if (propInfo.IsDefined(_arrayParameterAttribute.GetType(), false))
                    {
                        throw new NotSupportedException($"Parameter {propertyName} of {objType.Name} is an array and cannot be assigned a scalar value.");
                    }

                    propertyType = Nullable.GetUnderlyingType(propertyType) ?? propertyType;

                    if (!(TryGetEnumValue(propertyType, value, out newValue, true) ||
                          TryImplicitConversion(propertyType, value, out newValue) ||
                          TryFlatListConversion(obj, propInfo, value, configurationItemFactory, out newValue) ||
                          TryTypeConverterConversion(propertyType, value, out newValue)))
                    {
                        newValue = Convert.ChangeType(value, propertyType, CultureInfo.InvariantCulture);
                    }
                }

                propInfo.SetValue(obj, newValue, null);
            }
            catch (TargetInvocationException ex)
            {
                throw new NLogConfigurationException($"Error when setting property '{propInfo.Name}' on {objType.Name}", ex.InnerException);
            }
            catch (Exception exception)
            {
                InternalLogger.Warn(exception, "Error when setting property '{0}' on '{1}'", propInfo.Name, objType);

                if (exception.MustBeRethrownImmediately())
                {
                    throw;
                }

                throw new NLogConfigurationException($"Error when setting property '{propInfo.Name}' on {objType.Name}", exception);
            }
        }
Esempio n. 17
0
 internal SimpleLayout(LayoutRenderer[] renderers, string text, ConfigurationItemFactory configurationItemFactory)
 {
     _configurationItemFactory = configurationItemFactory;
     OriginalText = text;
     SetRenderers(renderers, text);
 }
        /// <summary>
        /// Try parse of string to (Generic) list, comma separated.
        /// </summary>
        /// <remarks>
        /// If there is a comma in the value, then (single) quote the value. For single quotes, use the backslash as escape
        /// </remarks>
        private static bool TryFlatListConversion(object obj, PropertyInfo propInfo, string valueRaw, ConfigurationItemFactory configurationItemFactory, out object newValue)
        {
            if (propInfo.PropertyType.IsGenericType() && TryCreateCollectionObject(obj, propInfo, valueRaw, out var newList, out var collectionAddMethod, out var propertyType))
            {
                var values = valueRaw.SplitQuoted(',', '\'', '\\');
                foreach (var value in values)
                {
                    if (!(TryGetEnumValue(propertyType, value, out newValue, false) ||
                          TryNLogSpecificConversion(propertyType, value, configurationItemFactory, out newValue) ||
                          TryImplicitConversion(propertyType, value, out newValue) ||
                          TryTypeConverterConversion(propertyType, value, out newValue)))
                    {
                        newValue = Convert.ChangeType(value, propertyType, CultureInfo.InvariantCulture);
                    }

                    collectionAddMethod.Invoke(newList, new object[] { newValue });
                }

                newValue = newList;
                return(true);
            }

            newValue = null;
            return(false);
        }
 private static object TryParseConditionValue(string stringValue, ConfigurationItemFactory configurationItemFactory)
 {
     return(ConditionParser.ParseExpression(stringValue, configurationItemFactory));
 }
 private static object TryParseLayoutValue(string stringValue, ConfigurationItemFactory configurationItemFactory)
 {
     return(new SimpleLayout(stringValue, configurationItemFactory));
 }
Esempio n. 21
0
 /// <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)
 {
     _configurationItemFactory = configurationItemFactory;
     _tokenizer = new ConditionTokenizer(stringReader);
 }
Esempio n. 22
0
 public void SetUp()
 {
     _config = new ConfigurationItemFactory(GetType().Assembly, typeof(Logger).Assembly);
 }
Esempio n. 23
0
 /// <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;
     this.Text = txt;
 }
Esempio n. 24
0
        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);
        }
Esempio n. 25
0
        public void ConfigurationItemFactoryDefaultTest()
        {
            var cif = new ConfigurationItemFactory();

            Assert.IsType(typeof(DebugTarget), cif.CreateInstance(typeof(DebugTarget)));
        }
Esempio n. 26
0
        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;

                Type 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);
            }
        }
Esempio n. 27
0
 /// <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(txt, configurationItemFactory, null)
 {
 }
Esempio n. 28
0
        private static LayoutRenderer ParseLayoutRenderer(ConfigurationItemFactory configurationItemFactory, Tokenizer sr)
        {
            int ch = sr.Read();

            Debug.Assert(ch == '{', "'{' expected in layout specification");

            string         name = ParseLayoutRendererName(sr);
            LayoutRenderer lr   = configurationItemFactory.LayoutRenderers.CreateInstance(name);

            var wrappers        = new Dictionary <Type, LayoutRenderer>();
            var orderedWrappers = new List <LayoutRenderer>();

            ch = sr.Read();
            while (ch != -1 && ch != '}')
            {
                string parameterName = ParseParameterName(sr).Trim();
                if (sr.Peek() == '=')
                {
                    sr.Read(); // skip the '='
                    PropertyInfo   pi;
                    LayoutRenderer 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;
                            LayoutRenderer[] renderers = CompileLayout(configurationItemFactory, sr, true, out txt);

                            nestedLayout.SetRenderers(renderers, txt);
                            pi.SetValue(parameterTarget, nestedLayout, null);
                        }
                        else
                        {
                            string value = ParseParameterValue(sr);
                            PropertyHelper.SetPropertyFromString(parameterTarget, parameterName, value);
                        }
                    }
                }
                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
                        {
                            string value = parameterName;
                            PropertyHelper.SetPropertyFromString(lr, pi.Name, value);
                        }
                    }
                    else
                    {
                        InternalLogger.Warn("{0} has no default property", lr.GetType().FullName);
                    }
                }

                ch = sr.Read();
            }

            lr = ApplyWrappers(configurationItemFactory, lr, orderedWrappers);

            return(lr);
        }
Esempio n. 29
0
        internal static LayoutRenderer[] CompileLayout(ConfigurationItemFactory configurationItemFactory, SimpleStringReader sr, bool?throwConfigExceptions, bool isNested, out string text)
        {
            var result     = new List <LayoutRenderer>();
            var literalBuf = new StringBuilder();

            int ch;

            int p0 = sr.Position;

            while ((ch = sr.Peek()) != -1)
            {
                if (isNested)
                {
                    //possible escape char `\`
                    if (ch == '\\')
                    {
                        sr.Read();
                        var nextChar = sr.Peek();

                        //escape chars
                        if (EndOfLayout(nextChar))
                        {
                            //read next char and append
                            sr.Read();
                            literalBuf.Append((char)nextChar);
                        }
                        else
                        {
                            //don't treat \ as escape char and just read it
                            literalBuf.Append('\\');
                        }
                        continue;
                    }

                    if (EndOfLayout(ch))
                    {
                        //end of innerlayout.
                        // `}` is when double nested inner layout.
                        // `:` when single nested layout
                        break;
                    }
                }

                sr.Read();

                //detect `${` (new layout-renderer)
                if (ch == '$' && sr.Peek() == '{')
                {
                    //stash already found layout-renderer.
                    AddLiteral(literalBuf, result);

                    LayoutRenderer newLayoutRenderer = ParseLayoutRenderer(configurationItemFactory, sr, throwConfigExceptions);
                    if (CanBeConvertedToLiteral(newLayoutRenderer))
                    {
                        newLayoutRenderer = ConvertToLiteral(newLayoutRenderer);
                    }

                    // layout renderer
                    result.Add(newLayoutRenderer);
                }
                else
                {
                    literalBuf.Append((char)ch);
                }
            }

            AddLiteral(literalBuf, result);

            int p1 = sr.Position;

            MergeLiterals(result);
            text = sr.Substring(p0, p1);

            return(result.ToArray());
        }
Esempio n. 30
0
 /// <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>
 /// <param name="throwConfigExceptions">Whether <see cref="NLogConfigurationException"/> should be thrown on parse errors.</param>
 internal SimpleLayout(string txt, ConfigurationItemFactory configurationItemFactory, bool?throwConfigExceptions)
 {
     _configurationItemFactory = configurationItemFactory;
     SetLayoutText(txt, throwConfigExceptions);
 }