1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.mycore.common.config;
20
21 import java.io.ByteArrayInputStream;
22 import java.io.ByteArrayOutputStream;
23 import java.io.File;
24 import java.io.FileInputStream;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.net.URL;
28 import java.nio.charset.StandardCharsets;
29 import java.util.ArrayList;
30 import java.util.Collections;
31 import java.util.Enumeration;
32 import java.util.LinkedList;
33 import java.util.List;
34 import java.util.Properties;
35
36 import org.apache.commons.io.IOUtils;
37 import org.apache.logging.log4j.LogManager;
38 import org.mycore.common.content.MCRContent;
39 import org.mycore.common.content.MCRFileContent;
40 import org.mycore.common.content.MCRURLContent;
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 public class MCRConfigurationInputStream extends InputStream {
56
57 private static final String MYCORE_PROPERTIES = "mycore.properties";
58
59
60 private static final byte[] LINE_BREAK = System.getProperty("line.separator").getBytes(StandardCharsets.ISO_8859_1);
61
62 InputStream in;
63
64 private Enumeration<? extends InputStream> e;
65
66 private boolean empty;
67
68
69
70
71
72
73
74
75 public MCRConfigurationInputStream(String filename) throws IOException {
76 this(filename, null);
77 }
78
79 private MCRConfigurationInputStream(String filename, InputStream initStream) throws IOException {
80 super();
81 this.empty = true;
82 this.e = getPropertyInputStreams(filename, initStream);
83 if (e.hasMoreElements()) {
84 nextStream();
85 }
86 }
87
88
89
90
91
92
93
94
95 public static MCRConfigurationInputStream getMyCoRePropertiesInstance() throws IOException {
96 File configurationDirectory = MCRConfigurationDir.getConfigurationDirectory();
97 InputStream initStream = null;
98 if (configurationDirectory != null) {
99 LogManager.getLogger().info("Current configuration directory: {}",
100 configurationDirectory.getAbsolutePath());
101
102 if (configurationDirectory.isDirectory()) {
103 initStream = getBaseDirInputStream(configurationDirectory);
104 }
105 }
106 return new MCRConfigurationInputStream(MYCORE_PROPERTIES, initStream);
107 }
108
109 public boolean isEmpty() {
110 return empty;
111 }
112
113 private Enumeration<? extends InputStream> getPropertyInputStreams(String filename, InputStream initStream)
114 throws IOException {
115 LinkedList<InputStream> cList = new LinkedList<>();
116 if (initStream != null) {
117 empty = false;
118 cList.add(initStream);
119 }
120 for (MCRComponent component : MCRRuntimeComponentDetector.getAllComponents()) {
121 InputStream is = component.getConfigFileStream(filename);
122 if (is != null) {
123 empty = false;
124 String comment = "\n\n#\n#\n# Component: " + component.getName() + "\n#\n#\n";
125 cList.add(new ByteArrayInputStream(comment.getBytes(StandardCharsets.ISO_8859_1)));
126 cList.add(is);
127
128 cList.add(new ByteArrayInputStream(LINE_BREAK));
129 } else {
130 cList.add(new ByteArrayInputStream(
131 ("# Unable to find " + filename + " in " + component.getResourceBase() + "\n")
132 .getBytes(StandardCharsets.ISO_8859_1)));
133 }
134 }
135 InputStream propertyStream = getConfigFileStream(filename);
136 if (propertyStream != null) {
137 empty = false;
138 cList.add(propertyStream);
139 cList.add(new ByteArrayInputStream(LINE_BREAK));
140 }
141 File localProperties = MCRConfigurationDir.getConfigFile(filename);
142 if (localProperties != null && localProperties.canRead()) {
143 empty = false;
144 LogManager.getLogger().info("Loading additional properties from {}", localProperties.getAbsolutePath());
145 cList.add(new FileInputStream(localProperties));
146 cList.add(new ByteArrayInputStream(LINE_BREAK));
147 }
148 return Collections.enumeration(cList);
149 }
150
151 private static ByteArrayInputStream getBaseDirInputStream(File configurationDirectory) throws IOException {
152 Properties dataProp = new Properties();
153
154 dataProp.setProperty("MCR.basedir", configurationDirectory.getAbsolutePath().replace('\\', '/'));
155 ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
156 dataProp.store(out, null);
157 return new ByteArrayInputStream(out.toByteArray());
158 }
159
160 private static InputStream getConfigFileStream(String filename) throws IOException {
161 File cfgFile = new File(filename);
162 MCRContent input = null;
163 if (cfgFile.canRead()) {
164 input = new MCRFileContent(cfgFile);
165 } else {
166 URL url = MCRConfigurationInputStream.class.getClassLoader().getResource(filename);
167 if (url != null) {
168 input = new MCRURLContent(url);
169 }
170 }
171 return input == null ? null : input.getInputStream();
172 }
173
174
175
176
177
178 public static List<byte[]> getConfigFileContents(String filename) throws IOException {
179 ArrayList<byte[]> cList = new ArrayList<>();
180 for (MCRComponent component : MCRRuntimeComponentDetector.getAllComponents()) {
181 try (InputStream is = component.getConfigFileStream(filename)) {
182 if (is != null) {
183 cList.add(IOUtils.toByteArray(is));
184 }
185 }
186 }
187
188 try (InputStream configStream = getConfigFileStream(filename)) {
189 if (configStream != null) {
190 LogManager.getLogger().debug("Loaded config file from classpath: " + filename);
191 cList.add(IOUtils.toByteArray(configStream));
192 }
193 }
194
195
196 File localConfigFile = MCRConfigurationDir.getConfigFile(filename);
197 if (localConfigFile != null && localConfigFile.canRead()) {
198 LogManager.getLogger().debug("Loaded config file from config dir: " + filename);
199 try (FileInputStream fis = new FileInputStream(localConfigFile)) {
200 cList.add(IOUtils.toByteArray(fis));
201 }
202 }
203 return cList;
204 }
205
206
207
208
209 final void nextStream() throws IOException {
210 if (in != null) {
211 in.close();
212 }
213
214 if (e.hasMoreElements()) {
215 in = e.nextElement();
216 if (in == null) {
217 throw new NullPointerException();
218 }
219 } else {
220 in = null;
221 }
222
223 }
224
225 @Override
226 public int available() throws IOException {
227 if (in == null) {
228 return 0;
229 }
230 return in.available();
231 }
232
233 @Override
234 public int read() throws IOException {
235 if (in == null) {
236 return -1;
237 }
238 int c = in.read();
239 if (c == -1) {
240 nextStream();
241 return read();
242 }
243 return c;
244 }
245
246 @Override
247 public int read(byte[] b, int off, int len) throws IOException {
248 if (in == null) {
249 return -1;
250 }
251
252 int n = in.read(b, off, len);
253 if (n <= 0) {
254 nextStream();
255 return read(b, off, len);
256 }
257 return n;
258 }
259
260 @Override
261 public void close() throws IOException {
262 do {
263 nextStream();
264 } while (in != null);
265 }
266 }