/* * 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.commons.io; import java.io.IOException; import java.io.Serializable; /** * An {@link IOException} decorator that adds a serializable tag to the * wrapped exception. Both the tag and the original exception can be used * to determine further processing when this exception is caught. * * @since 2.0 */ @SuppressWarnings("deprecation") // needs to extend deprecated IOExceptionWithCause to preserve binary compatibility public class TaggedIOException extends IOExceptionWithCause { /** * Generated serial version UID. */ private static final long serialVersionUID = -6994123481142850163L; /** * Checks whether the given throwable is tagged with the given tag. *

* This check can only succeed if the throwable is a * {@link TaggedIOException} and the tag is {@link Serializable}, but * the argument types are intentionally more generic to make it easier * to use this method without type casts. *

* A typical use for this method is in a {@code catch} block to * determine how a caught exception should be handled: *

     * Serializable tag = ...;
     * try {
     *     ...;
     * } catch (Throwable t) {
     *     if (TaggedIOException.isTaggedWith(t, tag)) {
     *         // special processing for tagged exception
     *     } else {
     *         // handling of other kinds of exceptions
     *     }
     * }
     * 
* * @param throwable The Throwable object to check * @param tag tag object * @return {@code true} if the throwable has the specified tag, * otherwise {@code false} */ public static boolean isTaggedWith(final Throwable throwable, final Object tag) { return tag != null && throwable instanceof TaggedIOException && tag.equals(((TaggedIOException) throwable).tag); } /** * Throws the original {@link IOException} if the given throwable is * a {@link TaggedIOException} decorator the given tag. Does nothing * if the given throwable is of a different type or if it is tagged * with some other tag. *

* This method is typically used in a {@code catch} block to * selectively rethrow tagged exceptions. *

     * Serializable tag = ...;
     * try {
     *     ...;
     * } catch (Throwable t) {
     *     TaggedIOException.throwCauseIfTagged(t, tag);
     *     // handle other kinds of exceptions
     * }
     * 
* * @param throwable an exception * @param tag tag object * @throws IOException original exception from the tagged decorator, if any */ public static void throwCauseIfTaggedWith(final Throwable throwable, final Object tag) throws IOException { if (isTaggedWith(throwable, tag)) { throw ((TaggedIOException) throwable).getCause(); } } /** * The tag of this exception. */ private final Serializable tag; /** * Creates a tagged wrapper for the given exception. * * @param original the exception to be tagged * @param tag tag of this exception */ public TaggedIOException(final IOException original, final Serializable tag) { super(original.getMessage(), original); this.tag = tag; } /** * Returns the wrapped exception. The only difference to the overridden * {@link Throwable#getCause()} method is the narrower return type. * * @return wrapped exception */ @Override public synchronized IOException getCause() { return (IOException) super.getCause(); } /** * Returns the serializable tag object. * * @return tag object */ public Serializable getTag() { return tag; } }