| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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 org.apache.hadoop.lib.lang; |
| |
| import org.apache.hadoop.lib.util.Check; |
| |
| import java.text.MessageFormat; |
| |
| /** |
| * Generic exception that requires error codes and uses the a message |
| * template from the error code. |
| */ |
| public class XException extends Exception { |
| |
| /** |
| * Interface to define error codes. |
| */ |
| public static interface ERROR { |
| |
| /** |
| * Returns the template for the error. |
| * |
| * @return the template for the error, the template must be in JDK |
| * <code>MessageFormat</code> syntax (using {#} positional parameters). |
| */ |
| public String getTemplate(); |
| |
| } |
| |
| private ERROR error; |
| |
| /** |
| * Private constructor used by the public constructors. |
| * |
| * @param error error code. |
| * @param message error message. |
| * @param cause exception cause if any. |
| */ |
| private XException(ERROR error, String message, Throwable cause) { |
| super(message, cause); |
| this.error = error; |
| } |
| |
| /** |
| * Creates an XException using another XException as cause. |
| * <p/> |
| * The error code and error message are extracted from the cause. |
| * |
| * @param cause exception cause. |
| */ |
| public XException(XException cause) { |
| this(cause.getError(), cause.getMessage(), cause); |
| } |
| |
| /** |
| * Creates an XException using the specified error code. The exception |
| * message is resolved using the error code template and the passed |
| * parameters. |
| * |
| * @param error error code for the XException. |
| * @param params parameters to use when creating the error message |
| * with the error code template. |
| */ |
| @SuppressWarnings({"ThrowableResultOfMethodCallIgnored"}) |
| public XException(ERROR error, Object... params) { |
| this(Check.notNull(error, "error"), format(error, params), getCause(params)); |
| } |
| |
| /** |
| * Returns the error code of the exception. |
| * |
| * @return the error code of the exception. |
| */ |
| public ERROR getError() { |
| return error; |
| } |
| |
| /** |
| * Creates a message using a error message template and arguments. |
| * <p/> |
| * The template must be in JDK <code>MessageFormat</code> syntax |
| * (using {#} positional parameters). |
| * |
| * @param error error code, to get the template from. |
| * @param args arguments to use for creating the message. |
| * |
| * @return the resolved error message. |
| */ |
| private static String format(ERROR error, Object... args) { |
| String template = error.getTemplate(); |
| if (template == null) { |
| StringBuilder sb = new StringBuilder(); |
| for (int i = 0; i < args.length; i++) { |
| sb.append(" {").append(i).append("}"); |
| } |
| template = sb.deleteCharAt(0).toString(); |
| } |
| return error + ": " + MessageFormat.format(template, args); |
| } |
| |
| /** |
| * Returns the last parameter if it is an instance of <code>Throwable</code> |
| * returns it else it returns NULL. |
| * |
| * @param params parameters to look for a cause. |
| * |
| * @return the last parameter if it is an instance of <code>Throwable</code> |
| * returns it else it returns NULL. |
| */ |
| private static Throwable getCause(Object... params) { |
| Throwable throwable = null; |
| if (params != null && params.length > 0 && params[params.length - 1] instanceof Throwable) { |
| throwable = (Throwable) params[params.length - 1]; |
| } |
| return throwable; |
| } |
| |
| } |