StackTraceFilter.java revision e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7
1/*
2 * Copyright (c) 2007 Mockito contributors
3 * This program is made available under the terms of the MIT License.
4 */
5
6package org.mockito.internal.exceptions.stacktrace;
7
8import org.mockito.exceptions.stacktrace.StackTraceCleaner;
9import org.mockito.internal.configuration.ClassPathLoader;
10
11import java.io.Serializable;
12import java.util.ArrayList;
13import java.util.Arrays;
14import java.util.LinkedList;
15import java.util.List;
16
17public class StackTraceFilter implements Serializable {
18
19    static final long serialVersionUID = -5499819791513105700L;
20
21    private static StackTraceCleaner cleaner =
22            ClassPathLoader.getStackTraceCleanerProvider().getStackTraceCleaner(new DefaultStackTraceCleaner());
23
24    /**
25     * Example how the filter works (+/- means good/bad):
26     * [a+, b+, c-, d+, e+, f-, g+] -> [a+, b+, g+]
27     * Basically removes all bad from the middle. If any good are in the middle of bad those are also removed.
28     */
29    public StackTraceElement[] filter(StackTraceElement[] target, boolean keepTop) {
30        //TODO: profile
31        List<StackTraceElement> unfilteredStackTrace = Arrays.asList(target);
32
33        int lastBad = -1;
34        int firstBad = -1;
35        for (int i = 0; i < unfilteredStackTrace.size(); i++) {
36            if (!cleaner.isOut(unfilteredStackTrace.get(i))) {
37                continue;
38            }
39            lastBad = i;
40            if (firstBad == -1) {
41                firstBad = i;
42            }
43        }
44
45        List<StackTraceElement> top;
46        if (keepTop && firstBad != -1) {
47            top = unfilteredStackTrace.subList(0, firstBad);
48        } else {
49            top = new LinkedList<StackTraceElement>();
50        }
51
52        List<StackTraceElement> bottom = unfilteredStackTrace.subList(lastBad + 1, unfilteredStackTrace.size());
53        List<StackTraceElement> filtered = new ArrayList<StackTraceElement>(top);
54        filtered.addAll(bottom);
55        return filtered.toArray(new StackTraceElement[]{});
56    }
57}