001/**
002 * Logback: the reliable, generic, fast and flexible logging framework.
003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
004 * <p>
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 * <p>
009 * or (per the licensee's choosing)
010 * <p>
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.core.status;
015
016import ch.qos.logback.core.Context;
017import ch.qos.logback.core.CoreConstants;
018
019import java.util.ArrayList;
020import java.util.List;
021import java.util.regex.Matcher;
022import java.util.regex.Pattern;
023
024public class StatusUtil {
025
026    StatusManager sm;
027
028    public StatusUtil(StatusManager sm) {
029        this.sm = sm;
030    }
031
032    public StatusUtil(Context context) {
033        this.sm = context.getStatusManager();
034    }
035
036    /**
037     * Returns true if the StatusManager associated with the context passed as
038     * parameter has one or more StatusListener instances registered. Returns false
039     * otherwise.
040     *
041     * @param context
042     * @return true if one or more StatusListeners registered, false otherwise
043     * @since 1.0.8
044     */
045    static public boolean contextHasStatusListener(Context context) {
046        StatusManager sm = context.getStatusManager();
047        if (sm == null)
048            return false;
049        List<StatusListener> listeners = sm.getCopyOfStatusListenerList();
050        if (listeners == null || listeners.size() == 0)
051            return false;
052        else
053            return true;
054    }
055
056    static public List<Status> filterStatusListByTimeThreshold(List<Status> rawList, long threshold) {
057        List<Status> filteredList = new ArrayList<Status>();
058        for (Status s : rawList) {
059            if (s.getDate() >= threshold)
060                filteredList.add(s);
061        }
062        return filteredList;
063    }
064
065    public void addStatus(Status status) {
066        if (sm != null) {
067            sm.add(status);
068        }
069    }
070
071    public void addInfo(Object caller, String msg) {
072        addStatus(new InfoStatus(msg, caller));
073    }
074
075    public void addWarn(Object caller, String msg) {
076        addStatus(new WarnStatus(msg, caller));
077    }
078
079    public void addError(Object caller, String msg, Throwable t) {
080        addStatus(new ErrorStatus(msg, caller, t));
081    }
082
083    public boolean hasXMLParsingErrors(long threshold) {
084        return containsMatch(threshold, Status.ERROR, CoreConstants.XML_PARSING);
085    }
086
087    public boolean noXMLParsingErrorsOccurred(long threshold) {
088        return !hasXMLParsingErrors(threshold);
089    }
090
091    public int getHighestLevel(long threshold) {
092        List<Status> filteredList = filterStatusListByTimeThreshold(sm.getCopyOfStatusList(), threshold);
093        int maxLevel = Status.INFO;
094        for (Status s : filteredList) {
095            if (s.getLevel() > maxLevel)
096                maxLevel = s.getLevel();
097        }
098        return maxLevel;
099    }
100
101    public boolean isErrorFree(long threshold) {
102        return Status.ERROR > getHighestLevel(threshold);
103    }
104
105    public boolean isWarningOrErrorFree(long threshold) {
106        return Status.WARN > getHighestLevel(threshold);
107    }
108
109    public boolean containsMatch(long threshold, int level, String regex) {
110        List<Status> filteredList = filterStatusListByTimeThreshold(sm.getCopyOfStatusList(), threshold);
111        Pattern p = Pattern.compile(regex);
112
113        for (Status status : filteredList) {
114            if (level != status.getLevel()) {
115                continue;
116            }
117            String msg = status.getMessage();
118            Matcher matcher = p.matcher(msg);
119            if (matcher.lookingAt()) {
120                return true;
121            }
122        }
123        return false;
124    }
125
126    public boolean containsMatch(int level, String regex) {
127        return containsMatch(0, level, regex);
128    }
129
130    public boolean containsMatch(String regex) {
131        Pattern p = Pattern.compile(regex);
132        for (Status status : sm.getCopyOfStatusList()) {
133            String msg = status.getMessage();
134            Matcher matcher = p.matcher(msg);
135            if (matcher.lookingAt()) {
136                return true;
137            }
138        }
139        return false;
140    }
141
142    public int levelCount(int level, long threshold) {
143        List<Status> filteredList = filterStatusListByTimeThreshold(sm.getCopyOfStatusList(), threshold);
144
145        int count = 0;
146        for (Status status : filteredList) {
147            if (status.getLevel() == level)
148                count++;
149        }
150        return count;
151    }
152
153    public int matchCount(String regex) {
154        int count = 0;
155        Pattern p = Pattern.compile(regex);
156        for (Status status : sm.getCopyOfStatusList()) {
157            String msg = status.getMessage();
158            Matcher matcher = p.matcher(msg);
159            if (matcher.lookingAt()) {
160                count++;
161            }
162        }
163        return count;
164    }
165
166    public boolean containsException(Class<?> exceptionType) {
167        return containsException(exceptionType, null);
168    }
169
170    public boolean containsException(Class<?> exceptionType, String msgRegex) {
171        for (Status status : sm.getCopyOfStatusList()) {
172            Throwable t = status.getThrowable();
173            while (t != null) {
174                if (t.getClass().getName().equals(exceptionType.getName())) {
175                    if (msgRegex == null) {
176                        return true;
177                    } else if (checkRegexMatch(t.getMessage(), msgRegex)) {
178                        return true;
179                    }
180                }
181                t = t.getCause();
182            }
183        }
184        return false;
185    }
186
187    private boolean checkRegexMatch(String message, String msgRegex) {
188        Pattern p = Pattern.compile(msgRegex);
189        Matcher matcher = p.matcher(message);
190        return matcher.lookingAt();
191    }
192
193
194    /**
195     * Return the time of last reset. -1 if last reset time could not be found
196     *
197     * @return time of last reset or -1
198     */
199    public long timeOfLastReset() {
200        List<Status> statusList = sm.getCopyOfStatusList();
201        if (statusList == null)
202            return -1;
203
204        int len = statusList.size();
205        for (int i = len - 1; i >= 0; i--) {
206            Status s = statusList.get(i);
207            if (CoreConstants.RESET_MSG_PREFIX.equals(s.getMessage())) {
208                return s.getDate();
209            }
210        }
211        return -1;
212    }
213
214}