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 *      https://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.channels;
019
020import java.io.FilterInputStream;
021import java.io.FilterOutputStream;
022import java.io.FilterReader;
023import java.io.IOException;
024import java.nio.channels.SeekableByteChannel;
025
026import org.apache.commons.io.input.ProxyInputStream;
027import org.apache.commons.io.input.ProxyReader;
028import org.apache.commons.io.output.ProxyOutputStream;
029import org.apache.commons.io.output.ProxyWriter;
030
031/**
032 * A {@link SeekableByteChannel} filter which delegates to the wrapped {@link SeekableByteChannel}.
033 * <p>
034 * A {@code FilterSeekableByteChannel} wraps some other channel, which it uses as its basic source of data, possibly transforming the data along the way or
035 * providing additional functionality. The class {@code FilterSeekableByteChannel} itself simply overrides methods of {@code SeekableByteChannel} with versions
036 * that pass all requests to the wrapped channel. Subclasses of {@code FilterSeekableByteChannel} may of course override any methods declared or inherited by
037 * {@code FilterSeekableByteChannel}, and may also provide additional fields and methods.
038 * </p>
039 * <p>
040 * You construct s simple instance with the {@link FilterSeekableByteChannel#FilterSeekableByteChannel(SeekableByteChannel) Channel constructor} and more
041 * advanced instances through the {@link Builder}.
042 * </p>
043 *
044 * @param <C> the {@link SeekableByteChannel} type.
045 * @see FilterInputStream
046 * @see FilterOutputStream
047 * @see FilterReader
048 * @see FilterWritableByteChannel
049 * @see ProxyInputStream
050 * @see ProxyOutputStream
051 * @see ProxyReader
052 * @see ProxyWriter
053 * @since 2.22.0
054 */
055public class FilterSeekableByteChannel<C extends SeekableByteChannel> extends FilterByteChannel<C> implements SeekableByteChannel {
056
057    /**
058     * Builds instances of {@link FilterSeekableByteChannel} for subclasses.
059     *
060     * @param <F> The {@link FilterSeekableByteChannel} type.
061     * @param <C> The {@link SeekableByteChannel} type wrapped by the FilterChannel.
062     * @param <B> The builder type.
063     */
064    public abstract static class AbstractBuilder<F extends FilterSeekableByteChannel<C>, C extends SeekableByteChannel, B extends AbstractBuilder<F, C, B>>
065            extends FilterByteChannel.AbstractBuilder<F, C, B> {
066
067        /**
068         * Constructs a new builder for {@link FilterSeekableByteChannel}.
069         */
070        public AbstractBuilder() {
071            // empty
072        }
073    }
074
075    /**
076     * Builds instances of {@link FilterSeekableByteChannel}.
077     */
078    public static class Builder extends AbstractBuilder<FilterSeekableByteChannel<SeekableByteChannel>, SeekableByteChannel, Builder> {
079
080        /**
081         * Builds instances of {@link FilterSeekableByteChannel}.
082         */
083        protected Builder() {
084            // empty
085        }
086
087        @Override
088        public FilterSeekableByteChannel<SeekableByteChannel> get() throws IOException {
089            return new FilterSeekableByteChannel<>(this);
090        }
091    }
092
093    /**
094     * Creates a new {@link Builder}.
095     *
096     * @return a new {@link Builder}.
097     */
098    public static Builder forSeekableByteChannel() {
099        return new Builder();
100    }
101
102    FilterSeekableByteChannel(final Builder builder) throws IOException {
103        super(builder);
104    }
105
106    /**
107     * Constructs a new instance.
108     *
109     * @param channel The channel to wrap.
110     */
111    public FilterSeekableByteChannel(final C channel) {
112        super(channel);
113    }
114
115    @Override
116    public long position() throws IOException {
117        return channel.position();
118    }
119
120    @Override
121    public SeekableByteChannel position(final long newPosition) throws IOException {
122        return channel.position(newPosition);
123    }
124
125    @Override
126    public long size() throws IOException {
127        return channel.size();
128    }
129
130    @Override
131    public SeekableByteChannel truncate(final long size) throws IOException {
132        return channel.truncate(size);
133    }
134}