/*******************************************************************************
* Copyright (c) 2000, 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Sebastian Davids: sdavids@gmx.de bug 37333, 26653
* David Corbin: dcorbin@users.sourceforge.net - editor opening
*******************************************************************************/
package org.rubypeople.rdt.internal.ui.util;
import java.io.File;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.core.resources.IProject;
import org.rubypeople.rdt.core.IRubyProject;
public class StackTraceLine {
// for better matching with 1.8, append /:in `(.*)'/ to the regex
private static Pattern OPEN_TRACE_LINE_PATTERN = Pattern.compile("\\s*(\\S.*?):(\\d+)(:|$)");
private static Pattern BRACKETED_TRACE_LINE_PATTERN = Pattern.compile("\\[(.*):(\\d+)\\]:");
private static Pattern OPTIONAL_PREFIX = Pattern.compile("^[ \\t^]*from ");
private String fFilename;
private int fLineNumber;
private int length;
private int offset;
public static boolean isTraceLine(String line) {
Matcher bracketedMatcher = BRACKETED_TRACE_LINE_PATTERN.matcher(line);
Matcher openMatcher = OPEN_TRACE_LINE_PATTERN.matcher(line);
return bracketedMatcher.find() || openMatcher.find();
}
public StackTraceLine(String traceLine) {
this(traceLine, (IProject) null);
}
public StackTraceLine(String traceLine, IRubyProject launchedProject) {
this(traceLine, launchedProject.getProject());
}
public StackTraceLine(String traceLine, IProject launchedProject) {
int prefix = 0;
Matcher matcher = OPTIONAL_PREFIX.matcher(traceLine);
if (matcher.find()) {
traceLine = traceLine.substring(matcher.group(0).length());
prefix = matcher.group(0).length();
}
matcher = BRACKETED_TRACE_LINE_PATTERN.matcher(traceLine);
if (!matcher.find()) {
matcher = OPEN_TRACE_LINE_PATTERN.matcher(traceLine);
if (!matcher.find())
return;
}
fFilename = matcher.group(1);
offset = matcher.start(1) + prefix;
if (fFilename.startsWith("[")) {
fFilename = fFilename.substring(1);
offset++;
}
String lineNumber = matcher.group(2);
fLineNumber = Integer.parseInt(lineNumber);
length = fFilename.length()+lineNumber.length()+1;
if (isRelativePath() && launchedProject != null) {
makeRelativeToWorkspace(launchedProject);
}
}
private void makeRelativeToWorkspace(IProject launchedProject) {
if (fFilename.startsWith("./")) {
fFilename = launchedProject.getFullPath().toPortableString() + fFilename.substring(1);
} else if (fFilename.startsWith("/")) {
fFilename = launchedProject.getFullPath().toPortableString() + fFilename;
} else {
fFilename = launchedProject.getFullPath().toPortableString() + '/' + fFilename;
}
}
private boolean isRelativePath() {
if (fFilename.startsWith("./")) return true;
if (fFilename.startsWith("/")) { // If it starts with '/' it could be relative to workspace or absolute on *-nix!
File file = new File(fFilename);
if (file.exists()) return false;
return true;
}
if (fFilename.contains(":")) return false;
return false;
}
public void openEditor() {
if (fFilename == null)
return;
new LineBasedEditorOpener(fFilename, fLineNumber).open();
}
public int getLineNumber() {
return fLineNumber;
}
public String getFilename() {
return fFilename;
}
public int offset() {
return offset;
}
public int length() {
return length;
}
}