jaulib v1.3.0
Jau Support Library (C++, Java, ..)
SourcedInterruptedException.java
Go to the documentation of this file.
1/**
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2021 Gothel Software e.K.
4 * Copyright (c) 2015 Gothel Software e.K.
5 * Copyright (c) 2015 JogAmp Community.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining
8 * a copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sublicense, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be
16 * included in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27package org.jau.lang;
28
29import java.io.PrintStream;
30
31import org.jau.lang.ExceptionUtils.CustomStackTrace;
32
33/**
34 * {@link InterruptedException}, which may include the source, see {@link #getInterruptSource()}.
35 * <p>
36 * This exception may be created directly where {@link #getCause()} returns {@code null},
37 * or by propagating an existing {@link InterruptedException} as returned by {@link #getCause()}.
38 * </p>
39 * @since 0.3.0
40 */
41@SuppressWarnings("serial")
42public class SourcedInterruptedException extends InterruptedException implements CustomStackTrace {
43 final Throwable interruptSource;
44
45 /**
46 * Wraps the given {@link InterruptedException} into a {@link SourcedInterruptedException}
47 * if it is not yet of the desired type and
48 * if the current thread if a {@link InterruptSource}, i.e. the source is known.
49 * <p>
50 * Otherwise the given {@link InterruptedException} instance is returned.
51 * </p>
52 * <p>
53 * In case method is creating a new wrapping instance,
54 * {@link InterruptSource#clearInterruptSource()} is being issued.
55 * </p>
56 *
57 * @param ie the to be wrapped {@link InterruptedException}
58 */
59 public static InterruptedException wrap(final InterruptedException ie) {
60 return wrap(ie, InterruptSource.Util.currentThread());
61 }
62
63 /**
64 * Wraps the given {@link InterruptedException} into a {@link SourcedInterruptedException}
65 * if it is not yet of the same type and if {@code source} is not {@code null}.
66 * <p>
67 * Otherwise the given {@link InterruptedException} instance is returned.
68 * </p>
69 * <p>
70 * In case method is creating a new wrapping instance,
71 * {@link InterruptSource#clearInterruptSource()} is being issued.
72 * </p>
73 *
74 * @param ie the to be wrapped {@link InterruptedException}
75 * @param source the {@link InterruptSource}
76 */
77 public static InterruptedException wrap(final InterruptedException ie, final InterruptSource source) {
78 if( !(ie instanceof SourcedInterruptedException) && null != source ) {
79 return new SourcedInterruptedException(ie, source.getInterruptSource(true));
80 } else {
81 return ie;
82 }
83 }
84
85 /**
86 * @param message mandatory message of this exception
87 * @param cause optional propagated cause
88 * @param interruptSource optional propagated source of {@link Thread#interrupt()} call
89 */
90 public SourcedInterruptedException(final String message, final InterruptedException cause, final Throwable interruptSource) {
91 super(message);
92 if( null != cause ) {
93 initCause(cause);
94 }
95 this.interruptSource = interruptSource;
96 }
97
98 /**
99 * @param cause mandatory propagated cause
100 * @param interruptSource optional propagated source of {@link Thread#interrupt()} call
101 */
102 public SourcedInterruptedException(final InterruptedException cause, final Throwable interruptSource) {
103 super(cause.getMessage());
104 initCause(cause);
105 this.interruptSource = interruptSource;
106 }
107
108 /**
109 * Returns the source of the {@link Thread#interrupt()} call if known,
110 * otherwise {@code null} is returned.
111 */
112 public final Throwable getInterruptSource() {
113 return interruptSource;
114 }
115
116 /**
117 * Returns the propagated {@link InterruptedException}, i.e. the cause of this exception,
118 * or {@code null} if not applicable.
119 * <p>
120 * {@inheritDoc}
121 * </p>
122 */
123 @Override
124 public InterruptedException getCause() {
125 return (InterruptedException)super.getCause();
126 }
127
128 @Override
129 public String toString() {
130 final StringBuilder sb = new StringBuilder(256);
131 sb.append(getClass().getSimpleName()).append(": ");
132 if (null != interruptSource) {
133 sb.append("[sourced]");
134 } else {
135 sb.append("[unknown]");
136 }
137 final String m = getLocalizedMessage();
138 if( null != m ) {
139 sb.append(" ").append(m);
140 }
141 return sb.toString();
142 }
143
144 @Override
145 public final void printCauseStack(final PrintStream s, final String causeStr, final int causeIdx, final int stackDepth) {
146 final String s0 = causeStr+"["+causeIdx+"]";
147 s.println(s0+" by "+getClass().getSimpleName()+": "+getMessage()+" on thread "+Thread.currentThread().getName());
148 ExceptionUtils.dumpStack(s, getStackTrace(), 0, stackDepth);
149 if( null != interruptSource ) {
150 ExceptionUtils.printCause(s, s0, interruptSource, 0, 1, stackDepth);
151 }
152 }
153
154 @Override
155 public final void printStackTrace(final PrintStream s, final int causeDepth, final int stackDepth) {
156 s.println(getClass().getSimpleName()+": "+getMessage()+" on thread "+Thread.currentThread().getName());
157 ExceptionUtils.dumpStack(s, getStackTrace(), 0, stackDepth);
158 ExceptionUtils.printCause(s, "Caused", getCause(), 0, causeDepth, stackDepth);
159 if( null != interruptSource ) {
160 ExceptionUtils.printCause(s, "InterruptSource", interruptSource, 0, causeDepth, stackDepth);
161 }
162 }
163}
static int printCause(final PrintStream s, final String causeStr, Throwable cause, final int causeIdx, final int causeDepth, final int stackDepth)
Prints the given Throwable cause to the output PrintStream s.
static void dumpStack(final PrintStream out)
static InterruptSource currentThread()
Casts current java.lang.Thread to InterruptSource if applicable, otherwise returns null.
InterruptedException, which may include the source, see getInterruptSource().
static InterruptedException wrap(final InterruptedException ie)
Wraps the given InterruptedException into a SourcedInterruptedException if it is not yet of the desir...
InterruptedException getCause()
Returns the propagated InterruptedException, i.e.
SourcedInterruptedException(final InterruptedException cause, final Throwable interruptSource)
final void printStackTrace(final PrintStream s, final int causeDepth, final int stackDepth)
Custom printStackTrace method, similar to Throwable#printStackTrace(PrintStream, int,...
SourcedInterruptedException(final String message, final InterruptedException cause, final Throwable interruptSource)
final Throwable getInterruptSource()
Returns the source of the Thread#interrupt() call if known, otherwise null is returned.
static InterruptedException wrap(final InterruptedException ie, final InterruptSource source)
Wraps the given InterruptedException into a SourcedInterruptedException if it is not yet of the same ...
final void printCauseStack(final PrintStream s, final String causeStr, final int causeIdx, final int stackDepth)
Prints this Throwable as a cause to the output PrintStream s, not iterating over all inner causes!
Interface allowing Throwable specializations to provide their custom stack trace presentation.
Interface exposing java.lang.Thread#interrupt() source, intended for java.lang.Thread specializations...
Throwable getInterruptSource(final boolean clear)
Returns the source of the last interrupt() call.