/**
* Copyright (c) 2014-2017 by the respective copyright holders.
* 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
*/
package org.eclipse.smarthome.model.script.engine;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
/**
* Abstract class for exceptions thrown by the script engine.
*
* @author Kai Kreuzer - Initial contribution and API
*
*/
public abstract class ScriptException extends Exception {
private static final long serialVersionUID = -4155948282895039148L;
private String scriptText;
private final List<ScriptError> errors;
protected ScriptException(String message) {
super(message);
this.errors = new ArrayList<ScriptError>(1);
errors.add(new ScriptError(message, 0, 0, -1));
}
/**
* @param message
* @param cause
*/
protected ScriptException(final String message, final String scriptText, final Throwable cause) {
super(message, cause);
this.scriptText = scriptText;
this.errors = new LinkedList<ScriptError>();
}
protected ScriptException(final String message, final String scriptText) {
super(message);
this.scriptText = scriptText;
this.errors = new LinkedList<ScriptError>();
}
public ScriptException(final String message, final String scriptText, final int line, final int column,
final int length) {
this(scriptText, new ScriptError(message, line, column, length));
}
public ScriptException(final Throwable cause, final String message, final String scriptText, final int line,
final int column, final int length) {
this(cause, scriptText, new ScriptError(message, line, column, length));
}
private ScriptException(final Throwable cause, final String scriptText, final ScriptError error) {
super(error.getMessage(), cause); // ?
this.scriptText = scriptText;
this.errors = new ArrayList<ScriptError>(1);
errors.add(error);
}
/**
* Creates a ScriptException with one Error.
*
* @param errors
*/
private ScriptException(final String scriptText, final ScriptError error) {
super(error.getMessage()); // ?
this.scriptText = scriptText;
this.errors = new ArrayList<ScriptError>(1);
errors.add(error);
}
public ScriptException(String message, Throwable cause) {
super(message, cause);
this.errors = new ArrayList<ScriptError>(0);
}
/**
* All Errors that lead to this Exception.
*
* @return List of Error. Size >= 1, there is at last one ScriptError.
*/
public List<ScriptError> getErrors() {
return errors;
}
public void setScriptText(final String scriptText) {
this.scriptText = scriptText;
}
/**
* Returns a concatenation of all errors in contained ScriptError instances.
* Separated by newline, except for last error; no \n if only one error.
*
* @return The Message.
*
* @see ScriptError#getMessage()
*/
@Override
public String getMessage() {
StringBuilder sb = new StringBuilder();
if (scriptText == null) {
sb.append(super.getMessage());
} else {
int l = 1;
int c = 0;
for (int x = 0; x < scriptText.length(); x++) {
if (hasMatchingError(l, c)) {
sb.append(" ___ ");
}
sb.append(scriptText.charAt(x));
if (scriptText.charAt(x) == '\n') {
++l;
c = 0;
} else {
++c;
}
}
int i = 1;
for (ScriptError e : getErrors()) {
if (sb.length() > 0) {
sb.append('\n');
}
sb.append(" ");
if (getErrors().size() > 1) {
sb.append(i++);
sb.append(". ");
}
sb.append(e.getMessage());
}
}
return sb.toString();
}
private boolean hasMatchingError(int l, int c) {
for (ScriptError e : getErrors()) {
if (e.getLineNumber() == l && e.getColumnNumber() == c) {
return true;
}
}
return false;
}
}