001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.math;
018
019 import java.io.EOFException;
020 import java.io.IOException;
021 import java.io.PrintStream;
022 import java.io.PrintWriter;
023 import java.text.MessageFormat;
024 import java.text.ParseException;
025 import java.util.ConcurrentModificationException;
026 import java.util.Locale;
027 import java.util.NoSuchElementException;
028 import java.util.Set;
029
030 import org.apache.commons.math.exception.util.Localizable;
031 import org.apache.commons.math.exception.util.LocalizedFormats;
032
033 /**
034 * Base class for commons-math unchecked exceptions.
035 *
036 * @version $Id: MathRuntimeException.java 1178040 2011-10-01 16:23:48Z erans $
037 * @since 2.0
038 * @deprecated To be removed before 3.0. Please do not use in any new code.
039 */
040 public class MathRuntimeException extends RuntimeException {
041
042 /** Serializable version identifier. */
043 private static final long serialVersionUID = 9058794795027570002L;
044
045 /** Deprecation message. */
046 private static final String DEPRECATION_MESSAGE = "This class is deprecated; calling this method is a bug.";
047
048 /**
049 * Pattern used to build the message.
050 */
051 private final Localizable pattern;
052
053 /**
054 * Arguments used to build the message.
055 */
056 private final Object[] arguments;
057
058 /**
059 * Constructs a new <code>MathRuntimeException</code> with specified
060 * formatted detail message.
061 * Message formatting is delegated to {@link java.text.MessageFormat}.
062 * @param pattern format specifier
063 * @param arguments format arguments
064 * @since 2.2
065 */
066 public MathRuntimeException(final Localizable pattern, final Object ... arguments) {
067 this.pattern = pattern;
068 this.arguments = (arguments == null) ? new Object[0] : arguments.clone();
069 }
070
071 /**
072 * Constructs a new <code>MathRuntimeException</code> with specified
073 * nested <code>Throwable</code> root cause.
074 *
075 * @param rootCause the exception or error that caused this exception
076 * to be thrown.
077 */
078 public MathRuntimeException(final Throwable rootCause) {
079 super(rootCause);
080 this.pattern = LocalizedFormats.SIMPLE_MESSAGE;
081 this.arguments = new Object[] { (rootCause == null) ? "" : rootCause.getMessage() };
082 }
083
084 /**
085 * Constructs a new <code>MathRuntimeException</code> with specified
086 * formatted detail message and nested <code>Throwable</code> root cause.
087 * Message formatting is delegated to {@link java.text.MessageFormat}.
088 * @param rootCause the exception or error that caused this exception
089 * to be thrown.
090 * @param pattern format specifier
091 * @param arguments format arguments
092 * @since 2.2
093 */
094 public MathRuntimeException(final Throwable rootCause,
095 final Localizable pattern, final Object ... arguments) {
096 super(rootCause);
097 this.pattern = pattern;
098 this.arguments = (arguments == null) ? new Object[0] : arguments.clone();
099 }
100
101 /**
102 * Sets a message.
103 *
104 * @param pat Message pattern.
105 * @param args Values for replacing the placeholders in the message
106 * pattern.
107 */
108 public void addMessage(Localizable pat,
109 Object ... args) {
110 throw new UnsupportedOperationException(DEPRECATION_MESSAGE);
111 }
112
113 /**
114 * Sets the context (key, value) pair.
115 * Keys are assumed to be unique within an instance. If the same key is
116 * assigned a new value, the previous one will be lost.
117 *
118 * @param key Context key (not null).
119 * @param value Context value.
120 */
121 public void setContext(String key, Object value) {
122 throw new UnsupportedOperationException(DEPRECATION_MESSAGE);
123 }
124
125 /**
126 * Gets the value associated to the given context key.
127 *
128 * @param key Context key.
129 * @return the context value or {@code null} if the key does not exist.
130 */
131 public Object getContext(String key) {
132 throw new UnsupportedOperationException(DEPRECATION_MESSAGE);
133 }
134
135 /**
136 * Gets all the keys stored in the exception
137 *
138 * @return the set of keys.
139 */
140 public Set<String> getContextKeys() {
141 throw new UnsupportedOperationException(DEPRECATION_MESSAGE);
142 }
143
144 /**
145 * Builds a message string by from a pattern and its arguments.
146 * @param locale Locale in which the message should be translated
147 * @param pattern format specifier
148 * @param arguments format arguments
149 * @return a message string
150 * @since 2.2
151 */
152 private static String buildMessage(final Locale locale, final Localizable pattern,
153 final Object ... arguments) {
154 return new MessageFormat(pattern.getLocalizedString(locale), locale).format(arguments);
155 }
156
157 /** Gets the message in a specified locale.
158 *
159 * @param locale Locale in which the message should be translated
160 *
161 * @return localized message
162 */
163 public String getMessage(final Locale locale) {
164 if (pattern != null) {
165 return buildMessage(locale, pattern, arguments);
166 }
167 return "";
168 }
169
170 /**
171 * Gets the message in a conventional US locale.
172 *
173 * @return localized message
174 */
175 @Override
176 public String getMessage() {
177 return getMessage(Locale.US);
178 }
179
180 /**
181 * Gets the message in the system default locale.
182 *
183 * @return localized message
184 */
185 @Override
186 public String getLocalizedMessage() {
187 return getMessage(Locale.getDefault());
188 }
189
190 /**
191 * Prints the stack trace of this exception to the standard error stream.
192 */
193 @Override
194 public void printStackTrace() {
195 printStackTrace(System.err);
196 }
197
198 /**
199 * Prints the stack trace of this exception to the specified stream.
200 *
201 * @param out the <code>PrintStream</code> to use for output
202 */
203 @Override
204 public void printStackTrace(final PrintStream out) {
205 synchronized (out) {
206 PrintWriter pw = new PrintWriter(out, false);
207 printStackTrace(pw);
208 // Flush the PrintWriter before it's GC'ed.
209 pw.flush();
210 }
211 }
212
213 /**
214 * Constructs a new <code>ArithmeticException</code> with specified formatted detail message.
215 * Message formatting is delegated to {@link java.text.MessageFormat}.
216 * @param pattern format specifier
217 * @param arguments format arguments
218 * @return built exception
219 * @since 2.2
220 */
221 public static ArithmeticException createArithmeticException(final Localizable pattern,
222 final Object ... arguments) {
223 return new ArithmeticException() {
224
225 /** Serializable version identifier. */
226 private static final long serialVersionUID = 5305498554076846637L;
227
228 /** {@inheritDoc} */
229 @Override
230 public String getMessage() {
231 return buildMessage(Locale.US, pattern, arguments);
232 }
233
234 /** {@inheritDoc} */
235 @Override
236 public String getLocalizedMessage() {
237 return buildMessage(Locale.getDefault(), pattern, arguments);
238 }
239
240 };
241 }
242
243 /**
244 * Constructs a new <code>ArrayIndexOutOfBoundsException</code> with specified formatted detail message.
245 * Message formatting is delegated to {@link java.text.MessageFormat}.
246 * @param pattern format specifier
247 * @param arguments format arguments
248 * @return built exception
249 * @since 2.2
250 */
251 public static ArrayIndexOutOfBoundsException createArrayIndexOutOfBoundsException(final Localizable pattern,
252 final Object ... arguments) {
253 return new ArrayIndexOutOfBoundsException() {
254
255 /** Serializable version identifier. */
256 private static final long serialVersionUID = 6718518191249632175L;
257
258 /** {@inheritDoc} */
259 @Override
260 public String getMessage() {
261 return buildMessage(Locale.US, pattern, arguments);
262 }
263
264 /** {@inheritDoc} */
265 @Override
266 public String getLocalizedMessage() {
267 return buildMessage(Locale.getDefault(), pattern, arguments);
268 }
269
270 };
271 }
272
273 /**
274 * Constructs a new <code>EOFException</code> with specified formatted detail message.
275 * Message formatting is delegated to {@link java.text.MessageFormat}.
276 * @param pattern format specifier
277 * @param arguments format arguments
278 * @return built exception
279 * @since 2.2
280 */
281 public static EOFException createEOFException(final Localizable pattern,
282 final Object ... arguments) {
283 return new EOFException() {
284
285 /** Serializable version identifier. */
286 private static final long serialVersionUID = 6067985859347601503L;
287
288 /** {@inheritDoc} */
289 @Override
290 public String getMessage() {
291 return buildMessage(Locale.US, pattern, arguments);
292 }
293
294 /** {@inheritDoc} */
295 @Override
296 public String getLocalizedMessage() {
297 return buildMessage(Locale.getDefault(), pattern, arguments);
298 }
299
300 };
301 }
302
303 /**
304 * Constructs a new <code>IOException</code> with specified nested
305 * <code>Throwable</code> root cause.
306 * <p>This factory method allows chaining of other exceptions within an
307 * <code>IOException</code> even for Java 5. The constructor for
308 * <code>IOException</code> with a cause parameter was introduced only
309 * with Java 6.</p>
310 * @param rootCause the exception or error that caused this exception
311 * to be thrown.
312 * @return built exception
313 */
314 public static IOException createIOException(final Throwable rootCause) {
315 IOException ioe = new IOException(rootCause.getLocalizedMessage());
316 ioe.initCause(rootCause);
317 return ioe;
318 }
319
320 /**
321 * Constructs a new <code>IllegalArgumentException</code> with specified formatted detail message.
322 * Message formatting is delegated to {@link java.text.MessageFormat}.
323 * @param pattern format specifier
324 * @param arguments format arguments
325 * @return built exception
326 * @since 2.2
327 */
328 public static IllegalArgumentException createIllegalArgumentException(final Localizable pattern,
329 final Object ... arguments) {
330 return new IllegalArgumentException() {
331
332 /** Serializable version identifier. */
333 private static final long serialVersionUID = -4284649691002411505L;
334
335 /** {@inheritDoc} */
336 @Override
337 public String getMessage() {
338 return buildMessage(Locale.US, pattern, arguments);
339 }
340
341 /** {@inheritDoc} */
342 @Override
343 public String getLocalizedMessage() {
344 return buildMessage(Locale.getDefault(), pattern, arguments);
345 }
346
347 };
348 }
349
350 /**
351 * Constructs a new <code>IllegalArgumentException</code> with specified nested
352 * <code>Throwable</code> root cause.
353 * @param rootCause the exception or error that caused this exception
354 * to be thrown.
355 * @return built exception
356 */
357 public static IllegalArgumentException createIllegalArgumentException(final Throwable rootCause) {
358 IllegalArgumentException iae = new IllegalArgumentException(rootCause.getLocalizedMessage());
359 iae.initCause(rootCause);
360 return iae;
361 }
362
363 /**
364 * Constructs a new <code>IllegalStateException</code> with specified formatted detail message.
365 * Message formatting is delegated to {@link java.text.MessageFormat}.
366 * @param pattern format specifier
367 * @param arguments format arguments
368 * @return built exception
369 * @since 2.2
370 */
371 public static IllegalStateException createIllegalStateException(final Localizable pattern,
372 final Object ... arguments) {
373 return new IllegalStateException() {
374
375 /** Serializable version identifier. */
376 private static final long serialVersionUID = 6880901520234515725L;
377
378 /** {@inheritDoc} */
379 @Override
380 public String getMessage() {
381 return buildMessage(Locale.US, pattern, arguments);
382 }
383
384 /** {@inheritDoc} */
385 @Override
386 public String getLocalizedMessage() {
387 return buildMessage(Locale.getDefault(), pattern, arguments);
388 }
389
390 };
391 }
392
393 /**
394 * Constructs a new <code>ConcurrentModificationException</code> with specified formatted detail message.
395 * Message formatting is delegated to {@link java.text.MessageFormat}.
396 * @param pattern format specifier
397 * @param arguments format arguments
398 * @return built exception
399 * @since 2.2
400 */
401 public static ConcurrentModificationException createConcurrentModificationException(final Localizable pattern,
402 final Object ... arguments) {
403 return new ConcurrentModificationException() {
404
405 /** Serializable version identifier. */
406 private static final long serialVersionUID = -1878427236170442052L;
407
408 /** {@inheritDoc} */
409 @Override
410 public String getMessage() {
411 return buildMessage(Locale.US, pattern, arguments);
412 }
413
414 /** {@inheritDoc} */
415 @Override
416 public String getLocalizedMessage() {
417 return buildMessage(Locale.getDefault(), pattern, arguments);
418 }
419
420 };
421 }
422
423 /**
424 * Constructs a new <code>NoSuchElementException</code> with specified formatted detail message.
425 * Message formatting is delegated to {@link java.text.MessageFormat}.
426 * @param pattern format specifier
427 * @param arguments format arguments
428 * @return built exception
429 * @since 2.2
430 */
431 public static NoSuchElementException createNoSuchElementException(final Localizable pattern,
432 final Object ... arguments) {
433 return new NoSuchElementException() {
434
435 /** Serializable version identifier. */
436 private static final long serialVersionUID = 1632410088350355086L;
437
438 /** {@inheritDoc} */
439 @Override
440 public String getMessage() {
441 return buildMessage(Locale.US, pattern, arguments);
442 }
443
444 /** {@inheritDoc} */
445 @Override
446 public String getLocalizedMessage() {
447 return buildMessage(Locale.getDefault(), pattern, arguments);
448 }
449
450 };
451 }
452
453 /**
454 * Constructs a new <code>ParseException</code> with specified
455 * formatted detail message.
456 * Message formatting is delegated to {@link java.text.MessageFormat}.
457 * @param offset offset at which error occurred
458 * @param pattern format specifier
459 * @param arguments format arguments
460 * @return built exception
461 * @since 2.2
462 */
463 public static ParseException createParseException(final int offset,
464 final Localizable pattern,
465 final Object ... arguments) {
466 return new ParseException(null, offset) {
467
468 /** Serializable version identifier. */
469 private static final long serialVersionUID = 8153587599409010120L;
470
471 /** {@inheritDoc} */
472 @Override
473 public String getMessage() {
474 return buildMessage(Locale.US, pattern, arguments);
475 }
476
477 /** {@inheritDoc} */
478 @Override
479 public String getLocalizedMessage() {
480 return buildMessage(Locale.getDefault(), pattern, arguments);
481 }
482
483 };
484 }
485
486 /** Create an {@link java.lang.RuntimeException} for an internal error.
487 * @param cause underlying cause
488 * @return an {@link java.lang.RuntimeException} for an internal error
489 */
490 public static RuntimeException createInternalError(final Throwable cause) {
491
492 final String argument = "https://issues.apache.org/jira/browse/MATH";
493
494 return new RuntimeException(cause) {
495
496 /** Serializable version identifier. */
497 private static final long serialVersionUID = -201865440834027016L;
498
499 /** {@inheritDoc} */
500 @Override
501 public String getMessage() {
502 return buildMessage(Locale.US, LocalizedFormats.INTERNAL_ERROR, argument);
503 }
504
505 /** {@inheritDoc} */
506 @Override
507 public String getLocalizedMessage() {
508 return buildMessage(Locale.getDefault(), LocalizedFormats.INTERNAL_ERROR, argument);
509 }
510
511 };
512
513 }
514
515 }