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 */
017package org.apache.juneau.common.utils;
018
019import static java.util.Optional.*;
020
021import java.io.*;
022import java.nio.charset.*;
023import java.nio.file.*;
024
025/**
026 * Utility class for creating {@link Path}-based {@link Reader} objects.
027 *
028 * @since 9.1.0
029 */
030public class PathReaderBuilder {
031
032   /**
033    * Creates a new builder.
034    *
035    * @return A new builder.
036    */
037   public static PathReaderBuilder create() {
038      return new PathReaderBuilder();
039   }
040
041   /**
042    * Creates a new builder initialized with the specified path.
043    *
044    * @param path The path being written to.
045    * @return A new builder.
046    */
047   public static PathReaderBuilder create(final Path path) {
048      return new PathReaderBuilder().path(path);
049   }
050
051   private Path path;
052
053   private Charset charset = Charset.defaultCharset();
054
055   private boolean allowNoFile;
056
057   /**
058    * If called and the path is <jk>null</jk> or non-existent, then the {@link #build()} command will return an empty reader instead of a {@link IOException}.
059    *
060    * @return This object.
061    */
062   public PathReaderBuilder allowNoFile() {
063      this.allowNoFile = true;
064      return this;
065   }
066
067   /**
068    * Creates a new File reader.
069    *
070    * @return A new File reader.
071    * @throws IOException if an I/O error occurs opening the path
072    */
073   public Reader build() throws IOException {
074      if (!allowNoFile && path == null) {
075         throw new IllegalStateException("No path");
076      }
077      if (!allowNoFile && !Files.exists(path)) {
078         throw new NoSuchFileException(path.toString());
079      }
080      return allowNoFile ? new StringReader("") : Files.newBufferedReader(path, ofNullable(charset).orElse(Charset.defaultCharset()));
081   }
082
083   /**
084    * Sets the character encoding of the path.
085    *
086    * @param charset The character encoding. The default is {@link Charset#defaultCharset()}. Null resets to the default.
087    * @return This object.
088    */
089   public PathReaderBuilder charset(final Charset charset) {
090      this.charset = charset;
091      return this;
092   }
093
094   /**
095    * Sets the character encoding of the path.
096    *
097    * @param charset The character encoding. The default is {@link Charset#defaultCharset()}. Null resets to the default.
098    * @return This object.
099    */
100   public PathReaderBuilder charset(final String charset) {
101      this.charset = charset != null ? Charset.forName(charset) : null;
102      return this;
103   }
104
105   /**
106    * Sets the path being written from.
107    *
108    * @param path The path being written from.
109    * @return This object.
110    */
111   public PathReaderBuilder path(final Path path) {
112      this.path = path;
113      return this;
114   }
115
116   /**
117    * Sets the path of the path being written from.
118    *
119    * @param path The path of the path being written from.
120    * @return This object.
121    */
122   public PathReaderBuilder path(final String path) {
123      this.path = Paths.get(path);
124      return this;
125   }
126}