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