1 /* 2 * Copyright 2007-2013 smartics, Kronseder & Reiner GmbH 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package de.smartics.exceptions; 17 18 import java.util.Date; 19 20 import de.smartics.exceptions.core.Code; 21 import de.smartics.exceptions.core.CodeMessageFormatter; 22 import de.smartics.exceptions.core.ExceptionId; 23 import de.smartics.exceptions.core.ThrowableHandleMode; 24 import de.smartics.exceptions.runtime.FallbackClassLoader; 25 import de.smartics.exceptions.runtime.ExceptionContextManager; 26 27 /** 28 * The base implementation of the core runtime exception that supports unique 29 * identifying and exception codes for unchecked exceptions. 30 */ 31 public abstract class AbstractCoreRuntimeException extends RuntimeException 32 implements CoreException 33 { 34 // ********************************* Fields ********************************* 35 36 // --- constants ------------------------------------------------------------ 37 38 /** 39 * The class version identifier. 40 */ 41 private static final long serialVersionUID = 4L; 42 43 // --- members -------------------------------------------------------------- 44 45 /** 46 * Reference to common exception information. Currently this is the exception 47 * identifier and the exception code. 48 * 49 * @serial 50 */ 51 protected final ExceptionInfo info; // NOPMD 52 53 // ****************************** Initializer ******************************* 54 55 // ****************************** Constructors ****************************** 56 57 /** 58 * Constructor. 59 * 60 * @param code the error or exception code of the exception. 61 * @see AbstractCoreRuntimeException#AbstractCoreRuntimeException(String, 62 * Throwable, Code) 63 */ 64 protected AbstractCoreRuntimeException(final Code code) 65 { 66 this(null, null, code); 67 } 68 69 /** 70 * Constructor. 71 * 72 * @param message the detail message (which is saved for later retrieval by 73 * the {@link #getMessage()} method). Only used if there is no 74 * localised message in the bundle. 75 * @param code the error or exception code of the exception. 76 * @see AbstractCoreRuntimeException#AbstractCoreRuntimeException(String, 77 * Throwable, Code) 78 */ 79 protected AbstractCoreRuntimeException(final String message, final Code code) 80 { 81 this(message, null, code); 82 } 83 84 /** 85 * Constructor. 86 * 87 * @param cause the cause (which is saved for later retrieval by the 88 * {@link #getCause()} method). (A <tt>null</tt> value is permitted, 89 * and indicates that the cause is nonexistent or unknown.) 90 * @param code the error or exception code of the exception. 91 * @see AbstractCoreRuntimeException#AbstractCoreRuntimeException(String, 92 * Throwable, Code) 93 */ 94 protected AbstractCoreRuntimeException(final Throwable cause, final Code code) 95 { 96 this(null, cause, code); 97 } 98 99 /** 100 * Constructor. 101 * 102 * @param message the detail message (which is saved for later retrieval by 103 * the {@link #getMessage()} method). Only used if there is no 104 * localised message in the bundle. 105 * @param cause the cause (which is saved for later retrieval by the 106 * {@link #getCause()} method). (A <tt>null</tt> value is permitted, 107 * and indicates that the cause is nonexistent or unknown.) 108 * @param code the error or exception code of the exception. 109 * @throws NullPointerException if the code is <code>null</code>. 110 * @see java.lang.RuntimeException#RuntimeException(java.lang.String,java.lang.Throwable) 111 */ 112 protected AbstractCoreRuntimeException(final String message, 113 final Throwable cause, final Code code) throws NullPointerException 114 { 115 super(message, Helper.provideException(cause)); 116 this.info = new ExceptionInfo(cause, code); 117 } 118 119 // ****************************** Inner Classes ***************************** 120 121 // ********************************* Methods ******************************** 122 123 // --- init ----------------------------------------------------------------- 124 125 // --- get&set -------------------------------------------------------------- 126 127 /** 128 * Returns the unique identifier of the exception. The identifier is used to 129 * track an exception in different tiers. 130 * <p> 131 * This identifier must never be <code>null</code>. 132 * </p> 133 * 134 * @return the unique identifier of the exception. 135 */ 136 @Override 137 public final ExceptionId<?> getId() 138 { 139 return info.getId(); 140 } 141 142 /** 143 * Returns the error or exception code of the exception. 144 * <p> 145 * This code must never be <code>null</code>. 146 * </p> 147 * 148 * @return the error or exception code of the exception. 149 */ 150 @Override 151 public final Code getCode() 152 { 153 return info.getCode(); 154 } 155 156 @Override 157 public final Date getTime() 158 { 159 return info.getTime(); 160 } 161 162 @Override 163 public final Throwable getCause() 164 { 165 if (Helper.getThrowableHandleMode() == ThrowableHandleMode.NORMAL) 166 { 167 return super.getCause(); 168 } 169 else 170 { 171 return info.removeableCause; 172 } 173 } 174 175 // --- business ------------------------------------------------------------- 176 177 @Override 178 public final void truncateCause() 179 { 180 Helper.truncateCause(this, this.info); 181 } 182 183 // --- object basics -------------------------------------------------------- 184 185 /** 186 * Returns a class loader to provide resources from the class path. 187 * 188 * @return a class loader to provide resources from the class path. 189 */ 190 protected final ClassLoader getClassLoader() 191 { 192 final ClassLoader loader = 193 new FallbackClassLoader(Thread.currentThread() 194 .getContextClassLoader(), getClass().getClassLoader()); // NOPMD 195 return loader; 196 } 197 198 /** 199 * Returns the string representation of the exception. 200 * <p> 201 * May be overridden by subclasses in an application (not a library) to change 202 * the string representation. Usually an implementation of 203 * {@code CodeMessageFormatter} should be set to the 204 * {@link de.smartics.exceptions.ExceptionContext}. 205 * </p> 206 * 207 * @return the string representation of the object. 208 */ 209 @Override 210 public String toString() 211 { 212 final CodeMessageFormatter formatter = 213 ExceptionContextManager.getFormatter(getClassLoader()); 214 final String string = formatter.format(this); 215 return string; 216 } 217 }