| /** |
| * |
| */ |
| package org.eclipse.jdt.internal.junit.ui; |
| |
| import java.io.BufferedReader; |
| import java.io.IOException; |
| import java.io.PrintWriter; |
| import java.io.StringReader; |
| import java.io.StringWriter; |
| |
| public class TextualTrace { |
| public static final int LINE_TYPE_EXCEPTION = 1; |
| |
| public static final int LINE_TYPE_NORMAL = 0; |
| |
| public static final int LINE_TYPE_STACKFRAME = 2; |
| |
| private final String fTrace; |
| |
| public TextualTrace(String trace, String[] filterPatterns) { |
| super(); |
| fTrace = filterStack(trace, filterPatterns); |
| } |
| |
| public void display(ITraceDisplay display, int maxLabelLength) { |
| StringReader stringReader = new StringReader(fTrace); |
| BufferedReader bufferedReader = new BufferedReader(stringReader); |
| String line; |
| |
| try { |
| // first line contains the thrown exception |
| line = readLine(bufferedReader); |
| if (line == null) |
| return; |
| |
| displayWrappedLine(display, maxLabelLength, line, |
| LINE_TYPE_EXCEPTION); |
| |
| // the stack frames of the trace |
| while ((line = readLine(bufferedReader)) != null) { |
| int type = isAStackFrame(line) ? LINE_TYPE_STACKFRAME |
| : LINE_TYPE_NORMAL; |
| displayWrappedLine(display, maxLabelLength, line, type); |
| } |
| } catch (IOException e) { |
| display.addTraceLine(LINE_TYPE_NORMAL, fTrace); |
| } |
| } |
| |
| private void displayWrappedLine(ITraceDisplay display, int maxLabelLength, |
| String line, int type) { |
| final int labelLength = line.length(); |
| if (labelLength < maxLabelLength) { |
| display.addTraceLine(type, line); |
| } else { |
| // workaround for bug 74647: JUnit view truncates |
| // failure message |
| display.addTraceLine(type, line.substring(0, maxLabelLength)); |
| int offset = maxLabelLength; |
| while (offset < labelLength) { |
| int nextOffset = Math.min(labelLength, offset + maxLabelLength); |
| display.addTraceLine(LINE_TYPE_NORMAL, line.substring(offset, |
| nextOffset)); |
| offset = nextOffset; |
| } |
| } |
| } |
| |
| private boolean filterLine(String[] patterns, String line) { |
| String pattern; |
| int len; |
| for (int i = (patterns.length - 1); i >= 0; --i) { |
| pattern = patterns[i]; |
| len = pattern.length() - 1; |
| if (pattern.charAt(len) == '*') { |
| // strip trailing * from a package filter |
| pattern = pattern.substring(0, len); |
| } else if (Character.isUpperCase(pattern.charAt(0))) { |
| // class in the default package |
| pattern = FailureTrace.FRAME_PREFIX + pattern + '.'; |
| } else { |
| // class names start w/ an uppercase letter after the . |
| final int lastDotIndex = pattern.lastIndexOf('.'); |
| if ((lastDotIndex != -1) |
| && (lastDotIndex != len) |
| && Character.isUpperCase(pattern.charAt(lastDotIndex + 1))) |
| pattern += '.'; // append . to a class filter |
| } |
| |
| if (line.indexOf(pattern) > 0) |
| return true; |
| } |
| return false; |
| } |
| |
| private String filterStack(String stackTrace, String[] filterPatterns) { |
| if (filterPatterns.length == 0 || stackTrace == null) |
| return stackTrace; |
| |
| StringWriter stringWriter = new StringWriter(); |
| PrintWriter printWriter = new PrintWriter(stringWriter); |
| StringReader stringReader = new StringReader(stackTrace); |
| BufferedReader bufferedReader = new BufferedReader(stringReader); |
| |
| String line; |
| String[] patterns = filterPatterns; |
| try { |
| while ((line = bufferedReader.readLine()) != null) { |
| if (!filterLine(patterns, line)) |
| printWriter.println(line); |
| } |
| } catch (IOException e) { |
| return stackTrace; // return the stack unfiltered |
| } |
| return stringWriter.toString(); |
| } |
| |
| private boolean isAStackFrame(String itemLabel) { |
| // heuristic for detecting a stack frame - works for JDK |
| return itemLabel.indexOf(" at ") >= 0; //$NON-NLS-1$ |
| } |
| |
| private String readLine(BufferedReader bufferedReader) throws IOException { |
| String readLine = bufferedReader.readLine(); |
| return readLine == null ? null : readLine.replace('\t', ' '); |
| } |
| } |