/**
* Copyright (c) 2013-2015 by Brainwy Software Ltda, Inc. All Rights Reserved.
* Licensed under the terms of the Eclipse Public License (EPL).
* Please see the license.txt included with this distribution for details.
* Any modifications to this file must keep this entire header intact.
*/
package org.python.pydev.debug.model;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import org.eclipse.core.runtime.IPath;
import org.python.pydev.core.log.Log;
import org.python.pydev.debug.core.ConfigureExceptionsFileUtils;
import org.python.pydev.shared_core.io.FileUtils;
import org.python.pydev.shared_core.string.FastStringBuffer;
import org.python.pydev.shared_core.string.StringUtils;
public class IgnoreCaughtExceptionsWhenThrownFrom {
private PyExceptionBreakPointManager manager;
/*default*/IgnoreCaughtExceptionsWhenThrownFrom(PyExceptionBreakPointManager manager) {
this.manager = manager;
}
private static final String IGNORE_EXCEPTIONS_FILE_NAME = "ignore_exceptions.prefs";
/**
* Helper class to hold info on ignored exceptions.
*/
public static class IgnoredExceptionInfo {
public final String filename;
public final int line;
public final String contents;
public IgnoredExceptionInfo(String s) {
List<String> split = StringUtils.split(s, '|', 3);
this.filename = split.get(0);
this.line = Integer.parseInt(split.get(1));
if (split.size() > 2) {
this.contents = split.get(2);
} else {
this.contents = "";
}
}
}
/**
* Public API to enable a forced refresh on the exceptions to be ignored.
*/
public void updateIgnoreThrownExceptions() {
for (IExceptionsBreakpointListener listener : this.manager.listeners.getListeners()) {
listener.onUpdateIgnoreThrownExceptions();
}
}
/**
* @return the path with the file containing the information on the exceptions to be ignored.
*/
public IPath getIgnoreThrownExceptionsPath() {
return ConfigureExceptionsFileUtils.getFilePathFromMetadata(IGNORE_EXCEPTIONS_FILE_NAME);
}
/**
* @return a list with the information on the ignored caught exceptions.
*/
public Collection<IgnoredExceptionInfo> getIgnoreThrownExceptionsForEdition() {
String metadataFile = ConfigureExceptionsFileUtils.readFromMetadataFile(IGNORE_EXCEPTIONS_FILE_NAME);
List<String> lines = StringUtils.splitInLines(metadataFile, false);
TreeSet<String> linesAsSet = new TreeSet<>(lines);
List<IgnoredExceptionInfo> ret = new ArrayList<>(linesAsSet.size());
for (String s : linesAsSet) {
try {
ret.add(new IgnoredExceptionInfo(s));
} catch (Exception e) {
Log.log(e);
}
}
return ret;
}
/**
* Gets a collection of file|lineNumber with exceptions to be ignored.
*/
public Collection<String> getIgnoreThrownExceptions() {
Set<String> set = new TreeSet<>();
String metadataFile = ConfigureExceptionsFileUtils.readFromMetadataFile(IGNORE_EXCEPTIONS_FILE_NAME);
List<String> lines = StringUtils.splitInLines(metadataFile, false);
TreeSet<String> linesAsSet = new TreeSet<>(lines);
FastStringBuffer temp = new FastStringBuffer();
for (Iterator<String> it = linesAsSet.iterator(); it.hasNext();) {
String s = it.next().trim();
if (s.length() == 0) {
it.remove();
continue;
}
if (StringUtils.count(s, '|') < 2) { //i.e.: the line itself could have more than one if the code has it...
Log.log("Unexpected line in thrown exceptions file: " + s);
continue;
}
List<String> split = StringUtils.split(s, '|');
String file = split.get(0);
int line;
try {
line = Integer.parseInt(split.get(1));
} catch (NumberFormatException e) {
Log.log("Unexpected line number in thrown exceptions file: " + s);
continue;
}
temp.clear().append(file).append('|').append(line);
String string = temp.toString();
set.add(string);
}
//I.e.: something changed: rewrite it.
if (linesAsSet.size() != lines.size()) {
ConfigureExceptionsFileUtils.writeToFile(IGNORE_EXCEPTIONS_FILE_NAME, StringUtils.join("\n", linesAsSet)
+ "\n",
false);
}
return set;
}
/**
* We create a file where each line has an entry and each entry contains:
* filename | lineNumber | trimmed line contents.
*/
public void addIgnoreThrownExceptionIn(File file, int lineNumber) {
boolean isAppend = false;
IPath path = ConfigureExceptionsFileUtils.getFilePathFromMetadata(IGNORE_EXCEPTIONS_FILE_NAME);
if (path.toFile().exists()) {
isAppend = true;
}
String fileAbsolutePath = FileUtils.getFileAbsolutePath(file);
String line;
try {
line = FileUtils.getLineFromFile(file, lineNumber);
} catch (Exception e) {
Log.log(StringUtils.format("Unable to ignore thrown exception in file: %s, line: %s", file, lineNumber), e);
return;
}
FastStringBuffer buf = new FastStringBuffer(fileAbsolutePath, 20 + line.length());
buf.append('|').append(lineNumber).append('|').append(line).append('\n');
ConfigureExceptionsFileUtils.writeToFile(IGNORE_EXCEPTIONS_FILE_NAME, buf.toString(), isAppend);
for (IExceptionsBreakpointListener listener : this.manager.listeners.getListeners()) {
listener.onAddIgnoreThrownExceptionIn(file, lineNumber);
}
}
}