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