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;
028
029public class JaninoEventEvaluator extends JaninoEventEvaluatorBase<ILoggingEvent> {
030
031    public final static String IMPORT_LEVEL = "import ch.qos.logback.classic.Level;\r\n";
032
033    public final static List<String> DEFAULT_PARAM_NAME_LIST = new ArrayList<>();
034    public final static List<Class<?>> DEFAULT_PARAM_TYPE_LIST = new ArrayList<>();
035
036    static {
037        DEFAULT_PARAM_NAME_LIST.add("DEBUG");
038        DEFAULT_PARAM_NAME_LIST.add("INFO");
039        DEFAULT_PARAM_NAME_LIST.add("WARN");
040        DEFAULT_PARAM_NAME_LIST.add("ERROR");
041
042        DEFAULT_PARAM_NAME_LIST.add("event");
043        DEFAULT_PARAM_NAME_LIST.add("message");
044
045        DEFAULT_PARAM_NAME_LIST.add("formattedMessage");
046        DEFAULT_PARAM_NAME_LIST.add("logger");
047        DEFAULT_PARAM_NAME_LIST.add("loggerContext");
048        DEFAULT_PARAM_NAME_LIST.add("level");
049        DEFAULT_PARAM_NAME_LIST.add("timeStamp");
050        // DEFAULT_PARAM_NAME_LIST.add("markerList");
051        DEFAULT_PARAM_NAME_LIST.add("mdc");
052        DEFAULT_PARAM_NAME_LIST.add("throwableProxy");
053        DEFAULT_PARAM_NAME_LIST.add("throwable");
054
055        DEFAULT_PARAM_TYPE_LIST.add(int.class);
056        DEFAULT_PARAM_TYPE_LIST.add(int.class);
057        DEFAULT_PARAM_TYPE_LIST.add(int.class);
058        DEFAULT_PARAM_TYPE_LIST.add(int.class);
059
060        DEFAULT_PARAM_TYPE_LIST.add(ILoggingEvent.class);
061        DEFAULT_PARAM_TYPE_LIST.add(String.class);
062        DEFAULT_PARAM_TYPE_LIST.add(String.class);
063        DEFAULT_PARAM_TYPE_LIST.add(String.class);
064        DEFAULT_PARAM_TYPE_LIST.add(LoggerContextVO.class);
065        DEFAULT_PARAM_TYPE_LIST.add(int.class);
066        DEFAULT_PARAM_TYPE_LIST.add(long.class);
067        // DEFAULT_PARAM_TYPE_LIST.add(List.class);
068        DEFAULT_PARAM_TYPE_LIST.add(Map.class);
069        DEFAULT_PARAM_TYPE_LIST.add(IThrowableProxy.class);
070        DEFAULT_PARAM_TYPE_LIST.add(Throwable.class);
071    }
072
073    protected String getDecoratedExpression() {
074        String expression = getExpression();
075        if (!expression.contains("return")) {
076            expression = "return " + expression + ";";
077            addInfo("Adding [return] prefix and a semicolon suffix. Expression becomes [" + expression + "]");
078            addInfo("See also " + CoreConstants.CODES_URL + "#block");
079
080        }
081        return IMPORT_LEVEL + expression;
082    }
083
084    protected String[] getParameterNames() {
085        List<String> fullNameList = new ArrayList<String>();
086        fullNameList.addAll(DEFAULT_PARAM_NAME_LIST);
087
088        for (int i = 0; i < matcherList.size(); i++) {
089            Matcher m = (Matcher) matcherList.get(i);
090            fullNameList.add(m.getName());
091        }
092
093        return (String[]) fullNameList.toArray(CoreConstants.EMPTY_STRING_ARRAY);
094    }
095
096    protected Class<?>[] getParameterTypes() {
097        List<Class<?>> fullTypeList = new ArrayList<>();
098        fullTypeList.addAll(DEFAULT_PARAM_TYPE_LIST);
099        for (int i = 0; i < matcherList.size(); i++) {
100            fullTypeList.add(Matcher.class);
101        }
102        return (Class[]) fullTypeList.toArray(CoreConstants.EMPTY_CLASS_ARRAY);
103    }
104
105    protected Object[] getParameterValues(ILoggingEvent loggingEvent) {
106        final int matcherListSize = matcherList.size();
107
108        int i = 0;
109        Object[] values = new Object[DEFAULT_PARAM_NAME_LIST.size() + matcherListSize];
110
111        values[i++] = Level.DEBUG_INTEGER;
112        values[i++] = Level.INFO_INTEGER;
113        values[i++] = Level.WARN_INTEGER;
114        values[i++] = Level.ERROR_INTEGER;
115
116        values[i++] = loggingEvent;
117        values[i++] = loggingEvent.getMessage();
118        values[i++] = loggingEvent.getFormattedMessage();
119        values[i++] = loggingEvent.getLoggerName();
120        values[i++] = loggingEvent.getLoggerContextVO();
121        values[i++] = loggingEvent.getLevel().toInteger();
122        values[i++] = loggingEvent.getTimeStamp();
123//        // In order to avoid NullPointerException, we could push a dummy marker if
124//        // the event's marker is null. However, this would surprise user who
125//        // expect to see a null marker instead of a dummy one.
126//        values[i++] = loggingEvent.getMarkerList();
127        values[i++] = loggingEvent.getMDCPropertyMap();
128
129        IThrowableProxy iThrowableProxy = loggingEvent.getThrowableProxy();
130
131        if (iThrowableProxy != null) {
132            values[i++] = iThrowableProxy;
133            if (iThrowableProxy instanceof ThrowableProxy) {
134                values[i++] = ((ThrowableProxy) iThrowableProxy).getThrowable();
135            } else {
136                values[i++] = null;
137            }
138        } else {
139            values[i++] = null;
140            values[i++] = null;
141        }
142
143        for (int j = 0; j < matcherListSize; j++) {
144            values[i++] = (Matcher) matcherList.get(j);
145        }
146
147        return values;
148    }
149
150}