| /* |
| * Copyright 2008 Google Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| * use this file except in compliance with the License. You may obtain a copy of |
| * the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations under |
| * the License. |
| */ |
| package java.lang; |
| |
| import com.google.gwt.core.client.impl.StackTraceCreator; |
| |
| import java.io.PrintStream; |
| import java.io.Serializable; |
| |
| /** |
| * See <a |
| * href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Throwable.html">the |
| * official Java API doc</a> for details. |
| */ |
| public class Throwable implements Serializable { |
| /* |
| * NOTE: We cannot use custom field serializers because we need the client and |
| * server to use different serialization strategies to deal with this type. |
| * The client uses the generated field serializers which can use JSNI. That |
| * leaves the server free to special case Throwable so that only the |
| * detailMessage field is serialized. |
| * |
| * Throwable is given special treatment by server's SerializabilityUtil class |
| * to ensure that only the detailMessage field is serialized. Changing the |
| * field modifiers below may necessitate a change to the server's |
| * SerializabilityUtil.fieldQualifiesForSerialization(Field) method. |
| */ |
| private transient Throwable cause; |
| private String detailMessage; |
| private transient StackTraceElement[] stackTrace; |
| |
| { |
| fillInStackTrace(); |
| } |
| |
| public Throwable() { |
| } |
| |
| public Throwable(String message) { |
| this.detailMessage = message; |
| } |
| |
| public Throwable(String message, Throwable cause) { |
| this.cause = cause; |
| this.detailMessage = message; |
| } |
| |
| public Throwable(Throwable cause) { |
| this.detailMessage = (cause == null) ? null : cause.toString(); |
| this.cause = cause; |
| } |
| |
| /** |
| * Populates the stack trace information for the Throwable. |
| * |
| * @return this |
| */ |
| public Throwable fillInStackTrace() { |
| StackTraceCreator.fillInStackTrace(this); |
| return this; |
| } |
| |
| public Throwable getCause() { |
| return cause; |
| } |
| |
| public String getLocalizedMessage() { |
| return getMessage(); |
| } |
| |
| public String getMessage() { |
| return detailMessage; |
| } |
| |
| /** |
| * Stack traces are not currently populated by GWT. This method will return a |
| * zero-length array unless a stack trace has been explicitly set with |
| * {@link #setStackTrace(StackTraceElement[])} |
| * |
| * @return the current stack trace |
| */ |
| public StackTraceElement[] getStackTrace() { |
| if (stackTrace == null) { |
| return new StackTraceElement[0]; |
| } |
| return stackTrace; |
| } |
| |
| public Throwable initCause(Throwable cause) { |
| if (this.cause != null) { |
| throw new IllegalStateException("Can't overwrite cause"); |
| } |
| if (cause == this) { |
| throw new IllegalArgumentException("Self-causation not permitted"); |
| } |
| this.cause = cause; |
| return this; |
| } |
| |
| public void printStackTrace() { |
| printStackTrace(System.err); |
| } |
| |
| public void printStackTrace(PrintStream out) { |
| StringBuffer msg = new StringBuffer(); |
| Throwable currentCause = this; |
| while (currentCause != null) { |
| String causeMessage = currentCause.getMessage(); |
| if (currentCause != this) { |
| msg.append("Caused by: "); |
| } |
| msg.append(currentCause.getClass().getName()); |
| msg.append(": "); |
| msg.append(causeMessage == null ? "(No exception detail)" : causeMessage); |
| msg.append("\n"); |
| currentCause = currentCause.getCause(); |
| } |
| out.println(msg); |
| } |
| |
| public void setStackTrace(StackTraceElement[] stackTrace) { |
| StackTraceElement[] copy = new StackTraceElement[stackTrace.length]; |
| for (int i = 0, c = stackTrace.length; i < c; ++i) { |
| if (stackTrace[i] == null) { |
| throw new NullPointerException(); |
| } |
| copy[i] = stackTrace[i]; |
| } |
| this.stackTrace = copy; |
| } |
| |
| @Override |
| public String toString() { |
| String className = this.getClass().getName(); |
| String msg = getMessage(); |
| if (msg != null) { |
| return className + ": " + msg; |
| } else { |
| return className; |
| } |
| } |
| |
| } |