/*
* RapidMiner
*
* Copyright (C) 2001-2008 by Rapid-I and the contributors
*
* Complete list of developers available at our web site:
*
* http://rapid-i.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
package com.rapidminer.operator;
import java.net.URL;
import java.text.MessageFormat;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import com.rapidminer.NoBugError;
import com.rapidminer.tools.Tools;
/**
* Exception class whose instances are thrown due to a user error, for example
* missing files or wrong operator architecture. <br>
* In order to create a UserError, do the following:
* <ul>
* <li>Open the file <code>UserErrorMessages.properties</code> in the
* <code>resources</code> directory. Look for an appropriate messsage. If you
* find one, remember its id number. If not, create a new one in the correct
* group</li>
* <li>The entry must include name, short message and long message. The name
* and long message will be presented to the user litarally. The short message
* will be parsed by <code>java.text.MessageFormat</code>. Especially, any
* ocurrence of curly brackets will be replaced. Be careful with quotes; it
* might be a good idea to read the ducumentation of MessageFormat first.</li>
* <li>Create a UserError by using this id. If the UserError is created because
* of another exception, e.g. a FileNotFoundException, this exception should be
* passed to the UserError in the constructor.</li>
* </ul>
*
* @author Simon Fischer, Ingo Mierswa
* @version $Id: UserError.java,v 1.3 2008/05/09 19:23:18 ingomierswa Exp $
*/
public class UserError extends OperatorException implements NoBugError {
private static final long serialVersionUID = -8441036860570180869L;
private static ResourceBundle messages = null;
private static final MessageFormat formatter = new MessageFormat("");
static {
try {
URL url = Tools.getResource("UserErrorMessages.properties");
if (url != null)
messages = new PropertyResourceBundle(url.openStream());
} catch (Throwable t) {
t.printStackTrace();
}
}
private int code;
private transient Operator operator;
/**
* Creates a new UserError.
*
* @param operator
* The {@link Operator} in which the exception occured.
* @param cause
* The exception that caused the user error. May be null. Using
* this makes debugging a lot easier.
* @param code
* The error code referring to a message in the file
* <code>UserErrorMessages.properties</code>
* @param arguments
* Arguments for the short message.
*/
public UserError(Operator operator, Throwable cause, int code, Object[] arguments) {
super(getErrorMessage(code, arguments), cause);
this.code = code;
this.operator = operator;
}
/** Convenience constructor for messages with no arguments and cause. */
public UserError(Operator operator, Throwable cause, int code) {
this(operator, code, new Object[0], cause);
}
public UserError(Operator operator, int code, Object[] arguments) {
this(operator, null, code, arguments);
}
/** Convenience constructor for messages with no arguments. */
public UserError(Operator operator, int code) {
this(operator, null, code, new Object[0]);
}
/** Convenience constructor for messages with exactly one argument. */
public UserError(Operator operator, int code, Object argument1) {
this(operator, null, code, new Object[] { argument1 });
}
/**
* Convenience constructor for messages with exactly one arguments and
* cause.
*/
public UserError(Operator operator, Throwable cause, int code, Object argument1) {
this(operator, cause, code, new Object[] { argument1 });
}
/** Convenience constructor for messages with exactly two arguments. */
public UserError(Operator operator, int code, Object argument1, Object argument2) {
this(operator, null, code, new Object[] { argument1, argument2 });
}
public String getDetails() {
return getResourceString(code, "long", "Description missing.");
}
public String getErrorName() {
return getResourceString(code, "name", "Unnamed error.");
}
public int getCode() {
return code;
}
public Operator getOperator() {
return operator;
}
public void setOperator(Operator operator) {
this.operator = operator;
}
public static String getErrorMessage(int code, Object[] arguments) {
String message = getResourceString(code, "short", "No message.");
try {
formatter.applyPattern(message);
String formatted = formatter.format(arguments);
return formatted;
} catch (Throwable t) {
return message;
}
}
/**
* Returns a resource message for the given error code.
*
* @param key
* one out of "name", "short",
* "long"
*/
public static String getResourceString(int code, String key, String deflt) {
if (messages == null)
return deflt;
try {
return messages.getString("error." + code + "." + key);
} catch (java.util.MissingResourceException e) {
return deflt;
}
}
public String getHTMLMessage() {
return "<html>Error in: <b>" + getOperator() + "</b><br>" + Tools.escapeXML(getMessage()) + "<hr>" + Tools.escapeXML(getDetails()) + "</html>";
}
}