diff --git a/src/main/java/org/codehaus/plexus/classworlds/launcher/ConfigurationParser.java b/src/main/java/org/codehaus/plexus/classworlds/launcher/ConfigurationParser.java
index cdec4fb..7f9f5b1 100644
--- a/src/main/java/org/codehaus/plexus/classworlds/launcher/ConfigurationParser.java
+++ b/src/main/java/org/codehaus/plexus/classworlds/launcher/ConfigurationParser.java
@@ -54,9 +54,15 @@ public class ConfigurationParser {
*/
public static final String OPTIONALLY_PREFIX = "optionally";
- private ConfigurationHandler handler;
+ protected static final String FROM_SEPARATOR = " from ";
- private Properties systemProperties;
+ protected static final String USING_SEPARATOR = " using ";
+
+ protected static final String DEFAULT_SEPARATOR = " default ";
+
+ private final ConfigurationHandler handler;
+
+ private final Properties systemProperties;
public ConfigurationParser(ConfigurationHandler handler, Properties systemProperties) {
this.handler = handler;
@@ -74,188 +80,225 @@ public ConfigurationParser(ConfigurationHandler handler, Properties systemProper
*/
public void parse(InputStream is)
throws IOException, ConfigurationException, DuplicateRealmException, NoSuchRealmException {
- BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
- String line;
+ String line;
- int lineNo = 0;
+ int lineNo = 0;
- boolean mainSet = false;
+ boolean mainSet = false;
- String curRealm = null;
+ String curRealm = null;
- while (true) {
- line = reader.readLine();
-
- if (line == null) {
- break;
- }
-
- ++lineNo;
- line = line.trim();
-
- if (canIgnore(line)) {
- continue;
- }
+ while (true) {
+ line = reader.readLine();
- if (line.startsWith(MAIN_PREFIX)) {
- if (mainSet) {
- throw new ConfigurationException("Duplicate main configuration", lineNo, line);
+ if (line == null) {
+ break;
}
- String conf = line.substring(MAIN_PREFIX.length()).trim();
+ ++lineNo;
+ line = line.trim();
- int fromLoc = conf.indexOf("from");
-
- if (fromLoc < 0) {
- throw new ConfigurationException("Missing from clause", lineNo, line);
+ if (canIgnore(line)) {
+ continue;
}
- String mainClassName = filter(conf.substring(0, fromLoc).trim());
+ char lineFirstChar = line.charAt(0);
+ switch (lineFirstChar) {
+ case 'm': {
+ if (line.startsWith(MAIN_PREFIX)) {
+ if (mainSet) {
+ throw new ConfigurationException("Duplicate main configuration", lineNo, line);
+ }
- String mainRealmName = filter(conf.substring(fromLoc + 4).trim());
+ int fromLoc = line.indexOf(FROM_SEPARATOR, MAIN_PREFIX.length());
- this.handler.setAppMain(mainClassName, mainRealmName);
+ if (fromLoc < 0) {
+ throw new ConfigurationException("Missing from clause", lineNo, line);
+ }
- mainSet = true;
- } else if (line.startsWith(SET_PREFIX)) {
- String conf = line.substring(SET_PREFIX.length()).trim();
+ String mainClassName = filter(line.substring(MAIN_PREFIX.length(), fromLoc)
+ .trim());
- int usingLoc = conf.indexOf(" using") + 1;
+ String mainRealmName = filter(line.substring(fromLoc + FROM_SEPARATOR.length())
+ .trim());
- String property = null;
+ this.handler.setAppMain(mainClassName, mainRealmName);
- String propertiesFileName = null;
+ mainSet = true;
- if (usingLoc > 0) {
- property = conf.substring(0, usingLoc).trim();
+ break;
+ }
+ throw new ConfigurationException("Unhandled configuration", lineNo, line);
+ }
+ case 's': {
+ if (line.startsWith(SET_PREFIX)) {
+ String conf = line.substring(SET_PREFIX.length()).trim();
- propertiesFileName = filter(conf.substring(usingLoc + 5).trim());
+ int usingLoc = conf.indexOf(USING_SEPARATOR);
- conf = propertiesFileName;
- }
+ String property = null;
- String defaultValue = null;
+ String propertiesFileName = null;
- int defaultLoc = conf.indexOf(" default") + 1;
+ if (usingLoc >= 0) {
+ property = conf.substring(0, usingLoc).trim();
- if (defaultLoc > 0) {
- defaultValue = filter(conf.substring(defaultLoc + 7).trim());
+ propertiesFileName = filter(conf.substring(usingLoc + USING_SEPARATOR.length())
+ .trim());
- if (property == null) {
- property = conf.substring(0, defaultLoc).trim();
- } else {
- propertiesFileName = conf.substring(0, defaultLoc).trim();
- }
- }
+ conf = propertiesFileName;
+ }
- String value = systemProperties.getProperty(property);
+ String defaultValue = null;
- if (value != null) {
- continue;
- }
+ int defaultLoc = conf.indexOf(DEFAULT_SEPARATOR);
- if (propertiesFileName != null) {
- File propertiesFile = new File(propertiesFileName);
+ if (defaultLoc >= 0) {
+ defaultValue = filter(conf.substring(defaultLoc + DEFAULT_SEPARATOR.length())
+ .trim());
- if (propertiesFile.exists()) {
- Properties properties = new Properties();
+ if (property == null) {
+ property = conf.substring(0, defaultLoc).trim();
+ } else {
+ propertiesFileName =
+ conf.substring(0, defaultLoc).trim();
+ }
+ }
- try {
- properties.load(Files.newInputStream(Paths.get(propertiesFileName)));
+ String value = systemProperties.getProperty(property);
- value = properties.getProperty(property);
- } catch (Exception e) {
- // do nothing
- }
- }
- }
+ if (value != null) {
+ continue;
+ }
- if (value == null && defaultValue != null) {
- value = defaultValue;
- }
+ if (propertiesFileName != null) {
+ File propertiesFile = new File(propertiesFileName);
- if (value != null) {
- value = filter(value);
- systemProperties.setProperty(property, value);
- }
- } else if (line.startsWith("[")) {
- int rbrack = line.indexOf("]");
+ if (propertiesFile.exists()) {
+ Properties properties = new Properties();
- if (rbrack < 0) {
- throw new ConfigurationException("Invalid realm specifier", lineNo, line);
- }
+ try (InputStream inputStream =
+ Files.newInputStream(Paths.get(propertiesFileName))) {
+ properties.load(inputStream);
+ value = properties.getProperty(property);
+ } catch (Exception e) {
+ // do nothing
+ }
+ }
+ }
- String realmName = line.substring(1, rbrack);
+ if (value == null && defaultValue != null) {
+ value = defaultValue;
+ }
- handler.addRealm(realmName);
+ if (value != null) {
+ value = filter(value);
+ systemProperties.setProperty(property, value);
+ }
- curRealm = realmName;
- } else if (line.startsWith(IMPORT_PREFIX)) {
- if (curRealm == null) {
- throw new ConfigurationException("Unhandled import", lineNo, line);
- }
+ break;
+ }
+ throw new ConfigurationException("Unhandled configuration", lineNo, line);
+ }
+ case '[': {
+ int rbrack = line.indexOf("]");
- String conf = line.substring(IMPORT_PREFIX.length()).trim();
+ if (rbrack < 0) {
+ throw new ConfigurationException("Invalid realm specifier", lineNo, line);
+ }
- int fromLoc = conf.indexOf("from");
+ String realmName = line.substring(1, rbrack);
- if (fromLoc < 0) {
- throw new ConfigurationException("Missing from clause", lineNo, line);
- }
+ handler.addRealm(realmName);
- String importSpec = conf.substring(0, fromLoc).trim();
+ curRealm = realmName;
- String relamName = conf.substring(fromLoc + 4).trim();
+ break;
+ }
+ case 'i': {
+ if (line.startsWith(IMPORT_PREFIX)) {
+ if (curRealm == null) {
+ throw new ConfigurationException("Unhandled import", lineNo, line);
+ }
+ int fromLoc = line.indexOf(FROM_SEPARATOR, IMPORT_PREFIX.length());
- handler.addImportFrom(relamName, importSpec);
+ if (fromLoc < 0) {
+ throw new ConfigurationException("Missing from clause", lineNo, line);
+ }
- } else if (line.startsWith(LOAD_PREFIX)) {
- String constituent = line.substring(LOAD_PREFIX.length()).trim();
+ String importSpec = line.substring(IMPORT_PREFIX.length(), fromLoc)
+ .trim();
- constituent = filter(constituent);
+ String relamName = line.substring(fromLoc + FROM_SEPARATOR.length())
+ .trim();
- if (constituent.contains("*")) {
- loadGlob(constituent, false /*not optionally*/);
- } else {
- File file = new File(constituent);
+ handler.addImportFrom(relamName, importSpec);
- if (file.exists()) {
- handler.addLoadFile(file);
- } else {
- try {
- handler.addLoadURL(new URL(constituent));
- } catch (MalformedURLException e) {
- throw new FileNotFoundException(constituent);
+ break;
}
+ throw new ConfigurationException("Unhandled configuration", lineNo, line);
}
- }
- } else if (line.startsWith(OPTIONALLY_PREFIX)) {
- String constituent = line.substring(OPTIONALLY_PREFIX.length()).trim();
-
- constituent = filter(constituent);
-
- if (constituent.contains("*")) {
- loadGlob(constituent, true /*optionally*/);
- } else {
- File file = new File(constituent);
-
- if (file.exists()) {
- handler.addLoadFile(file);
- } else {
- try {
- handler.addLoadURL(new URL(constituent));
- } catch (MalformedURLException e) {
- // swallow
+ case 'l': {
+ if (line.startsWith(LOAD_PREFIX)) {
+ String constituent =
+ line.substring(LOAD_PREFIX.length()).trim();
+
+ constituent = filter(constituent);
+
+ if (constituent.contains("*")) {
+ loadGlob(constituent, false /*not optionally*/);
+ } else {
+ File file = new File(constituent);
+
+ if (file.exists()) {
+ handler.addLoadFile(file);
+ } else {
+ try {
+ handler.addLoadURL(new URL(constituent));
+ } catch (MalformedURLException e) {
+ throw new FileNotFoundException(constituent);
+ }
+ }
+ }
+
+ break;
}
+ throw new ConfigurationException("Unhandled configuration", lineNo, line);
}
+ case 'o': {
+ if (line.startsWith(OPTIONALLY_PREFIX)) {
+ String constituent =
+ line.substring(OPTIONALLY_PREFIX.length()).trim();
+
+ constituent = filter(constituent);
+
+ if (constituent.contains("*")) {
+ loadGlob(constituent, true /*optionally*/);
+ } else {
+ File file = new File(constituent);
+
+ if (file.exists()) {
+ handler.addLoadFile(file);
+ } else {
+ try {
+ handler.addLoadURL(new URL(constituent));
+ } catch (MalformedURLException e) {
+ // swallow
+ }
+ }
+ }
+
+ break;
+ }
+ throw new ConfigurationException("Unhandled configuration", lineNo, line);
+ }
+ default:
+ throw new ConfigurationException("Unhandled configuration", lineNo, line);
}
- } else {
- throw new ConfigurationException("Unhandled configuration", lineNo, line);
}
}
-
- reader.close();
}
/**
@@ -373,6 +416,6 @@ protected String filter(String text) throws ConfigurationException {
* otherwise false
.
*/
private boolean canIgnore(String line) {
- return (line.length() == 0 || line.startsWith("#"));
+ return (line.isEmpty() || line.startsWith("#"));
}
}
diff --git a/src/test/java/org/codehaus/plexus/classworlds/launcher/ConfiguratorTest.java b/src/test/java/org/codehaus/plexus/classworlds/launcher/ConfiguratorTest.java
index 526a814..ddbd86a 100644
--- a/src/test/java/org/codehaus/plexus/classworlds/launcher/ConfiguratorTest.java
+++ b/src/test/java/org/codehaus/plexus/classworlds/launcher/ConfiguratorTest.java
@@ -303,6 +303,40 @@ void testSet_Using_Filtered_Default() throws Exception {
assertEquals(System.getProperty("user.home") + "/m2", System.getProperty("set.using.filtered.default"));
}
+ @Test
+ void testFromFromFrom() throws Exception {
+ this.configurator.configure(getConfigPath("valid-from-from-from.conf"));
+
+ assertEquals("com.from.from.from.Main", this.launcher.getMainClassName());
+
+ assertEquals("from", this.launcher.getMainRealmName());
+
+ ClassWorld world = this.launcher.getWorld();
+
+ {
+ ClassRealm realm = world.getRealm("ant");
+ Collection importRealms = realm.getImportRealms();
+ assertEquals(1, importRealms.size());
+ assertEquals("from", importRealms.stream().findFirst().get().getId());
+ }
+ {
+ ClassRealm realm = world.getRealm("maven");
+ Collection importRealms = realm.getImportRealms();
+ assertEquals(1, importRealms.size());
+ assertEquals("from", importRealms.stream().findFirst().get().getId());
+ }
+ {
+ ClassRealm realm = world.getRealm("glob");
+ Collection importRealms = realm.getImportRealms();
+ assertEquals(0, importRealms.size());
+ }
+ {
+ ClassRealm realm = world.getRealm("from");
+ Collection importRealms = realm.getImportRealms();
+ assertEquals(0, importRealms.size());
+ }
+ }
+
private FileInputStream getConfigPath(String name) throws Exception {
return new FileInputStream(new File(new File(TestUtil.getBasedir(), "src/test/test-data"), name));
}
diff --git a/src/test/test-data/from-from-0.0.1-from-load-import.jar b/src/test/test-data/from-from-0.0.1-from-load-import.jar
new file mode 100644
index 0000000..1688b67
Binary files /dev/null and b/src/test/test-data/from-from-0.0.1-from-load-import.jar differ
diff --git a/src/test/test-data/valid-from-from-from.conf b/src/test/test-data/valid-from-from-from.conf
new file mode 100644
index 0000000..e4bcf8a
--- /dev/null
+++ b/src/test/test-data/valid-from-from-from.conf
@@ -0,0 +1,24 @@
+
+# ------------------------------------------------------------
+# Define the main entry-point
+# ------------------------------------------------------------
+
+main is com.from.from.from.Main from from
+
+# ------------------------------------------------------------
+# Start defining realms
+# ------------------------------------------------------------
+
+[from]
+ load ${basedir}/src/test/test-data/from-from-0.0.1-from-load-import.jar
+
+[ant]
+ import com.from.from.from from from
+ load ${basedir}/target/test-lib/ant-1.10.14.jar
+
+[maven]
+ import com.from.from.from from from
+ load ${basedir}/target/test-lib/log4j-api-2.23.1.jar
+
+[glob]
+ load ${basedir}/src/test/test-data/*.jar