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.logging.log4j.core.config; 019 020import java.io.ByteArrayInputStream; 021import java.io.ByteArrayOutputStream; 022import java.io.File; 023import java.io.FileInputStream; 024import java.io.IOException; 025import java.io.InputStream; 026import java.net.URL; 027import java.util.Objects; 028 029/** 030 * Represents the source for the logging configuration. 031 */ 032public class ConfigurationSource { 033 /** 034 * ConfigurationSource to use with Configurations that do not require a "real" configuration source. 035 */ 036 public static final ConfigurationSource NULL_SOURCE = new ConfigurationSource(new byte[0]); 037 038 private final File file; 039 private final URL url; 040 private final String location; 041 private final InputStream stream; 042 private final byte[] data; 043 044 /** 045 * Constructs a new {@code ConfigurationSource} with the specified input stream that originated from the specified 046 * file. 047 * 048 * @param stream the input stream 049 * @param file the file where the input stream originated 050 */ 051 public ConfigurationSource(final InputStream stream, final File file) { 052 this.stream = Objects.requireNonNull(stream, "stream is null"); 053 this.file = Objects.requireNonNull(file, "file is null"); 054 this.location = file.getAbsolutePath(); 055 this.url = null; 056 this.data = null; 057 } 058 059 /** 060 * Constructs a new {@code ConfigurationSource} with the specified input stream that originated from the specified 061 * url. 062 * 063 * @param stream the input stream 064 * @param url the URL where the input stream originated 065 */ 066 public ConfigurationSource(final InputStream stream, final URL url) { 067 this.stream = Objects.requireNonNull(stream, "stream is null"); 068 this.url = Objects.requireNonNull(url, "URL is null"); 069 this.location = url.toString(); 070 this.file = null; 071 this.data = null; 072 } 073 074 /** 075 * Constructs a new {@code ConfigurationSource} with the specified input stream. Since the stream is the only source 076 * of data, this constructor makes a copy of the stream contents. 077 * 078 * @param stream the input stream 079 * @throws IOException if an exception occurred reading from the specified stream 080 */ 081 public ConfigurationSource(final InputStream stream) throws IOException { 082 this(toByteArray(stream)); 083 } 084 085 private ConfigurationSource(final byte[] data) { 086 this.data = Objects.requireNonNull(data, "data is null"); 087 this.stream = new ByteArrayInputStream(data); 088 this.file = null; 089 this.url = null; 090 this.location = null; 091 } 092 093 /** 094 * Returns the contents of the specified {@code InputStream} as a byte array. 095 * 096 * @param inputStream the stream to read 097 * @return the contents of the specified stream 098 * @throws IOException if a problem occurred reading from the stream 099 */ 100 private static byte[] toByteArray(final InputStream inputStream) throws IOException { 101 final int buffSize = Math.max(4096, inputStream.available()); 102 final ByteArrayOutputStream contents = new ByteArrayOutputStream(buffSize); 103 final byte[] buff = new byte[buffSize]; 104 105 int length = inputStream.read(buff); 106 while (length > 0) { 107 contents.write(buff, 0, length); 108 length = inputStream.read(buff); 109 } 110 return contents.toByteArray(); 111 } 112 113 /** 114 * Returns the file configuration source, or {@code null} if this configuration source is based on an URL or has 115 * neither a file nor an URL. 116 * 117 * @return the configuration source file, or {@code null} 118 */ 119 public File getFile() { 120 return file; 121 } 122 123 /** 124 * Returns the configuration source URL, or {@code null} if this configuration source is based on a file or has 125 * neither a file nor an URL. 126 * 127 * @return the configuration source URL, or {@code null} 128 */ 129 public URL getURL() { 130 return url; 131 } 132 133 /** 134 * Returns a string describing the configuration source file or URL, or {@code null} if this configuration source 135 * has neither a file nor an URL. 136 * 137 * @return a string describing the configuration source file or URL, or {@code null} 138 */ 139 public String getLocation() { 140 return location; 141 } 142 143 /** 144 * Returns the input stream that this configuration source was constructed with. 145 * 146 * @return the input stream that this configuration source was constructed with. 147 */ 148 public InputStream getInputStream() { 149 return stream; 150 } 151 152 /** 153 * Returns a new {@code ConfigurationSource} whose input stream is reset to the beginning. 154 * 155 * @return a new {@code ConfigurationSource} 156 * @throws IOException if a problem occurred while opening the new input stream 157 */ 158 public ConfigurationSource resetInputStream() throws IOException { 159 if (file != null) { 160 return new ConfigurationSource(new FileInputStream(file), file); 161 } else if (url != null) { 162 return new ConfigurationSource(url.openStream(), url); 163 } else { 164 return new ConfigurationSource(data); 165 } 166 } 167 168 @Override 169 public String toString() { 170 if (location != null) { 171 return location; 172 } 173 if (this == NULL_SOURCE) { 174 return "NULL_SOURCE"; 175 } 176 final int length = data == null ? -1 : data.length; 177 return "stream (" + length + " bytes, unknown location)"; 178 } 179}