001/**
002 * Logback: the reliable, generic, fast and flexible logging framework.
003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
004 *
005 * This program and the accompanying materials are dual-licensed under
006 * either the terms of the Eclipse Public License v1.0 as published by
007 * the Eclipse Foundation
008 *
009 *   or (per the licensee's choosing)
010 *
011 * under the terms of the GNU Lesser General Public License version 2.1
012 * as published by the Free Software Foundation.
013 */
014package ch.qos.logback.classic.boolex;
015
016import java.util.ArrayList;
017import java.util.List;
018import java.util.Map;
019
020import ch.qos.logback.classic.Level;
021import ch.qos.logback.classic.spi.ILoggingEvent;
022import ch.qos.logback.classic.spi.IThrowableProxy;
023import ch.qos.logback.classic.spi.LoggerContextVO;
024import ch.qos.logback.classic.spi.ThrowableProxy;
025import ch.qos.logback.core.CoreConstants;
026import ch.qos.logback.core.boolex.JaninoEventEvaluatorBase;
027import ch.qos.logback.core.boolex.Matcher;
028import org.slf4j.Marker;
029
030public class JaninoEventEvaluator extends JaninoEventEvaluatorBase<ILoggingEvent> {
031
032    public final static String IMPORT_LEVEL = "import ch.qos.logback.classic.Level;\r\n";
033
034    public final static List<String> DEFAULT_PARAM_NAME_LIST = new ArrayList<>();
035    public final static List<Class<?>> DEFAULT_PARAM_TYPE_LIST = new ArrayList<>();
036
037    static {
038        DEFAULT_PARAM_NAME_LIST.add("DEBUG");
039        DEFAULT_PARAM_NAME_LIST.add("INFO");
040        DEFAULT_PARAM_NAME_LIST.add("WARN");
041        DEFAULT_PARAM_NAME_LIST.add("ERROR");
042
043        DEFAULT_PARAM_NAME_LIST.add("event");
044        DEFAULT_PARAM_NAME_LIST.add("message");
045
046        DEFAULT_PARAM_NAME_LIST.add("formattedMessage");
047        DEFAULT_PARAM_NAME_LIST.add("logger");
048        DEFAULT_PARAM_NAME_LIST.add("loggerContext");
049        DEFAULT_PARAM_NAME_LIST.add("level");
050        DEFAULT_PARAM_NAME_LIST.add("timeStamp");
051        DEFAULT_PARAM_NAME_LIST.add("marker");
052        DEFAULT_PARAM_NAME_LIST.add("markerList");
053        DEFAULT_PARAM_NAME_LIST.add("mdc");
054        DEFAULT_PARAM_NAME_LIST.add("throwableProxy");
055        DEFAULT_PARAM_NAME_LIST.add("throwable");
056
057        DEFAULT_PARAM_TYPE_LIST.add(int.class);
058        DEFAULT_PARAM_TYPE_LIST.add(int.class);
059        DEFAULT_PARAM_TYPE_LIST.add(int.class);
060        DEFAULT_PARAM_TYPE_LIST.add(int.class);
061
062        DEFAULT_PARAM_TYPE_LIST.add(ILoggingEvent.class);
063        DEFAULT_PARAM_TYPE_LIST.add(String.class);
064        DEFAULT_PARAM_TYPE_LIST.add(String.class);
065        DEFAULT_PARAM_TYPE_LIST.add(String.class);
066        DEFAULT_PARAM_TYPE_LIST.add(LoggerContextVO.class);
067        DEFAULT_PARAM_TYPE_LIST.add(int.class);
068        DEFAULT_PARAM_TYPE_LIST.add(long.class);
069        DEFAULT_PARAM_TYPE_LIST.add(Marker.class);
070        DEFAULT_PARAM_TYPE_LIST.add(MarkerList.class);
071        DEFAULT_PARAM_TYPE_LIST.add(Map.class);
072        DEFAULT_PARAM_TYPE_LIST.add(IThrowableProxy.class);
073        DEFAULT_PARAM_TYPE_LIST.add(Throwable.class);
074    }
075
076    protected String getDecoratedExpression() {
077        String expression = getExpression();
078        if (!expression.contains("return")) {
079            expression = "return " + expression + ";";
080            addInfo("Adding [return] prefix and a semicolon suffix. Expression becomes [" + expression + "]");
081            addInfo("See also " + CoreConstants.CODES_URL + "#block");
082
083        }
084        return IMPORT_LEVEL + expression;
085    }
086
087    protected String[] getParameterNames() {
088        List<String> fullNameList = new ArrayList<String>();
089        fullNameList.addAll(DEFAULT_PARAM_NAME_LIST);
090
091        for (int i = 0; i < matcherList.size(); i++) {
092            Matcher m = (Matcher) matcherList.get(i);
093            fullNameList.add(m.getName());
094        }
095
096        return (String[]) fullNameList.toArray(CoreConstants.EMPTY_STRING_ARRAY);
097    }
098
099    protected Class<?>[] getParameterTypes() {
100        List<Class<?>> fullTypeList = new ArrayList<>();
101        fullTypeList.addAll(DEFAULT_PARAM_TYPE_LIST);
102        for (int i = 0; i < matcherList.size(); i++) {
103            fullTypeList.add(Matcher.class);
104        }
105        return (Class[]) fullTypeList.toArray(CoreConstants.EMPTY_CLASS_ARRAY);
106    }
107
108    protected Object[] getParameterValues(ILoggingEvent loggingEvent) {
109        final int matcherListSize = matcherList.size();
110
111        int i = 0;
112        Object[] values = new Object[DEFAULT_PARAM_NAME_LIST.size() + matcherListSize];
113
114        values[i++] = Level.DEBUG_INTEGER;
115        values[i++] = Level.INFO_INTEGER;
116        values[i++] = Level.WARN_INTEGER;
117        values[i++] = Level.ERROR_INTEGER;
118
119        values[i++] = loggingEvent;
120        values[i++] = loggingEvent.getMessage();
121        values[i++] = loggingEvent.getFormattedMessage();
122        values[i++] = loggingEvent.getLoggerName();
123        values[i++] = loggingEvent.getLoggerContextVO();
124        values[i++] = loggingEvent.getLevel().toInteger();
125        values[i++] = loggingEvent.getTimeStamp();
126//        // In order to avoid NullPointerException, we could push a dummy marker if
127//        // the event's marker is null. However, this would surprise user who
128//        // expect to see a null marker instead of a dummy one.
129
130        MarkerList markerList = new MarkerList(loggingEvent.getMarkerList());
131        Marker marker = markerList.getFirstMarker();
132        values[i++] = marker;
133        values[i++] = markerList;
134
135        values[i++] = loggingEvent.getMDCPropertyMap();
136
137        IThrowableProxy iThrowableProxy = loggingEvent.getThrowableProxy();
138
139        if (iThrowableProxy != null) {
140            values[i++] = iThrowableProxy;
141            if (iThrowableProxy instanceof ThrowableProxy) {
142                values[i++] = ((ThrowableProxy) iThrowableProxy).getThrowable();
143            } else {
144                values[i++] = null;
145            }
146        } else {
147            values[i++] = null;
148            values[i++] = null;
149        }
150
151        for (int j = 0; j < matcherListSize; j++) {
152            values[i++] = (Matcher) matcherList.get(j);
153        }
154
155        return values;
156    }
157}