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
    18  package org.apache.logging.log4j.core.config;
    19
    20  import java.io.ByteArrayInputStream;
    21  import java.io.ByteArrayOutputStream;
    22  import java.io.File;
    23  import java.io.FileInputStream;
    24  import java.io.IOException;
    25  import java.io.InputStream;
    26  import java.net.URL;
    27
    28  import org.apache.logging.log4j.core.util.Assert;
    29
    30  /**
    31   * Represents the source for the logging configuration.
    32   */
    33  public class ConfigurationSource {
    34      public static final ConfigurationSource NULL_SOURCE = new ConfigurationSource(new byte[0]);
    35
    36      private final File file;
    37      private final URL url;
    38      private final String location;
    39      private final InputStream stream;
    40      private final byte[] data;
    41
    42      /**
    43       * Returns the contents of the specified {@code InputStream} as a byte array.
    44       *
    45       * @param inputStream the stream to read
    46       * @return the contents of the specified stream
    47       * @throws IOException if a problem occurred reading from the stream
    48       */
    49      private static byte[] toByteArray(final InputStream inputStream) throws IOException {
    50          final int buffSize = Math.max(4096, inputStream.available());
    51          final ByteArrayOutputStream contents = new ByteArrayOutputStream(buffSize);
    52          final byte[] buff = new byte[buffSize];
    53
    54          int length = inputStream.read(buff);
    55          while (length > 0) {
    56              contents.write(buff, 0, length);
    57              length = inputStream.read(buff);
    58          }
    59          return contents.toByteArray();
    60      }
    61
    62      /**
    63       * Constructs a new {@code ConfigurationSource} with the specified input stream. Since the stream is the only source
    64       * of data, this constructor makes a copy of the stream contents.
    65       *
    66       * @param stream the input stream
    67       * @throws IOException if an exception occurred reading from the specified stream
    68       */
    69      public ConfigurationSource(final InputStream stream) throws IOException {
    70          this(toByteArray(stream));
    71      }
    72
    73      private ConfigurationSource(final byte[] data) {
    74          this.data = Assert.requireNonNull(data, "data is null");
    75          this.stream = new ByteArrayInputStream(data);
    76          this.file = null;
    77          this.url = null;
    78          this.location = null;
    79      }
    80
    81      /**
    82       * Constructs a new {@code ConfigurationSource} with the specified input stream that originated from the specified
    83       * file.
    84       *
    85       * @param stream the input stream
    86       * @param file the file where the input stream originated
    87       */
    88      public ConfigurationSource(final InputStream stream, final File file) {
    89          this.stream = Assert.requireNonNull(stream, "stream is null");
    90          this.file = Assert.requireNonNull(file, "file is null");
    91          this.location = file.getAbsolutePath();
    92          this.url = null;
    93          this.data = null;
    94      }
    95
    96      /**
    97       * Constructs a new {@code ConfigurationSource} with the specified input stream that originated from the specified
    98       * url.
    99       *
    100      * @param stream the input stream
    101      * @param url the URL where the input stream originated
    102      */
    103     public ConfigurationSource(final InputStream stream, final URL url) {
    104         this.stream = Assert.requireNonNull(stream, "stream is null");
    105         this.url = Assert.requireNonNull(url, "URL is null");
    106         this.location = url.toString();
    107         this.file = null;
    108         this.data = null;
    109     }
    110
    111     /**
    112      * Returns the file configuration source, or {@code null} if this configuration source is based on an URL or has
    113      * neither a file nor an URL.
    114      *
    115      * @return the configuration source file, or {@code null}
    116      */
    117     public File getFile() {
    118         return file;
    119     }
    120
    121     /**
    122      * Returns the configuration source URL, or {@code null} if this configuration source is based on a file or has
    123      * neither a file nor an URL.
    124      *
    125      * @return the configuration source URL, or {@code null}
    126      */
    127     public URL getURL() {
    128         return url;
    129     }
    130
    131     /**
    132      * Returns a string describing the configuration source file or URL, or {@code null} if this configuration source
    133      * has neither a file nor an URL.
    134      *
    135      * @return a string describing the configuration source file or URL, or {@code null}
    136      */
    137     public String getLocation() {
    138         return location;
    139     }
    140
    141     /**
    142      * Returns the input stream that this configuration source was constructed with.
    143      *
    144      * @return the input stream that this configuration source was constructed with.
    145      */
    146     public InputStream getInputStream() {
    147         return stream;
    148     }
    149
    150     /**
    151      * Returns a new {@code ConfigurationSource} whose input stream is reset to the beginning.
    152      *
    153      * @return a new {@code ConfigurationSource}
    154      * @throws IOException if a problem occurred while opening the new input stream
    155      */
    156     public ConfigurationSource resetInputStream() throws IOException {
    157         if (file != null) {
    158             return new ConfigurationSource(new FileInputStream(file), file);
    159         } else if (url != null) {
    160             return new ConfigurationSource(url.openStream(), url);
    161         } else {
    162             return new ConfigurationSource(data);
    163         }
    164     }
    165
    166     @Override
    167     public String toString() {
    168         if (location != null) {
    169             return location;
    170         }
    171         if (this == NULL_SOURCE) {
    172             return "NULL_SOURCE";
    173         }
    174         final int length = data == null ? -1 : data.length;
    175         return "stream (" + length + " bytes, unknown location)";
    176     }
    177 }