Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/bugzilla/ui/tasks/StackTrace.java')
-rw-r--r--org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/bugzilla/ui/tasks/StackTrace.java373
1 files changed, 373 insertions, 0 deletions
diff --git a/org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/bugzilla/ui/tasks/StackTrace.java b/org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/bugzilla/ui/tasks/StackTrace.java
new file mode 100644
index 000000000..617599738
--- /dev/null
+++ b/org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/bugzilla/ui/tasks/StackTrace.java
@@ -0,0 +1,373 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2005 University Of British Columbia and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * University Of British Columbia - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylar.bugzilla.ui.tasks;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Class to hold all of the information about a stack trace
+ *
+ * @author Shawn Minto
+ */
+public class StackTrace {
+
+ /** The length of the stack trace in the original string */
+ private int length;
+
+ /** The offset of the stack trace in the orignal string */
+ private int offset;
+
+ /** The string of the stack trace */
+ private String stackTrace;
+
+ /** This is the comment that the stack trace appeared in. String if desciption else Comment */
+ private Object comment;
+
+ /**
+ * Constructor
+ *
+ * @param stackTrace
+ * The stack trace string
+ * @param offset
+ * The offset of the stack trace in the original string
+ * @param length
+ * The length of the stack trace in the original string
+ * @param comment
+ * The comment that the stack trace came from
+ */
+ public StackTrace(String stackTrace, int offset, int length, Object comment) {
+ this.stackTrace = stackTrace;
+ this.offset = offset;
+ this.length = length;
+ this.comment = comment;
+ }
+
+ /**
+ * Get the offset for the stack trace
+ *
+ * @return Returns the offset.
+ */
+ public int getOffset() {
+ return offset;
+ }
+
+ /**
+ * Get the stack trace for the bug
+ *
+ * @return Returns the stackTrace.
+ */
+ public String getStackTrace() {
+ return stackTrace;
+ }
+
+ /**
+ * Get the length of the bug
+ *
+ * @return Returns the length.
+ */
+ public int getLength() {
+ return length;
+ }
+
+ /**
+ * Get the Comment that this stack trace came from
+ *
+ * @return Returns the Comment if it was a comment else a String if it was the description
+ */
+ public Object getComment() {
+ return comment;
+ }
+
+ /**
+ * Find a standard java stack trace in the given string
+ *
+ *
+ * @param s
+ * The string to search for stack traces
+ * @param comment
+ * The comment that the text came from.<br>
+ * Comment if a comment else a String
+ * @return String[] of stack traces - each element is 1 trace
+ */
+ public static StackTrace[] getStackTrace(String s, Object comment) {
+
+ // setup the regex used to determine if it looks like we are at a
+ // stack trace and whether it is something that should be skipped
+ String regexExceptionType = "^(.*\\.)+.+(Exception|Error|Throwable).*";
+ String regexSkip = ".*\\.\\..*";
+
+ // get all of the individual lines for the string
+ String[] lines = s.split("\r\n");
+
+ // the character start of the current stack trace
+ int charStackStart = 0;
+
+ // the current character in the string - used for the start and the
+ // offset
+ int[] charPos = { 0 }; // array so pass by reference
+
+ boolean inStackTrace = false;
+ List<String> stackTrace = null;
+ List<StackTrace> stackTraces = new ArrayList<StackTrace>();
+
+ // go through each of the lines of the string
+ for (int i = 0; i < lines.length; i++) {
+
+ if (lines[i].matches(regexSkip)){
+
+ // update the current character position
+ charPos[0] += lines[i].length() + 2;
+
+ }else if (lines[i].trim().matches(regexExceptionType) && !inStackTrace) {
+
+ // we have matched the stack trace and we are not already in one
+
+ // add the old stack trace to the list of stack traces
+ if (stackTrace != null && stackTrace.size() > 1) {
+ stackTraces.add(getStackTrace(stackTrace, charStackStart,
+ charPos[0] - charStackStart, comment));
+ }
+
+ // prepare for a new stack trace
+ stackTrace = new ArrayList<String>();
+ inStackTrace = true;
+
+ // the current line is the start of our stack trace
+ stackTrace.add(lines[i]);
+ charStackStart = charPos[0];
+ charPos[0] += lines[i].length() + 2;
+ } else if (inStackTrace) {
+ // we are in a stack trace
+
+ int[] pos = { i }; // array so pass by reference
+
+ // get the next at clause of the stack trace
+ String stack = getNextAt(lines, pos, charPos);
+
+ // check if there was an at
+ if (stack == null) {
+
+ // there wasn't so we are done this stack trace
+ inStackTrace = false;
+ if (stackTrace != null && stackTrace.size() > 1) {
+ stackTraces.add(getStackTrace(stackTrace,
+ charStackStart, charPos[0] - charStackStart, comment));
+ }
+ stackTrace = null;
+ } else {
+
+ // we had one, so add it to this stack trace
+ stackTrace.add(stack);
+ }
+
+ // update the position
+ i = pos[0];
+ } else {
+ // update the current character position
+ charPos[0] += lines[i].length() + 2;
+ }
+ }
+
+ // make sure to add the stack trace if it was the last in the string
+ if (stackTrace != null && stackTrace.size() > 1) {
+ stackTraces.add(getStackTrace(stackTrace, charStackStart,
+ charPos[0] - charStackStart, comment));
+ }
+
+ if (stackTraces.size() == 0)
+ return null;
+
+ // get the string values of the stack traces and return it
+ return getTracesFromList(stackTraces);
+ }
+
+ /**
+ * Get the next at clause from a potential stack trace -- looks ahead 4
+ * lines
+ *
+ * @param lines
+ * The array of all of the lines in the bug
+ * @param i
+ * The current position to start at
+ * @param charPos
+ * The current character position in the original string
+ * @return The next at clause, or <code>null</code><br>
+ * If an at line is matched, but the end isn't within the 4 lines,
+ * only the first line is returned. Also, charPos is updated as well
+ * as i
+ */
+ private static String getNextAt(String[] lines, int[] i, int[] charPos) {
+ String regexAtString = "^at.*";
+ String regexEndString = ".*:\\d+\\)$";
+ int index = i[0];
+ String l1, l2, l3, l4;
+ l1 = l2 = l3 = l4 = null;
+ String res = null;
+
+ // get the first line to look at
+ if (lines.length > index) {
+ l1 = lines[index];
+ } else {
+ // if the first line doesn't exist, we are done and should
+ // return
+ return null;
+ }
+
+ // get the next 3 lines
+ if (lines.length > index + 1) {
+ l2 = lines[index + 1];
+ }
+ if (lines.length > index + 2) {
+ l3 = lines[index + 2];
+ }
+ if (lines.length > index + 3) {
+ l4 = lines[index + 3];
+ }
+
+ // make sure that the first line is the start of an at
+ // if not, return null
+ if (l1.trim().matches(regexAtString)) {
+ charPos[0] += l1.length() + 2;
+ res = l1;
+ } else
+ return null;
+
+ // now determine where the end is if it wasn't on 1 line
+ if (!res.trim().matches(regexEndString)) {
+
+ if (l2 != null && l2.trim().matches(regexEndString)) {
+
+ // it was on the second line
+ // update the current position and the result string
+ i[0] = index + 1;
+ charPos[0] += l2.length() + 2;
+ res += l2.trim();
+ } else if (l3 != null && l3.trim().matches(regexEndString)) {
+
+ // it was on the third line
+ // update the current position and the result string
+ i[0] = index + 2;
+ charPos[0] += l2.length() + l3.length() + 4;
+ res += l2.trim();
+ res += l3.trim();
+ } else if (l4 != null && l4.trim().matches(regexEndString)) {
+
+ // it was on the fourth line
+ // update the current position and the result string
+ i[0] = index + 3;
+ charPos[0] += l2.length() + l3.length() + l4.length() + 6;
+ res += l2.trim();
+ res += l3.trim();
+ res += l4.trim();
+ }
+ }
+
+ // return the result
+ return res;
+ }
+
+ /**
+ * Get the StackTrace
+ *
+ * @param l
+ * the list of lines that contain the trace
+ * @param start
+ * the start of the stack trace
+ * @param offset
+ * the offset of the stack trace
+ * @param comment
+ * The comment that the stack trace came from
+ * @return The StackTrace for the given data
+ */
+ private static StackTrace getStackTrace(List<String> l, int offset, int length, Object comment) {
+ String s = "";
+ for(String s2 : l) {
+ s += s2 + "\r\n";
+ }
+
+ return new StackTrace(s, offset, length, comment);
+ }
+
+ /**
+ * Convert a List StackTraces to a StackTrace[] <br>
+ *
+ * @param l
+ * The List of StackTraces
+ * @return StackTrace[] of the List
+ */
+ private static StackTrace[] getTracesFromList(List<StackTrace> l) {
+
+ // make sure that there is something to convert, else return null
+ if (l == null || l.size() == 0)
+ return null;
+
+ // convert the list of strings to an array of strings
+ int i = 0;
+ StackTrace[] s = new StackTrace[l.size()];
+
+ for(StackTrace st : l) {
+ s[i] = st;
+ i++;
+ }
+
+ // return the string array
+ return s;
+ }
+
+ /**
+ * Escape all of the special regex characters from the string
+ *
+ * @param s
+ * The string to escape the characters for
+ * @return A string with all of the special characters escaped <br>
+ * <code>
+ * . => \.<br>
+ * $ => \$<br>
+ * ? => \?<br>
+ * { => \{<br>
+ * } => \}<br>
+ * ( => \(<br>
+ * ) => \)<br>
+ * [ => \[<br>
+ * ] => \]<br>
+ * + => \+<br>
+ * * => \*<br>
+ * | => \|<br>
+ * ^ => \^<br>
+ * \ => \\<br>
+ * / => \/<br>
+ * </code>
+ */
+ public static String escapeForRegex(String s) {
+ String sFixed = s;
+
+ // replace all special regex characters
+ sFixed = sFixed.replaceAll("\\\\", "\\\\\\\\");
+ sFixed = sFixed.replaceAll("\\$", "\\\\\\$");
+ sFixed = sFixed.replaceAll("\\.", "\\\\.");
+ sFixed = sFixed.replaceAll("\\?", "\\\\?");
+ sFixed = sFixed.replaceAll("\\{", "\\\\{");
+ sFixed = sFixed.replaceAll("\\}", "\\\\}");
+ sFixed = sFixed.replaceAll("\\(", "\\\\(");
+ sFixed = sFixed.replaceAll("\\)", "\\\\)");
+ sFixed = sFixed.replaceAll("\\[", "\\\\[");
+ sFixed = sFixed.replaceAll("\\]", "\\\\]");
+ sFixed = sFixed.replaceAll("\\+", "\\\\+");
+ sFixed = sFixed.replaceAll("\\*", "\\\\*");
+ sFixed = sFixed.replaceAll("\\|", "\\\\|");
+ sFixed = sFixed.replaceAll("\\^", "\\\\^");
+ sFixed = sFixed.replaceAll("\\/", "\\\\/");
+
+ return sFixed;
+ }
+} \ No newline at end of file

Back to the top