com.espertech.esper.event.util.JSONRendererImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.espertech.esper.event.util.JSONRendererImpl.java

Source

/*
 * *************************************************************************************
 *  Copyright (C) 2008 EsperTech, Inc. All rights reserved.                            *
 *  http://esper.codehaus.org                                                          *
 *  http://www.espertech.com                                                           *
 *  ---------------------------------------------------------------------------------- *
 *  The software in this package is published under the terms of the GPL license       *
 *  a copy of which has been included with this distribution in the license.txt file.  *
 * *************************************************************************************
 */

package com.espertech.esper.event.util;

import com.espertech.esper.client.EventBean;
import com.espertech.esper.client.EventType;
import com.espertech.esper.client.util.EventPropertyRenderer;
import com.espertech.esper.client.util.EventPropertyRendererContext;
import com.espertech.esper.client.util.JSONEventRenderer;
import com.espertech.esper.client.util.JSONRenderingOptions;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.lang.reflect.Array;
import java.util.Iterator;
import java.util.Map;
import java.util.Stack;

/**
 * Render for the JSON format.
 */
public class JSONRendererImpl implements JSONEventRenderer {
    private static final Log log = LogFactory.getLog(JSONRendererImpl.class);

    private final static String NEWLINE = System.getProperty("line.separator");
    private final static String COMMA_DELIMITER_NEWLINE = "," + NEWLINE;

    private final RendererMeta meta;
    private final RendererMetaOptions rendererOptions;

    /**
     * Ctor.
     * @param eventType type of event(s)
     * @param options rendering options
     */
    public JSONRendererImpl(EventType eventType, JSONRenderingOptions options) {
        EventPropertyRenderer propertyRenderer = null;
        EventPropertyRendererContext propertyRendererContext = null;
        if (options.getRenderer() != null) {
            propertyRenderer = options.getRenderer();
            propertyRendererContext = new EventPropertyRendererContext(eventType, true);
        }

        rendererOptions = new RendererMetaOptions(options.isPreventLooping(), false, propertyRenderer,
                propertyRendererContext);
        meta = new RendererMeta(eventType, new Stack<EventTypePropertyPair>(), rendererOptions);
    }

    public String render(String title, EventBean theEvent) {
        StringBuilder buf = new StringBuilder();
        buf.append('{');
        buf.append(NEWLINE);

        ident(buf, 1);
        buf.append('\"');
        buf.append(title);
        buf.append("\": {");
        buf.append(NEWLINE);

        recursiveRender(theEvent, buf, 2, meta, rendererOptions);

        ident(buf, 1);
        buf.append('}');
        buf.append(NEWLINE);

        buf.append('}');
        buf.append(NEWLINE);

        return buf.toString();
    }

    public String render(EventBean theEvent) {
        StringBuilder buf = new StringBuilder();
        buf.append('{');
        recursiveRender(theEvent, buf, 2, meta, rendererOptions);
        buf.append('}');
        return buf.toString();
    }

    private static void ident(StringBuilder buf, int level) {
        for (int i = 0; i < level; i++) {
            indentChar(buf);
        }
    }

    private static void indentChar(StringBuilder buf) {
        buf.append(' ');
        buf.append(' ');
    }

    private static void recursiveRender(EventBean theEvent, StringBuilder buf, int level, RendererMeta meta,
            RendererMetaOptions rendererOptions) {
        String delimiter = "";

        // simple properties
        GetterPair[] simpleProps = meta.getSimpleProperties();
        if (rendererOptions.getRenderer() == null) {
            for (GetterPair simpleProp : simpleProps) {
                Object value = simpleProp.getGetter().get(theEvent);
                writeDelimitedIndentedProp(buf, delimiter, level, simpleProp.getName());
                simpleProp.getOutput().render(value, buf);
                delimiter = COMMA_DELIMITER_NEWLINE;
            }
        } else {
            EventPropertyRendererContext context = rendererOptions.getRendererContext();
            context.setStringBuilderAndReset(buf);
            for (GetterPair simpleProp : simpleProps) {
                Object value = simpleProp.getGetter().get(theEvent);
                writeDelimitedIndentedProp(buf, delimiter, level, simpleProp.getName());
                context.setDefaultRenderer(simpleProp.getOutput());
                context.setPropertyName(simpleProp.getName());
                context.setPropertyValue(value);
                rendererOptions.getRenderer().render(context);
                delimiter = COMMA_DELIMITER_NEWLINE;
            }
        }

        GetterPair[] indexProps = meta.getIndexProperties();
        for (GetterPair indexProp : indexProps) {
            Object value = indexProp.getGetter().get(theEvent);
            writeDelimitedIndentedProp(buf, delimiter, level, indexProp.getName());

            if (value == null) {
                buf.append("null");
            } else {
                if (!value.getClass().isArray()) {
                    buf.append("[]");
                } else {
                    buf.append('[');
                    String arrayDelimiter = "";

                    if (rendererOptions.getRenderer() == null) {
                        for (int i = 0; i < Array.getLength(value); i++) {
                            Object arrayItem = Array.get(value, i);
                            buf.append(arrayDelimiter);
                            indexProp.getOutput().render(arrayItem, buf);
                            arrayDelimiter = ", ";
                        }
                    } else {
                        EventPropertyRendererContext context = rendererOptions.getRendererContext();
                        context.setStringBuilderAndReset(buf);
                        for (int i = 0; i < Array.getLength(value); i++) {
                            Object arrayItem = Array.get(value, i);
                            buf.append(arrayDelimiter);
                            context.setPropertyName(indexProp.getName());
                            context.setPropertyValue(arrayItem);
                            context.setIndexedPropertyIndex(i);
                            context.setDefaultRenderer(indexProp.getOutput());
                            rendererOptions.getRenderer().render(context);
                            arrayDelimiter = ", ";
                        }
                    }
                    buf.append(']');
                }
            }
            delimiter = COMMA_DELIMITER_NEWLINE;
        }

        GetterPair[] mappedProps = meta.getMappedProperties();
        for (GetterPair mappedProp : mappedProps) {
            Object value = mappedProp.getGetter().get(theEvent);

            if ((value != null) && (!(value instanceof Map))) {
                log.warn("Property '" + mappedProp.getName() + "' expected to return Map and returned "
                        + value.getClass() + " instead");
                continue;
            }

            writeDelimitedIndentedProp(buf, delimiter, level, mappedProp.getName());

            if (value == null) {
                buf.append("null");
                buf.append(NEWLINE);
            } else {
                Map<String, Object> map = (Map<String, Object>) value;
                if (map.isEmpty()) {
                    buf.append("{}");
                    buf.append(NEWLINE);
                } else {
                    buf.append('{');
                    buf.append(NEWLINE);

                    String localDelimiter = "";
                    Iterator<Map.Entry<String, Object>> it = map.entrySet().iterator();
                    for (; it.hasNext();) {
                        Map.Entry<String, Object> entry = it.next();
                        if (entry.getKey() == null) {
                            continue;
                        }

                        buf.append(localDelimiter);
                        ident(buf, level + 1);
                        buf.append('\"');
                        buf.append(entry.getKey());
                        buf.append("\": ");

                        if (entry.getValue() == null) {
                            buf.append("null");
                        } else {
                            OutputValueRenderer outRenderer = OutputValueRendererFactory
                                    .getOutputValueRenderer(entry.getValue().getClass(), rendererOptions);
                            if (rendererOptions.getRenderer() == null) {
                                outRenderer.render(entry.getValue(), buf);
                            } else {
                                EventPropertyRendererContext context = rendererOptions.getRendererContext();
                                context.setStringBuilderAndReset(buf);
                                context.setPropertyName(mappedProp.getName());
                                context.setPropertyValue(entry.getValue());
                                context.setMappedPropertyKey(entry.getKey());
                                context.setDefaultRenderer(outRenderer);
                                rendererOptions.getRenderer().render(context);
                            }
                        }
                        localDelimiter = COMMA_DELIMITER_NEWLINE;
                    }

                    buf.append(NEWLINE);
                    ident(buf, level);
                    buf.append('}');
                }
            }

            delimiter = COMMA_DELIMITER_NEWLINE;
        }

        NestedGetterPair[] nestedProps = meta.getNestedProperties();
        for (NestedGetterPair nestedProp : nestedProps) {
            Object value = nestedProp.getGetter().getFragment(theEvent);

            writeDelimitedIndentedProp(buf, delimiter, level, nestedProp.getName());

            if (value == null) {
                buf.append("null");
            } else if (!nestedProp.isArray()) {
                if (!(value instanceof EventBean)) {
                    log.warn("Property '" + nestedProp.getName() + "' expected to return EventBean and returned "
                            + value.getClass() + " instead");
                    buf.append("null");
                    continue;
                }
                EventBean nestedEventBean = (EventBean) value;
                buf.append('{');
                buf.append(NEWLINE);

                recursiveRender(nestedEventBean, buf, level + 1, nestedProp.getMetadata(), rendererOptions);

                ident(buf, level);
                buf.append('}');
            } else {
                if (!(value instanceof EventBean[])) {
                    log.warn("Property '" + nestedProp.getName() + "' expected to return EventBean[] and returned "
                            + value.getClass() + " instead");
                    buf.append("null");
                    continue;
                }

                StringBuilder arrayDelimiterBuf = new StringBuilder();
                arrayDelimiterBuf.append(',');
                arrayDelimiterBuf.append(NEWLINE);
                ident(arrayDelimiterBuf, level + 1);

                EventBean[] nestedEventArray = (EventBean[]) value;
                String arrayDelimiter = "";
                buf.append('[');

                for (int i = 0; i < nestedEventArray.length; i++) {
                    EventBean arrayItem = nestedEventArray[i];
                    buf.append(arrayDelimiter);
                    arrayDelimiter = arrayDelimiterBuf.toString();

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

                    recursiveRender(arrayItem, buf, level + 2, nestedProp.getMetadata(), rendererOptions);

                    ident(buf, level + 1);
                    buf.append('}');
                }
                buf.append(']');
            }
            delimiter = COMMA_DELIMITER_NEWLINE;
        }

        buf.append(NEWLINE);
    }

    private static void writeDelimitedIndentedProp(StringBuilder buf, String delimiter, int level, String name) {
        buf.append(delimiter);
        ident(buf, level);
        buf.append('\"');
        buf.append(name);
        buf.append("\": ");
    }
}