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