Beispiel #1
0
        private void RenderAttributes(
            EventBean theEvent,
            StringBuilder buf,
            RendererMeta meta)
        {
            var delimiter = " ";
            var simpleProps = meta.SimpleProperties;
            foreach (var simpleProp in simpleProps) {
                var value = simpleProp.Getter.Get(theEvent);
                if (value == null) {
                    continue;
                }

                buf.Append(delimiter);
                buf.Append(simpleProp.Name);
                buf.Append("=\"");
                if (rendererMetaOptions.Renderer == null) {
                    simpleProp.Output.Render(value, buf);
                }
                else {
                    var context = rendererMetaOptions.RendererContext;
                    context.SetStringBuilderAndReset(buf);
                    context.PropertyName = simpleProp.Name;
                    context.PropertyValue = value;
                    context.DefaultRenderer = simpleProp.Output;
                    rendererMetaOptions.Renderer.Render(context);
                }

                buf.Append('"');
            }
        }
Beispiel #2
0
 /// <summary>
 ///     Ctor.
 /// </summary>
 /// <param name="getter">for retrieving the value</param>
 /// <param name="name">property name</param>
 /// <param name="metadata">the nested properties metadata</param>
 /// <param name="isArray">indicates whether this is an indexed property</param>
 public NestedGetterPair(
     EventPropertyGetter getter,
     string name,
     RendererMeta metadata,
     bool isArray)
 {
     Getter = getter;
     Name = name;
     Metadata = metadata;
     IsArray = isArray;
 }
Beispiel #3
0
        /// <summary>
        ///     Ctor.
        /// </summary>
        /// <param name="eventType">type of event to render</param>
        /// <param name="options">rendering options</param>
        public XMLRendererImpl(
            EventType eventType,
            XMLRenderingOptions options)
        {
            EventPropertyRenderer propertyRenderer = null;
            EventPropertyRendererContext propertyRendererContext = null;
            if (options.Renderer != null) {
                propertyRenderer = options.Renderer;
                propertyRendererContext = new EventPropertyRendererContext(eventType, false);
            }

            rendererMetaOptions = new RendererMetaOptions(
                options.PreventLooping,
                true,
                propertyRenderer,
                propertyRendererContext);
            meta = new RendererMeta(eventType, new Stack<EventTypePropertyPair>(), rendererMetaOptions);
            this.options = options;
        }
Beispiel #4
0
        /// <summary>Ctor. </summary>
        /// <param name="eventType">type of Event(s)</param>
        /// <param name="options">rendering options</param>
        public JSONRendererImpl(
            EventType eventType,
            JSONRenderingOptions options)
        {
            EventPropertyRenderer        propertyRenderer        = null;
            EventPropertyRendererContext propertyRendererContext = null;

            if (options.Renderer != null)
            {
                propertyRenderer        = options.Renderer;
                propertyRendererContext = new EventPropertyRendererContext(eventType, true);
            }

            _rendererOptions = new RendererMetaOptions(
                options.PreventLooping,
                false,
                propertyRenderer,
                propertyRendererContext);
            _meta = new RendererMeta(eventType, new Stack <EventTypePropertyPair>(), _rendererOptions);
        }
Beispiel #5
0
        private static void RecursiveRender(
            EventBean theEvent,
            StringBuilder buf,
            int level,
            RendererMeta meta,
            RendererMetaOptions rendererOptions)
        {
            var delimiter = "";

            var renderActions = new SortedList <string, Action>();

            // simple properties
            var simpleProps = meta.SimpleProperties;

            if (rendererOptions.Renderer == null)
            {
                foreach (var simpleProp in simpleProps.OrderBy(prop => prop.Name))
                {
                    var name  = simpleProp.Name;
                    var value = simpleProp.Getter.Get(theEvent);
                    renderActions.Add(
                        name,
                        () => {
                        WriteDelimitedIndentedProp(buf, delimiter, level, name);
                        simpleProp.Output.Render(value, buf);
                        delimiter = COMMA_DELIMITER_NEWLINE;
                    });
                }
            }
            else
            {
                var context = rendererOptions.RendererContext;
                context.SetStringBuilderAndReset(buf);
                foreach (var simpleProp in simpleProps.OrderBy(prop => prop.Name))
                {
                    var name  = simpleProp.Name;
                    var value = simpleProp.Getter.Get(theEvent);
                    renderActions.Add(
                        name,
                        () => {
                        WriteDelimitedIndentedProp(buf, delimiter, level, simpleProp.Name);
                        context.DefaultRenderer = simpleProp.Output;
                        context.PropertyName    = simpleProp.Name;
                        context.PropertyValue   = value;
                        rendererOptions.Renderer.Render(context);
                        delimiter = COMMA_DELIMITER_NEWLINE;
                    });
                }
            }

            var indexProps = meta.IndexProperties;

            foreach (var indexProp in indexProps.OrderBy(prop => prop.Name))
            {
                var name = indexProp.Name;

                renderActions.Add(
                    name,
                    () => {
                    WriteDelimitedIndentedProp(buf, delimiter, level, name);

                    var value = indexProp.Getter.Get(theEvent);
                    if (value == null)
                    {
                        buf.Append("null");
                    }
                    else if (value is string)
                    {
                        if (rendererOptions.Renderer == null)
                        {
                            indexProp.Output.Render(value, buf);
                        }
                        else
                        {
                            var context = rendererOptions.RendererContext;
                            context.SetStringBuilderAndReset(buf);
                            context.DefaultRenderer = indexProp.Output;
                            context.PropertyName    = name;
                            context.PropertyValue   = value;
                            rendererOptions.Renderer.Render(context);
                        }
                    }
                    else
                    {
                        var asArray = value as Array;
                        if (asArray == null)
                        {
                            buf.Append("[]");
                        }
                        else
                        {
                            buf.Append('[');

                            var arrayDelimiter = "";

                            if (rendererOptions.Renderer == null)
                            {
                                for (var i = 0; i < asArray.Length; i++)
                                {
                                    var arrayItem = asArray.GetValue(i);
                                    buf.Append(arrayDelimiter);
                                    indexProp.Output.Render(arrayItem, buf);
                                    arrayDelimiter = ", ";
                                }
                            }
                            else
                            {
                                var context = rendererOptions.RendererContext;
                                context.SetStringBuilderAndReset(buf);
                                for (var i = 0; i < asArray.Length; i++)
                                {
                                    var arrayItem = asArray.GetValue(i);
                                    buf.Append(arrayDelimiter);
                                    context.PropertyName         = indexProp.Name;
                                    context.PropertyValue        = arrayItem;
                                    context.IndexedPropertyIndex = i;
                                    context.DefaultRenderer      = indexProp.Output;
                                    rendererOptions.Renderer.Render(context);
                                    arrayDelimiter = ", ";
                                }
                            }

                            buf.Append(']');
                        }
                    }

                    delimiter = COMMA_DELIMITER_NEWLINE;
                });
            }

            var mappedProps = meta.MappedProperties;

            foreach (var mappedProp in mappedProps.OrderBy(prop => prop.Name))
            {
                var name  = mappedProp.Name;
                var value = mappedProp.Getter.Get(theEvent);

                if (value != null && !value.GetType().IsGenericStringDictionary())
                {
                    Log.Warn(
                        "Property '" +
                        mappedProp.Name +
                        "' expected to return Map and returned " +
                        value.GetType() +
                        " instead");
                    continue;
                }

                renderActions.Add(
                    name,
                    () => {
                    WriteDelimitedIndentedProp(buf, delimiter, level, mappedProp.Name);

                    if (value == null)
                    {
                        buf.Append("null");
                        buf.Append(NEWLINE);
                    }
                    else
                    {
                        var map = MagicMarker.SingletonInstance.GetStringDictionary(value);
                        if (map.IsEmpty())
                        {
                            buf.Append("{}");
                            buf.Append(NEWLINE);
                        }
                        else
                        {
                            buf.Append('{');
                            buf.Append(NEWLINE);

                            var localDelimiter = "";
                            foreach (var entry in map)
                            {
                                if (entry.Key == null)
                                {
                                    continue;
                                }

                                buf.Append(localDelimiter);
                                Ident(buf, level + 1);
                                buf.Append('\"');
                                buf.Append(entry.Key);
                                buf.Append("\": ");

                                if (entry.Value == null)
                                {
                                    buf.Append("null");
                                }
                                else
                                {
                                    var outRenderer = OutputValueRendererFactory.GetOutputValueRenderer(
                                        entry.Value.GetType(),
                                        rendererOptions);
                                    if (rendererOptions.Renderer == null)
                                    {
                                        outRenderer.Render(entry.Value, buf);
                                    }
                                    else
                                    {
                                        var context = rendererOptions.RendererContext;
                                        context.SetStringBuilderAndReset(buf);
                                        context.PropertyName      = mappedProp.Name;
                                        context.PropertyValue     = entry.Value;
                                        context.MappedPropertyKey = entry.Key;
                                        context.DefaultRenderer   = outRenderer;
                                        rendererOptions.Renderer.Render(context);
                                    }
                                }

                                localDelimiter = COMMA_DELIMITER_NEWLINE;
                            }

                            buf.Append(NEWLINE);
                            Ident(buf, level);
                            buf.Append('}');
                        }
                    }

                    delimiter = COMMA_DELIMITER_NEWLINE;
                });
            }

            var nestedProps = meta.NestedProperties;

            foreach (var nestedProp in nestedProps.OrderBy(prop => prop.Name))
            {
                var name  = nestedProp.Name;
                var value = nestedProp.Getter.GetFragment(theEvent);

                renderActions.Add(
                    name,
                    () => {
                    WriteDelimitedIndentedProp(buf, delimiter, level, nestedProp.Name);

                    if (value == null)
                    {
                        buf.Append("null");
                    }
                    else if (!nestedProp.IsArray)
                    {
                        if (!(value is EventBean))
                        {
                            Log.Warn(
                                "Property '" +
                                nestedProp.Name +
                                "' expected to return EventBean and returned " +
                                value.GetType() +
                                " instead");
                            buf.Append("null");
                            return;
                        }

                        var nestedEventBean = (EventBean)value;
                        buf.Append('{');
                        buf.Append(NEWLINE);

                        RecursiveRender(nestedEventBean, buf, level + 1, nestedProp.Metadata, rendererOptions);

                        Ident(buf, level);
                        buf.Append('}');
                    }
                    else
                    {
                        if (!(value is EventBean[]))
                        {
                            Log.Warn(
                                "Property '" +
                                nestedProp.Name +
                                "' expected to return EventBean[] and returned " +
                                value.GetType() +
                                " instead");
                            buf.Append("null");
                            return;
                        }

                        var arrayDelimiterBuf = new StringBuilder();
                        arrayDelimiterBuf.Append(',');
                        arrayDelimiterBuf.Append(NEWLINE);
                        Ident(arrayDelimiterBuf, level + 1);

                        var nestedEventArray = (EventBean[])value;
                        var arrayDelimiter   = "";
                        buf.Append('[');

                        for (var i = 0; i < nestedEventArray.Length; i++)
                        {
                            var arrayItem = nestedEventArray[i];
                            buf.Append(arrayDelimiter);
                            arrayDelimiter = arrayDelimiterBuf.ToString();

                            buf.Append('{');
                            buf.Append(NEWLINE);

                            RecursiveRender(arrayItem, buf, level + 2, nestedProp.Metadata, rendererOptions);

                            Ident(buf, level + 1);
                            buf.Append('}');
                        }

                        buf.Append(']');
                    }

                    delimiter = COMMA_DELIMITER_NEWLINE;
                });
            }

            foreach (var entry in renderActions)
            {
                entry.Value.Invoke();
            }

            buf.Append(NEWLINE);
        }
Beispiel #6
0
        /// <summary>
        ///     Ctor.
        /// </summary>
        /// <param name="eventType">to render</param>
        /// <param name="stack">the stack of properties to avoid looping</param>
        /// <param name="options">rendering options</param>
        public RendererMeta(
            EventType eventType,
            Stack<EventTypePropertyPair> stack,
            RendererMetaOptions options)
        {
            var gettersSimple = new List<GetterPair>();
            var gettersIndexed = new List<GetterPair>();
            var gettersMapped = new List<GetterPair>();
            var gettersNested = new List<NestedGetterPair>();

            var descriptors = eventType.PropertyDescriptors;
            foreach (var desc in descriptors.OrderBy(d => d.PropertyName)) {
                var propertyName = desc.PropertyName;

                if (!desc.IsIndexed && !desc.IsMapped && !desc.IsFragment) {
                    var getter = eventType.GetGetter(propertyName);
                    if (getter == null) {
                        Log.Warn(
                            "No getter returned for event type '" +
                            eventType.Name +
                            "' and property '" +
                            propertyName +
                            "'");
                        continue;
                    }

                    gettersSimple.Add(
                        new GetterPair(
                            getter,
                            propertyName,
                            OutputValueRendererFactory.GetOutputValueRenderer(desc.PropertyType, options)));
                }

                if (desc.IsIndexed && !desc.IsRequiresIndex && !desc.IsFragment) {
                    var getter = eventType.GetGetter(propertyName);
                    if (getter == null) {
                        Log.Warn(
                            "No getter returned for event type '" +
                            eventType.Name +
                            "' and property '" +
                            propertyName +
                            "'");
                        continue;
                    }

                    if (desc.PropertyType != typeof(string)) {
                        gettersIndexed.Add(
                            new GetterPair(
                                getter,
                                propertyName,
                                OutputValueRendererFactory.GetOutputValueRenderer(desc.PropertyType, options)));
                    }
                    else {
                        gettersSimple.Add(
                            new GetterPair(
                                getter,
                                propertyName,
                                OutputValueRendererFactory.GetOutputValueRenderer(desc.PropertyType, options)));
                    }
                }

                if (desc.IsMapped && !desc.IsRequiresMapKey && !desc.IsFragment) {
                    var getter = eventType.GetGetter(propertyName);
                    if (getter == null) {
                        Log.Warn(
                            "No getter returned for event type '" +
                            eventType.Name +
                            "' and property '" +
                            propertyName +
                            "'");
                        continue;
                    }

                    gettersMapped.Add(
                        new GetterPair(
                            getter,
                            propertyName,
                            OutputValueRendererFactory.GetOutputValueRenderer(desc.PropertyType, options)));
                }

                if (desc.IsFragment) {
                    var getter = eventType.GetGetter(propertyName);
                    var fragmentType = eventType.GetFragmentType(propertyName);
                    if (getter == null) {
                        Log.Warn(
                            "No getter returned for event type '" +
                            eventType.Name +
                            "' and property '" +
                            propertyName +
                            "'");
                        continue;
                    }

                    if (fragmentType == null) {
                        Log.Warn(
                            "No fragment type returned for event type '" +
                            eventType.Name +
                            "' and property '" +
                            propertyName +
                            "'");
                        continue;
                    }

                    var pair = new EventTypePropertyPair(fragmentType.FragmentType, propertyName);
                    if (options.PreventLooping && stack.Contains(pair)) {
                        continue; // prevent looping behavior on self-references
                    }

                    stack.Push(pair);
                    var fragmentMetaData = new RendererMeta(fragmentType.FragmentType, stack, options);
                    stack.Pop();

                    gettersNested.Add(
                        new NestedGetterPair(getter, propertyName, fragmentMetaData, fragmentType.IsIndexed));
                }
            }

            SimpleProperties = gettersSimple.ToArray();
            IndexProperties = gettersIndexed.ToArray();
            MappedProperties = gettersMapped.ToArray();
            NestedProperties = gettersNested.ToArray();
        }
Beispiel #7
0
        private static void RecursiveRender(
            EventBean theEvent,
            StringBuilder buf,
            int level,
            RendererMeta meta,
            RendererMetaOptions rendererMetaOptions)
        {
            foreach (var simpleProp in meta.SimpleProperties.OrderBy(p => p.Name)) {
                var value = simpleProp.Getter.Get(theEvent);

                if (value == null) {
                    continue;
                }

                Ident(buf, level);
                buf.Append('<');
                buf.Append(simpleProp.Name);
                buf.Append('>');

                if (rendererMetaOptions.Renderer == null) {
                    simpleProp.Output.Render(value, buf);
                }
                else {
                    var context = rendererMetaOptions.RendererContext;
                    context.SetStringBuilderAndReset(buf);
                    context.PropertyName = simpleProp.Name;
                    context.PropertyValue = value;
                    context.DefaultRenderer = simpleProp.Output;
                    rendererMetaOptions.Renderer.Render(context);
                }

                buf.Append("</");
                buf.Append(simpleProp.Name);
                buf.Append('>');
                buf.Append(Newline);
            }

            foreach (var indexProp in meta.IndexProperties.OrderBy(p => p.Name)) {
                var value = indexProp.Getter.Get(theEvent);

                if (value == null) {
                    continue;
                }

                // Strings are rendered like simple properties
                if (value is string) {
                    Ident(buf, level);
                    buf.Append('<');
                    buf.Append(indexProp.Name);
                    buf.Append('>');

                    if (rendererMetaOptions.Renderer == null) {
                        indexProp.Output.Render(value, buf);
                    }
                    else {
                        var context = rendererMetaOptions.RendererContext;
                        context.SetStringBuilderAndReset(buf);
                        context.PropertyName = indexProp.Name;
                        context.PropertyValue = value;
                        context.DefaultRenderer = indexProp.Output;
                        rendererMetaOptions.Renderer.Render(context);
                    }

                    buf.Append("</");
                    buf.Append(indexProp.Name);
                    buf.Append('>');
                    buf.Append(Newline);
                }
                // Arrays
                else if (value is Array array) {
                    for (var i = 0; i < array.Length; i++) {
                        var arrayItem = array.GetValue(i);
                        if (arrayItem == null) {
                            continue;
                        }

                        Ident(buf, level);
                        buf.Append('<');
                        buf.Append(indexProp.Name);
                        buf.Append('>');
                        if (rendererMetaOptions.Renderer == null) {
                            indexProp.Output.Render(arrayItem, buf);
                        }
                        else {
                            var context = rendererMetaOptions.RendererContext;
                            context.SetStringBuilderAndReset(buf);
                            context.PropertyName = indexProp.Name;
                            context.PropertyValue = arrayItem;
                            context.IndexedPropertyIndex = i;
                            context.DefaultRenderer = indexProp.Output;
                            rendererMetaOptions.Renderer.Render(context);
                        }

                        buf.Append("</");
                        buf.Append(indexProp.Name);
                        buf.Append('>');
                        buf.Append(Newline);
                    }
                }
                // Lists
                else if (value.GetType().IsGenericList()) {
                    // All lists are generically enumerable
                    int listItemIndex = 0;
                    foreach (var listItem in value.UnwrapEnumerable<object>()) {
                        if (listItem != null) {
                            Ident(buf, level);
                            buf.Append('<');
                            buf.Append(indexProp.Name);
                            buf.Append('>');
                            if (rendererMetaOptions.Renderer == null)
                            {
                                indexProp.Output.Render(listItem, buf);
                            }
                            else
                            {
                                var context = rendererMetaOptions.RendererContext;
                                context.SetStringBuilderAndReset(buf);
                                context.PropertyName = indexProp.Name;
                                context.PropertyValue = listItem;
                                context.IndexedPropertyIndex = listItemIndex;
                                context.DefaultRenderer = indexProp.Output;
                                rendererMetaOptions.Renderer.Render(context);
                            }

                            buf.Append("</");
                            buf.Append(indexProp.Name);
                            buf.Append('>');
                            buf.Append(Newline);
                        }

                        listItemIndex++;
                    }
                }
                else {
                    Log.Warn("Property '" + indexProp.Name + "' returned a non-array object");
                }
            }

            foreach (var mappedProp in meta.MappedProperties.OrderBy(p => p.Name)) {
                var value = mappedProp.Getter.Get(theEvent);

                if (value != null && !(value is IDictionary<string, object>)) {
                    Log.Warn(
                        "Property '" +
                        mappedProp.Name +
                        "' expected to return Map and returned " +
                        value.GetType() +
                        " instead");
                    continue;
                }

                Ident(buf, level);
                buf.Append('<');
                buf.Append(mappedProp.Name);
                buf.Append('>');
                buf.Append(Newline);

                if (value != null) {
                    var map = (IDictionary<string, object>) value;
                    if (!map.IsEmpty()) {
                        var localDelimiter = "";
                        foreach (var entry in map)
                        {
                            if (entry.Key == null) {
                                continue;
                            }

                            buf.Append(localDelimiter);
                            Ident(buf, level + 1);
                            buf.Append('<');
                            buf.Append(entry.Key);
                            buf.Append('>');

                            if (entry.Value != null) {
                                var outputValueRenderer =
                                    OutputValueRendererFactory.GetOutputValueRenderer(
                                        entry.Value.GetType(),
                                        rendererMetaOptions);
                                if (rendererMetaOptions.Renderer == null) {
                                    outputValueRenderer.Render(entry.Value, buf);
                                }
                                else {
                                    var context = rendererMetaOptions.RendererContext;
                                    context.SetStringBuilderAndReset(buf);
                                    context.PropertyName = mappedProp.Name;
                                    context.PropertyValue = entry.Value;
                                    context.MappedPropertyKey = entry.Key;
                                    context.DefaultRenderer = outputValueRenderer;
                                    rendererMetaOptions.Renderer.Render(context);
                                }
                            }

                            buf.Append("</");
                            buf.Append(entry.Key);
                            buf.Append('>');
                            localDelimiter = Newline;
                        }
                    }
                }

                buf.Append(Newline);
                Ident(buf, level);
                buf.Append("</");
                buf.Append(mappedProp.Name);
                buf.Append('>');
                buf.Append(Newline);
            }

            var nestedProps = meta.NestedProperties;
            foreach (var nestedProp in nestedProps.OrderBy(p => p.Name)) {
                var value = nestedProp.Getter.GetFragment(theEvent);

                if (value == null) {
                    continue;
                }

                if (!nestedProp.IsArray) {
                    if (!(value is EventBean)) {
                        Log.Warn(
                            "Property '" +
                            nestedProp.Name +
                            "' expected to return EventBean and returned " +
                            value.GetType() +
                            " instead");
                        buf.Append("null");
                        continue;
                    }

                    RenderElementFragment((EventBean) value, buf, level, nestedProp, rendererMetaOptions);
                }
                else {
                    if (!(value is EventBean[])) {
                        Log.Warn(
                            "Property '" +
                            nestedProp.Name +
                            "' expected to return EventBean[] and returned " +
                            value.GetType() +
                            " instead");
                        buf.Append("null");
                        continue;
                    }

                    var nestedEventArray = (EventBean[]) value;
                    for (var i = 0; i < nestedEventArray.Length; i++) {
                        var arrayItem = nestedEventArray[i];
                        if (arrayItem == null) {
                            continue;
                        }

                        RenderElementFragment(arrayItem, buf, level, nestedProp, rendererMetaOptions);
                    }
                }
            }
        }
Beispiel #8
0
        private string RenderAttElements(
            EventBean theEvent,
            int level,
            RendererMeta meta)
        {
            var buf = new StringBuilder();

            var indexProps = meta.IndexProperties;
            foreach (var indexProp in indexProps) {
                var value = indexProp.Getter.Get(theEvent);

                if (value == null) {
                    continue;
                }

                var array = value as Array;
                if (array == null) {
                    Log.Warn("Property '" + indexProp.Name + "' returned a non-array object");
                    continue;
                }

                for (var i = 0; i < array.Length; i++) {
                    var arrayItem = array.GetValue(i);

                    if (arrayItem == null) {
                        continue;
                    }

                    Ident(buf, level);
                    buf.Append('<');
                    buf.Append(indexProp.Name);
                    buf.Append('>');
                    if (rendererMetaOptions.Renderer == null) {
                        indexProp.Output.Render(arrayItem, buf);
                    }
                    else {
                        var context = rendererMetaOptions.RendererContext;
                        context.SetStringBuilderAndReset(buf);
                        context.PropertyName = indexProp.Name;
                        context.PropertyValue = arrayItem;
                        context.IndexedPropertyIndex = i;
                        context.DefaultRenderer = indexProp.Output;
                        rendererMetaOptions.Renderer.Render(context);
                    }

                    buf.Append("</");
                    buf.Append(indexProp.Name);
                    buf.Append('>');
                    buf.Append(Newline);
                }
            }

            var mappedProps = meta.MappedProperties;
            foreach (var mappedProp in mappedProps) {
                var value = mappedProp.Getter.Get(theEvent);

                if (value != null && !(value is IDictionary<string, object>)) {
                    Log.Warn(
                        "Property '" +
                        mappedProp.Name +
                        "' expected to return Map and returned " +
                        value.GetType() +
                        " instead");
                    continue;
                }

                Ident(buf, level);
                buf.Append('<');
                buf.Append(mappedProp.Name);

                if (value != null) {
                    var map = value.AsStringDictionary();
                    if (!map.IsEmpty()) {
                        using (var enumerator = map.GetEnumerator()) {
                            while (enumerator.MoveNext()) {
                                var entry = enumerator.Current;
                                if (entry.Key == null || entry.Value == null) {
                                    continue;
                                }

                                buf.Append(" ");
                                buf.Append(entry.Key);
                                buf.Append("=\"");
                                var outputValueRenderer =
                                    OutputValueRendererFactory.GetOutputValueRenderer(
                                        entry.Value.GetType(),
                                        rendererMetaOptions);

                                if (rendererMetaOptions.Renderer == null) {
                                    outputValueRenderer.Render(entry.Value, buf);
                                }
                                else {
                                    var context = rendererMetaOptions.RendererContext;
                                    context.SetStringBuilderAndReset(buf);
                                    context.PropertyName = mappedProp.Name;
                                    context.PropertyValue = entry.Value;
                                    context.MappedPropertyKey = entry.Key;
                                    context.DefaultRenderer = outputValueRenderer;
                                    rendererMetaOptions.Renderer.Render(context);
                                }

                                buf.Append("\"");
                            }
                        }
                    }
                }

                buf.Append("/>");
                buf.Append(Newline);
            }

            var nestedProps = meta.NestedProperties;
            foreach (var nestedProp in nestedProps) {
                var value = nestedProp.Getter.GetFragment(theEvent);

                if (value == null) {
                    continue;
                }

                if (!nestedProp.IsArray) {
                    if (!(value is EventBean)) {
                        Log.Warn(
                            "Property '" +
                            nestedProp.Name +
                            "' expected to return EventBean and returned " +
                            value.GetType() +
                            " instead");
                        buf.Append("null");
                        continue;
                    }

                    var nestedEventBean = (EventBean) value;
                    RenderAttInner(buf, level, nestedEventBean, nestedProp);
                }
                else {
                    if (!(value is EventBean[])) {
                        Log.Warn(
                            "Property '" +
                            nestedProp.Name +
                            "' expected to return EventBean[] and returned " +
                            value.GetType() +
                            " instead");
                        buf.Append("null");
                        continue;
                    }

                    var nestedEventArray = (EventBean[]) value;
                    for (var i = 0; i < nestedEventArray.Length; i++) {
                        var arrayItem = nestedEventArray[i];
                        RenderAttInner(buf, level, arrayItem, nestedProp);
                    }
                }
            }

            return buf.ToString();
        }