View Javadoc

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 }