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.build;
019
020import java.io.File;
021import java.io.InputStream;
022import java.io.OutputStream;
023import java.io.RandomAccessFile;
024import java.io.Reader;
025import java.io.Writer;
026import java.net.URI;
027import java.nio.channels.Channel;
028import java.nio.file.Path;
029import java.nio.file.Paths;
030
031import org.apache.commons.io.IORandomAccessFile;
032import org.apache.commons.io.build.AbstractOrigin.ByteArrayOrigin;
033import org.apache.commons.io.build.AbstractOrigin.ChannelOrigin;
034import org.apache.commons.io.build.AbstractOrigin.CharSequenceOrigin;
035import org.apache.commons.io.build.AbstractOrigin.FileOrigin;
036import org.apache.commons.io.build.AbstractOrigin.IORandomAccessFileOrigin;
037import org.apache.commons.io.build.AbstractOrigin.InputStreamOrigin;
038import org.apache.commons.io.build.AbstractOrigin.OutputStreamOrigin;
039import org.apache.commons.io.build.AbstractOrigin.PathOrigin;
040import org.apache.commons.io.build.AbstractOrigin.RandomAccessFileOrigin;
041import org.apache.commons.io.build.AbstractOrigin.ReaderOrigin;
042import org.apache.commons.io.build.AbstractOrigin.URIOrigin;
043import org.apache.commons.io.build.AbstractOrigin.WriterOrigin;
044
045/**
046 * Abstracts <em>building</em> an instance of type {@code T} where {@code T} is unbounded from a wrapped {@linkplain AbstractOrigin origin}.
047 *
048 * @param <T> the type of instances to build.
049 * @param <B> the type of builder subclass.
050 * @since 2.12.0
051 */
052public abstract class AbstractOriginSupplier<T, B extends AbstractOriginSupplier<T, B>> extends AbstractSupplier<T, B> {
053
054    /**
055     * Constructs a new byte array origin for a byte array.
056     *
057     * @param origin the byte array.
058     * @return a new byte array origin.
059     */
060    protected static ByteArrayOrigin newByteArrayOrigin(final byte[] origin) {
061        return new ByteArrayOrigin(origin);
062    }
063
064    /**
065     * Constructs a new channel origin for a channel.
066     *
067     * @param origin the channel.
068     * @return a new channel origin.
069     * @since 2.21.0
070     */
071    protected static ChannelOrigin newChannelOrigin(final Channel origin) {
072        return new ChannelOrigin(origin);
073    }
074
075    /**
076     * Constructs a new CharSequence origin for a CharSequence.
077     *
078     * @param origin the CharSequence.
079     * @return a new file origin.
080     * @since 2.13.0
081     */
082    protected static CharSequenceOrigin newCharSequenceOrigin(final CharSequence origin) {
083        return new CharSequenceOrigin(origin);
084    }
085
086    /**
087     * Constructs a new file origin for a file.
088     *
089     * @param origin the file.
090     * @return a new file origin.
091     */
092    protected static FileOrigin newFileOrigin(final File origin) {
093        return new FileOrigin(origin);
094    }
095
096    /**
097     * Constructs a new file origin for a file path.
098     *
099     * @param origin the file path.
100     * @return a new file origin.
101     */
102    protected static FileOrigin newFileOrigin(final String origin) {
103        return new FileOrigin(new File(origin));
104    }
105
106    /**
107     * Constructs a new input stream origin for a file.
108     *
109     * @param origin the input stream.
110     * @return a new input stream origin.
111     */
112    protected static InputStreamOrigin newInputStreamOrigin(final InputStream origin) {
113        return new InputStreamOrigin(origin);
114    }
115
116    /**
117     * Constructs a new output stream origin for a file.
118     *
119     * @param origin the output stream.
120     * @return a new output stream origin.
121     */
122    protected static OutputStreamOrigin newOutputStreamOrigin(final OutputStream origin) {
123        return new OutputStreamOrigin(origin);
124    }
125
126    /**
127     * Constructs a new path origin for a file.
128     *
129     * @param origin the path.
130     * @return a new path origin.
131     */
132    protected static PathOrigin newPathOrigin(final Path origin) {
133        return new PathOrigin(origin);
134    }
135
136    /**
137     * Constructs a new path name origin for a path name.
138     *
139     * @param origin the path name.
140     * @return a new path name origin.
141     */
142    protected static PathOrigin newPathOrigin(final String origin) {
143        return new PathOrigin(Paths.get(origin));
144    }
145
146    /**
147     * Constructs a new RandomAccessFile origin for a RandomAccessFile.
148     *
149     * @param origin the reader.
150     * @return a new reader origin.
151     * @since 2.18.0
152     */
153    protected static IORandomAccessFileOrigin newRandomAccessFileOrigin(final IORandomAccessFile origin) {
154        return new IORandomAccessFileOrigin(origin);
155    }
156
157    /**
158     * Constructs a new RandomAccessFile origin for a RandomAccessFile.
159     *
160     * @param origin the reader.
161     * @return a new reader origin.
162     * @since 2.18.0
163     */
164    protected static RandomAccessFileOrigin newRandomAccessFileOrigin(final RandomAccessFile origin) {
165        return new RandomAccessFileOrigin(origin);
166    }
167
168    /**
169     * Constructs a new reader origin for a reader.
170     *
171     * @param origin the reader.
172     * @return a new reader origin.
173     */
174    protected static ReaderOrigin newReaderOrigin(final Reader origin) {
175        return new ReaderOrigin(origin);
176    }
177
178    /**
179     * Constructs a new reader origin for a URI.
180     *
181     * @param origin the URI.
182     * @return a new URI origin.
183     */
184    protected static URIOrigin newURIOrigin(final URI origin) {
185        return new URIOrigin(origin);
186    }
187
188    /**
189     * Constructs a new writer origin for a file.
190     *
191     * @param origin the writer.
192     * @return a new writer.
193     */
194    protected static WriterOrigin newWriterOrigin(final Writer origin) {
195        return new WriterOrigin(origin);
196    }
197
198    /**
199     * The underlying origin.
200     */
201    private AbstractOrigin<?, ?> origin;
202
203    /**
204     * Constructs a new instance for subclasses.
205     */
206    public AbstractOriginSupplier() {
207        // empty
208    }
209
210    /**
211     * Checks whether the origin is null.
212     *
213     * @return the origin.
214     * @throws IllegalStateException if the {@code origin} is {@code null}.
215     */
216    protected AbstractOrigin<?, ?> checkOrigin() {
217        if (origin == null) {
218            throw new IllegalStateException("origin == null");
219        }
220        return origin;
221    }
222
223    /**
224     * Gets the origin.
225     *
226     * @return the origin.
227     */
228    protected AbstractOrigin<?, ?> getOrigin() {
229        return origin;
230    }
231
232    /**
233     * Tests whether the origin is null.
234     *
235     * @return whether the origin is null.
236     */
237    protected boolean hasOrigin() {
238        return origin != null;
239    }
240
241    /**
242     * Sets a new origin.
243     *
244     * @param origin the new origin.
245     * @return {@code this} instance.
246     */
247    public B setByteArray(final byte[] origin) {
248        return setOrigin(newByteArrayOrigin(origin));
249    }
250
251    /**
252     * Sets a new origin.
253     *
254     * @param origin the new origin.
255     * @return {@code this} instance.
256     * @since 2.21.0
257     */
258    public B setChannel(final Channel origin) {
259        return setOrigin(newChannelOrigin(origin));
260    }
261
262    /**
263     * Sets a new origin.
264     *
265     * @param origin the new origin.
266     * @return {@code this} instance.
267     * @since 2.13.0
268     */
269    public B setCharSequence(final CharSequence origin) {
270        return setOrigin(newCharSequenceOrigin(origin));
271    }
272
273    /**
274     * Sets a new origin.
275     *
276     * @param origin the new origin.
277     * @return {@code this} instance.
278     */
279    public B setFile(final File origin) {
280        return setOrigin(newFileOrigin(origin));
281    }
282
283    /**
284     * Sets a new origin.
285     *
286     * @param origin the new origin.
287     * @return {@code this} instance.
288     */
289    public B setFile(final String origin) {
290        return setOrigin(newFileOrigin(origin));
291    }
292
293    /**
294     * Sets a new origin.
295     *
296     * @param origin the new origin.
297     * @return {@code this} instance.
298     */
299    public B setInputStream(final InputStream origin) {
300        return setOrigin(newInputStreamOrigin(origin));
301    }
302
303    /**
304     * Sets a new origin.
305     *
306     * @param origin the new origin.
307     * @return {@code this} instance.
308     */
309    protected B setOrigin(final AbstractOrigin<?, ?> origin) {
310        this.origin = origin;
311        return asThis();
312    }
313
314    /**
315     * Sets a new origin.
316     *
317     * @param origin the new origin.
318     * @return {@code this} instance.
319     */
320    public B setOutputStream(final OutputStream origin) {
321        return setOrigin(newOutputStreamOrigin(origin));
322    }
323
324    /**
325     * Sets a new origin.
326     *
327     * @param origin the new origin.
328     * @return {@code this} instance.
329     */
330    public B setPath(final Path origin) {
331        return setOrigin(newPathOrigin(origin));
332    }
333
334    /**
335     * Sets a new origin.
336     *
337     * @param origin the new origin.
338     * @return {@code this} instance.
339     */
340    public B setPath(final String origin) {
341        return setOrigin(newPathOrigin(origin));
342    }
343
344    /**
345     * Sets a new origin.
346     *
347     * @param origin the new origin.
348     * @return {@code this} instance.
349     * @since 2.18.0
350     */
351    public B setRandomAccessFile(final IORandomAccessFile origin) {
352        return setOrigin(newRandomAccessFileOrigin(origin));
353    }
354
355    /**
356     * Sets a new origin.
357     *
358     * @param origin the new origin.
359     * @return {@code this} instance.
360     * @since 2.18.0
361     */
362    public B setRandomAccessFile(final RandomAccessFile origin) {
363        return setOrigin(newRandomAccessFileOrigin(origin));
364    }
365
366    /**
367     * Sets a new origin.
368     *
369     * @param origin the new origin.
370     * @return {@code this} instance.
371     */
372    public B setReader(final Reader origin) {
373        return setOrigin(newReaderOrigin(origin));
374    }
375
376    /**
377     * Sets a new origin.
378     *
379     * @param origin the new origin.
380     * @return {@code this} instance.
381     */
382    public B setURI(final URI origin) {
383        return setOrigin(newURIOrigin(origin));
384    }
385
386    /**
387     * Sets a new origin.
388     *
389     * @param origin the new origin.
390     * @return {@code this} instance.
391     */
392    public B setWriter(final Writer origin) {
393        return setOrigin(newWriterOrigin(origin));
394    }
395}