1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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.FileNotFoundException;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.net.MalformedURLException;
28 import java.net.URI;
29 import java.net.URISyntaxException;
30 import java.net.URL;
31 import java.net.URLConnection;
32 import java.util.Objects;
33
34 import org.apache.logging.log4j.Level;
35 import org.apache.logging.log4j.core.net.UrlConnectionFactory;
36 import org.apache.logging.log4j.core.util.FileUtils;
37 import org.apache.logging.log4j.core.util.Loader;
38 import org.apache.logging.log4j.core.util.Source;
39 import org.apache.logging.log4j.util.LoaderUtil;
40
41
42
43
44 public class ConfigurationSource {
45
46
47
48
49 public static final ConfigurationSource NULL_SOURCE = new ConfigurationSource(new byte[0], null, 0);
50 private static final String HTTPS = "https";
51 private static final String HTTP = "http";
52
53 private final File file;
54 private final URL url;
55 private final String location;
56 private final InputStream stream;
57 private volatile byte[] data;
58 private volatile Source source = null;
59 private final long lastModified;
60
61 private volatile long modifiedMillis;
62
63
64
65
66
67
68
69
70 public ConfigurationSource(final InputStream stream, final File file) {
71 this.stream = Objects.requireNonNull(stream, "stream is null");
72 this.file = Objects.requireNonNull(file, "file is null");
73 this.location = file.getAbsolutePath();
74 this.url = null;
75 this.data = null;
76 long modified = 0;
77 try {
78 modified = file.lastModified();
79 } catch (Exception ex) {
80
81 }
82 this.lastModified = modified;
83 }
84
85
86
87
88
89
90
91
92 public ConfigurationSource(final InputStream stream, final URL url) {
93 this.stream = Objects.requireNonNull(stream, "stream is null");
94 this.url = Objects.requireNonNull(url, "URL is null");
95 this.location = url.toString();
96 this.file = null;
97 this.data = null;
98 this.lastModified = 0;
99 }
100
101
102
103
104
105
106
107
108
109 public ConfigurationSource(final InputStream stream, final URL url, long lastModified) {
110 this.stream = Objects.requireNonNull(stream, "stream is null");
111 this.url = Objects.requireNonNull(url, "URL is null");
112 this.location = url.toString();
113 this.file = null;
114 this.data = null;
115 this.lastModified = lastModified;
116 }
117
118
119
120
121
122
123
124
125 public ConfigurationSource(final InputStream stream) throws IOException {
126 this(toByteArray(stream), null, 0);
127 }
128
129 public ConfigurationSource(final Source source, final byte[] data, long lastModified) throws IOException {
130 Objects.requireNonNull(source, "source is null");
131 this.data = Objects.requireNonNull(data, "data is null");
132 this.stream = new ByteArrayInputStream(data);
133 this.file = source.getFile();
134 this.url = source.getURI().toURL();
135 this.location = source.getLocation();
136 this.lastModified = lastModified;
137 }
138
139 private ConfigurationSource(final byte[] data, final URL url, long lastModified) {
140 Objects.requireNonNull(data, "data is null");
141 this.stream = new ByteArrayInputStream(data);
142 this.file = null;
143 this.url = url;
144 this.location = null;
145 this.lastModified = lastModified;
146 }
147
148
149
150
151
152
153
154
155 private static byte[] toByteArray(final InputStream inputStream) throws IOException {
156 final int buffSize = Math.max(4096, inputStream.available());
157 final ByteArrayOutputStream contents = new ByteArrayOutputStream(buffSize);
158 final byte[] buff = new byte[buffSize];
159
160 int length = inputStream.read(buff);
161 while (length > 0) {
162 contents.write(buff, 0, length);
163 length = inputStream.read(buff);
164 }
165 return contents.toByteArray();
166 }
167
168
169
170
171
172
173
174 public File getFile() {
175 return file;
176 }
177
178
179
180
181
182
183
184 public URL getURL() {
185 return url;
186 }
187
188 public void setSource(Source source) {
189 this.source = source;
190 }
191
192 public void setData(byte[] data) {
193 this.data = data;
194 }
195
196 public void setModifiedMillis(long modifiedMillis) {
197 this.modifiedMillis = modifiedMillis;
198 }
199
200
201
202
203
204 public URI getURI() {
205 URI sourceURI = null;
206 if (url != null) {
207 try {
208 sourceURI = url.toURI();
209 } catch (final URISyntaxException ex) {
210
211 }
212 }
213 if (sourceURI == null && file != null) {
214 sourceURI = file.toURI();
215 }
216 if (sourceURI == null && location != null) {
217 try {
218 sourceURI = new URI(location);
219 } catch (final URISyntaxException ex) {
220
221 try {
222 sourceURI = new URI("file://" + location);
223 } catch (final URISyntaxException uriEx) {
224
225 }
226 }
227 }
228 return sourceURI;
229 }
230
231
232
233
234
235 public long getLastModified() {
236 return lastModified;
237 }
238
239
240
241
242
243
244
245 public String getLocation() {
246 return location;
247 }
248
249
250
251
252
253
254 public InputStream getInputStream() {
255 return stream;
256 }
257
258
259
260
261
262
263
264 public ConfigurationSource resetInputStream() throws IOException {
265 if (source != null) {
266 return new ConfigurationSource(source, data, this.lastModified);
267 } else if (file != null) {
268 return new ConfigurationSource(new FileInputStream(file), file);
269 } else if (url != null && data != null) {
270
271 return new ConfigurationSource(data, url, modifiedMillis == 0 ? lastModified : modifiedMillis);
272 } else if (url != null) {
273 return fromUri(getURI());
274 } else if (data != null) {
275 return new ConfigurationSource(data, null, lastModified);
276 }
277 return null;
278 }
279
280 @Override
281 public String toString() {
282 if (location != null) {
283 return location;
284 }
285 if (this == NULL_SOURCE) {
286 return "NULL_SOURCE";
287 }
288 final int length = data == null ? -1 : data.length;
289 return "stream (" + length + " bytes, unknown location)";
290 }
291
292
293
294
295
296
297 public static ConfigurationSource fromUri(final URI configLocation) {
298 final File configFile = FileUtils.fileFromUri(configLocation);
299 if (configFile != null && configFile.exists() && configFile.canRead()) {
300 try {
301 return new ConfigurationSource(new FileInputStream(configFile), configFile);
302 } catch (final FileNotFoundException ex) {
303 ConfigurationFactory.LOGGER.error("Cannot locate file {}", configLocation.getPath(), ex);
304 }
305 }
306 if (ConfigurationFactory.isClassLoaderUri(configLocation)) {
307 final ClassLoader loader = LoaderUtil.getThreadContextClassLoader();
308 final String path = ConfigurationFactory.extractClassLoaderUriPath(configLocation);
309 final ConfigurationSource source = fromResource(path, loader);
310 if (source != null) {
311 return source;
312 }
313 }
314 if (!configLocation.isAbsolute()) {
315 ConfigurationFactory.LOGGER.error("File not found in file system or classpath: {}", configLocation.toString());
316 return null;
317 }
318 try {
319 URL url = configLocation.toURL();
320 URLConnection urlConnection = UrlConnectionFactory.createConnection(url);
321 InputStream is = urlConnection.getInputStream();
322 long lastModified = urlConnection.getLastModified();
323 return new ConfigurationSource(is, configLocation.toURL(), lastModified);
324 } catch (final MalformedURLException ex) {
325 ConfigurationFactory.LOGGER.error("Invalid URL {}", configLocation.toString(), ex);
326 } catch (final Exception ex) {
327 ConfigurationFactory.LOGGER.error("Unable to access {}", configLocation.toString(), ex);
328 }
329 return null;
330 }
331
332
333
334
335
336
337
338 public static ConfigurationSource fromResource(final String resource, final ClassLoader loader) {
339 final URL url = Loader.getResource(resource, loader);
340 if (url == null) {
341 return null;
342 }
343 InputStream is = null;
344 try {
345 is = url.openStream();
346 } catch (final IOException ioe) {
347 ConfigurationFactory.LOGGER.catching(Level.DEBUG, ioe);
348 return null;
349 }
350 if (is == null) {
351 return null;
352 }
353
354 if (FileUtils.isFile(url)) {
355 try {
356 return new ConfigurationSource(is, FileUtils.fileFromUri(url.toURI()));
357 } catch (final URISyntaxException ex) {
358
359 ConfigurationFactory.LOGGER.catching(Level.DEBUG, ex);
360 }
361 }
362 return new ConfigurationSource(is, url);
363 }
364 }