1 package org.codehaus.plexus.classworlds.launcher;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import java.io.BufferedReader;
20 import java.io.File;
21 import java.io.FileNotFoundException;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.io.InputStreamReader;
25 import java.net.MalformedURLException;
26 import java.net.URL;
27 import java.nio.charset.StandardCharsets;
28 import java.nio.file.Files;
29 import java.nio.file.Paths;
30 import java.util.Properties;
31
32 import org.codehaus.plexus.classworlds.realm.DuplicateRealmException;
33 import org.codehaus.plexus.classworlds.realm.NoSuchRealmException;
34
35
36
37
38
39
40
41
42
43 public class ConfigurationParser {
44 public static final String MAIN_PREFIX = "main is";
45
46 public static final String SET_PREFIX = "set";
47
48 public static final String IMPORT_PREFIX = "import";
49
50 public static final String LOAD_PREFIX = "load";
51
52
53
54
55 public static final String OPTIONALLY_PREFIX = "optionally";
56
57 protected static final String FROM_SEPARATOR = " from ";
58
59 protected static final String USING_SEPARATOR = " using ";
60
61 protected static final String DEFAULT_SEPARATOR = " default ";
62
63 private final ConfigurationHandler handler;
64
65 private final Properties systemProperties;
66
67 public ConfigurationParser(ConfigurationHandler handler, Properties systemProperties) {
68 this.handler = handler;
69 this.systemProperties = systemProperties;
70 }
71
72
73
74
75
76
77
78
79
80
81 public void parse(InputStream is)
82 throws IOException, ConfigurationException, DuplicateRealmException, NoSuchRealmException {
83 try (BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
84
85 String line;
86
87 int lineNo = 0;
88
89 boolean mainSet = false;
90
91 String curRealm = null;
92
93 while (true) {
94 line = reader.readLine();
95
96 if (line == null) {
97 break;
98 }
99
100 ++lineNo;
101 line = line.trim();
102
103 if (canIgnore(line)) {
104 continue;
105 }
106
107 char lineFirstChar = line.charAt(0);
108 switch (lineFirstChar) {
109 case 'm': {
110 if (line.startsWith(MAIN_PREFIX)) {
111 if (mainSet) {
112 throw new ConfigurationException("Duplicate main configuration", lineNo, line);
113 }
114
115 int fromLoc = line.indexOf(FROM_SEPARATOR, MAIN_PREFIX.length());
116
117 if (fromLoc < 0) {
118 throw new ConfigurationException("Missing from clause", lineNo, line);
119 }
120
121 String mainClassName = filter(line.substring(MAIN_PREFIX.length(), fromLoc)
122 .trim());
123
124 String mainRealmName = filter(line.substring(fromLoc + FROM_SEPARATOR.length())
125 .trim());
126
127 this.handler.setAppMain(mainClassName, mainRealmName);
128
129 mainSet = true;
130
131 break;
132 }
133 throw new ConfigurationException("Unhandled configuration", lineNo, line);
134 }
135 case 's': {
136 if (line.startsWith(SET_PREFIX)) {
137 String conf = line.substring(SET_PREFIX.length()).trim();
138
139 int usingLoc = conf.indexOf(USING_SEPARATOR);
140
141 String property = null;
142
143 String propertiesFileName = null;
144
145 if (usingLoc >= 0) {
146 property = conf.substring(0, usingLoc).trim();
147
148 propertiesFileName = filter(conf.substring(usingLoc + USING_SEPARATOR.length())
149 .trim());
150
151 conf = propertiesFileName;
152 }
153
154 String defaultValue = null;
155
156 int defaultLoc = conf.indexOf(DEFAULT_SEPARATOR);
157
158 if (defaultLoc >= 0) {
159 defaultValue = filter(conf.substring(defaultLoc + DEFAULT_SEPARATOR.length())
160 .trim());
161
162 if (property == null) {
163 property = conf.substring(0, defaultLoc).trim();
164 } else {
165 propertiesFileName =
166 conf.substring(0, defaultLoc).trim();
167 }
168 }
169
170 String value = systemProperties.getProperty(property);
171
172 if (value != null) {
173 continue;
174 }
175
176 if (propertiesFileName != null) {
177 File propertiesFile = new File(propertiesFileName);
178
179 if (propertiesFile.exists()) {
180 Properties properties = new Properties();
181
182 try (InputStream inputStream =
183 Files.newInputStream(Paths.get(propertiesFileName))) {
184 properties.load(inputStream);
185 value = properties.getProperty(property);
186 } catch (Exception e) {
187
188 }
189 }
190 }
191
192 if (value == null && defaultValue != null) {
193 value = defaultValue;
194 }
195
196 if (value != null) {
197 value = filter(value);
198 systemProperties.setProperty(property, value);
199 }
200
201 break;
202 }
203 throw new ConfigurationException("Unhandled configuration", lineNo, line);
204 }
205 case '[': {
206 int rbrack = line.indexOf("]");
207
208 if (rbrack < 0) {
209 throw new ConfigurationException("Invalid realm specifier", lineNo, line);
210 }
211
212 String realmName = line.substring(1, rbrack);
213
214 handler.addRealm(realmName);
215
216 curRealm = realmName;
217
218 break;
219 }
220 case 'i': {
221 if (line.startsWith(IMPORT_PREFIX)) {
222 if (curRealm == null) {
223 throw new ConfigurationException("Unhandled import", lineNo, line);
224 }
225 int fromLoc = line.indexOf(FROM_SEPARATOR, IMPORT_PREFIX.length());
226
227 if (fromLoc < 0) {
228 throw new ConfigurationException("Missing from clause", lineNo, line);
229 }
230
231 String importSpec = line.substring(IMPORT_PREFIX.length(), fromLoc)
232 .trim();
233
234 String relamName = line.substring(fromLoc + FROM_SEPARATOR.length())
235 .trim();
236
237 handler.addImportFrom(relamName, importSpec);
238
239 break;
240 }
241 throw new ConfigurationException("Unhandled configuration", lineNo, line);
242 }
243 case 'l': {
244 if (line.startsWith(LOAD_PREFIX)) {
245 String constituent =
246 line.substring(LOAD_PREFIX.length()).trim();
247
248 constituent = filter(constituent);
249
250 if (constituent.contains("*")) {
251 loadGlob(constituent, false );
252 } else {
253 File file = new File(constituent);
254
255 if (file.exists()) {
256 handler.addLoadFile(file);
257 } else {
258 try {
259 handler.addLoadURL(new URL(constituent));
260 } catch (MalformedURLException e) {
261 throw new FileNotFoundException(constituent);
262 }
263 }
264 }
265
266 break;
267 }
268 throw new ConfigurationException("Unhandled configuration", lineNo, line);
269 }
270 case 'o': {
271 if (line.startsWith(OPTIONALLY_PREFIX)) {
272 String constituent =
273 line.substring(OPTIONALLY_PREFIX.length()).trim();
274
275 constituent = filter(constituent);
276
277 if (constituent.contains("*")) {
278 loadGlob(constituent, true );
279 } else {
280 File file = new File(constituent);
281
282 if (file.exists()) {
283 handler.addLoadFile(file);
284 } else {
285 try {
286 handler.addLoadURL(new URL(constituent));
287 } catch (MalformedURLException e) {
288
289 }
290 }
291 }
292
293 break;
294 }
295 throw new ConfigurationException("Unhandled configuration", lineNo, line);
296 }
297 default:
298 throw new ConfigurationException("Unhandled configuration", lineNo, line);
299 }
300 }
301 }
302 }
303
304
305
306
307
308
309
310
311
312
313
314
315 protected void loadGlob(String line, boolean optionally)
316 throws MalformedURLException, FileNotFoundException, ConfigurationException {
317 File globFile = new File(line);
318
319 File dir = globFile.getParentFile();
320 if (!dir.exists()) {
321 if (optionally) {
322 return;
323 } else {
324 throw new FileNotFoundException(dir.toString());
325 }
326 }
327
328 String localName = globFile.getName();
329
330 int starLoc = localName.indexOf("*");
331
332 final String prefix = localName.substring(0, starLoc);
333
334 final String suffix = localName.substring(starLoc + 1);
335
336 File[] matches = dir.listFiles((dir1, name) -> {
337 if (!name.startsWith(prefix)) {
338 return false;
339 }
340
341 if (!name.endsWith(suffix)) {
342 return false;
343 }
344
345 return true;
346 });
347
348 for (File match : matches) {
349 handler.addLoadFile(match);
350 }
351 }
352
353
354
355
356
357
358
359
360
361 protected String filter(String text) throws ConfigurationException {
362 StringBuilder result = new StringBuilder();
363
364 int cur = 0;
365 int textLen = text.length();
366
367 int propStart;
368 int propStop;
369
370 String propName;
371 String propValue;
372
373 while (cur < textLen) {
374 propStart = text.indexOf("${", cur);
375
376 if (propStart < 0) {
377 break;
378 }
379
380 result.append(text, cur, propStart);
381
382 propStop = text.indexOf("}", propStart);
383
384 if (propStop < 0) {
385 throw new ConfigurationException("Unterminated property: " + text.substring(propStart));
386 }
387
388 propName = text.substring(propStart + 2, propStop);
389
390 propValue = systemProperties.getProperty(propName);
391
392
393 if (propName.equals("basedir") && (propValue == null || propValue.equals(""))) {
394 propValue = (new File("")).getAbsolutePath();
395 }
396
397 if (propValue == null) {
398 throw new ConfigurationException("No such property: " + propName);
399 }
400 result.append(propValue);
401
402 cur = propStop + 1;
403 }
404
405 result.append(text.substring(cur));
406
407 return result.toString();
408 }
409
410
411
412
413
414
415
416
417
418 private boolean canIgnore(String line) {
419 return (line.isEmpty() || line.startsWith("#"));
420 }
421 }