/* * This file is a part of Alchemy OS project. * Copyright (C) 2011-2014, Sergey Basalaev <sbasalaev@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package alchemy.system; import alchemy.util.ArrayList; import java.io.IOException; import javax.microedition.media.MediaException; /** * Exception thrown by function instances. * Maintains stack of function calls. * * @author Sergey Basalaev */ public final class AlchemyException extends Exception { private ArrayList names = new ArrayList(); private ArrayList infos = new ArrayList(); public final int errcode; /** * General code for successful program termination. * Cannot be used to construct AlchemyException. */ public static final int SUCCESS = 0; /** General code for unsuccessful program termination. */ public static final int FAIL = 1; /** Code for serious system failures. */ public static final int ERR_SYSTEM = 100; /** Code for NullPointerException. */ public static final int ERR_NULL = 101; /** Code for IOException. */ public static final int ERR_IO = 102; /** Code for IndexOutOfBoundsException. */ public static final int ERR_RANGE = 103; /** Code for NegativeArraySizeException. */ public static final int ERR_NEGARRSIZE = 104; /** Code for IllegalArgumentException. */ public static final int ERR_ILLARG = 105; /** Code for IllegalStateException. */ public static final int ERR_ILLSTATE = 106; /** Code for SecurityException. */ public static final int ERR_SECURITY = 107; /** Code for ClassCastException. */ public static final int ERR_CLASSCAST = 108; /** Code for ArithmeticException. */ public static final int ERR_DIVBYZERO = 109; /** Code for InterruptedException. */ public static final int ERR_INTERRUPT = 110; /** Code for MediaException. */ public static final int ERR_MEDIA = 111; /** * Creates new AlchemyException from given exception. * Appropriate error code is determined from the class * of cause. Detail message is read from cause. */ public AlchemyException(Throwable cause) { super(cause.getMessage()); errcode = (cause instanceof NullPointerException) ? ERR_NULL : (cause instanceof Error) ? ERR_SYSTEM : (cause instanceof IOException) ? ERR_IO : (cause instanceof IllegalArgumentException) ? ERR_ILLARG : (cause instanceof IllegalStateException) ? ERR_ILLSTATE : (cause instanceof SecurityException) ? ERR_SECURITY : (cause instanceof IndexOutOfBoundsException) ? ERR_RANGE : (cause instanceof ClassCastException) ? ERR_CLASSCAST : (cause instanceof ArithmeticException) ? ERR_DIVBYZERO : (cause instanceof InterruptedException) ? ERR_INTERRUPT : (cause instanceof MediaException) ? ERR_MEDIA : (cause instanceof AlchemyException) ? ((AlchemyException)cause).errcode : FAIL; } /** * Creates new AlchemyException with given error * code and detail message. */ public AlchemyException(int errcode, String msg) { super(msg); this.errcode = errcode; if (errcode == 0) throw new IllegalArgumentException(); } /** * Adds element to the stack trace. * * @param func function * @param info debugging info */ public void addTraceElement(Function func, String info) { names.add(func.toString()); infos.add(info); } /** Returns length of the stack trace. */ public int getTraceLength() { return names.size(); } /** Returns function name at the given index of the stack trace. */ public String getTraceElementName(int index) { return (String) names.get(index); } /** Returns debugging info at the given index of the stack trace. */ public String getTraceElementInfo(int index) { return (String) infos.get(index); } /** Returns stack trace as string. */ public String trace() { // print stack trace StringBuffer sb = new StringBuffer(); int size = names.size(); for (int i=0; i < size; i++) { sb.append('\n') .append('@') .append(names.get(i)) .append('(') .append(infos.get(i)) .append(')'); } return sb.toString(); } public static String errstring(int code) { switch (code) { case ERR_SYSTEM: return "System error"; case ERR_NULL: return "null value"; case ERR_IO: return "Input/output error"; case ERR_RANGE: return "Out of range"; case ERR_NEGARRSIZE: return "Negative array size"; case ERR_SECURITY: return "Permission denied"; case ERR_ILLARG: return "Illegal argument"; case ERR_ILLSTATE: return "Illegal state"; case ERR_CLASSCAST: return "Type mismatch"; case ERR_DIVBYZERO: return "Division by zero"; case ERR_INTERRUPT: return "Process interrupted"; case ERR_MEDIA: return "Media error"; default: return "Error"; } } public String toString() { StringBuffer sb = new StringBuffer(errstring(errcode)); String msg = getMessage(); if (msg != null && msg.length() != 0) { sb.append(": ").append(msg); } return sb.append(trace()).toString(); } }