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 018package org.apache.commons.io.input; 019 020import java.io.FilterReader; 021import java.io.IOException; 022import java.io.Reader; 023import java.io.UncheckedIOException; 024import java.nio.CharBuffer; 025import java.nio.charset.Charset; 026 027import org.apache.commons.io.build.AbstractOrigin; 028import org.apache.commons.io.build.AbstractStreamBuilder; 029import org.apache.commons.io.function.Uncheck; 030 031/** 032 * A {@link FilterReader} that throws {@link UncheckedIOException} instead of {@link IOException}. 033 * <p> 034 * To build an instance, see {@link Builder}. 035 * </p> 036 * 037 * @see FilterReader 038 * @see IOException 039 * @see UncheckedIOException 040 * @since 2.12.0 041 */ 042public final class UncheckedFilterReader extends FilterReader { 043 044 /** 045 * Builds a new {@link UncheckedFilterReader} instance. 046 * <p> 047 * Using File IO: 048 * </p> 049 * <pre>{@code 050 * UncheckedFilterReader s = UncheckedFilterReader.builder() 051 * .setFile(file) 052 * .get();} 053 * </pre> 054 * <p> 055 * Using NIO Path: 056 * </p> 057 * <pre>{@code 058 * UncheckedFilterReader s = UncheckedFilterReader.builder() 059 * .setPath(path) 060 * .get();} 061 * </pre> 062 */ 063 public static class Builder extends AbstractStreamBuilder<UncheckedFilterReader, Builder> { 064 065 /** 066 * Constructs a new instance. 067 * <p> 068 * This builder use the aspects Reader and Charset. 069 * </p> 070 * <p> 071 * You must provide an origin that can be converted to a Reader by this builder, otherwise, this call will throw an 072 * {@link UnsupportedOperationException}. 073 * </p> 074 * 075 * @return a new instance. 076 * @throws UnsupportedOperationException if the origin cannot provide a Reader. 077 * @throws IllegalStateException if the {@code origin} is {@code null}. 078 * @see AbstractOrigin#getReader(Charset) 079 */ 080 @Override 081 public UncheckedFilterReader get() { 082 // This an unchecked class, so this method is as well. 083 return Uncheck.get(() -> new UncheckedFilterReader(checkOrigin().getReader(getCharset()))); 084 } 085 086 } 087 088 /** 089 * Constructs a new {@link Builder}. 090 * 091 * @return a new {@link Builder}. 092 */ 093 public static Builder builder() { 094 return new Builder(); 095 } 096 097 /** 098 * Constructs a new filtered reader. 099 * 100 * @param reader a Reader object providing the underlying stream. 101 * @throws NullPointerException if {@code reader} is {@code null}. 102 */ 103 private UncheckedFilterReader(final Reader reader) { 104 super(reader); 105 } 106 107 /** 108 * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}. 109 */ 110 @Override 111 public void close() throws UncheckedIOException { 112 Uncheck.run(super::close); 113 } 114 115 /** 116 * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}. 117 */ 118 @Override 119 public void mark(final int readAheadLimit) throws UncheckedIOException { 120 Uncheck.accept(super::mark, readAheadLimit); 121 } 122 123 /** 124 * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}. 125 */ 126 @Override 127 public int read() throws UncheckedIOException { 128 return Uncheck.get(super::read); 129 } 130 131 /** 132 * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}. 133 */ 134 @Override 135 public int read(final char[] cbuf) throws UncheckedIOException { 136 return Uncheck.apply(super::read, cbuf); 137 } 138 139 /** 140 * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}. 141 */ 142 @Override 143 public int read(final char[] cbuf, final int off, final int len) throws UncheckedIOException { 144 return Uncheck.apply(super::read, cbuf, off, len); 145 } 146 147 /** 148 * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}. 149 */ 150 @Override 151 public int read(final CharBuffer target) throws UncheckedIOException { 152 return Uncheck.apply(super::read, target); 153 } 154 155 /** 156 * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}. 157 */ 158 @Override 159 public boolean ready() throws UncheckedIOException { 160 return Uncheck.get(super::ready); 161 } 162 163 /** 164 * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}. 165 */ 166 @Override 167 public void reset() throws UncheckedIOException { 168 Uncheck.run(super::reset); 169 } 170 171 /** 172 * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}. 173 */ 174 @Override 175 public long skip(final long n) throws UncheckedIOException { 176 return Uncheck.apply(super::skip, n); 177 } 178 179}