diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java b/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java
index 853c60ae7d7..b8fc9a8cd77 100644
--- a/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java
+++ b/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java
@@ -52,6 +52,8 @@ import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Pattern;
+import org.eclipse.jetty.start.StartIni.IncludeListener;
+
/*-------------------------------------------*/
/**
*
@@ -63,7 +65,7 @@ import java.util.regex.Pattern;
* The behaviour of Main is controlled by the parsing of the {@link Config} "org/eclipse/start/start.config" file obtained as a resource or file.
*
*/
-public class Main
+public class Main implements IncludeListener
{
private static final String START_LOG_FILENAME = "start.log";
private static final SimpleDateFormat START_LOG_ROLLOVER_DATEFORMAT = new SimpleDateFormat("yyyy_MM_dd-HHmmSSSSS.'" + START_LOG_FILENAME + "'");
@@ -212,20 +214,7 @@ public class Main
{
String name = arg.substring(6);
File file = _config.getHomeBase().getFile(name);
- StartIni startini = new StartIni(file);
- int idx;
- while ((idx = startini.lineIndexOf(0,Pattern.compile("^.*/$"))) >= 0)
- {
- String subPath = startini.getLines().get(idx);
- startini.getLines().remove(idx);
- // find the sub ini files (based on HomeBase)
- List childInis = _config.getHomeBase().listFiles(subPath,new FS.IniFilter());
- for (File childIni : childInis)
- {
- StartIni cini = new StartIni(childIni);
- idx += startini.overlayAt(idx,cini);
- }
- }
+ StartIni startini = new StartIni(file,this);
arguments.addAll(i + 1,startini.getLines());
}
@@ -380,6 +369,17 @@ public class Main
return xmls;
}
+
+ @Override
+ public List onIniInclude(String path) throws IOException
+ {
+ List included = new ArrayList<>();
+ for(File file: _config.getHomeBase().listFiles(path,new FS.IniFilter()))
+ {
+ included.add(new StartIni(file));
+ }
+ return included;
+ }
private void download(String arg)
{
diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/StartIni.java b/jetty-start/src/main/java/org/eclipse/jetty/start/StartIni.java
index ab4c477191c..59a574793cd 100644
--- a/jetty-start/src/main/java/org/eclipse/jetty/start/StartIni.java
+++ b/jetty-start/src/main/java/org/eclipse/jetty/start/StartIni.java
@@ -34,10 +34,20 @@ import java.util.regex.Pattern;
*/
public class StartIni implements Iterable
{
+ public static interface IncludeListener
+ {
+ public List onIniInclude(String path) throws IOException;
+ }
+
private final File file;
private final LinkedList lines;
public StartIni(File file) throws FileNotFoundException, IOException
+ {
+ this(file,null);
+ }
+
+ public StartIni(File file, IncludeListener listener) throws FileNotFoundException, IOException
{
this.file = file;
this.lines = new LinkedList<>();
@@ -54,48 +64,68 @@ public class StartIni implements Iterable
// skip (empty line)
continue;
}
+
if (line.charAt(0) == '#')
{
// skip (comment)
continue;
}
- // Smart Handling, split into multiple OPTIONS lines
+ // Smart Handling, split into multiple OPTIONS lines (for dup check reasons)
if (line.startsWith("OPTIONS="))
{
- for (String part : line.split(","))
+ int idx = line.indexOf('=');
+ String value = line.substring(idx + 1);
+ for (String part : value.split(","))
{
- lines.add("OPTIONS=" + part);
+ addUniqueLine("OPTION=" + part);
+ }
+ }
+ // Smart Handling, includes
+ else if (line.endsWith("/"))
+ {
+ if (listener == null)
+ {
+ System.err.printf("Nested includes not supported: %s (found in %s)%n",line,file.getAbsolutePath());
+ }
+ else
+ {
+ // Collect HomeBase resolved included StartIni's
+ for (StartIni included : listener.onIniInclude(line))
+ {
+ // Merge each line with prior lines to prevent duplicates
+ for (String includedLine : included)
+ {
+ addUniqueLine(includedLine);
+ }
+ }
}
}
else
{
// Add line as-is
- lines.add(line);
+ addUniqueLine(line);
}
}
}
}
}
+ private void addUniqueLine(String line)
+ {
+ if (lines.contains(line))
+ {
+ // skip
+ return;
+ }
+ lines.add(line);
+ }
+
public File getFile()
{
return file;
}
- public int lineIndexOf(int offset, Pattern pattern)
- {
- int len = lines.size();
- for (int i = offset; i < len; i++)
- {
- if (pattern.matcher(lines.get(i)).matches())
- {
- return i;
- }
- }
- return -1;
- }
-
public List getLineMatches(Pattern pattern)
{
List ret = new ArrayList<>();
@@ -119,31 +149,4 @@ public class StartIni implements Iterable
{
return lines.iterator();
}
-
- public int overlayAt(int index, StartIni child)
- {
- int idx = index;
- int count = 0;
- for (String line : child)
- {
- if (this.hasLine(line))
- {
- // skip
- continue;
- }
- lines.add(idx++,line);
- count++;
- }
- return count;
- }
-
- private boolean hasLine(String line)
- {
- return lines.contains(line);
- }
-
- public void removeLine(String line)
- {
- lines.remove(line);
- }
}
diff --git a/jetty-start/src/test/java/org/eclipse/jetty/start/MainTest.java b/jetty-start/src/test/java/org/eclipse/jetty/start/MainTest.java
index 69a5c6c5552..6d643258d34 100644
--- a/jetty-start/src/test/java/org/eclipse/jetty/start/MainTest.java
+++ b/jetty-start/src/test/java/org/eclipse/jetty/start/MainTest.java
@@ -25,13 +25,12 @@ import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Vector;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
-import org.hamcrest.Matchers;
-import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@@ -56,7 +55,8 @@ public class MainTest
{
Main main = new Main();
List xmls = main.processCommandLine(new String[] {});
-
+
+ // Order is important here
List expectedXmls = new ArrayList();
expectedXmls.add("etc/jetty.xml"); // from start.ini
expectedXmls.add("etc/jetty-jmx.xml"); // from start.d/10-jmx.ini
@@ -65,11 +65,26 @@ public class MainTest
expectedXmls.add("etc/jetty-deploy.xml"); // from start.ini
expectedXmls.add("etc/jetty-webapps.xml"); // from start.ini
expectedXmls.add("etc/jetty-contexts.xml"); // from start.ini
-
- Assert.assertThat("XML Resolution Order "+xmls, xmls, contains(expectedXmls.toArray()));
+ assertThat("XML Resolution Order " + xmls,xmls,contains(expectedXmls.toArray()));
+
+ // Order is irrelevant here
Set options = main.getConfig().getOptions();
- assertThat(options,Matchers.contains("Server","ext","jmx","jsp","newOption","resources","websocket"));
+ Set expectedOptions = new HashSet<>();
+ // from start.ini
+ expectedOptions.add("Server");
+ expectedOptions.add("jsp");
+ expectedOptions.add("resources");
+ expectedOptions.add("websocket");
+ expectedOptions.add("ext");
+ expectedOptions.add("newOption");
+ // from start.d/10-jmx.ini
+ expectedOptions.add("jmx");
+ // from start.d/20-websocket.ini
+ expectedOptions.add("websocket");
+ // no options from start.d/90-testrealm.ini
+
+ assertThat("Options " + options,options,containsInAnyOrder(expectedOptions.toArray()));
}
@Test
@@ -99,14 +114,14 @@ public class MainTest
hasItems("/jetty/home with spaces/somejar.jar:/jetty/home with spaces/someotherjar.jar"));
assertThat("args does not contain --exec",commandArgs,hasItems("--exec"));
assertThat("CommandLine should contain jvmArgs",commandArgs,hasItems("-Xms1024m"));
- assertThat("CommandLine should contain jvmArgs", commandArgs, hasItems("-Xmx1024m"));
+ assertThat("CommandLine should contain jvmArgs",commandArgs,hasItems("-Xmx1024m"));
assertThat("CommandLine should contain xmls",commandArgs,hasItems("jetty.xml"));
assertThat("CommandLine should contain xmls",commandArgs,hasItems("jetty-jmx.xml"));
- assertThat("CommandLine should contain xmls", commandArgs, hasItems("jetty-logging.xml"));
+ assertThat("CommandLine should contain xmls",commandArgs,hasItems("jetty-logging.xml"));
String commandLine = cmd.toString();
- assertThat("cmd.toString() should be properly escaped",commandLine,containsString("-cp /jetty/home\\ with\\ " +
- "spaces/somejar.jar:/jetty/home\\ with\\ spaces/someotherjar.jar"));
+ assertThat("cmd.toString() should be properly escaped",commandLine,containsString("-cp /jetty/home\\ with\\ "
+ + "spaces/somejar.jar:/jetty/home\\ with\\ spaces/someotherjar.jar"));
assertThat("cmd.toString() doesn't contain xml config files",commandLine,containsString(" jetty.xml jetty-jmx.xml jetty-logging.xml"));
}