View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.tika.io;
18  
19   import java.io.IOException;
20  import java.io.InputStream;
21  
22  /**
23   * An input stream decorator that tags potential exceptions so that the
24   * stream that caused the exception can easily be identified. This is
25   * done by using the {@link TaggedIOException} class to wrap all thrown
26   * {@link IOException}s. See below for an example of using this class.
27   * <pre>
28   * TaggedInputStream stream = new TaggedInputStream(...);
29   * try {
30   *     // Processing that may throw an IOException either from this stream
31   *     // or from some other IO activity like temporary files, etc.
32   *     processStream(stream);
33   * } catch (IOException e) {
34   *     if (stream.isCauseOf(e)) {
35   *         // The exception was caused by this stream.
36   *         // Use e.getCause() to get the original exception.
37   *     } else {
38   *         // The exception was caused by something else.
39   *     }
40   * }
41   * </pre>
42   * <p>
43   * Alternatively, the {@link #throwIfCauseOf(Exception)} method can be
44   * used to let higher levels of code handle the exception caused by this
45   * stream while other processing errors are being taken care of at this
46   * lower level.
47   * <pre>
48   * TaggedInputStream stream = new TaggedInputStream(...);
49   * try {
50   *     processStream(stream);
51   * } catch (IOException e) {
52   *     stream.throwIfCauseOf(e);
53   *     // ... or process the exception that was caused by something else
54   * }
55   * </pre>
56   *
57   * @see TaggedIOException
58   */
59  public class TaggedInputStream extends ProxyInputStream {
60  
61      /**
62       * Creates a tagging decorator for the given input stream.
63       *
64       * @param proxy input stream to be decorated
65       */
66      public TaggedInputStream(InputStream proxy) {
67          super(proxy);
68      }
69  
70      /**
71       * Tests if the given exception was caused by this stream.
72       *
73       * @param exception an exception
74       * @return <code>true</code> if the exception was thrown by this stream,
75       *         <code>false</code> otherwise
76       */
77      public boolean isCauseOf(IOException exception) {
78          if (exception instanceof TaggedIOException) {
79              TaggedIOException tagged = (TaggedIOException) exception;
80              return this == tagged.getTag();
81          } else {
82              return false;
83          }
84      }
85  
86      /**
87       * Re-throws the original exception thrown by this stream. This method
88       * first checks whether the given exception is a {@link TaggedIOException}
89       * wrapper created by this decorator, and then unwraps and throws the
90       * original wrapped exception. Returns normally if the exception was
91       * not thrown by this stream.
92       *
93       * @param exception an exception
94       * @throws IOException original exception, if any, thrown by this stream
95       */
96      public void throwIfCauseOf(Exception exception) throws IOException {
97          if (exception instanceof TaggedIOException) {
98              TaggedIOException tagged = (TaggedIOException) exception;
99              if (this == tagged.getTag()) {
100                 throw tagged.getCause();
101             }
102         }
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, this);
114     }
115 
116 }