com.espertech.esper.dataflow.ops.LogSink.java Source code

Java tutorial

Introduction

Here is the source code for com.espertech.esper.dataflow.ops.LogSink.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.dataflow.ops;

import com.espertech.esper.client.EPRuntime;
import com.espertech.esper.client.EventBean;
import com.espertech.esper.client.EventType;
import com.espertech.esper.client.util.*;
import com.espertech.esper.dataflow.annotations.DataFlowOpParameter;
import com.espertech.esper.dataflow.annotations.DataFlowOperator;
import com.espertech.esper.dataflow.interfaces.*;
import com.espertech.esper.epl.expression.ExprValidationException;
import com.espertech.esper.event.EventBeanSPI;
import com.espertech.esper.event.EventBeanUtility;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.StringWriter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

@DataFlowOperator
public class LogSink implements DataFlowOpLifecycle {

    private static final Log logme = LogFactory.getLog(LogSink.class);

    @DataFlowOpParameter
    private String title;

    @DataFlowOpParameter
    private String layout;

    @DataFlowOpParameter
    private String format;

    @DataFlowOpParameter
    private boolean log = true;

    @DataFlowOpParameter
    private boolean linefeed = true;

    private String dataflowName;
    private String dataFlowInstanceId;
    private ConsoleOpRenderer renderer;

    private EventBeanSPI[] shellPerStream;

    public DataFlowOpInitializeResult initialize(DataFlowOpInitializateContext context) throws Exception {
        if (!context.getOutputPorts().isEmpty()) {
            throw new IllegalArgumentException("LogSink operator does not provide an output stream");
        }

        dataflowName = context.getDataflowName();
        dataFlowInstanceId = context.getDataflowInstanceId();

        shellPerStream = new EventBeanSPI[context.getInputPorts().size()];
        for (Map.Entry<Integer, DataFlowOpInputPort> entry : context.getInputPorts().entrySet()) {
            EventType eventType = entry.getValue().getTypeDesc().getEventType();
            if (eventType != null) {
                shellPerStream[entry.getKey()] = context.getStatementContext().getEventAdapterService()
                        .getShellForType(eventType);
            }
        }

        if (format == null) {
            renderer = new ConsoleOpRendererSummary();
        } else {
            try {
                LogSinkOutputFormat formatEnum = LogSinkOutputFormat.valueOf(format.trim().toLowerCase());
                if (formatEnum == LogSinkOutputFormat.summary) {
                    renderer = new ConsoleOpRendererSummary();
                } else {
                    renderer = new ConsoleOpRendererXmlJSon(formatEnum, context.getEngine().getEPRuntime());
                }
            } catch (RuntimeException ex) {
                throw new ExprValidationException("Format '" + format + "' is not supported, expecting any of "
                        + Arrays.toString(LogSinkOutputFormat.values()));
            }
        }

        return null;
    }

    public void open(DataFlowOpOpenContext openContext) {
    }

    public void close(DataFlowOpCloseContext openContext) {
    }

    public void onInput(int port, Object theEvent) {

        String line;
        if (layout == null) {

            StringWriter writer = new StringWriter();

            writer.write("[");
            writer.write(dataflowName);
            writer.write("] ");

            if (title != null) {
                writer.write("[");
                writer.write(title);
                writer.write("] ");
            }

            if (dataFlowInstanceId != null) {
                writer.write("[");
                writer.write(dataFlowInstanceId);
                writer.write("] ");
            }

            writer.write("[port ");
            writer.write(Integer.toString(port));
            writer.write("] ");

            getEventOut(port, theEvent, writer);
            line = writer.toString();
        } else {
            String result = layout.replace("%df", dataflowName).replace("%p", Integer.toString(port));
            if (dataFlowInstanceId != null) {
                result = result.replace("%i", dataFlowInstanceId);
            }
            if (title != null) {
                result = result.replace("%t", title);
            }

            StringWriter writer = new StringWriter();
            getEventOut(port, theEvent, writer);
            result = result.replace("%e", writer.toString());

            line = result;
        }

        if (!linefeed) {
            line = line.replaceAll("\n", "").replaceAll("\r", "");
        }

        // output
        if (log) {
            logme.info(line);
        } else {
            System.out.println(line);
        }
    }

    private void getEventOut(int port, Object theEvent, StringWriter writer) {

        if (theEvent instanceof EventBean) {
            renderer.render((EventBean) theEvent, writer);
            return;
        }

        if (shellPerStream[port] != null) {
            synchronized (this) {
                shellPerStream[port].setUnderlying(theEvent);
                renderer.render(shellPerStream[port], writer);
            }
            return;
        }

        writer.write("Unrecognized underlying: ");
        writer.write(theEvent.toString());
    }

    public static enum LogSinkOutputFormat {
        json, xml, summary
    }

    public interface ConsoleOpRenderer {
        public void render(EventBean eventBean, StringWriter writer);
    }

    public static class ConsoleOpRendererSummary implements ConsoleOpRenderer {
        public void render(EventBean theEvent, StringWriter writer) {
            EventBeanUtility.summarize(theEvent, writer);
        }
    }

    public static class ConsoleOpRendererXmlJSon implements ConsoleOpRenderer {
        private final LogSinkOutputFormat format;
        private final EPRuntime runtime;

        private final Map<EventType, JSONEventRenderer> jsonRendererCache = new HashMap<EventType, JSONEventRenderer>();
        private final Map<EventType, XMLEventRenderer> xmlRendererCache = new HashMap<EventType, XMLEventRenderer>();

        public ConsoleOpRendererXmlJSon(LogSinkOutputFormat format, EPRuntime runtime) {
            this.format = format;
            this.runtime = runtime;
        }

        public void render(EventBean theEvent, StringWriter writer) {
            String result;
            if (format == LogSinkOutputFormat.json) {
                JSONEventRenderer renderer = jsonRendererCache.get(theEvent.getEventType());
                if (renderer == null) {
                    renderer = getJsonRenderer(theEvent.getEventType());
                    jsonRendererCache.put(theEvent.getEventType(), renderer);
                }
                result = renderer.render(theEvent.getEventType().getName(), theEvent);
            } else {
                XMLEventRenderer renderer = xmlRendererCache.get(theEvent.getEventType());
                if (renderer == null) {
                    renderer = getXmlRenderer(theEvent.getEventType());
                    xmlRendererCache.put(theEvent.getEventType(), renderer);
                }
                result = renderer.render(theEvent.getEventType().getName(), theEvent);
            }
            writer.append(result);
        }

        protected JSONEventRenderer getJsonRenderer(EventType eventType) {
            return runtime.getEventRenderer().getJSONRenderer(eventType, RenderingOptions.getJsonOptions());
        }

        protected XMLEventRenderer getXmlRenderer(EventType eventType) {
            return runtime.getEventRenderer().getXMLRenderer(eventType, RenderingOptions.getXmlOptions());
        }
    }

    public static class RenderingOptions {
        private static XMLRenderingOptions xmlOptions;
        private static JSONRenderingOptions jsonOptions;

        static {
            xmlOptions = new XMLRenderingOptions();
            xmlOptions.setPreventLooping(true);
            xmlOptions.setRenderer(ConsoleOpEventPropertyRenderer.INSTANCE);

            jsonOptions = new JSONRenderingOptions();
            jsonOptions.setPreventLooping(true);
            jsonOptions.setRenderer(ConsoleOpEventPropertyRenderer.INSTANCE);
        }

        public static XMLRenderingOptions getXmlOptions() {
            return xmlOptions;
        }

        public static void setXmlOptions(XMLRenderingOptions xmlOptions) {
            RenderingOptions.xmlOptions = xmlOptions;
        }

        public static JSONRenderingOptions getJsonOptions() {
            return jsonOptions;
        }

        public static void setJsonOptions(JSONRenderingOptions jsonOptions) {
            RenderingOptions.jsonOptions = jsonOptions;
        }
    }

    public static class ConsoleOpEventPropertyRenderer implements EventPropertyRenderer {
        public static ConsoleOpEventPropertyRenderer INSTANCE = new ConsoleOpEventPropertyRenderer();

        public void render(EventPropertyRendererContext context) {
            if (context.getPropertyValue() instanceof Object[]) {
                context.getStringBuilder().append(Arrays.toString((Object[]) context.getPropertyValue()));
            } else {
                context.getDefaultRenderer().render(context.getPropertyValue(), context.getStringBuilder());
            }
        }
    }
}