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.io.output; 018 019 import java.io.IOException; 020 import java.io.OutputStream; 021 import java.io.Serializable; 022 import java.util.UUID; 023 024 import org.apache.commons.io.TaggedIOException; 025 026 /** 027 * An output stream decorator that tags potential exceptions so that the 028 * stream that caused the exception can easily be identified. This is 029 * done by using the {@link TaggedIOException} class to wrap all thrown 030 * {@link IOException}s. See below for an example of using this class. 031 * <pre> 032 * TaggedOutputStream stream = new TaggedOutputStream(...); 033 * try { 034 * // Processing that may throw an IOException either from this stream 035 * // or from some other IO activity like temporary files, etc. 036 * writeToStream(stream); 037 * } catch (IOException e) { 038 * if (stream.isCauseOf(e)) { 039 * // The exception was caused by this stream. 040 * // Use e.getCause() to get the original exception. 041 * } else { 042 * // The exception was caused by something else. 043 * } 044 * } 045 * </pre> 046 * <p> 047 * Alternatively, the {@link #throwIfCauseOf(Exception)} method can be 048 * used to let higher levels of code handle the exception caused by this 049 * stream while other processing errors are being taken care of at this 050 * lower level. 051 * <pre> 052 * TaggedOutputStream stream = new TaggedOutputStream(...); 053 * try { 054 * writeToStream(stream); 055 * } catch (IOException e) { 056 * stream.throwIfCauseOf(e); 057 * // ... or process the exception that was caused by something else 058 * } 059 * </pre> 060 * 061 * @see TaggedIOException 062 * @since Commons IO 2.0 063 */ 064 public class TaggedOutputStream extends ProxyOutputStream { 065 066 /** 067 * The unique tag associated with exceptions from stream. 068 */ 069 private final Serializable tag = UUID.randomUUID(); 070 071 /** 072 * Creates a tagging decorator for the given output stream. 073 * 074 * @param proxy output stream to be decorated 075 */ 076 public TaggedOutputStream(OutputStream proxy) { 077 super(proxy); 078 } 079 080 /** 081 * Tests if the given exception was caused by this stream. 082 * 083 * @param exception an exception 084 * @return <code>true</code> if the exception was thrown by this stream, 085 * <code>false</code> otherwise 086 */ 087 public boolean isCauseOf(Exception exception) { 088 return TaggedIOException.isTaggedWith(exception, tag); 089 } 090 091 /** 092 * Re-throws the original exception thrown by this stream. This method 093 * first checks whether the given exception is a {@link TaggedIOException} 094 * wrapper created by this decorator, and then unwraps and throws the 095 * original wrapped exception. Returns normally if the exception was 096 * not thrown by this stream. 097 * 098 * @param exception an exception 099 * @throws IOException original exception, if any, thrown by this stream 100 */ 101 public void throwIfCauseOf(Exception exception) throws IOException { 102 TaggedIOException.throwCauseIfTaggedWith(exception, tag); 103 } 104 105 /** 106 * Tags any IOExceptions thrown, wrapping and re-throwing. 107 * 108 * @param e The IOException thrown 109 * @throws IOException if an I/O error occurs 110 */ 111 @Override 112 protected void handleIOException(IOException e) throws IOException { 113 throw new TaggedIOException(e, tag); 114 } 115 116 }